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

79 阅读4分钟

函数实现详解

解析响应消息中的syscap信息
/*
    函数功能:解析响应消息中的syscap信息
    函数参数:@reply:接收的响应信息
             @sysCaps:存放syscap的数组
             @sysCapNum:数组中syscap的个数
             @isEnd:标记是否读取到结尾
             @nextRequestIdx:记录未读取的syscap下标,作为下一次读取操作的起始位置
    函数描述:从接收到的响应消息中解析syscap信息,并存储在sysCaps数组中。
             更新sysCapNum值,记录sysCaps数组中syscap的个数。
             更新isEnd值,记录是否读取到末尾。
             更新nextRequestIdx值,记录未读取的syscap下标,作为下一次读取操作的起始位置
*/
static int32 ParseGetAllSysCapsReply(IpcIo *reply, char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],
                                     int32 *sysCapNum, BOOL *isEnd, uint32 *nextRequestIdx)
{
    //从reply中读取消息
    int32 ret = IpcIoPopInt32(reply);
    if (ret != EC_SUCCESS)
    {
        //若操作失败,则标识读取已结束
        *isEnd = TRUE;
        return ret;
    }
    //操作成功,进行消息解析
    //读取一个bool大小的消息作为isEnd的值
    *isEnd = IpcIoPopBool(reply);
    //读取一个Uint32大小的消息作为nextRequestIdx的值
    *nextRequestIdx = IpcIoPopUint32(reply);
    //读取size值
    uint32 size = IpcIoPopUint32(reply);
    //防止size值超出限制
    size = ((size > MAX_SYSCAP_NUM) ? MAX_SYSCAP_NUM : size);
    //获取syscaps中已有syscap的数目
    int cnt = *sysCapNum;
    //循环读取reply,解析关于syscap的信息
    for (int i = 0; i < size; i++)
    {
        int len = 0;
        //获取len和sysCap
        char *sysCap = (char *)IpcIoPopString(reply, &len);
        if (sysCap == NULL || len == 0)
        {
            continue;
        }
        //拷贝复制
        if (strcpy_s(sysCaps[cnt], sizeof(sysCaps[cnt]), sysCap) != EC_SUCCESS)
        {
            continue;
        }
        cnt++;
    }
    //更新个数
    *sysCapNum = cnt;
    return ret;
}
查询所有的syscap信息
/*
    函数功能:向主endpoint查询所有的syscap
    函数参数:@endpoint:当前进程的通信端点
             @sysCaps:存储syscap的数组
             @sysCapNum:数组中syscap的个数
    函数返回:查询成功 返回EC_SUCCESS,查询失败 返回EC_INVALID
    函数描述:向主endpoint发起查询syscap的请求,若未查询到末尾则不断查询,直到查询到末尾才返回。
             每次循环查询都会从上一次查询的下标开始。
             查询的syscap保存在sysCaps中,并更新sysCapNum的值。
*/
int32 SAMGR_GetSystemCapabilities(const Endpoint *endpoint,
                                  char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum)
{
    //参数检查
    if (sysCapNum == NULL)
    {
        return EC_INVALID;
    }
    //初始值
    *sysCapNum = 0;
    if (endpoint == NULL)
    {
        return EC_INVALID;
    }
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities begin");
    //定义请求结构
    IpcIo reply;
    void *replyBuf = NULL;
    //查询的起始索引
    int startIdx = 0;
    //标记查询操作是否达到末尾
    BOOL isEnd = TRUE;
    int ret;
    do
    {
        //向主endpoint发送查询syscap的请求消息,操作类型为OP_ALL,查询的起始下标为startIdx。响应信息由reply和replyBuf返回
        ret = SendGetAllSysCapsRequest(endpoint, startIdx, &reply, &replyBuf);
        if (ret == EC_SUCCESS)
        {//请求成功
            //从接收到的响应消息中解析syscap信息,并存储在sysCaps数组中。
            //更新sysCapNum值,记录sysCaps数组中syscap的个数。
            //更新isEnd值,记录是否读取到末尾。
            //更新nextRequestIdx值,记录未读取的syscap下标,作为下一次查询操作的起始位置
            ret = ParseGetAllSysCapsReply(&reply, sysCaps, sysCapNum, &isEnd, &startIdx);
        }
        if (replyBuf != NULL)
        {
            //释放内存
            FreeBuffer(endpoint, replyBuf);
        }
    } while (isEnd == FALSE && ret == EC_SUCCESS);//isEnd == FALSE,即还存在syscap待读
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities ret = %d", ret);
    return ret;
}
为endpoint启动监听程序
//为endpoint创建监听,即创建一个线程,用于接收消息
static void Listen(Endpoint *endpoint)
{
    if (endpoint->boss != NULL)
    {
        //已绑定线程,则返回
        return;
    }
    //指定线程属性
    ThreadAttr attr = {endpoint->name, MAX_STACK_SIZE, PRI_ABOVE_NORMAL, 0, 0};
    /*
        为endpoint创建一个线程,用于接收其他进程发送的消息
        @1:创建的线程开始运行的函数地址
        @2:运行函数需要的参数
        @3:线程属性
    */
    endpoint->boss = (ThreadId)THREAD_Create(Receive, endpoint, &attr);
}
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.鸿蒙版性能优化指南
.......
通信代理的比较函数
//比较两个proxy
static int CompareIServerProxy(const IServerProxy *proxy1, const IServerProxy *proxy2)
{
    //比较的是指针存储的地址值
    if (proxy1 == proxy2)
    {
        return 0;
    }
    return (proxy1 > proxy2) ? 1 : -1;
}
获取router中通信代理的键值
//将指定的对象转换为可用作比较的数据
//当前函数即将router的proxy返回,作为比较对象
static IServerProxy *GetIServerProxy(const Router *router)
{
    if (router == NULL)
    {
        return NULL;
    }
    //返回类型IServerProxy的服务端代理
    return router->proxy;
}