往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- 【OpenHarmony】鸿蒙南向开发保姆级知识点汇总~
- OpenHarmony源码分析之分布式软总线:authmanager模块(1)/设备认证连接管理
- OpenHarmony源码分析之分布式软总线:authmanager模块(2)/设备认证通信管理
- OpenHarmony深度解读之分布式软总线:authmanager模块(3)/设备身份认证过程
- OpenHarmony深度解读之分布式软总线:authmanager模块(4)/设备身份认证过程
- OpenHarmony深度解读之分布式软总线:authmanager模块(5)/设备身份认证过程
- 持续更新中……
一、概述
本文将继续介绍设备之间的身份认证过程的相关细节,关于加密数据包的不同类型的处理。本文主要分析数据包类型为MODULE_TRUST_ENGINE的处理过程。源代码主要位于wifi_auth_manager.c文件的函数OnModuleMessageReceived()中。
二、源码分析
- 如果数据包类型为MODULE_TRUST_ENGINE且数据包头部flags字段为FLAG_REPLY,则调用函数OnMsgOpenChannelReq()进行处理。
/*
函数功能:处理对端设备发来的请求消息并做相应回复
函数参数:
conn:设备连接信息
seq:数据包序列号
msg:cJSON格式的数据负载
函数返回值:无
详细:
*/
void OnMsgOpenChannelReq(AuthConn *conn, long long seq, const cJSON *msg)
{
int ret = MsgGetDeviceIdUnPack(msg, conn);//解析消息获取设备id(deviceId)和认证id(authId)保存在conn中
if (ret != 0) {
CloseConn(conn);
return;
}
#ifdef SOFTBUS_DEBUG
if (strcpy_s(g_peerAuthId, MAX_AUTH_ID_LEN, conn->authId) != EOK) {
SOFTBUS_PRINT("[AUTH] OnMsgOpenChannelReq save peer auth id fail\n");
}
#endif
DeviceInfo *localDevInfo = BusGetLocalDeviceInfo();//获取本地设备信息
if (localDevInfo == NULL) {
CloseConn(conn);//关闭连接
return;
}
cJSON *reply = MsgGetDeviceIdPack(localDevInfo);//将deviceId打包成cJSON格式的Get消息作为回复消息
if (reply == NULL) {
CloseConn(conn);//关闭连接
SOFTBUS_PRINT("[AUTH] OnMsgOpenChannelReq pack reply fail\n");
return;
}
ret = AuthConnPostMessage(conn->fd, MODULE_TRUST_ENGINE, FLAG_REPLY, seq, reply);//构造/封装身份认证Post消息并发送给对端,MODULE_TRUST_ENGINE表示可信设备(暂定)
if (ret != 0) {
SOFTBUS_PRINT("[AUTH] OnMsgOpenChannelReq post msg fail\n");
CloseConn(conn);//关闭连接
}
cJSON_Delete(reply);
SOFTBUS_PRINT("[AUTH] OnMsgOpenChannelReq ok\n");
}
- 下面再详细分析函数OnMsgOpenChannelReq()的处理过程,首先在MsgGetDeviceIdUnPack函数中解析消息获取设备id(deviceId)和认证id(authId)保存在conn中。
/*
函数功能:解析消息获取设备id(deviceId)和认证id(authId)
函数参数:
msg:接收到的cJSON消息
conn:认证设备连接信息
cmd:命令
函数返回值:
成功:返回0
失败:返回-1
详细:
*/
static int MsgGetDeviceIdunpack(const cJSON *msg, AuthConn *conn, const char *cmd)
{
char *msgCmd = GetJsonString(msg, CMD_TAG);//获取消息中键为CMD_TAG的值
char *msgData = GetJsonString(msg, DATA_TAG);//获取消息中键为DATA_TAG的值
char *msgAuthId = GetJsonString(msg, DEVICEID_TAG);//获取消息中键为DEVICEID_TAG的值
if (msgCmd == NULL || msgData == NULL || msgAuthId == NULL) {//若数据包不合法,则返回-1
return -1;
}
if (strcmp(msgCmd, cmd) != 0) {//如果消息中命令与传入的命令不符,则返回-1
return -1;
}
if (strcpy_s(conn->deviceId, sizeof(conn->deviceId), msgData) != EOK) {//将消息中的msgData拷贝给认证设备连接的设备id
return -1;
}
if (strcpy_s(conn->authId, sizeof(conn->authId), msgAuthId) != EOK) {//将消息中的msgAuthId拷贝给认证设备连接的认证id
return -1;
}
return 0;
}
/*函数功能:解析消息获取设备id(deviceId)和认证id(authId)*/
int MsgGetDeviceIdUnPack(const cJSON *msg, AuthConn *conn)
{
if (msg == NULL || conn == NULL) {
return -1;
}
int ret = MsgGetDeviceIdunpack(msg, conn, CMD_GET_AUTH_INFO);
if (ret != 0) {
return -1;
}
return 0;
}
- 然后在函数MsgGetDeviceIdPack()中,将deviceId打包成cJSON格式的Get消息作为回复消息。
/*函数功能:将deviceId打包成json格式的Get消息*/
cJSON *MsgGetDeviceIdPack(const DeviceInfo *devInfo)
{
if (devInfo == NULL) {
return NULL;
}
return MsgGetDeviceIdpack(devInfo, CMD_RET_AUTH_INFO);
}
/*
函数功能:将deviceId打包成json格式的Get消息
函数参数:
devInfo:本地设备信息
cmd:Get命令内容
函数返回值:
成功:返回封装好的cJSON格式的消息
失败:返回NULL
详细:
*/
static cJSON *MsgGetDeviceIdpack(const DeviceInfo *devInfo, const char *cmd)
{
cJSON *msg = cJSON_CreateObject();//创建一个cJSON对象
if (msg == NULL) {
return NULL;
}
if (cJSON_AddStringToObject(msg, CMD_TAG, cmd) == NULL) {//添加一个string类型的成员到cJSON对象msg中,键为CMD_TAG,值为传入cmd的值
cJSON_Delete(msg);
return NULL;
}
if (cJSON_AddStringToObject(msg, DATA_TAG, devInfo->deviceId) == NULL) {//添加一个string类型的成员到cJSON对象msg中,键为DATA_TAG,值为deviceId
cJSON_Delete(msg);
return NULL;
}
return msg;
}
- 最后在AuthConnPostMessage()函数中,构造/封装身份认证Post消息并发送给对端,MODULE_TRUST_ENGINE表示可信设备。
/*
函数功能:构造/封装身份认证Post消息并发送给对端
函数参数:
fd:通信fd
module:数据包类型
flags:消息类型标记
seqNum:数据包序列号
msg:cJSON格式的数据负载
函数返回值:
成功:返回0
失败:返回-1
详细:
*/
int AuthConnPostMessage(int fd, int module, int flags, long long seqNum, const cJSON *msg)
{
if (msg == NULL) {
return -1;
}
char *msgStr = cJSON_PrintUnformatted(msg);//将cJSON对象输出为无格式的字符串
if (msgStr == NULL) {
return -1;
}
int ret = AuthConnPostBytes(fd, module, flags, seqNum, msgStr);//按字节构造身份认证连接的POST消息并通过TCP协议发送
free(msgStr);
msgStr = NULL;
return ret;
}
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示: