mirror of
https://github.com/espressif/openthread.git
synced 2026-08-20 17:39:51 +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:
@@ -138,6 +138,9 @@ otError otBleSecureSetTcatVendorInfo(otInstance *aInstance, const otTcatVendorIn
|
|||||||
/**
|
/**
|
||||||
* Enables the TCAT protocol over BLE Secure.
|
* Enables the TCAT protocol over BLE Secure.
|
||||||
*
|
*
|
||||||
|
* Vendor info must be set before calling this function. Depending on the policy defined in the vendor info, TCAT may
|
||||||
|
* start in standby mode if the device is commissioned and Thread is enabled.
|
||||||
|
*
|
||||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
* @param[in] aJoinHandler A pointer to a function that is called when a network join or leave
|
* @param[in] aJoinHandler A pointer to a function that is called when a network join or leave
|
||||||
* operation is requested under guidance of the TCAT Commissioner.
|
* operation is requested under guidance of the TCAT Commissioner.
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @note This number versions both OpenThread platform and user APIs.
|
* @note This number versions both OpenThread platform and user APIs.
|
||||||
*/
|
*/
|
||||||
#define OPENTHREAD_API_VERSION (599)
|
#define OPENTHREAD_API_VERSION (600)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup api-instance
|
* @addtogroup api-instance
|
||||||
|
|||||||
+122
-32
@@ -75,6 +75,58 @@ extern "C" {
|
|||||||
#define OT_TCAT_MAX_DEVICEID_SIZE 64 ///< TCAT max size of device ID.
|
#define OT_TCAT_MAX_DEVICEID_SIZE 64 ///< TCAT max size of device ID.
|
||||||
#define OT_TCAT_ENABLE_MAX 600 ///< TCAT_ENABLE_MAX, default max TMF TCAT enable time, in seconds.
|
#define OT_TCAT_ENABLE_MAX 600 ///< TCAT_ENABLE_MAX, default max TMF TCAT enable time, in seconds.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents TCAT command TLV type.
|
||||||
|
*/
|
||||||
|
typedef enum otTcatCommandTlvType
|
||||||
|
{
|
||||||
|
// Command Class General
|
||||||
|
OT_TCAT_TLV_RESPONSE_WITH_STATUS = 0x01, ///< TCAT response with status value TLV
|
||||||
|
OT_TCAT_TLV_RESPONSE_WITH_PAYLOAD = 0x02, ///< TCAT response with payload TLV
|
||||||
|
OT_TCAT_TLV_RESPONSE_EVENT = 0x03, ///< TCAT response event TLV (reserved)
|
||||||
|
OT_TCAT_TLV_GET_NETWORK_NAME = 0x08, ///< TCAT network name query TLV
|
||||||
|
OT_TCAT_TLV_DISCONNECT = 0x09, ///< TCAT disconnect request TLV
|
||||||
|
OT_TCAT_TLV_PING = 0x0A, ///< TCAT ping request TLV
|
||||||
|
OT_TCAT_TLV_GET_DEVICE_ID = 0x0B, ///< TCAT device ID query TLV
|
||||||
|
OT_TCAT_TLV_GET_EXTENDED_PAN_ID = 0x0C, ///< TCAT extended PAN ID query TLV
|
||||||
|
OT_TCAT_TLV_GET_PROVISIONING_URL = 0x0D, ///< TCAT provisioning URL query TLV
|
||||||
|
OT_TCAT_TLV_PRESENT_PSKD_HASH = 0x10, ///< TCAT rights elevation request TLV using PSKd hash
|
||||||
|
OT_TCAT_TLV_PRESENT_PSKC_HASH = 0x11, ///< TCAT rights elevation request TLV using PSKc hash
|
||||||
|
OT_TCAT_TLV_PRESENT_INSTALL_CODE_HASH = 0x12, ///< TCAT rights elevation TLV using install code
|
||||||
|
OT_TCAT_TLV_REQUEST_RANDOM_CHALLENGE = 0x13, ///< TCAT random number challenge query TLV
|
||||||
|
|
||||||
|
// Command Class Commissioning
|
||||||
|
OT_TCAT_TLV_SET_ACTIVE_OPERATIONAL_DATASET = 0x20, ///< TCAT active operational dataset TLV
|
||||||
|
OT_TCAT_TLV_SET_ACTIVE_OPERATIONAL_DATASET_ALT = 0x21, ///< TCAT active dataset alt #1 TLV (reserved)
|
||||||
|
OT_TCAT_TLV_GET_COMMISSIONER_CERTIFICATE = 0x25, ///< TCAT commissioner certificate query TLV
|
||||||
|
OT_TCAT_TLV_GET_DIAGNOSTIC_TLVS = 0x26, ///< TCAT diagnostics TLVs query TLV
|
||||||
|
OT_TCAT_TLV_START_THREAD_INTERFACE = 0x27, ///< TCAT start thread interface request TLV
|
||||||
|
OT_TCAT_TLV_STOP_THREAD_INTERFACE = 0x28, ///< TCAT stop thread interface request TLV
|
||||||
|
|
||||||
|
// Command Class Extraction
|
||||||
|
OT_TCAT_TLV_GET_ACTIVE_OPERATIONAL_DATASET = 0x40, ///< TCAT active operational dataset query TLV
|
||||||
|
OT_TCAT_TLV_GET_ACTIVE_OPERATIONAL_DATASET_ALT = 0x41, ///< TCAT active dataset alt #1 query TLV (reserved)
|
||||||
|
|
||||||
|
// Command Class Decommissioning
|
||||||
|
OT_TCAT_TLV_DECOMMISSION = 0x60, ///< TCAT decommission request TLV
|
||||||
|
|
||||||
|
// Command Class Application
|
||||||
|
OT_TCAT_TLV_GET_APPLICATION_LAYERS = 0x80, ///< TCAT get application layers request TLV
|
||||||
|
OT_TCAT_TLV_SEND_APPLICATION_DATA_1 = 0x81, ///< TCAT send application data 1 TLV
|
||||||
|
OT_TCAT_TLV_SEND_APPLICATION_DATA_2 = 0x82, ///< TCAT send application data 2 TLV
|
||||||
|
OT_TCAT_TLV_SEND_APPLICATION_DATA_3 = 0x83, ///< TCAT send application data 3 TLV
|
||||||
|
OT_TCAT_TLV_SEND_APPLICATION_DATA_4 = 0x84, ///< TCAT send application data 4 TLV
|
||||||
|
OT_TCAT_TLV_SERVICE_NAME_UDP = 0x89, ///< TCAT service name UDP sub-TLV (not used as a command)
|
||||||
|
OT_TCAT_TLV_SERVICE_NAME_TCP = 0x8A, ///< TCAT service name TCP sub-TLV (not used as a command)
|
||||||
|
OT_TCAT_TLV_SEND_VENDOR_SPECIFIC_DATA = 0x9F, ///< TCAT send vendor specific command or data TLV
|
||||||
|
|
||||||
|
// Command Class CCM
|
||||||
|
OT_TCAT_TLV_SET_LDEV_ID_OPERATIONAL_CERT = 0xA0, ///< TCAT set LDevID certificate TLV (reserved)
|
||||||
|
OT_TCAT_TLV_SET_LDEV_ID_PRIVATE_KEY = 0xA1, ///< TCAT set LDevID certificate private key TLV (reserved)
|
||||||
|
OT_TCAT_TLV_SET_DOMAIN_CA_CERT = 0xA2, ///< TCAT set domain CA certificate TLV (reserved)
|
||||||
|
|
||||||
|
} otTcatCommandTlvType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents TCAT status code.
|
* Represents TCAT status code.
|
||||||
*/
|
*/
|
||||||
@@ -153,35 +205,6 @@ typedef struct otTcatGeneralDeviceId
|
|||||||
uint8_t mDeviceId[OT_TCAT_MAX_DEVICEID_SIZE];
|
uint8_t mDeviceId[OT_TCAT_MAX_DEVICEID_SIZE];
|
||||||
} otTcatGeneralDeviceId;
|
} otTcatGeneralDeviceId;
|
||||||
|
|
||||||
/**
|
|
||||||
* This structure represents a TCAT vendor information.
|
|
||||||
*
|
|
||||||
* The content of this structure MUST persist and remain unchanged while a TCAT session is running.
|
|
||||||
*/
|
|
||||||
typedef struct otTcatVendorInfo
|
|
||||||
{
|
|
||||||
const char *mProvisioningUrl; ///< Provisioning URL path string
|
|
||||||
const char *mVendorName; ///< Vendor name string
|
|
||||||
const char *mVendorModel; ///< Vendor model string
|
|
||||||
const char *mVendorSwVersion; ///< Vendor software version string
|
|
||||||
const char *mVendorData; ///< Vendor specific data string
|
|
||||||
const char *mPskdString; ///< Vendor managed pre-shared key for device
|
|
||||||
const char *mInstallCode; ///< Vendor managed install code string
|
|
||||||
const otTcatAdvertisedDeviceId
|
|
||||||
*mAdvertisedDeviceIds; /** Vendor managed advertised device ID array.
|
|
||||||
Array is terminated like C string with OT_TCAT_DEVICE_ID_EMPTY */
|
|
||||||
const otTcatGeneralDeviceId *mGeneralDeviceId; /** Vendor managed general device ID array.
|
|
||||||
(if NULL: device ID is set to EUI-64 in binary format) */
|
|
||||||
const char *mApplicationServiceName[OT_TCAT_APPLICATION_LAYER_MAX_COUNT]; /** Array with application service names
|
|
||||||
as C string with maximum length
|
|
||||||
OT_TCAT_SERVICE_NAME_MAX_LENGTH or
|
|
||||||
NULL if not supported */
|
|
||||||
bool mApplicationServiceIsTcp[OT_TCAT_APPLICATION_LAYER_MAX_COUNT]; /** Array with boolean values indicating
|
|
||||||
if the service is of TCP type (otherwise
|
|
||||||
UDP) */
|
|
||||||
|
|
||||||
} otTcatVendorInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to call when application data or vendor-specific data was received over a TCAT TLS connection.
|
* Pointer to call when application data or vendor-specific data was received over a TCAT TLS connection.
|
||||||
* The application may generate a response to an incoming TCAT application data packet. The TCAT agent
|
* The application may generate a response to an incoming TCAT application data packet. The TCAT agent
|
||||||
@@ -201,9 +224,12 @@ typedef void (*otHandleTcatApplicationDataReceive)(otInstance *aIn
|
|||||||
void *aContext);
|
void *aContext);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to call to notify the completion of a network join/leave operation performed under
|
* Pointer to call to notify of a network join/leave operation initiated under guidance of a TCAT Commissioner.
|
||||||
* guidance of a TCAT Commissioner.
|
|
||||||
*
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
* @param[in] aIsJoin True if the operation was a network join (OT_TCAT_TLV_START_THREAD_INTERFACE),
|
||||||
|
* false if it was a network leave (OT_TCAT_TLV_STOP_THREAD_INTERFACE or
|
||||||
|
* OT_TCAT_TLV_DECOMMISSION).
|
||||||
* @param[in] aError OT_ERROR_NONE if the network join/leave operation was successfully started.
|
* @param[in] aError OT_ERROR_NONE if the network join/leave operation was successfully started.
|
||||||
* OT_ERROR_INVALID_STATE if network join was requested but network credentials
|
* OT_ERROR_INVALID_STATE if network join was requested but network credentials
|
||||||
* were missing or incomplete.
|
* were missing or incomplete.
|
||||||
@@ -213,7 +239,71 @@ typedef void (*otHandleTcatApplicationDataReceive)(otInstance *aIn
|
|||||||
* credential mismatch.
|
* credential mismatch.
|
||||||
* @param[in] aContext A pointer to arbitrary context information.
|
* @param[in] aContext A pointer to arbitrary context information.
|
||||||
*/
|
*/
|
||||||
typedef void (*otHandleTcatJoin)(otError aError, void *aContext);
|
typedef void (*otHandleTcatJoin)(otInstance *aInstance, bool aIsJoin, otError aError, void *aContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to call to control if a TCAT TLV of a specific type is supported. The application may allow
|
||||||
|
* or reject processing of a received TCAT command based on an application defined policy.
|
||||||
|
* If no handler is defined, all received TCAT commands will be allowed if the respective command class
|
||||||
|
* is authorized. If a handler is defined and returns false, the TCAT command will be rejected with status
|
||||||
|
* OT_TCAT_STATUS_UNSUPPORTED. If the handler returns true, the TCAT command will be allowed if the respective
|
||||||
|
* command class is authorized.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
* @param[in] aTlvType A TLV type to be authorized.
|
||||||
|
* @param[in] aContext A pointer to arbitrary context information.
|
||||||
|
*
|
||||||
|
* @returns a boolean value indicating whether the TLV type is supported, based on current policy.
|
||||||
|
*/
|
||||||
|
typedef bool (*otHandleTcatTlvSupport)(otInstance *aInstance, otTcatCommandTlvType aTlvType, void *aContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure represents a TCAT vendor information.
|
||||||
|
*
|
||||||
|
* The content of this structure MUST persist and remain unchanged while a TCAT session is running.
|
||||||
|
*/
|
||||||
|
typedef struct otTcatVendorInfo
|
||||||
|
{
|
||||||
|
const char *mProvisioningUrl; ///< Provisioning URL path string
|
||||||
|
const char *mVendorName; ///< Vendor name string
|
||||||
|
const char *mVendorModel; ///< Vendor model string
|
||||||
|
const char *mVendorSwVersion; ///< Vendor software version string
|
||||||
|
const char *mVendorData; ///< Vendor specific data string
|
||||||
|
const char *mPskdString; ///< Vendor managed pre-shared key for device
|
||||||
|
const char *mInstallCode; ///< Vendor managed install code string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor managed advertised device ID array. Array is terminated like C string with OT_TCAT_DEVICE_ID_EMPTY.
|
||||||
|
*/
|
||||||
|
const otTcatAdvertisedDeviceId *mAdvertisedDeviceIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor managed general device ID array (if NULL: device ID is set to EUI-64 in binary format)
|
||||||
|
*/
|
||||||
|
const otTcatGeneralDeviceId *mGeneralDeviceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array with application service names as C string with maximum length OT_TCAT_SERVICE_NAME_MAX_LENGTH or NULL if
|
||||||
|
* not supported.
|
||||||
|
*/
|
||||||
|
const char *mApplicationServiceName[OT_TCAT_APPLICATION_LAYER_MAX_COUNT];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array with boolean values indicating if the service is of TCP type (otherwise UDP).
|
||||||
|
*/
|
||||||
|
bool mApplicationServiceIsTcp[OT_TCAT_APPLICATION_LAYER_MAX_COUNT];
|
||||||
|
|
||||||
|
bool mKeepActiveAfterJoining; ///< Continue advertising after thread interface has joined a network
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent activating advertising indefinitely after the TCAT command OT_TCAT_TLV_STOP_THREAD_INTERFACE or
|
||||||
|
* OT_TCAT_TLV_DECOMMISSION has been received.
|
||||||
|
*/
|
||||||
|
bool mDoNotActivateAfterLeaving;
|
||||||
|
|
||||||
|
otHandleTcatTlvSupport mTlvSupportHandler; ///< Optional pointer to a function to control TCAT TLV support
|
||||||
|
|
||||||
|
} otTcatVendorInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
|||||||
@@ -193,6 +193,9 @@ void Notifier::EmitEvents(void)
|
|||||||
#if OPENTHREAD_CONFIG_LINK_METRICS_MANAGER_ENABLE
|
#if OPENTHREAD_CONFIG_LINK_METRICS_MANAGER_ENABLE
|
||||||
Get<Utils::LinkMetricsManager>().HandleNotifierEvents(events);
|
Get<Utils::LinkMetricsManager>().HandleNotifierEvents(events);
|
||||||
#endif
|
#endif
|
||||||
|
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
||||||
|
Get<MeshCoP::TcatAgent>().HandleNotifierEvents(events);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (ExternalCallback &callback : mExternalCallbacks)
|
for (ExternalCallback &callback : mExternalCallbacks)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ TcatAgent::TcatAgent(Instance &aInstance)
|
|||||||
, mActiveOrStandbyTimer(aInstance)
|
, mActiveOrStandbyTimer(aInstance)
|
||||||
, mTcatActiveDurationMs(0)
|
, mTcatActiveDurationMs(0)
|
||||||
, mHashVerificationAttempts(1)
|
, mHashVerificationAttempts(1)
|
||||||
|
, mLastDeviceRole(Mle::kRoleDisabled)
|
||||||
{
|
{
|
||||||
ClearCommissionerState();
|
ClearCommissionerState();
|
||||||
mLastHashVerificationTimestamp = Get<UptimeTracker>().GetUptimeInSeconds();
|
mLastHashVerificationTimestamp = Get<UptimeTracker>().GetUptimeInSeconds();
|
||||||
@@ -95,8 +96,16 @@ Error TcatAgent::Start(AppDataReceiveCallback aAppDataReceiveCallback, JoinCallb
|
|||||||
mState = kStateActive;
|
mState = kStateActive;
|
||||||
mNextState = kStateActive;
|
mNextState = kStateActive;
|
||||||
mTcatActiveDurationMs = 0;
|
mTcatActiveDurationMs = 0;
|
||||||
|
mLastDeviceRole = Get<Mle::Mle>().GetRole();
|
||||||
|
|
||||||
LogInfo("Start");
|
LogInfo("Start");
|
||||||
|
|
||||||
|
if (!mVendorInfo->mKeepActiveAfterJoining && mLastDeviceRole != Mle::kRoleDisabled &&
|
||||||
|
Get<ActiveDatasetManager>().IsCommissioned())
|
||||||
|
{
|
||||||
|
IgnoreError(Standby());
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
LogWarnOnError(error, "Start");
|
LogWarnOnError(error, "Start");
|
||||||
return error;
|
return error;
|
||||||
@@ -400,10 +409,19 @@ Error TcatAgent::HandleSingleTlv(const Message &aIncomingMessage, Message &aOutg
|
|||||||
const uint16_t initialOutgoingMsgLength = aOutgoingMessage.GetLength();
|
const uint16_t initialOutgoingMsgLength = aOutgoingMessage.GetLength();
|
||||||
bool response = false;
|
bool response = false;
|
||||||
|
|
||||||
|
VerifyOrExit(mVendorInfo != nullptr, error = kErrorInvalidState);
|
||||||
VerifyOrExit(IsConnected(), error = kErrorInvalidState);
|
VerifyOrExit(IsConnected(), error = kErrorInvalidState);
|
||||||
|
|
||||||
SuccessOrExit(error = tlvInfo.ParseFrom(aIncomingMessage, aIncomingMessage.GetOffset()));
|
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())
|
switch (tlvInfo.GetType())
|
||||||
{
|
{
|
||||||
case kTlvDisconnect:
|
case kTlvDisconnect:
|
||||||
@@ -665,13 +683,19 @@ Error TcatAgent::HandleDecommission(void)
|
|||||||
|
|
||||||
VerifyOrExit(IsCommandClassAuthorized(kDecommissioning), error = kErrorRejected);
|
VerifyOrExit(IsCommandClassAuthorized(kDecommissioning), error = kErrorRejected);
|
||||||
SuccessOrExit(error = Get<Ble::BleSecure>().GetPeerCertificateDer(buf, &bufLen, bufLen));
|
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<ActiveDatasetManager>().Clear();
|
||||||
Get<PendingDatasetManager>().Clear();
|
Get<PendingDatasetManager>().Clear();
|
||||||
|
|
||||||
IgnoreReturnValue(Get<Instance>().ErasePersistentInfo());
|
IgnoreReturnValue(Get<Instance>().ErasePersistentInfo());
|
||||||
|
Get<Settings>().SaveTcatCommissionerCertificate(buf, static_cast<uint16_t>(bufLen));
|
||||||
|
|
||||||
#if !OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
#if !OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||||
{
|
{
|
||||||
@@ -681,6 +705,7 @@ Error TcatAgent::HandleDecommission(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mJoinCallback.InvokeIfSet(&GetInstance(), /* aIsJoin */ false, error);
|
||||||
mIsCommissioned = false; // enable repeated commissioning/decommissioning in a session
|
mIsCommissioned = false; // enable repeated commissioning/decommissioning in a session
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -979,24 +1004,29 @@ Error TcatAgent::HandleStartThreadInterface(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Get<ThreadNetif>().Up();
|
Get<ThreadNetif>().Up();
|
||||||
error = Get<Mle::Mle>().Start();
|
SuccessOrExit(error = Get<Mle::Mle>().Start());
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
// error values for callback MUST be limited to the allowed set, see #JoinCallback
|
// error values for callback MUST be limited to the allowed set, see #JoinCallback
|
||||||
mJoinCallback.InvokeIfSet(error);
|
mJoinCallback.InvokeIfSet(&GetInstance(), /* aIsJoin */ true, error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error TcatAgent::HandleStopThreadInterface(void)
|
Error TcatAgent::HandleStopThreadInterface(void)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error = kErrorNone;
|
||||||
|
|
||||||
VerifyOrExit(IsCommandClassAuthorized(kCommissioning), error = kErrorRejected);
|
VerifyOrExit(IsCommandClassAuthorized(kCommissioning), error = kErrorRejected);
|
||||||
|
|
||||||
error = otThreadSetEnabled(&GetInstance(), false);
|
Get<Mle::Mle>().Stop();
|
||||||
|
|
||||||
|
if (!mVendorInfo->mDoNotActivateAfterLeaving)
|
||||||
|
{
|
||||||
|
IgnoreError(Activate(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mJoinCallback.InvokeIfSet(error);
|
mJoinCallback.InvokeIfSet(&GetInstance(), /* aIsJoin */ false, error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1043,6 +1073,26 @@ void TcatAgent::NotifyStateChange(void)
|
|||||||
mState == kStateConnected);
|
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)
|
template <> void TcatAgent::HandleTmf<kUriTcatEnable>(Coap::Msg &aMsg)
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#include "common/log.hpp"
|
#include "common/log.hpp"
|
||||||
#include "common/message.hpp"
|
#include "common/message.hpp"
|
||||||
#include "common/non_copyable.hpp"
|
#include "common/non_copyable.hpp"
|
||||||
|
#include "common/notifier.hpp"
|
||||||
#include "common/uptime.hpp"
|
#include "common/uptime.hpp"
|
||||||
#include "mac/mac_types.hpp"
|
#include "mac/mac_types.hpp"
|
||||||
#include "meshcop/dataset.hpp"
|
#include "meshcop/dataset.hpp"
|
||||||
@@ -74,6 +75,7 @@ class TcatAgent : public InstanceLocator, private NonCopyable
|
|||||||
{
|
{
|
||||||
friend class Ble::BleSecure;
|
friend class Ble::BleSecure;
|
||||||
friend class UnitTester;
|
friend class UnitTester;
|
||||||
|
friend class ot::Notifier;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -164,49 +166,44 @@ public:
|
|||||||
enum CommandTlvType : uint8_t
|
enum CommandTlvType : uint8_t
|
||||||
{
|
{
|
||||||
// Command Class General
|
// Command Class General
|
||||||
kTlvResponseWithStatus = 0x01, ///< TCAT response with status value TLV
|
kTlvResponseWithStatus = OT_TCAT_TLV_RESPONSE_WITH_STATUS,
|
||||||
kTlvResponseWithPayload = 0x02, ///< TCAT response with payload TLV
|
kTlvResponseWithPayload = OT_TCAT_TLV_RESPONSE_WITH_PAYLOAD,
|
||||||
kTlvResponseEvent = 0x03, ///< TCAT response event TLV (reserved)
|
kTlvResponseEvent = OT_TCAT_TLV_RESPONSE_EVENT,
|
||||||
kTlvGetNetworkName = 0x08, ///< TCAT network name query TLV
|
kTlvGetNetworkName = OT_TCAT_TLV_GET_NETWORK_NAME,
|
||||||
kTlvDisconnect = 0x09, ///< TCAT disconnect request TLV
|
kTlvDisconnect = OT_TCAT_TLV_DISCONNECT,
|
||||||
kTlvPing = 0x0A, ///< TCAT ping request TLV
|
kTlvPing = OT_TCAT_TLV_PING,
|
||||||
kTlvGetDeviceId = 0x0B, ///< TCAT device ID query TLV
|
kTlvGetDeviceId = OT_TCAT_TLV_GET_DEVICE_ID,
|
||||||
kTlvGetExtendedPanID = 0x0C, ///< TCAT extended PAN ID query TLV
|
kTlvGetExtendedPanID = OT_TCAT_TLV_GET_EXTENDED_PAN_ID,
|
||||||
kTlvGetProvisioningURL = 0x0D, ///< TCAT provisioning URL query TLV
|
kTlvGetProvisioningURL = OT_TCAT_TLV_GET_PROVISIONING_URL,
|
||||||
kTlvPresentPskdHash = 0x10, ///< TCAT commissioner rights elevation request TLV using PSKd hash
|
kTlvPresentPskdHash = OT_TCAT_TLV_PRESENT_PSKD_HASH,
|
||||||
kTlvPresentPskcHash = 0x11, ///< TCAT commissioner rights elevation request TLV using PSKc hash
|
kTlvPresentPskcHash = OT_TCAT_TLV_PRESENT_PSKC_HASH,
|
||||||
kTlvPresentInstallCodeHash = 0x12, ///< TCAT commissioner rights elevation request TLV using install code
|
kTlvPresentInstallCodeHash = OT_TCAT_TLV_PRESENT_INSTALL_CODE_HASH,
|
||||||
kTlvRequestRandomNumChallenge = 0x13, ///< TCAT random number challenge query TLV
|
kTlvRequestRandomNumChallenge = OT_TCAT_TLV_REQUEST_RANDOM_CHALLENGE,
|
||||||
|
|
||||||
// Command Class Commissioning
|
// Command Class Commissioning
|
||||||
kTlvSetActiveOperationalDataset = 0x20, ///< TCAT active operational dataset TLV
|
kTlvSetActiveOperationalDataset = OT_TCAT_TLV_SET_ACTIVE_OPERATIONAL_DATASET,
|
||||||
kTlvSetActiveOperationalDatasetAlt = 0x21, ///< TCAT active operational dataset alternative #1 TLV (reserved)
|
kTlvSetActiveOperationalDatasetAlt = OT_TCAT_TLV_SET_ACTIVE_OPERATIONAL_DATASET_ALT,
|
||||||
kTlvGetCommissionerCertificate = 0x25, ///< TCAT commissioner certificate query TLV
|
kTlvGetCommissionerCertificate = OT_TCAT_TLV_GET_COMMISSIONER_CERTIFICATE,
|
||||||
kTlvGetDiagnosticTlvs = 0x26, ///< TCAT diagnostics TLVs query TLV
|
kTlvGetDiagnosticTlvs = OT_TCAT_TLV_GET_DIAGNOSTIC_TLVS,
|
||||||
kTlvStartThreadInterface = 0x27, ///< TCAT start thread interface request TLV
|
kTlvStartThreadInterface = OT_TCAT_TLV_START_THREAD_INTERFACE,
|
||||||
kTlvStopThreadInterface = 0x28, ///< TCAT stop thread interface request TLV
|
kTlvStopThreadInterface = OT_TCAT_TLV_STOP_THREAD_INTERFACE,
|
||||||
|
|
||||||
// Command Class Extraction
|
// Command Class Extraction
|
||||||
kTlvGetActiveOperationalDataset = 0x40, ///< TCAT active operational dataset query TLV
|
kTlvGetActiveOperationalDataset = OT_TCAT_TLV_GET_ACTIVE_OPERATIONAL_DATASET,
|
||||||
kTlvGetActiveOperationalDatasetAlt = 0x41, ///< TCAT active operational dataset alternative #1 query TLV (rsv)
|
kTlvGetActiveOperationalDatasetAlt = OT_TCAT_TLV_GET_ACTIVE_OPERATIONAL_DATASET_ALT,
|
||||||
|
|
||||||
// Command Class Decommissioning
|
// Command Class Decommissioning
|
||||||
kTlvDecommission = 0x60, ///< TCAT decommission request TLV
|
kTlvDecommission = OT_TCAT_TLV_DECOMMISSION,
|
||||||
|
|
||||||
// Command Class Application
|
// Command Class Application
|
||||||
kTlvGetApplicationLayers = 0x80, ///< TCAT get application layers request TLV
|
kTlvGetApplicationLayers = OT_TCAT_TLV_GET_APPLICATION_LAYERS,
|
||||||
kTlvSendApplicationData1 = 0x81, ///< TCAT send application data 1 TLV
|
kTlvSendApplicationData1 = OT_TCAT_TLV_SEND_APPLICATION_DATA_1,
|
||||||
kTlvSendApplicationData2 = 0x82, ///< TCAT send application data 2 TLV
|
kTlvSendApplicationData2 = OT_TCAT_TLV_SEND_APPLICATION_DATA_2,
|
||||||
kTlvSendApplicationData3 = 0x83, ///< TCAT send application data 3 TLV
|
kTlvSendApplicationData3 = OT_TCAT_TLV_SEND_APPLICATION_DATA_3,
|
||||||
kTlvSendApplicationData4 = 0x84, ///< TCAT send application data 4 TLV
|
kTlvSendApplicationData4 = OT_TCAT_TLV_SEND_APPLICATION_DATA_4,
|
||||||
kTlvServiceNameUdp = 0x89, ///< TCAT service name UDP sub-TLV (not used as a command)
|
kTlvServiceNameUdp = OT_TCAT_TLV_SERVICE_NAME_UDP,
|
||||||
kTlvServiceNameTcp = 0x8A, ///< TCAT service name TCP sub-TLV (not used as a command)
|
kTlvServiceNameTcp = OT_TCAT_TLV_SERVICE_NAME_TCP,
|
||||||
kTlvSendVendorSpecificData = 0x9F, ///< TCAT send vendor specific command or data TLV
|
kTlvSendVendorSpecificData = OT_TCAT_TLV_SEND_VENDOR_SPECIFIC_DATA,
|
||||||
|
|
||||||
// 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)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -441,6 +438,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void NotifyApplicationResponseSent(void) { mApplicationResponsePending = false; }
|
void NotifyApplicationResponseSent(void) { mApplicationResponsePending = false; }
|
||||||
void NotifyStateChange(void);
|
void NotifyStateChange(void);
|
||||||
|
void HandleNotifierEvents(Events aEvents);
|
||||||
void ClearCommissionerState();
|
void ClearCommissionerState();
|
||||||
Error Connected(MeshCoP::Tls::Extension &aTls);
|
Error Connected(MeshCoP::Tls::Extension &aTls);
|
||||||
void Disconnected(void);
|
void Disconnected(void);
|
||||||
@@ -520,10 +518,11 @@ private:
|
|||||||
bool mIsCommissioned : 1;
|
bool mIsCommissioned : 1;
|
||||||
bool mApplicationResponsePending : 1;
|
bool mApplicationResponsePending : 1;
|
||||||
using ExpireTimer = TimerMilliIn<TcatAgent, &TcatAgent::HandleTimer>;
|
using ExpireTimer = TimerMilliIn<TcatAgent, &TcatAgent::HandleTimer>;
|
||||||
ExpireTimer mActiveOrStandbyTimer;
|
ExpireTimer mActiveOrStandbyTimer;
|
||||||
uint32_t mTcatActiveDurationMs;
|
uint32_t mTcatActiveDurationMs;
|
||||||
UptimeSec mLastHashVerificationTimestamp;
|
UptimeSec mLastHashVerificationTimestamp;
|
||||||
uint8_t mHashVerificationAttempts;
|
uint8_t mHashVerificationAttempts;
|
||||||
|
Mle::DeviceRole mLastDeviceRole;
|
||||||
};
|
};
|
||||||
|
|
||||||
DeclareTmfHandler(TcatAgent, kUriTcatEnable);
|
DeclareTmfHandler(TcatAgent, kUriTcatEnable);
|
||||||
|
|||||||
@@ -310,6 +310,8 @@ proc spawn_tcat_client_for_node {id {cert_path "tools/tcat_ble_client/auth"}} {
|
|||||||
|
|
||||||
send "tcat start\n"
|
send "tcat start\n"
|
||||||
expect_line "Done"
|
expect_line "Done"
|
||||||
|
send "tcat active\n"
|
||||||
|
expect_line "Done"
|
||||||
|
|
||||||
spawn python "tools/tcat_ble_client/bbtc.py" --simulation $id --cert_path $cert_path
|
spawn python "tools/tcat_ble_client/bbtc.py" --simulation $id --cert_path $cert_path
|
||||||
expect_line "Done"
|
expect_line "Done"
|
||||||
|
|||||||
Reference in New Issue
Block a user