diff --git a/src/dbus/common/dbus_message_helper.hpp b/src/dbus/common/dbus_message_helper.hpp index 60d19534ded..66c66588bc7 100644 --- a/src/dbus/common/dbus_message_helper.hpp +++ b/src/dbus/common/dbus_message_helper.hpp @@ -119,6 +119,12 @@ otbrError DBusMessageEncode(DBusMessageIter *aIter, const TrelInfo &aTrelInfo); otbrError DBusMessageExtract(DBusMessageIter *aIter, TrelInfo &aTrelInfo); otbrError DBusMessageEncode(DBusMessageIter *aIter, const TrelInfo::TrelPacketCounters &aCounters); otbrError DBusMessageExtract(DBusMessageIter *aIter, TrelInfo::TrelPacketCounters &aCounters); +otbrError DBusMessageEncode(DBusMessageIter *aIter, const AdministrationInfo &aAdministrationInfo); +otbrError DBusMessageExtract(DBusMessageIter *aIter, AdministrationInfo &aAdministrationInfo); +otbrError DBusMessageEncode(DBusMessageIter *aIter, const AdministrationInfo::EpskcInfo &aEpskcInfo); +otbrError DBusMessageExtract(DBusMessageIter *aIter, AdministrationInfo::EpskcInfo &aEpskcInfo); +otbrError DBusMessageEncode(DBusMessageIter *aIter, const AdministrationInfo::PskcInfo &aPskcInfo); +otbrError DBusMessageExtract(DBusMessageIter *aIter, AdministrationInfo::PskcInfo &aPskcInfo); template struct DBusTypeTrait; @@ -407,6 +413,35 @@ template <> struct DBusTypeTrait static constexpr const char *TYPE_AS_STRING = "(sbbbuuu)"; }; +template <> struct DBusTypeTrait +{ + static constexpr int TYPE = DBUS_TYPE_BYTE; + static constexpr const char *TYPE_AS_STRING = DBUS_TYPE_BYTE_AS_STRING; +}; + +template <> struct DBusTypeTrait +{ + // struct of { struct of {uint8, uint32, uint32, uint32, uint32, uint32, + // uint32, uint32, uint32, uint32, uint32, uint32 }, + // struct of {uint32, uint32, uint32}, + // uint32, + // uint32 } + static constexpr const char *TYPE_AS_STRING = "((yuuuuuuuuuuu)(uuu)uu)"; +}; + +template <> struct DBusTypeTrait +{ + // struct of {uint8, uint32, uint32, uint32, uint32, uint32, uint32, + // uint32, uint32, uint32, uint32, uint32 } + static constexpr const char *TYPE_AS_STRING = "(yuuuuuuuuuuu)"; +}; + +template <> struct DBusTypeTrait +{ + // struct of {uint32, uint32, uint32 } + static constexpr const char *TYPE_AS_STRING = "(uuu)"; +}; + template <> struct DBusTypeTrait { static constexpr int TYPE = DBUS_TYPE_BYTE; diff --git a/src/dbus/common/dbus_message_helper_openthread.cpp b/src/dbus/common/dbus_message_helper_openthread.cpp index e8a62b056b9..5eee33edccb 100644 --- a/src/dbus/common/dbus_message_helper_openthread.cpp +++ b/src/dbus/common/dbus_message_helper_openthread.cpp @@ -1258,5 +1258,121 @@ otbrError DBusMessageExtract(DBusMessageIter *aIter, TrelInfo::TrelPacketCounter return error; } +otbrError DBusMessageEncode(DBusMessageIter *aIter, const AdministrationInfo &aAdministrationInfo) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS); + + SuccessOrExit(error = DBusMessageEncode(&sub, aAdministrationInfo.mEpskcInfo)); + SuccessOrExit(error = DBusMessageEncode(&sub, aAdministrationInfo.mPskcInfo)); + SuccessOrExit(error = DBusMessageEncode(&sub, aAdministrationInfo.mMgmtActiveGetCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aAdministrationInfo.mMgmtPendingGetCount)); + + VerifyOrExit(dbus_message_iter_close_container(aIter, &sub), error = OTBR_ERROR_DBUS); +exit: + return error; +} + +otbrError DBusMessageExtract(DBusMessageIter *aIter, AdministrationInfo &aAdministrationInfo) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + dbus_message_iter_recurse(aIter, &sub); + + SuccessOrExit(error = DBusMessageExtract(&sub, aAdministrationInfo.mEpskcInfo)); + SuccessOrExit(error = DBusMessageExtract(&sub, aAdministrationInfo.mPskcInfo)); + SuccessOrExit(error = DBusMessageExtract(&sub, aAdministrationInfo.mMgmtActiveGetCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aAdministrationInfo.mMgmtPendingGetCount)); + + dbus_message_iter_next(aIter); +exit: + return error; +} + +otbrError DBusMessageEncode(DBusMessageIter *aIter, const AdministrationInfo::EpskcInfo &aEpskcInfo) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS); + + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mState)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mActivationCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mDeactivationClearCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mDeactivationTimeoutCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mDeactivationMaxAttemptsCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mDeactivationDisconnectCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mInvalidBaStateErrorCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mInvalidArgsErrorCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mStartSecureSessionErrorCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mSecureSessionSuccessCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mSecureSessionFailureCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aEpskcInfo.mCommissionerPetitionCount)); + + VerifyOrExit(dbus_message_iter_close_container(aIter, &sub), error = OTBR_ERROR_DBUS); +exit: + return error; +} + +otbrError DBusMessageExtract(DBusMessageIter *aIter, AdministrationInfo::EpskcInfo &aEpskcInfo) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + dbus_message_iter_recurse(aIter, &sub); + + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mState)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mActivationCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mDeactivationClearCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mDeactivationTimeoutCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mDeactivationMaxAttemptsCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mDeactivationDisconnectCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mInvalidBaStateErrorCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mInvalidArgsErrorCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mStartSecureSessionErrorCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mSecureSessionSuccessCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mSecureSessionFailureCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aEpskcInfo.mCommissionerPetitionCount)); + + dbus_message_iter_next(aIter); +exit: + return error; +} + +otbrError DBusMessageEncode(DBusMessageIter *aIter, const AdministrationInfo::PskcInfo &aPskcInfo) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS); + + SuccessOrExit(error = DBusMessageEncode(&sub, aPskcInfo.mSecureSessionSuccessCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aPskcInfo.mSecureSessionFailureCount)); + SuccessOrExit(error = DBusMessageEncode(&sub, aPskcInfo.mCommissionerPetitionCount)); + + VerifyOrExit(dbus_message_iter_close_container(aIter, &sub), error = OTBR_ERROR_DBUS); +exit: + return error; +} + +otbrError DBusMessageExtract(DBusMessageIter *aIter, AdministrationInfo::PskcInfo &aPskcInfo) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + dbus_message_iter_recurse(aIter, &sub); + + SuccessOrExit(error = DBusMessageExtract(&sub, aPskcInfo.mSecureSessionSuccessCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aPskcInfo.mSecureSessionFailureCount)); + SuccessOrExit(error = DBusMessageExtract(&sub, aPskcInfo.mCommissionerPetitionCount)); + + dbus_message_iter_next(aIter); +exit: + return error; +} + } // namespace DBus } // namespace otbr diff --git a/src/dbus/common/types.hpp b/src/dbus/common/types.hpp index 94687e05178..a93aba7d9fa 100644 --- a/src/dbus/common/types.hpp +++ b/src/dbus/common/types.hpp @@ -719,6 +719,44 @@ struct TrelInfo TrelPacketCounters mTrelCounters; ///< The TREL counters. }; +enum EpskcState : uint8_t +{ + EPSKC_STATE_READY_FOR_CONNECTION = 0, ///< The ephemeral key is set and ready for secure connection. + EPSKC_STATE_CONNECTED = 1, ///< The ephemeral key is active with a commissioner connected. + EPSKC_STATE_INACTIVE = 2, ///< The ephemeral key is inactive. +}; + +struct AdministrationInfo +{ + struct EpskcInfo + { + EpskcState mState; ///< The ePSKc state + uint64_t mActivationCount; ///< The number of activations + uint64_t mDeactivationClearCount; ///< The number of deactivations due to cleared via API + uint64_t mDeactivationTimeoutCount; ///< The number of deactivations due to timeout + uint64_t mDeactivationMaxAttemptsCount; ///< The number of deactivations due to max connection attempts + uint64_t mDeactivationDisconnectCount; ///< The number of deactivations due to commissioner disconnected + uint64_t mInvalidBaStateErrorCount; ///< The number of activation failures caused by invalid border agent state + uint64_t mInvalidArgsErrorCount; ///< The number of activation failures caused by invalid argument + uint64_t mStartSecureSessionErrorCount; ///< The number of activation failures due to start secure session error + uint64_t mSecureSessionSuccessCount; ///< The number of successful secure session establishment + uint64_t mSecureSessionFailureCount; ///< The number of failed secure session establishement + uint64_t mCommissionerPetitionCount; ///< The number of active commissioner petitioned + }; + + struct PskcInfo + { + uint64_t mSecureSessionSuccessCount; ///< The number of successful secure session establishment + uint64_t mSecureSessionFailureCount; ///< The number of failed secure session establishement + uint64_t mCommissionerPetitionCount; ///< The number of active commissioner petitioned + }; + + EpskcInfo mEpskcInfo; ///< The ePSKc stats info. + PskcInfo mPskcInfo; ///< The PSKc stats info. + uint64_t mMgmtActiveGetCount; ///< The number of MGMT_ACTIVE_GET.req received + uint64_t mMgmtPendingGetCount; ///< The number of MGMT_PENDING_GET.req received +}; + } // namespace DBus } // namespace otbr diff --git a/src/proto/thread_telemetry.proto b/src/proto/thread_telemetry.proto index 9ffba63b6ec..6e918498933 100644 --- a/src/proto/thread_telemetry.proto +++ b/src/proto/thread_telemetry.proto @@ -513,6 +513,75 @@ message TelemetryData { optional bool has_others_route_added = 3; } + enum EpskcState { + EPSKC_STATE_READY_FOR_CONNECTION = 0; + EPSKC_STATE_CONNECTED = 1; + EPSKC_STATE_INACTIVE = 2; + } + + message EpskcInfo { + // Whether there is an active ePSKc + optional EpskcState state = 1; + + // The number of ePSKc activations + optional uint32 activation_count = 2; + + // The number of ePSKc deactivations due to cleared via API + optional uint32 deactivation_clear_count = 3; + + // The number of ePSKc deactivations due to timeout + optional uint32 deactivation_timeout_count = 4; + + // The number of ePSKc deactivations due to max connection attempts reached + optional uint32 deactivation_max_connection_reached_count = 5; + + // The number of ePSKc deactivations due to commissioner disconnected + optional uint32 deactivation_disconnect_count = 6; + + // The number of ePSKc activation failures caused by invalid border agent state + optional uint32 invalid_ba_state_error_count = 7; + + // The number of ePSKc activation failures caused by invalid argument + optional uint32 invalid_args_error_count = 8; + + // The number of ePSKc activation failures caused by failed to start secure session + optional uint32 start_secure_session_error_count = 9; + + // The number of successful secure session establishment with ePSKc + optional uint32 secure_session_success_count = 10; + + // The number of failed secure session establishement with ePSKc + optional uint32 secure_session_failure_count = 11; + + // The number of active commissioner petitioned over secure session establishment with ePSKc + optional uint32 commissioner_petition_count = 12; + } + + message PskcInfo { + // The number of successful secure session establishment with PSKc + optional uint32 secure_session_success_count = 1; + + // The number of failed secure session establishement with PSKc + optional uint32 secure_session_failure_count = 2; + + // The number of active commissioner petitioned over secure session establishment with PSKc + optional uint32 commissioner_petition_count = 3; + } + + message AdministrationInfo { + // The ePSKc stats info + optional EpskcInfo epskc_info = 1; + + // The PSKc stats info + optional PskcInfo pskc_info = 2; + + // The number of MGMT_ACTIVE_GET.req received + optional uint32 mgmt_active_get_count = 3; + + // The number of MGMT_PENDING_GET.req received + optional uint32 mgmt_pending_get_count = 4; + } + message WpanBorderRouter { // Border routing counters optional BorderRoutingCounters border_routing_counters = 1; @@ -552,6 +621,9 @@ message TelemetryData { // Information about the external routes in network data. optional ExternalRoutes external_route_info = 13; + + // Information about the Thread administration procedures + optional AdministrationInfo administration_info = 14; } message RcpStabilityStatistics { diff --git a/src/utils/thread_helper.cpp b/src/utils/thread_helper.cpp index 0bacbd1b3b3..5907a1400e8 100644 --- a/src/utils/thread_helper.cpp +++ b/src/utils/thread_helper.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -224,6 +225,21 @@ void CopyMdnsResponseCounters(const MdnsResponseCounters &from, threadnetwork::T to->set_aborted_count(from.mAborted); to->set_invalid_state_count(from.mInvalidState); } + +threadnetwork::TelemetryData_EpskcState GetEpskcState(otInstance *aInstance) +{ + if (!otBorderAgentIsEphemeralKeyActive(aInstance)) + { + return threadnetwork::TelemetryData::EPSKC_STATE_INACTIVE; + } + + if (otBorderAgentGetState(aInstance) == OT_BORDER_AGENT_STATE_ACTIVE) + { + return threadnetwork::TelemetryData::EPSKC_STATE_CONNECTED; + } + + return threadnetwork::TelemetryData::EPSKC_STATE_READY_FOR_CONNECTION; +} #endif // OTBR_ENABLE_TELEMETRY_DATA_API } // namespace @@ -1596,8 +1612,35 @@ otError ThreadHelper::RetrieveTelemetryData(Mdns::Publisher *aPublisher, threadn #endif // OTBR_ENABLE_NAT64 #if OTBR_ENABLE_DHCP6_PD RetrievePdInfo(wpanBorderRouter); -#endif // OTBR_ENABLE_DHCP6_PD - // End of WpanBorderRouter section. +#endif // + { + auto administrationInfo = wpanBorderRouter->mutable_administration_info(); + auto epskcInfo = administrationInfo->mutable_epskc_info(); + auto pskcInfo = administrationInfo->mutable_pskc_info(); + auto otBorderAgentCounters = *otBorderAgentGetCounters(mInstance); + + epskcInfo->set_state(GetEpskcState(mInstance)); + epskcInfo->set_activation_count(otBorderAgentCounters.mEpskcActivations); + epskcInfo->set_deactivation_clear_count(otBorderAgentCounters.mEpskcDeactivationClears); + epskcInfo->set_deactivation_timeout_count(otBorderAgentCounters.mEpskcDeactivationTimeouts); + epskcInfo->set_deactivation_max_connection_reached_count( + otBorderAgentCounters.mEpskcDeactivationMaxAttempts); + epskcInfo->set_deactivation_disconnect_count(otBorderAgentCounters.mEpskcDeactivationDisconnects); + epskcInfo->set_invalid_ba_state_error_count(otBorderAgentCounters.mEpskcInvalidBaStateErrors); + epskcInfo->set_invalid_args_error_count(otBorderAgentCounters.mEpskcInvalidArgsErrors); + epskcInfo->set_start_secure_session_error_count(otBorderAgentCounters.mEpskcStartSecureSessionErrors); + epskcInfo->set_secure_session_success_count(otBorderAgentCounters.mEpskcSecureSessionSuccesses); + epskcInfo->set_secure_session_failure_count(otBorderAgentCounters.mEpskcSecureSessionFailures); + epskcInfo->set_commissioner_petition_count(otBorderAgentCounters.mEpskcCommissionerPetitions); + + pskcInfo->set_secure_session_success_count(otBorderAgentCounters.mPskcSecureSessionSuccesses); + pskcInfo->set_secure_session_failure_count(otBorderAgentCounters.mPskcSecureSessionFailures); + pskcInfo->set_commissioner_petition_count(otBorderAgentCounters.mPskcCommissionerPetitions); + + administrationInfo->set_mgmt_active_get_count(otBorderAgentCounters.mMgmtActiveGets); + administrationInfo->set_mgmt_pending_get_count(otBorderAgentCounters.mMgmtPendingGets); + } + // End of WpanBorderRouter section. // Start of WpanRcp section. { diff --git a/tests/dbus/test_dbus_client.cpp b/tests/dbus/test_dbus_client.cpp index b28fdddb7f9..aae169e64aa 100644 --- a/tests/dbus/test_dbus_client.cpp +++ b/tests/dbus/test_dbus_client.cpp @@ -349,6 +349,39 @@ void CheckTelemetryData(ThreadApiDBus *aApi) #if OTBR_ENABLE_LINK_METRICS_TELEMETRY TEST_ASSERT(telemetryData.low_power_metrics().link_metrics_entries_size() >= 0); #endif +#if OTBR_ENABLE_BORDER_AGENT + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().state() == + threadnetwork::TelemetryData::EPSKC_STATE_INACTIVE); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().activation_count() == 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().deactivation_clear_count() == 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().deactivation_timeout_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router() + .administration_info() + .epskc_info() + .deactivation_max_connection_reached_count() == 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().deactivation_disconnect_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().invalid_ba_state_error_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().invalid_args_error_count() == 0); + TEST_ASSERT( + telemetryData.wpan_border_router().administration_info().epskc_info().start_secure_session_error_count() == 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().secure_session_success_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().secure_session_failure_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().epskc_info().commissioner_petition_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().pskc_info().secure_session_success_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().pskc_info().secure_session_failure_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().pskc_info().commissioner_petition_count() == + 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().mgmt_active_get_count() == 0); + TEST_ASSERT(telemetryData.wpan_border_router().administration_info().mgmt_pending_get_count() == 0); +#endif } #endif