软总线源码分析7:认证模块

根据上一章节对发现模块的分析,我们知道当发现了外部设备后,InnerDeviceFound会被调用,InnerDeviceFound函数会根据infoNode是否为内部节点,调用回调函数。

回想第4章节我们介绍组网模块的时候,组网会调用EnableCoapDisc函数将本地服务发布后,主动发现外部服务,EnableCoapDisc的源码如下:

static int32_t EnableCoapDisc(void)
{
    LOG_INFO("EnableCoapDisc begin");
    int32_t ret = DiscSetDiscoverCallback(MODULE_LNN, &g_discCb);
    if (ret != SOFTBUS_OK) {
        LOG_ERR("DiscSetDiscoverCallback error!");
        return SOFTBUS_ERR;
    }
    PublishInnerInfo publishInfo = {
        .publishId = LNN_PUBLISH_ID,
        .medium = COAP,
        .freq = HIGH,
        .capability = LNN_DISC_CAPABILITY,
        .capabilityData = (unsigned char *)LNN_DISC_CAPABILITY,
        .dataLen = strlen(LNN_DISC_CAPABILITY) + 1,
    };
    LOG_INFO("DiscStartScan!");
    ret = DiscStartScan(MODULE_LNN, &publishInfo);
    if (ret != SOFTBUS_OK) {
        LOG_ERR("DiscStartScan fail!");
        return SOFTBUS_ERR;
    }

    SubscribeInnerInfo subscribeInfo = {
        .subscribeId = LNN_SUBSCRIBE_ID,
        .medium = COAP,
        .freq = HIGH,
        .isSameAccount = false,
        .isWakeRemote = false,
        .capability = LNN_DISC_CAPABILITY,
        .capabilityData = (unsigned char *)LNN_DISC_CAPABILITY,
        .dataLen = strlen(LNN_DISC_CAPABILITY) + 1,
    };
    LOG_INFO("DiscStartAdvertise!");
    ret = DiscStartAdvertise(MODULE_LNN, &subscribeInfo);
    if (ret != SOFTBUS_OK) {
        LOG_ERR("DiscStartAdvertise fail!");
        return SOFTBUS_ERR;
    }
    return SOFTBUS_OK;
}

我们主要关心该函数的第一行,其将g_discCb挂载到本地,具体调用链不展开,总之在组网场景下,当发现外部设备后,InnerDeviceFound函数会调用g_discCb的OnDeviceFound函数指针进行处理,其函数名为DeviceFound,源码如下:

static void DeviceFound(const DeviceInfo *device)
{
    ConnectionAddr *para = NULL;
    if (device == NULL) {
        LOG_ERR("DeviceFound error!");
        return;
    }
    LOG_INFO("DeviceFound! type = %d", g_status.type);
    para = (ConnectionAddr *)SoftBusCalloc(sizeof(ConnectionAddr));
    if (para == NULL) {
        LOG_ERR("malloc init message fail");
        return;
    }
    para->type = g_status.type;
    para->info.ip.port = device->addr[0].port;
    if (strncpy_s(para->info.ip.ip, IP_STR_MAX_LEN, device->addr[0].addr, strlen(device->addr[0].addr)) != EOK) {
        LOG_ERR("STR ERROR!");
        SoftBusFree(para);
        return;
    }

    if (g_status.fsm != NULL) {
        LOG_INFO("PostMessageToFsm!");
        (void)LnnFsmRemoveMessage(g_status.fsm, FSM_MSG_TYPE_DISCOVERY_TIMEOUT);
        if (LnnFsmPostMessage(g_status.fsm, FSM_MSG_TYPE_JOIN_LNN, para) != SOFTBUS_OK) {
            LOG_ERR("LnnFsmPostMessage FSM_MSG_TYPE_JOIN_LNN error!");
            SoftBusFree(para);
        }
    } else {
        LOG_ERR("DeviceFound don't post to fsm!");
        SoftBusFree(para);
    }
    return;
}

该函数首先根据发现的设备信息,构造para地址信息,然后移除掉给状态机设置的超时定时器,然后向状态机提交FSM_MSG_TYPE_JOIN_LNN消息。

此时,该设备即向对端设备请求认证,这种场景下我们成本地发送认证消息的设备为客户端,对端接收认证消息的设备为服务端。

发送认证请求

状态机的机制已经在之前的章节介绍过了,因为当前状态机还在初始AUTH_INDEX状态下,因此该消息触发状态机的OnJoinLNNInAuth的函数。其源码如下:

static int32_t OnJoinLNNInAuth(ConnectionAddr *addr)
{
    int32_t rc;
    ConnInfo *connInfo = &g_netBuilder.connInfo;
    ConnectOption option;

    if (addr == NULL) {
        return SOFTBUS_INVALID_PARAM;
    }
    if (ConvertAddrToOption(addr, &option) == false) {
        SoftBusFree(addr);
        return SOFTBUS_ERR;
    }

    if ((connInfo->flag & (CONN_INFO_FLAG_JOINING_ACTIVE |
        CONN_INFO_FLAG_JOINING_PASSIVE)) != 0) {
        if (LnnIsSameConnectionAddr(addr, &connInfo->addr) == true) {
            LOG_INFO("addr is same, waiting...");
            SoftBusFree(addr);
            return SOFTBUS_OK;
        }
        LOG_ERR("previous request is ongoing, reject it");
        LnnNotifyJoinResult(addr, NULL, SOFTBUS_ERR);
        SoftBusFree(addr);
        return SOFTBUS_OK;
    }
    LOG_INFO("begin a new join request");
    connInfo->addr = *addr;
    connInfo->flag |= CONN_INFO_FLAG_JOINING_ACTIVE;
    (void)AuthVerifyInit();
    LOG_INFO("hichain init ok....");
    rc = AuthVerifyDevice(LNN, &option);
    if (rc != SOFTBUS_OK) {
        CompleteJoinLNN(NULL, SOFTBUS_ERR);
        (void)AuthVerifyDeinit();
    } else {
        LnnFsmPostMessageDelay(&g_netBuilder.fsm, FSM_MSG_TYPE_JOIN_LNN_TIMEOUT,
            NULL, JOIN_LNN_TIMEOUT_LEN);
    }
    SoftBusFree(addr);
    LOG_INFO("rc = %d", rc);
    return rc;
}

OnJoinLNNInAuth首先将Addr转为Option,然后判断当前系统是否正在进行组网过程,如果是则直接返回。如果不是,则首先调用AuthVerifyInit初始化认证工作,然后调用AuthVerifyDevice进行认证处理,最后调用LnnFsmPostMessageDelay启动15S超时定时器。

认证处理初始化

AuthVerifyInit的源码如下:

int32_t AuthVerifyInit(void)
{
    if (HichainServiceInit() != SOFTBUS_OK) {
        LOG_ERR("HichainServiceInit failed");
        return SOFTBUS_ERR;
    }
    return SOFTBUS_OK;
}

该函数即调用了HichainServiceInit,其源码如下:

static int32_t HichainServiceInit(void)
{
    if (InitDeviceAuthService() != 0) {
        LOG_ERR("auth InitDeviceAuthService failed");
        return SOFTBUS_ERR;
    }
    g_hichainGaInstance = GetGaInstance();
    if (g_hichainGaInstance == NULL) {
        LOG_ERR("auth GetGaInstance failed");
        return SOFTBUS_ERR;
    }
    g_hichainGmInstance = GetGmInstance();
    if (g_hichainGmInstance == NULL) {
        LOG_ERR("auth GetGmInstance failed");
        return SOFTBUS_ERR;
    }
    (void)memset_s(&g_hichainCallback, sizeof(DeviceAuthCallback), 0, sizeof(DeviceAuthCallback));
    g_hichainCallback.onTransmit = AuthOnTransmit;
    g_hichainCallback.onSessionKeyReturned = AuthOnSessionKeyReturned;
    g_hichainCallback.onFi
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值