> 文档中心 > OpenHarmony解读之设备认证:数据接收管理-通知对端

OpenHarmony解读之设备认证:数据接收管理-通知对端


一、概述

在HiChain本端接收数据的处理过程中:(1)在正确解析并处理完接收的数据之后,应构造相应的通知消息回复给对端。(2)在消息处理过程中会有出现错误的情况,在发现错误之后,应针对相应的错误情况通知对端,否则对端会一直处于未知状态。本文将介绍回复通知的相应过程。

二、源码分析

这一模块的源码位于:/base/security/deviceauth。

  1. receive_data函数中,出现错误会跳转到inform处,在inform阶段,首先调用函数encap_inform_message为通知消息申请内存空间,详细分析如下:
//为通知消息负载申请空间static void encap_inform_message(int32_t error_code, struct message *send){    if ((error_code == HC_OK) || (send->msg_code != INFORM_MESSAGE) || (send->payload != NULL)) { return;//如果错误码为0或者不等于INFORM_MESSAGE或者发送负载为空就直接返回    }    int32_t *err = (int32_t *)MALLOC(sizeof(int32_t));//申请内存空间    if (err == NULL) { LOGE("Malloc for encape inform message failed"); return;    }    *err = error_code;//赋值错误码    send->payload = err;//赋值负载地址}
  1. 紧接着执行build_send_data_by_struct函数,构造通知消息,详细分析如下:
/*函数功能:构造结构化的发送消息函数参数:    message:输出参数,消息地址    send_data:输出参数,消息有效载荷地址    send_data_len:输出参数,消息有效载荷长度函数返回值:    成功:返回0    失败:返回错误码*/static int32_t build_send_data_by_struct(const struct message *message, void **send_data, uint32_t *send_data_len){    //消息构造表    const struct make_message_map map[] = { { PAKE_REQUEST, make_pake_request },//构造pake请求消息  { PAKE_RESPONSE, make_pake_response },//构造pake响应消息  { PAKE_CLIENT_CONFIRM, make_pake_client_confirm },//构造pake协议客户端认证消息  { PAKE_SERVER_CONFIRM_RESPONSE, make_pake_server_confirm },//构造pake协议服务端认证消息  { AUTH_START_REQUEST, make_auth_start_request },//构造认证开始请求消息  { AUTH_START_RESPONSE, make_auth_start_response },//构造认证开始响应消息  { AUTH_ACK_REQUEST, make_auth_ack_request },//构造认证确认请求消息  { AUTH_ACK_RESPONSE, make_auth_ack_response },//构造认证确认响应消息  { ADD_AUTHINFO_REQUEST, make_add_auth_info_request },//构造添加认证信息请求消息  { REMOVE_AUTHINFO_REQUEST, make_rmv_auth_info_request },//构造移除认证信息请求消息  { ADD_AUTHINFO_RESPONSE, make_add_auth_info_response },//构造添加认证信息响应消息  { REMOVE_AUTHINFO_RESPONSE, make_rmv_auth_info_response },//构造移除认证信息响应消息  { EXCHANGE_REQUEST, make_exchange_request },//构造交换信息请求消息  { EXCHANGE_RESPONSE, make_exchange_response },//构造交换信息响应消息  { SEC_CLONE_START_RESPONSE, sec_clone_make_srv_proof },  { SEC_CLONE_ACK_RESPONSE, sec_clone_make_clone_ret },  { INFORM_MESSAGE, make_inform_message } };//构造通知消息    if (message->msg_code == INVALID_MESSAGE) {//如果消息码为无效,则返回“无消息发送” return HC_NO_MESSAGE_TO_SEND;    }    if (message->payload == NULL) {//如果发送负载为空,则返回错误码 LOGE("Message payload is null"); return HC_BUILD_SEND_DATA_FAILED;    }    for (uint32_t i = 0; i < sizeof(map) / sizeof(struct make_message_map); i++) {//遍历消息构造表 if (map[i].msg_code != message->msg_code) {     continue; } *send_data = map[i].make_message(message->payload);//调用构造消息回调函数!!! if (*send_data == NULL) {//构造消息失败     return HC_BUILD_SEND_DATA_FAILED; } *send_data_len = strlen(*send_data);//构造消息成功,获取长度 return HC_OK;    }    LOGE("Unsupport encape 0x%04x message", message->msg_code);    return HC_INNER_ERROR;}
  1. 然后调用软总线模块的数据传输模块发送通知消息,最后执行set_result函数设置hichain的处理结果及状态,该函数的分析如下:
/*函数功能:设置最终结果信息,即HiChain状态函数参数:    hichain:hichain实例对象    rcv_msg_code:接收消息码    snd_msg_code:发送消息码    error_code:错误码函数返回值:无*/static void set_result(struct hichain *hichain, uint16_t rcv_msg_code, uint16_t snd_msg_code, int32_t error_code){    if (error_code != HC_OK) {//如果错误码不是0,则直接跳转到error,按对应错误码设置结果 LOGE("Error code is not ok, and set end failed"); goto error;    }    if (snd_msg_code == INFORM_MESSAGE) {//如果发送消息码为通知消息,则直接跳转到error LOGE("Send an inform message, and set end failed"); goto error;    }    //消息结果表    const struct msg_result_map map[] = { { PAKE_REQUEST, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE },//密钥协商过程中{ PAKE_RESPONSE, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE },//密钥协商过程中{ PAKE_CLIENT_CONFIRM, KEY_AGREEMENT_END, OPERATION_STATE },//密钥协商结束{ PAKE_SERVER_CONFIRM_RESPONSE, KEY_AGREEMENT_END, OPERATION_STATE },//密钥协商结束{ EXCHANGE_REQUEST, END_SUCCESS, OVER_STATE },{ EXCHANGE_RESPONSE, END_SUCCESS, OVER_STATE },{ AUTH_START_REQUEST, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE },{ AUTH_START_RESPONSE, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE },{ AUTH_ACK_REQUEST, KEY_AGREEMENT_END, OPERATION_STATE },{ AUTH_ACK_RESPONSE, KEY_AGREEMENT_END, OPERATION_STATE },{ ADD_AUTHINFO_REQUEST, END_SUCCESS, OVER_STATE },{ ADD_AUTHINFO_RESPONSE, END_SUCCESS, OVER_STATE },{ REMOVE_AUTHINFO_REQUEST, END_SUCCESS, OVER_STATE },{ REMOVE_AUTHINFO_RESPONSE, END_SUCCESS, OVER_STATE },{ SEC_CLONE_START_REQUEST, OPERATION_PROCESSING, OPERATION_STATE },{ SEC_CLONE_ACK_REQUEST, END_SUCCESS, OVER_STATE },{ INFORM_MESSAGE, END_FAILED, OVER_STATE },{ INVALID_MESSAGE, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE } };    const struct msg_result_map *map_ptr = select_result_map(rcv_msg_code, map, sizeof(map) / sizeof(struct msg_result_map));//根据接收的消息码查找结果表    set_result_by_map(hichain, map_ptr);//根据结果表内容设置最终结果    return;error:    hichain->last_state = hichain->state;//将hc当前状态赋给last_state    hichain->state = OVER_STATE;//设置hc当前状态为OVER_STATE    hichain->cb.set_service_result(&hichain->identity, END_FAILED);//调用软总线模块回调函数设置服务结果为END_FAILED}//查找结果表const struct msg_result_map *select_result_map(uint16_t rcv_msg_code, const struct msg_result_map *map, uint32_t n){    for (uint32_t i = 0; i < n; i++) {//遍历结果表,通过接收消息码查找对应结果及状态 if (rcv_msg_code == map[i].msg_code) {     return &map[i]; }    }    return NULL;}/*函数功能:根据结果表内容设置最终结果函数参数:    hichain:hichain实例对象    map:结果表对应表项函数返回值:无*/static void set_result_by_map(struct hichain *hichain, const struct msg_result_map *map){    if (map == NULL) {//如果结果表为空,则直接返回 return;    }    if (map->state != OPERATION_STATE) {//如果hc状态不是操作状态,跳转到out goto out;    }    if ((hichain->operation_code != AUTHENTICATE) && (hichain->operation_code != AUTH_KEY_AGREEMENT)) {//如果hc操作码不是身份认证和密钥协商,则跳转out goto out;    }    if (hichain->state != OVER_STATE) {//如果hc当前状态不是OVER_STATE hichain->last_state = hichain->state;//将hc当前状态赋给last_state hichain->state = OVER_STATE;//设置当前状态为OVER_STATE    }    hichain->cb.set_service_result(&hichain->identity, END_SUCCESS);//调用软总线模块回调函数设置服务结果为END_SUCCESS    return;out:    if (hichain->state != map->state) {//如果hc当前状态不是结果表对应状态 hichain->last_state = hichain->state;//将hc当前状态赋给last_state hichain->state = map->state;//设置当前状态为结果表对应状态    }    hichain->cb.set_service_result(&hichain->identity, map->result);//调用软总线模块回调函数设置服务结果为结果表对应结果}