mirror of
https://github.com/espressif/openthread.git
synced 2026-07-29 23:27:46 +00:00
[tcat] implement vendor policy for TLV support and automatic advertisement activation/deactivation (#13038)
This commit implements additional vendor application or ecosystem policy settings for TCAT including: 1) Automatic deactivation of the TCAT agent / TCAT advertisement after the thread network has been started over TCAT 2) Automatic activation of the TCAT agent / TCAT advertisement after the thread network has been stopped over TCAT 3) Automatic activation of the TCAT agent / TCAT advertisement after decommissioning over TCAT 4) Blocking support of certain TCAT TLVs by the application / ecosystem The commit also fixes an issue with certificate storage after decommissioning.
This commit is contained in:
@@ -193,6 +193,9 @@ void Notifier::EmitEvents(void)
|
||||
#if OPENTHREAD_CONFIG_LINK_METRICS_MANAGER_ENABLE
|
||||
Get<Utils::LinkMetricsManager>().HandleNotifierEvents(events);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
||||
Get<MeshCoP::TcatAgent>().HandleNotifierEvents(events);
|
||||
#endif
|
||||
|
||||
for (ExternalCallback &callback : mExternalCallbacks)
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@ TcatAgent::TcatAgent(Instance &aInstance)
|
||||
, mActiveOrStandbyTimer(aInstance)
|
||||
, mTcatActiveDurationMs(0)
|
||||
, mHashVerificationAttempts(1)
|
||||
, mLastDeviceRole(Mle::kRoleDisabled)
|
||||
{
|
||||
ClearCommissionerState();
|
||||
mLastHashVerificationTimestamp = Get<UptimeTracker>().GetUptimeInSeconds();
|
||||
@@ -95,8 +96,16 @@ Error TcatAgent::Start(AppDataReceiveCallback aAppDataReceiveCallback, JoinCallb
|
||||
mState = kStateActive;
|
||||
mNextState = kStateActive;
|
||||
mTcatActiveDurationMs = 0;
|
||||
mLastDeviceRole = Get<Mle::Mle>().GetRole();
|
||||
|
||||
LogInfo("Start");
|
||||
|
||||
if (!mVendorInfo->mKeepActiveAfterJoining && mLastDeviceRole != Mle::kRoleDisabled &&
|
||||
Get<ActiveDatasetManager>().IsCommissioned())
|
||||
{
|
||||
IgnoreError(Standby());
|
||||
}
|
||||
|
||||
exit:
|
||||
LogWarnOnError(error, "Start");
|
||||
return error;
|
||||
@@ -400,10 +409,19 @@ Error TcatAgent::HandleSingleTlv(const Message &aIncomingMessage, Message &aOutg
|
||||
const uint16_t initialOutgoingMsgLength = aOutgoingMessage.GetLength();
|
||||
bool response = false;
|
||||
|
||||
VerifyOrExit(mVendorInfo != nullptr, error = kErrorInvalidState);
|
||||
VerifyOrExit(IsConnected(), error = kErrorInvalidState);
|
||||
|
||||
SuccessOrExit(error = tlvInfo.ParseFrom(aIncomingMessage, aIncomingMessage.GetOffset()));
|
||||
|
||||
if (mVendorInfo->mTlvSupportHandler != nullptr &&
|
||||
!mVendorInfo->mTlvSupportHandler(&GetInstance(), static_cast<otTcatCommandTlvType>(tlvInfo.GetType()),
|
||||
mJoinCallback.GetContext()))
|
||||
{
|
||||
statusCode = kStatusUnsupported;
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
switch (tlvInfo.GetType())
|
||||
{
|
||||
case kTlvDisconnect:
|
||||
@@ -665,13 +683,19 @@ Error TcatAgent::HandleDecommission(void)
|
||||
|
||||
VerifyOrExit(IsCommandClassAuthorized(kDecommissioning), error = kErrorRejected);
|
||||
SuccessOrExit(error = Get<Ble::BleSecure>().GetPeerCertificateDer(buf, &bufLen, bufLen));
|
||||
Get<Settings>().SaveTcatCommissionerCertificate(buf, static_cast<uint16_t>(bufLen));
|
||||
|
||||
IgnoreReturnValue(otThreadSetEnabled(&GetInstance(), false));
|
||||
Get<Mle::Mle>().Stop();
|
||||
|
||||
if (!mVendorInfo->mDoNotActivateAfterLeaving)
|
||||
{
|
||||
IgnoreError(Activate(0, 0));
|
||||
}
|
||||
|
||||
Get<ActiveDatasetManager>().Clear();
|
||||
Get<PendingDatasetManager>().Clear();
|
||||
|
||||
IgnoreReturnValue(Get<Instance>().ErasePersistentInfo());
|
||||
Get<Settings>().SaveTcatCommissionerCertificate(buf, static_cast<uint16_t>(bufLen));
|
||||
|
||||
#if !OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
{
|
||||
@@ -681,6 +705,7 @@ Error TcatAgent::HandleDecommission(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
mJoinCallback.InvokeIfSet(&GetInstance(), /* aIsJoin */ false, error);
|
||||
mIsCommissioned = false; // enable repeated commissioning/decommissioning in a session
|
||||
|
||||
exit:
|
||||
@@ -979,24 +1004,29 @@ Error TcatAgent::HandleStartThreadInterface(void)
|
||||
#endif
|
||||
|
||||
Get<ThreadNetif>().Up();
|
||||
error = Get<Mle::Mle>().Start();
|
||||
SuccessOrExit(error = Get<Mle::Mle>().Start());
|
||||
|
||||
exit:
|
||||
// error values for callback MUST be limited to the allowed set, see #JoinCallback
|
||||
mJoinCallback.InvokeIfSet(error);
|
||||
mJoinCallback.InvokeIfSet(&GetInstance(), /* aIsJoin */ true, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
Error TcatAgent::HandleStopThreadInterface(void)
|
||||
{
|
||||
Error error;
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(IsCommandClassAuthorized(kCommissioning), error = kErrorRejected);
|
||||
|
||||
error = otThreadSetEnabled(&GetInstance(), false);
|
||||
Get<Mle::Mle>().Stop();
|
||||
|
||||
if (!mVendorInfo->mDoNotActivateAfterLeaving)
|
||||
{
|
||||
IgnoreError(Activate(0, 0));
|
||||
}
|
||||
|
||||
exit:
|
||||
mJoinCallback.InvokeIfSet(error);
|
||||
mJoinCallback.InvokeIfSet(&GetInstance(), /* aIsJoin */ false, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1043,6 +1073,26 @@ void TcatAgent::NotifyStateChange(void)
|
||||
mState == kStateConnected);
|
||||
}
|
||||
|
||||
void TcatAgent::HandleNotifierEvents(Events aEvents)
|
||||
{
|
||||
VerifyOrExit(IsStarted());
|
||||
VerifyOrExit(mVendorInfo != nullptr);
|
||||
|
||||
if (aEvents.ContainsAny(kEventThreadRoleChanged))
|
||||
{
|
||||
if (!mVendorInfo->mKeepActiveAfterJoining && Get<Mle::Mle>().IsAttached() &&
|
||||
(mLastDeviceRole == Mle::kRoleDisabled || mLastDeviceRole == Mle::kRoleDetached))
|
||||
{
|
||||
IgnoreError(Standby());
|
||||
}
|
||||
|
||||
mLastDeviceRole = Get<Mle::Mle>().GetRole();
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
template <> void TcatAgent::HandleTmf<kUriTcatEnable>(Coap::Msg &aMsg)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "common/log.hpp"
|
||||
#include "common/message.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/uptime.hpp"
|
||||
#include "mac/mac_types.hpp"
|
||||
#include "meshcop/dataset.hpp"
|
||||
@@ -74,6 +75,7 @@ class TcatAgent : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
friend class Ble::BleSecure;
|
||||
friend class UnitTester;
|
||||
friend class ot::Notifier;
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -164,49 +166,44 @@ public:
|
||||
enum CommandTlvType : uint8_t
|
||||
{
|
||||
// Command Class General
|
||||
kTlvResponseWithStatus = 0x01, ///< TCAT response with status value TLV
|
||||
kTlvResponseWithPayload = 0x02, ///< TCAT response with payload TLV
|
||||
kTlvResponseEvent = 0x03, ///< TCAT response event TLV (reserved)
|
||||
kTlvGetNetworkName = 0x08, ///< TCAT network name query TLV
|
||||
kTlvDisconnect = 0x09, ///< TCAT disconnect request TLV
|
||||
kTlvPing = 0x0A, ///< TCAT ping request TLV
|
||||
kTlvGetDeviceId = 0x0B, ///< TCAT device ID query TLV
|
||||
kTlvGetExtendedPanID = 0x0C, ///< TCAT extended PAN ID query TLV
|
||||
kTlvGetProvisioningURL = 0x0D, ///< TCAT provisioning URL query TLV
|
||||
kTlvPresentPskdHash = 0x10, ///< TCAT commissioner rights elevation request TLV using PSKd hash
|
||||
kTlvPresentPskcHash = 0x11, ///< TCAT commissioner rights elevation request TLV using PSKc hash
|
||||
kTlvPresentInstallCodeHash = 0x12, ///< TCAT commissioner rights elevation request TLV using install code
|
||||
kTlvRequestRandomNumChallenge = 0x13, ///< TCAT random number challenge query TLV
|
||||
kTlvResponseWithStatus = OT_TCAT_TLV_RESPONSE_WITH_STATUS,
|
||||
kTlvResponseWithPayload = OT_TCAT_TLV_RESPONSE_WITH_PAYLOAD,
|
||||
kTlvResponseEvent = OT_TCAT_TLV_RESPONSE_EVENT,
|
||||
kTlvGetNetworkName = OT_TCAT_TLV_GET_NETWORK_NAME,
|
||||
kTlvDisconnect = OT_TCAT_TLV_DISCONNECT,
|
||||
kTlvPing = OT_TCAT_TLV_PING,
|
||||
kTlvGetDeviceId = OT_TCAT_TLV_GET_DEVICE_ID,
|
||||
kTlvGetExtendedPanID = OT_TCAT_TLV_GET_EXTENDED_PAN_ID,
|
||||
kTlvGetProvisioningURL = OT_TCAT_TLV_GET_PROVISIONING_URL,
|
||||
kTlvPresentPskdHash = OT_TCAT_TLV_PRESENT_PSKD_HASH,
|
||||
kTlvPresentPskcHash = OT_TCAT_TLV_PRESENT_PSKC_HASH,
|
||||
kTlvPresentInstallCodeHash = OT_TCAT_TLV_PRESENT_INSTALL_CODE_HASH,
|
||||
kTlvRequestRandomNumChallenge = OT_TCAT_TLV_REQUEST_RANDOM_CHALLENGE,
|
||||
|
||||
// Command Class Commissioning
|
||||
kTlvSetActiveOperationalDataset = 0x20, ///< TCAT active operational dataset TLV
|
||||
kTlvSetActiveOperationalDatasetAlt = 0x21, ///< TCAT active operational dataset alternative #1 TLV (reserved)
|
||||
kTlvGetCommissionerCertificate = 0x25, ///< TCAT commissioner certificate query TLV
|
||||
kTlvGetDiagnosticTlvs = 0x26, ///< TCAT diagnostics TLVs query TLV
|
||||
kTlvStartThreadInterface = 0x27, ///< TCAT start thread interface request TLV
|
||||
kTlvStopThreadInterface = 0x28, ///< TCAT stop thread interface request TLV
|
||||
kTlvSetActiveOperationalDataset = OT_TCAT_TLV_SET_ACTIVE_OPERATIONAL_DATASET,
|
||||
kTlvSetActiveOperationalDatasetAlt = OT_TCAT_TLV_SET_ACTIVE_OPERATIONAL_DATASET_ALT,
|
||||
kTlvGetCommissionerCertificate = OT_TCAT_TLV_GET_COMMISSIONER_CERTIFICATE,
|
||||
kTlvGetDiagnosticTlvs = OT_TCAT_TLV_GET_DIAGNOSTIC_TLVS,
|
||||
kTlvStartThreadInterface = OT_TCAT_TLV_START_THREAD_INTERFACE,
|
||||
kTlvStopThreadInterface = OT_TCAT_TLV_STOP_THREAD_INTERFACE,
|
||||
|
||||
// Command Class Extraction
|
||||
kTlvGetActiveOperationalDataset = 0x40, ///< TCAT active operational dataset query TLV
|
||||
kTlvGetActiveOperationalDatasetAlt = 0x41, ///< TCAT active operational dataset alternative #1 query TLV (rsv)
|
||||
kTlvGetActiveOperationalDataset = OT_TCAT_TLV_GET_ACTIVE_OPERATIONAL_DATASET,
|
||||
kTlvGetActiveOperationalDatasetAlt = OT_TCAT_TLV_GET_ACTIVE_OPERATIONAL_DATASET_ALT,
|
||||
|
||||
// Command Class Decommissioning
|
||||
kTlvDecommission = 0x60, ///< TCAT decommission request TLV
|
||||
kTlvDecommission = OT_TCAT_TLV_DECOMMISSION,
|
||||
|
||||
// Command Class Application
|
||||
kTlvGetApplicationLayers = 0x80, ///< TCAT get application layers request TLV
|
||||
kTlvSendApplicationData1 = 0x81, ///< TCAT send application data 1 TLV
|
||||
kTlvSendApplicationData2 = 0x82, ///< TCAT send application data 2 TLV
|
||||
kTlvSendApplicationData3 = 0x83, ///< TCAT send application data 3 TLV
|
||||
kTlvSendApplicationData4 = 0x84, ///< TCAT send application data 4 TLV
|
||||
kTlvServiceNameUdp = 0x89, ///< TCAT service name UDP sub-TLV (not used as a command)
|
||||
kTlvServiceNameTcp = 0x8A, ///< TCAT service name TCP sub-TLV (not used as a command)
|
||||
kTlvSendVendorSpecificData = 0x9F, ///< TCAT send vendor specific command or data TLV
|
||||
|
||||
// Command Class CCM
|
||||
kTlvSetLDevIdOperationalCert = 0xA0, ///< TCAT set LDevID operational certificate TLV (reserved)
|
||||
kTlvSetLDevIdPrivateKey = 0xA1, ///< TCAT set LDevID operational certificate private key TLV (reserved)
|
||||
kTlvSetDomainCaCert = 0xA2, ///< TCAT set domain CA certificate TLV (reserved)
|
||||
kTlvGetApplicationLayers = OT_TCAT_TLV_GET_APPLICATION_LAYERS,
|
||||
kTlvSendApplicationData1 = OT_TCAT_TLV_SEND_APPLICATION_DATA_1,
|
||||
kTlvSendApplicationData2 = OT_TCAT_TLV_SEND_APPLICATION_DATA_2,
|
||||
kTlvSendApplicationData3 = OT_TCAT_TLV_SEND_APPLICATION_DATA_3,
|
||||
kTlvSendApplicationData4 = OT_TCAT_TLV_SEND_APPLICATION_DATA_4,
|
||||
kTlvServiceNameUdp = OT_TCAT_TLV_SERVICE_NAME_UDP,
|
||||
kTlvServiceNameTcp = OT_TCAT_TLV_SERVICE_NAME_TCP,
|
||||
kTlvSendVendorSpecificData = OT_TCAT_TLV_SEND_VENDOR_SPECIFIC_DATA,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -441,6 +438,7 @@ public:
|
||||
private:
|
||||
void NotifyApplicationResponseSent(void) { mApplicationResponsePending = false; }
|
||||
void NotifyStateChange(void);
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
void ClearCommissionerState();
|
||||
Error Connected(MeshCoP::Tls::Extension &aTls);
|
||||
void Disconnected(void);
|
||||
@@ -520,10 +518,11 @@ private:
|
||||
bool mIsCommissioned : 1;
|
||||
bool mApplicationResponsePending : 1;
|
||||
using ExpireTimer = TimerMilliIn<TcatAgent, &TcatAgent::HandleTimer>;
|
||||
ExpireTimer mActiveOrStandbyTimer;
|
||||
uint32_t mTcatActiveDurationMs;
|
||||
UptimeSec mLastHashVerificationTimestamp;
|
||||
uint8_t mHashVerificationAttempts;
|
||||
ExpireTimer mActiveOrStandbyTimer;
|
||||
uint32_t mTcatActiveDurationMs;
|
||||
UptimeSec mLastHashVerificationTimestamp;
|
||||
uint8_t mHashVerificationAttempts;
|
||||
Mle::DeviceRole mLastDeviceRole;
|
||||
};
|
||||
|
||||
DeclareTmfHandler(TcatAgent, kUriTcatEnable);
|
||||
|
||||
Reference in New Issue
Block a user