OpenHarmony深度解读之分布式软总线:auth_interface.c文件部分源码解析

一、概述

auth_interface.c文件主要是提供一些设备间进行身份认证所需要的接口,如认证会话的管理、会话密钥的管理、HiChain的管理等。下面本文将对auth_interface.c文件的部分代码进行分析,因为有的代码会涉及到另一个模块的内容,那一块将会在接下来的文章中进行分析。

二、源码分析

auth_interface.h文件分析:

arduino 复制代码
#ifndef LITE_AUTH_INTERFACE_H   //头文件守卫,防止重复包含
#define LITE_AUTH_INTERFACE_H
#include "auth_conn.h"
#define AUTH_DEFAULT_ID "default"   //默认认证ID
#define AUTH_DEFAULT_ID_LEN 7       //默认认证ID长度
#define AUTH_SESSION_KEY_LEN 16     //认证会话密钥长度
#define AUTH_SESSION_KEY_MAX_NUM 2  //认证会话密钥最大数量
#define AUTH_SESSION_MAX_NUM 2      //认证会话最大数量
/*会话密钥*/
typedef struct SessionKey {
    char key[AUTH_SESSION_KEY_LEN];//会话密钥
    int index;//会话密钥索引
    int fd;//通信套接字描述符
} SessionKey;
/*会话密钥结点*/
typedef struct SessionKeyNode {
    List head;
    SessionKey sKey;//会话密钥结构体
} SessionKeyNode;
/*认证会话信息结构体*/
typedef struct AuthSession {
    int isUsed;//指示当前认证会话是否被使用,0为未被使用,1为已被使用
    long long seqId;//数据包序列号
    uint32_t sessionId;//会话id
    AuthConn *conn;//连接信息
} AuthSession;
void AuthInterfaceOnDataReceived(const AuthConn *conn, int module, long long seqId, const char *data, int dataLen);//处理新数据的函数接口
SessionKey *AuthGetSessionKeyByIndex(int index);//通过索引获取设备认证过程中的会话密钥
SessionKey *AuthGetNewSessionKey(void);//获取新认证会话密钥
void ClearSessionKeyByFd(int fd);//根据fd清除会话密钥
#endif

DD一下: 欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。

erlang 复制代码
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.鸿蒙版性能优化指南
.......

auth_interface.c文件部分代码解析:

ini 复制代码
#include "auth_interface.h"
#include "hichain.h"
#include "securec.h"
#include "auth_conn.h"
#include "bus_manager.h"
#include "os_adapter.h"
#include "wifi_auth_manager.h"
static uint32_t g_authSessionId = 1;//全局认证会话id
static List *g_sessionKeyList = NULL;//全局会话密钥链表表头
static AuthSession *g_authSessionMap = NULL;//全局认证会话表
static hc_handle g_hcHandle = NULL;//
/*
函数功能:认证会话表初始化
函数参数:无
函数返回值:
    成功:返回0
    失败:返回-1
详细:具体就是为全局认证会话表指针g_authSessionMap申请空间并初始化为0
*/
static int AuthSessionMapInit(void)
{
    if (g_authSessionMap != NULL) {
        return 0;
    }
    int len = sizeof(AuthSession) * AUTH_SESSION_MAX_NUM;
    g_authSessionMap = (AuthSession *)malloc(len);
    if (g_authSessionMap == NULL) {
        return -1;
    }
    (void)memset_s(g_authSessionMap, len, 0, len);
    return 0;
}
/*
函数功能:根据SeqId在全局会话表中查找认证会话
函数参数:
    SeqId:数据包序列号
函数返回值:
    成功:返回认证会话首地址
    失败:返回NULL
详细:
*/
static AuthSession *AuthGetAuthSessionBySeqId(long long seqId)
{
    if (g_authSessionMap == NULL) {
        return NULL;
    }
    for (int i = 0; i < AUTH_SESSION_MAX_NUM; i++) {
        if (g_authSessionMap[i].isUsed == 0) {//如果该会话未被使用,则continue
            continue;
        }
        if (g_authSessionMap[i].seqId == seqId) {//查找到seqId对应的认证会话,返回该认证会话地址
            return &g_authSessionMap[i];
        }
    }
    return NULL;
}
/*
函数功能:构造新的认证会话
函数参数:
    conn:连接信息
    seqId:数据包序列号
    sessionId:会话id
函数返回值:
    成功:返回认证会话结构体地址
    失败:返回NULL
详细:
*/
static AuthSession *AuthGetNewAuthSession(const AuthConn *conn, long long seqId, uint32_t sessionId)
{
    if (conn == NULL || g_authSessionMap == NULL) {//边界检查
        return NULL;
    }
    for (int i = 0; i < AUTH_SESSION_MAX_NUM; i++) {
        if (g_authSessionMap[i].isUsed == 0) {//将未被使用的认证会话初始化
            g_authSessionMap[i].isUsed = 1;
            g_authSessionMap[i].seqId = seqId;
            g_authSessionMap[i].sessionId = sessionId;
            g_authSessionMap[i].conn = (AuthConn *)conn;
            return &g_authSessionMap[i];//返回认证会话表中首次被使用的认证会话结构体地址
        }
    }
    return NULL;
}
/*
函数功能:根据fd清除会话密钥
函数参数:
    fd:通信套接字描述符
函数返回值:无
*/
void ClearSessionKeyByFd(int fd)
{
    if (g_sessionKeyList == NULL) {//健壮性检查
        return;
    }
    bool flag = false;//查找成功的标志
    List *pos = NULL;//遍历链表的临时指针
    List *tmp = NULL;
    SessionKeyNode *node = NULL;
    LIST_FOR_EACH_SAFE(pos, tmp, g_sessionKeyList) {//遍历全局认证会话密钥链表
        node = (SessionKeyNode *)pos;
        if (node->sKey.fd == fd) {//根据fd查找到该密钥
            flag = true;
            break;
        }
    }
    if (flag) {
        ListRemoveNode(&(node->head));//将该节点从链表中移除
        free(node);
        node = NULL;
    }
    SOFTBUS_PRINT("[AUTH] ClearSessionKeyByFd(%d) ok\n", fd);
    return;
}
/*
函数功能:通过索引获取设备认证过程中的会话密钥
函数参数:
    index:密钥索引
函数返回值:
    成功:返回会话密钥的结构体地址
    失败:返回NULL
详细:
*/
SessionKey *AuthGetSessionKeyByIndex(int index)
{
    if (g_sessionKeyList == NULL) {
        return NULL;
    }
    List *pos = NULL;
    List *tmp = NULL;
    SessionKeyNode *node = NULL;
    LIST_FOR_EACH_SAFE(pos, tmp, g_sessionKeyList) {//遍历链表,查找满足条件的值
        node = (SessionKeyNode *)pos;
        if (node->sKey.index == index) {
            return &node->sKey;
        }
    }
    return NULL;
}
/*获取新认证会话密钥*/
SessionKey *AuthGetNewSessionKey(void)
{
    if (g_sessionKeyList == NULL) {
        return NULL;
    }
    List *pos = NULL;
    List *tmp = NULL;
    SessionKeyNode *node = NULL;
    SessionKey *sKey = NULL;
    LIST_FOR_EACH_SAFE(pos, tmp, g_sessionKeyList) {//遍历全局认证会话密钥链表
        node = (SessionKeyNode *)pos;
        sKey = &node->sKey;
    }
    return sKey;
}
/*
函数功能:在身份认证过程中,初始化HiChain
函数参数:
    sessionId:会话id
函数返回值:
    成功:返回0
    失败:返回-1
*/
static int AuthInitHiChain(uint32_t sessionId)
{
    SOFTBUS_PRINT("[AUTH] AuthInitHiChain begin\n");
    struct session_identity serverIdentity = {
        sessionId,
        {AUTH_DEFAULT_ID_LEN, AUTH_DEFAULT_ID},
        {AUTH_DEFAULT_ID_LEN, AUTH_DEFAULT_ID},
        0
    };
    struct hc_call_back hiChainCallback = {
        AuthOnTransmit,
        AuthGetProtocolParams,
        AuthSetSessionKey,
        AuthSetServiceResult,
        AuthConfirmReceiveRequest
    };
    g_hcHandle = get_instance(&serverIdentity, HC_ACCESSORY, &hiChainCallback);
    if (g_hcHandle == NULL) {
        return -1;
    }
    SOFTBUS_PRINT("[AUTH] AuthInitHiChain ok\n");
    return 0;
}
/*
函数功能:处理身份认证过程中接收到的数据
函数参数:
    sessionId:会话id
    data:数据负载部分首地址
    dataLen:数据长度
函数返回值:无
详细:
*/
static void AuthProcessReceivedData(uint32_t sessionId, const char *data, int dataLen)
{
    if (g_hcHandle == NULL) {
        if (AuthInitHiChain(sessionId) != 0) {//初始化HiChain
            AuthDelAuthSessionBySessionId(sessionId);//根据sessionId删除该认证会话
            return;
        }
    }
    struct uint8_buff request = {(uint8_t *)data, dataLen, dataLen};//封装request数据
    if (receive_data(g_hcHandle, &request) != HC_OK) {//在其他模块继续处理该数据包
        return;
    }
}
/*
函数功能:若数据包类型为MODULE_AUTH_SDK,则调用本函数进行处理,此函数为认证接口
函数参数:
    conn:当前连接信息
    module:数据包类型
    seqId:数据包序列号
    data:数据负载
    dataLen:负载长度
函数返回值:无
*/
void AuthInterfaceOnDataReceived(const AuthConn *conn, int module, long long seqId, const char *data, int dataLen)
{
    SOFTBUS_PRINT("[AUTH] AuthInterfaceOnDataReceived begin\n");
    if (conn == NULL || data == NULL || dataLen > PACKET_DATA_SIZE) {//若产生越界,则返回
        return;
    }
    if (AuthSessionMapInit() != 0) {//初始化认证会话表
        return;
    }
    AuthSession *auth = AuthGetAuthSessionBySeqId(seqId);//根据SeqId查找认证会话
    if (auth == NULL) {//如果不存在
        auth = AuthGetNewAuthSession(conn, seqId, g_authSessionId);//构造新的认证会话,g_authSessionId初值为1
        if (auth == NULL) {
            return;
        }
        ++g_authSessionId;//全局认证会话id加1
    }
    switch (module) {
        case MODULE_AUTH_SDK://如果数据包类型是MODULE_AUTH_SDK:
            AuthProcessReceivedData(auth->sessionId, data, dataLen);//处理身份认证过程中接收到的数据
            break;
        default:
            break;
    }
    return;
}
相关推荐
kill bert2 分钟前
第30周Java分布式入门 ThreadLocal
java·分布式·wpf
高铭杰2 小时前
Citus源码(1)分布式表行为测试
数据库·分布式·citus
申耀的科技观察2 小时前
【观察】分布式智能云:破解AI转型困局,打通智能化落地“最后一公里”
人工智能·分布式
李游Leo3 小时前
HarmonyOS 之 @Require 装饰器自学指南
harmonyos
SameX3 小时前
HarmonyOS Next ohpm-repo 数据存储安全与多实例高可用部署
前端·harmonyos
ChinaDragon4 小时前
HarmonyOS:通过(SQLite)关系型数据库实现数据持久化
harmonyos
ChinaDragon4 小时前
HarmonyOS:MVVM模式
harmonyos
今阳4 小时前
鸿蒙开发笔记-14-应用上下文Context
android·华为·harmonyos
澜堇4 小时前
企业级部署zabbix分布式监控系统
分布式·zabbix
山河已无恙4 小时前
SpringBoot + SSE + rabbitMQ 实现服务端分布式广播推送
spring boot·分布式·java-rabbitmq