diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..570b3af3031977a544ec019286ad827803135569 --- /dev/null +++ b/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_manager.h" +#include "deviceprofile_connector.h" +#include "dm_anonymous.h" +#include "dm_auth_context.h" +#include "dm_auth_state.h" +#include "dm_auth_state_machine.h" +#include "dm_dialog_manager.h" +#include "dm_log.h" + +namespace OHOS { +namespace DistributedHardware { + +constexpr const char* TAG_CUSTOM_DESCRIPTION = "CUSTOMDESC"; +constexpr const char* TAG_LOCAL_DEVICE_TYPE = "LOCALDEVICETYPE"; +constexpr const char* TAG_REQUESTER = "REQUESTER"; +constexpr const char* TAG_HOST_PKGLABEL = "hostPkgLabel"; + +std::set g_shareByPinAuthDeviceTypeSet{DmDeviceType::DEVICE_TYPE_SMART_DISPLAY}; + +DmAuthStateType AuthSrcConfirmState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_CONFIRM_STATE; +} + +int32_t AuthSrcConfirmState::DoPinAuth(std::shared_ptr context) +{ + LOGI("AuthSrcConfirmState::DoPinAuth start"); + int32_t authResult = context->authResult; + if (authResult != USER_OPERATION_TYPE_ALLOW_AUTH && + authResult != USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS) { + LOGE("AuthSrcConfirmState::DoPinAuth authResult not allow"); + context->reason = ERR_DM_BIND_USER_CANCEL; + return ERR_DM_BIND_USER_CANCEL; + } + + if (context->authTypeList.empty()) { + LOGE("AuthSrcConfirmState::DoPinAuth authTypeList empty"); + context->reason = ERR_DM_UNSUPPORTED_AUTH_TYPE; + return ERR_DM_UNSUPPORTED_AUTH_TYPE; + } + + context->currentAuthTypeIdx = 0; + context->authType = context->authTypeList[0]; + if (!context->authResultReady) { + // send 100 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_USER_CONFIRM, context); + + context->timer->StartTimer(std::string(CONFIRM_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, CONFIRM_TIMEOUT_TASK, CONFIRM_TIMEOUT), + [context] (std::string name) { + HandleAuthenticateTimeout(context, name); + }); + } else { + // skip 100, 110 msg + context->authStateMachine->TransitionTo(std::make_shared()); + } + return DM_OK; +} + +int32_t AuthSrcConfirmState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcConfirmState::Action start"); + // check version compatibility + context->timer->DeleteTimer(std::string(NEGOTIATE_TIMEOUT_TASK)); + if (CompareVersion(context->accessee.dmVersion, std::string(DM_VERSION_5_1_0))) { + LOGE("AuthSrcConfirmState::Action incompatible version %{public}s compare to 5.1.0", + context->accessee.dmVersion.c_str()); + context->reason = ERR_DM_VERSION_INCOMPATIBLE; + return ERR_DM_VERSION_INCOMPATIBLE; + } + + // no credential, try to do pin auth + return DoPinAuth(context); +} + +DmAuthStateType AuthSinkConfirmState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_CONFIRM_STATE; +} + +int32_t AuthSinkConfirmState::ShowConfigDialog(std::shared_ptr context) +{ + LOGI("AuthSinkConfirmState::ShowConfigDialog start"); + + if (IsScreenLocked()) { + LOGE("AuthSinkConfirmState::ShowStartAuthDialog screen is locked."); + context->reason = ERR_DM_BIND_USER_CANCEL; + context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + return STOP_BIND; + } + + JsonObject jsonObj; + jsonObj[TAG_CUSTOM_DESCRIPTION] = context->customData; + jsonObj[TAG_LOCAL_DEVICE_TYPE] = context->accesser.deviceType; + jsonObj[TAG_REQUESTER] = context->accesser.deviceName; + jsonObj[TAG_USER_ID] = context->accessee.userId; + jsonObj[TAG_HOST_PKGLABEL] = context->sessionName; + + const std::string params = jsonObj.Dump(); + DmDialogManager::GetInstance().ShowConfirmDialog(params); + + LOGI("AuthSinkConfirmState::ShowConfigDialog end"); + return DM_OK; +} + +int32_t AuthSinkConfirmState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkConfirmState::Action start"); + context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); + + if (context->authTypeList.empty()) { + LOGE("AuthSinkConfirmState::Action authTypeList empty"); + context->reason = ERR_DM_UNSUPPORTED_AUTH_TYPE; + return ERR_DM_UNSUPPORTED_AUTH_TYPE; + } + context->authType = context->authTypeList[context->currentAuthTypeIdx]; + + if (context->authBoxType == DistributedDeviceProfile::NUM_1) { // tristate box + LOGI("AuthSinkConfirmState::Action 3box"); + // show user confirmation dialog + auto ret = ShowConfigDialog(context); + if (ret != DM_OK) { + return ret; + } + // wait for user opration + if (DmEventType::ON_USER_OPERATION != + context->authStateMachine->WaitExpectEvent(DmEventType::ON_USER_OPERATION)) { + LOGE("AuthSinkConfirmState::Action wait ON_USER_OPERATION err"); + return STOP_BIND; + } + if (context->reply != USER_OPERATION_TYPE_ALLOW_AUTH) { + LOGI("AuthSinkConfirmState::Action USER_OPERATION_TYPE_CANCEL_AUTH"); + context->reason = ERR_DM_BIND_USER_CANCEL; + return STOP_BIND; + } + } else if (context->authBoxType == DistributedDeviceProfile::NUM_2) { // no authorization box + if (context->authResult == USER_OPERATION_TYPE_CANCEL_AUTH) { + LOGI("AuthSinkConfirmState::Action USER_OPERATION_TYPE_CANCEL_AUTH"); + context->reason = ERR_DM_BIND_USER_CANCEL; + return STOP_BIND; + } + } else { + LOGE("AuthSinkConfirmState::Action authBoxType not support"); + context->reason = ERR_DM_UNSUPPORTED_AUTH_TYPE; + return ERR_DM_UNSUPPORTED_AUTH_TYPE; + } + + // send 110 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_USER_CONFIRM, context); + + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc6a91bdfea09081f7b75e39aadc82d08dbdcd7f --- /dev/null +++ b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_manager.h" +#include "deviceprofile_connector.h" +#include "dm_anonymous.h" +#include "dm_auth_context.h" +#include "dm_auth_message_processor.h" +#include "dm_auth_state_machine.h" +#include "dm_auth_state.h" +#include "dm_auth_state_machine.h" +#include "dm_dialog_manager.h" +#include "dm_log.h" +#include "dm_random.h" +#include "hichain_auth_connector.h" +#include "multiple_user_connector.h" +#include "service_info_profile.h" + +namespace OHOS { +namespace DistributedHardware { + +constexpr int32_t MAX_AUTH_INPUT_PIN_FAIL_TIMES = 3; +constexpr int32_t MIN_PIN_CODE = 100000; +constexpr int32_t MAX_PIN_CODE = 999999; + +int32_t AuthSinkStatePinAuthComm::ShowAuthInfoDialog(std::shared_ptr context) +{ + LOGI("AuthSinkConfirmState::ShowAuthInfoDialog start"); + if (DmAuthState::IsScreenLocked()) { + LOGE("AuthSinkConfirmState::ShowAuthInfoDialog screen is locked."); + context->reason = ERR_DM_BIND_USER_CANCEL; + context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + return STOP_BIND; + } + + DmDialogManager::GetInstance().ShowPinDialog(std::to_string(context->pinCode)); + + context->timer->StartTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, SESSION_HEARTBEAT_TIMEOUT_TASK, SESSION_HEARTBEAT_TIMEOUT), + [context] (std::string name) { + AuthSinkStatePinAuthComm::HandleSessionHeartbeat(context, name); + }); + return DM_OK; +} + +void AuthSinkStatePinAuthComm::HandleSessionHeartbeat(std::shared_ptr context, std::string name) +{ + context->timer->DeleteTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK)); + if (context->isFinished) { + return; + } + + LOGI("DmAuthManager::HandleSessionHeartbeat name %{public}s", name.c_str()); + JsonObject jsonObj; + jsonObj[TAG_SESSION_HEARTBEAT] = TAG_SESSION_HEARTBEAT; + std::string message = jsonObj.Dump(); + context->softbusConnector->GetSoftbusSession()->SendHeartbeatData(context->sessionId, message); + + context->timer->StartTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, SESSION_HEARTBEAT_TIMEOUT_TASK, SESSION_HEARTBEAT_TIMEOUT), + [context] (std::string name) { + AuthSinkStatePinAuthComm::HandleSessionHeartbeat(context, name); + }); + + LOGI("DmAuthManager::HandleSessionHeartbeat complete."); +} + +void AuthSinkStatePinAuthComm::GeneratePincode(std::shared_ptr context) +{ + context->pinCode = GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE); +} + +DmAuthStateType AuthSrcPinAuthStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE; +} + +int32_t AuthSrcPinAuthStartState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcPinAuthStartState::Action start"); + // auth pincode + int32_t osAccountId = MultipleUserConnector::GetCurrentAccountUserID(); + auto ret = context->hiChainAuthConnector->AuthCredentialPinCode(osAccountId, context->requestId, + context->pinCode); + if (ret != DM_OK) { + LOGE("AuthSrcPinAuthStartState::AuthDevice call AuthCredentialPinCode failed."); + return ret; + } + // wait for onTransmit from hiChain + auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT); + if (retEvent == DmEventType::ON_TRANSMIT) { + // send 120 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_START, context); + return DM_OK; + } else if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSrcPinAuthStartState::AuthDevice ON_ERROR failed, maybe retry."); + return DM_OK; + } + + return STOP_BIND; +} + +DmAuthStateType AuthSinkPinAuthStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE; +} + +int32_t AuthSinkPinAuthStartState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkPinAuthStartState::Action start"); + context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); + if (!context->pinNegotiateStarted) { + context->pinNegotiateStarted = true; + context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT), + [context] (std::string name) { + HandleAuthenticateTimeout(context, name); + }); + } + + // Stop the abnormal authentication process + if (context->authTypeList.empty() || + (context->authResult != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH && + context->authResult != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS)) { + LOGE("AuthSinkPinAuthStartState::Action invalid parameter."); + return ERR_DM_INPUT_PARA_INVALID; + } + + // process pincode auth + auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); + if (ret != DM_OK) { + LOGE("AuthSinkPinAuthStartState::Action call ProcessCredData err."); + return ret; + } + // wait for onTransmit from hiChain + auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT); + if (retEvent == DmEventType::ON_TRANSMIT) { + // send 130 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_PIN_AUTH_START, context); + return DM_OK; + } + if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSrcPinAuthStartState::AuthDevice ON_ERROR failed, maybe retry."); + return DM_OK; + } + return STOP_BIND; +} + +DmAuthStateType AuthSrcPinAuthMsgNegotiateState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE; +} + +int32_t AuthSrcPinAuthMsgNegotiateState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcPinAuthMsgNegotiateState::Action start"); + auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); + if (ret != DM_OK) { + LOGE("AuthSrcPinAuthMsgNegotiateState::Action call ProcessCredData err."); + return ret; + } + // wait for onTransmit from hiChain + auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT); + if (retEvent == DmEventType::ON_TRANSMIT) { + // send 121 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_MSG_NEGOTIATE, context); + return DM_OK; + } + if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSrcPinAuthMsgNegotiateState::AuthDevice ON_ERROR failed, maybe retry."); + return DM_OK; + } + LOGE("AuthSrcPinAuthMsgNegotiateState::Action failed."); + return STOP_BIND; +} + +DmAuthStateType AuthSinkPinAuthMsgNegotiateState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE; +} + +int32_t AuthSinkPinAuthMsgNegotiateState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkPinAuthMsgNegotiateState::Action start"); + auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); + if (ret != DM_OK) { + LOGE("AuthSinkPinAuthMsgNegotiateState::Action call ProcessCredData err."); + return ret; + } + // wait for onTransmit from hiChain + auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT); + if (retEvent == DmEventType::ON_TRANSMIT) { + // send 131 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_PIN_AUTH_MSG_NEGOTIATE, context); + } else if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSinkPinAuthMsgNegotiateState::AuthDevice WAIT ON_TRANSMIT ON_ERROR failed, maybe retry."); + return DM_OK; + } else { + return STOP_BIND; + } + + retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_SESSION_KEY_RETURNED); + if (retEvent == DmEventType::ON_SESSION_KEY_RETURNED) { + retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_FINISH); + if (retEvent == DmEventType::ON_FINISH || retEvent == DmEventType::ON_ERROR) { + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } + } else if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSinkPinAuthMsgNegotiateState::AuthDevice WAIT ON_SESSION_KEY_RETURNED ON_ERROR failed, maybe retry."); + return DM_OK; + } + + LOGE("AuthSinkPinAuthMsgNegotiateState::AuthDevice failed."); + return STOP_BIND; +} + +DmAuthStateType AuthSinkPinAuthDoneState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE; +} + +int32_t AuthSinkPinAuthDoneState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkPinAuthDoneState Action"); + return DM_OK; +} + +DmAuthStateType AuthSrcPinAuthDoneState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE; +} + +int32_t AuthSrcPinAuthDoneState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcPinAuthDoneState::Action start"); + std::string onTransmitData = context->transmitData; + if (context->hiChainAuthConnector->ProcessCredData(context->requestId, onTransmitData) != DM_OK) { + LOGE("AuthSrcPinAuthDoneState::Action failed, processCredData failed."); + return ERR_DM_FAILED; + } + + // wait for ON_SESSION_KEY_RETURNED from hichain + DmEventType ret = context->authStateMachine->WaitExpectEvent(ON_SESSION_KEY_RETURNED); + if (ret != ON_SESSION_KEY_RETURNED) { + if (ret == ON_ERROR) { + LOGE("AuthSrcPinAuthDoneState::Action, ON_SESSION_KEY_RETURNED event not arriverd, maybe retry."); + return DM_OK; + } else { + LOGE("AuthSrcPinAuthDoneState::Action failed, ON_SESSION_KEY_RETURNED event failed, other event arriverd."); + return ERR_DM_FAILED; + } + } + + // wait for ON_FINISH from hichain + ret = context->authStateMachine->WaitExpectEvent(ON_FINISH); + if (ret == ON_FINISH) { + LOGI("AuthSrcPinAuthDoneState::Action wait ON_FINISH done"); + return DM_OK; + } else if (ret == ON_ERROR) { + return DM_OK; + LOGE("AuthSrcPinAuthDoneState::Action, ON_FINISH event not arriverd, maybe retry."); + } + + return ERR_DM_FAILED; +} + +DmAuthStateType AuthSrcPinNegotiateStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE; +} + +int32_t AuthSrcPinNegotiateStartState::Action(std::shared_ptr context) +{ + if (!context->pinNegotiateStarted) { + context->pinNegotiateStarted = true; + context->timer->DeleteTimer(std::string(CONFIRM_TIMEOUT_TASK)); + int32_t authResult = context->authResult; + if (context->authTypeList.empty() || + (authResult != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH && + authResult != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS)) { + LOGE("AuthSrcPinNegotiateStartState::Action authResult not allow"); + context->reason = ERR_DM_BIND_USER_CANCEL; + return ERR_DM_BIND_USER_CANCEL; + } + } else { + if (context->authType == DmAuthType::AUTH_TYPE_PIN && + context->inputPinAuthFailTimes < MAX_AUTH_INPUT_PIN_FAIL_TIMES) { + LOGI("AuthSrcPinNegotiateStartState::Action input pin auth err, retry"); + } else { + // try to fallback to next auth type + if (context->currentAuthTypeIdx + 1 >= context->authTypeList.size()) { + LOGE("AuthSrcPinNegotiateStartState::Action all auth type failed"); + context->reason = ERR_DM_AUTH_REJECT; + return ERR_DM_AUTH_REJECT; + } + context->currentAuthTypeIdx++; + context->authType = context->authTypeList[context->currentAuthTypeIdx]; + } + } + + // restart pin auth timer + context->timer->DeleteTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK)); + context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT), + [context] (std::string name) { + HandleAuthenticateTimeout(context, name); + }); + if (context->authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE) { + context->authStateMachine->TransitionTo(std::make_shared()); + } else if (context->authType == DmAuthType::AUTH_TYPE_PIN) { + context->authStateMachine->TransitionTo(std::make_shared()); + } else if (context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) { + context->authStateMachine->TransitionTo(std::make_shared()); + } else { + LOGE("AuthSrcPinNegotiateStartState::Action authType not support"); + return ERR_DM_FAILED; + } + return DM_OK; +} + +DmAuthStateType AuthSrcPinInputState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_INPUT_STATE; +} + +int32_t AuthSrcPinInputState::ShowStartAuthDialog(std::shared_ptr context) +{ + LOGI("AuthSrcPinInputState::ShowStartAuthDialog start."); + if (DmAuthState::IsScreenLocked()) { + LOGE("AuthSrcPinInputState screen is locked."); + context->reason = ERR_DM_BIND_USER_CANCEL; + return STOP_BIND; + } + DmDialogManager::GetInstance().ShowInputDialog(context->accessee.deviceName); + return DM_OK; +} + +int32_t AuthSrcPinInputState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcPinInputState::Action start"); + if (context->inputPinAuthFailTimes == 0) { + auto ret = ShowStartAuthDialog(context); + if (ret != DM_OK) { + return ret; + } + } else { + // clear input pin box, and show try again + context->authUiStateMgr->UpdateUiState(DmUiStateMsg::MSG_PIN_CODE_ERROR); + } + + LOGI("AuthSrcPinInputState::Action waitting user operation"); + // wait for user operation + if (DmEventType::ON_USER_OPERATION != + context->authStateMachine->WaitExpectEvent(DmEventType::ON_USER_OPERATION)) { + LOGI("AuthSrcPinInputState::Action wait ON_USER_OPERATION err"); + return STOP_BIND; + } + + if (context->pinInputResult != USER_OPERATION_TYPE_DONE_PINCODE_INPUT) { + LOGE("AuthSrcPinInputState::Action not USER_OPERATION_TYPE_DONE_PINCODE_INPUT err"); + return STOP_BIND; + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +DmAuthStateType AuthSinkPinNegotiateStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE; +} + +int32_t AuthSinkPinNegotiateStartState::Action(std::shared_ptr context) +{ + if (!context->pinNegotiateStarted) { + context->pinNegotiateStarted = true; + } else { + if (context->authType == DmAuthType::AUTH_TYPE_PIN && + context->inputPinAuthFailTimes < MAX_AUTH_INPUT_PIN_FAIL_TIMES) { + LOGI("AuthSinkPinNegotiateStartState::Action input pin auth err, retry"); + } else { + // try to fallback to next auth type + auto idx = context->currentAuthTypeIdx; + if (idx + 1 >= context->authTypeList.size()) { + LOGE("AuthSinkPinNegotiateStartState::Action all auth type failed"); + context->reason = ERR_DM_AUTH_REJECT; + return ERR_DM_AUTH_REJECT; + } + ++idx; + context->currentAuthTypeIdx = idx; + context->authType = context->authTypeList[idx]; + } + } + // restart pin auth timer + context->timer->DeleteTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK)); + context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT), + [context] (std::string name) { + HandleAuthenticateTimeout(context, name); + }); + if (context->authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE) { + LOGI("AuthSinkPinNegotiateStartState::Action import auth code"); + } else if (context->authType == DmAuthType::AUTH_TYPE_PIN) { + LOGI("AuthSinkPinNegotiateStartState::Action input pin"); + context->authStateMachine->TransitionTo(std::make_shared()); + } else if (context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) { + LOGI("AuthSinkPinNegotiateStartState::Action ultrasonic pin"); + } else { + LOGE("AuthSrcPinNegotiateStartState::Action authType not support"); + return ERR_DM_FAILED; + } + return DM_OK; +} + +DmAuthStateType AuthSinkPinDisplayState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_DISPLAY_STATE; +} + +int32_t AuthSinkPinDisplayState::Action(std::shared_ptr context) +{ + if (context->inputPinAuthFailTimes == 0) { + // gen pincode + AuthSinkStatePinAuthComm::GeneratePincode(context); + // show pincode + return AuthSinkStatePinAuthComm::ShowAuthInfoDialog(context); + } + return DM_OK; +} + +DmAuthStateType AuthSrcPinNegotiateUltrasonicPinState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE; +} + +int32_t AuthSrcPinNegotiateUltrasonicPinState::Action(std::shared_ptr context) +{ + return ERR_DM_FAILED; +} + +DmAuthStateType AuthSinkPinNegotiateUltrasonicPinState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE; +} + +int32_t AuthSinkPinNegotiateUltrasonicPinState::Action(std::shared_ptr context) +{ + return ERR_DM_FAILED; +} + +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file