前情回顾
上一篇博客中,我们介绍了samgr_server文件下的两个函数封装,大致介绍了封装的函数的实现流程,今天我们将对流程里的一些函数的实现进行深度分析
三个Pro函数的实现
这三个Pro函数分别是:
ProcPutFeature //进程输出特征
ProcGetFeature //进程获取特征
ProcGetAllSysCap //进程获取所有系统能力
ProcPutFeature
static int ProcSysCap(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
函数中调用了多个指针,其中req是客户发出的请求,origin表示req发出的起源端口,可以理解为客户,server则就是接收req并进行回应的服务端,reply则是server对origin发出的请求的回应
现在我们从代码中分析他的实现流程:
首先从req中获取要添加的 service 名字,接着再获取请求方进程的 pid 与 uid,然后检查该终端(endpoint)是否已经注册,返回该终端的 Pidhandle。到这,前期的准备就做好了
这个时候需要进行一个判断:
- 用户是第一次注册
- 用户已经注册过了
注意这段代码:
*identity = SASTORA_Find(&server->store, service, feature);
if (identity->handle != INVALID_INDEX && identity->handle != handle.handle) {
MUTEX_Unlock(server->mtx);
IpcIoPushInt32(reply, EC_INVALID);
return EC_INVALID;
}
identity->token = IpcIoPopUint32(req);
identity->handle = handle.handle;
注意:serviceNode->info.handle与endpoint的handle必须是一样
所以这个时候就来判断:
①如果存在该 feature对应的service,即说明注册过,则其identity应该是与handle一样的。
②如果identity->handle==INVALID_INDEX说明是第一次创建fearure,还没有对应的service结点。
接下来生成policy,与pid,uid对比,检查该进程是否有权限添加该 service 的 feature,若没有,则添加 feature 结点。最后将得到的ret,identity,policy 写入 reply再输出。
可以用一个流程图简单描述该函数的功能实现流程:
ProcGetFeature
进程获取特性,指针的设定还是一样,所以我们直接开始介绍流程。
首先在程序中寻找feature,判断其是否存在,若存在则将handle,token存入identity,然后会在 g_server.SAStore.maps 中查找该 service/feature 的提供方(通过 serviceNode->identity->handle即可找到其 endpoint);
PidHandle providerPid = SASTORA_FindPidHandleByIpcHandle(&server->store, identity->handle);
MUTEX_Unlock(server->mtx);
//若身份满足如下条件,则提示找不到该功能,报错
if (providerPid.pid == INVALID_INDEX || providerPid.uid == INVALID_INDEX) {
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Cannot Find PidHandle<%s, %s> id<%d, %d> ret:%d",
service, feature, identity->handle, identity->token, EC_FAILURE);
return EC_FAILURE;
}
接着检查该请求方是否有权限享受该服务,如果有权限在 identity 中,就会拿到该项服务的 router 下标,从而获得使用该项服务的能力
AuthParams authParams = { //权限认证参数集
.providerService = service,
.providerfeature = feature,
.consumerPid = GetCallingPid(origin),
.consumerUid = GetCallingUid(origin),
.providerPid = providerPid.pid,
.providerUid = providerPid.uid
};
用一个流程图描述该函数的功能的实现流程:
ProcGetAllSysCap
进程获取所有系统能力,顾名思义,该函数将所有有效的 SysCap->name 都写入了 reply 中,
它的功能实现流程如下:
运行时,程序首先统计id的下标位置,并计算出有效的sysCap的数量
//这是最后的答复
IpcIoPushBool(reply, nextRequestIdx == size);
//这是下一个开始idx
IpcIoPushUint32(reply, nextRequestIdx);
最后将所有的有效的sysCap的名称写入reply进行输出
下期预告
不知不觉,已经到了比赛的尾声,接下来就是最后的总结,欢迎收看下期博客**《最终篇——终末的博客》**
相关博客
OpenHarmony模块二下文件samgr_server解析(1)
OpenHarmony模块二下文件samgr_server解析(2)
OpenHarmony模块二下文件samgr_server解析(3)
OpenHarmony模块二下文件samgr_server解析(4)
OpenHarmony模块二下文件samgr_server解析(5)
服务端的那些事儿