Skip to content

Commit 9075bc1

Browse files
nikita-s-wrkdvdm-qorvo
nikita-s-wrk
authored andcommitted
[qpg] Added test event delegate for fault injection (project-chip#22691)
* [qpg]Added test event delegate for fault injection * Check for eventTrigger in GenericFault delegate
1 parent 3a0251d commit 9075bc1

10 files changed

+324
-3
lines changed

examples/lighting-app/qpg/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ qpg_executable("lighting_app") {
5353
output_name = "chip-${qpg_target_ic}-lighting-example.out"
5454

5555
sources = [
56+
"${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerDelegate.cpp",
5657
"${examples_plat_dir}/app/main.cpp",
5758
"${examples_plat_dir}/ota/ota.cpp",
5859
"include/LightingManager.h",

examples/lighting-app/qpg/src/AppTask.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <app-common/zap-generated/attribute-type.h>
3030
#include <app-common/zap-generated/attributes/Accessors.h>
3131
#include <app-common/zap-generated/cluster-id.h>
32+
#include <app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerDelegate.h>
33+
#include <app/clusters/general-diagnostics-server/general-diagnostics-server.h>
3234
#include <app/clusters/identify-server/identify-server.h>
3335
#include <app/clusters/on-off-server/on-off-server.h>
3436

@@ -68,6 +70,9 @@ bool sIsThreadProvisioned = false;
6870
bool sIsThreadEnabled = false;
6971
bool sHaveBLEConnections = false;
7072

73+
// NOTE! This key is for test/certification only and should not be available in production devices!
74+
uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
75+
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
7176
uint8_t sAppEventQueueBuffer[APP_EVENT_QUEUE_SIZE * sizeof(AppEvent)];
7277

7378
StaticQueue_t sAppEventQueueStruct;
@@ -225,6 +230,12 @@ void AppTask::InitServer(intptr_t arg)
225230
nativeParams.unlockCb = UnlockOpenThreadTask;
226231
nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance();
227232
initParams.endpointNativeParams = static_cast<void *>(&nativeParams);
233+
234+
// Use GenericFaultTestEventTriggerDelegate to inject faults
235+
static GenericFaultTestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) };
236+
(void) initParams.InitializeStaticResourcesBeforeServerInit();
237+
initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
238+
228239
chip::Server::GetInstance().Init(initParams);
229240

230241
#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
*
3+
* Copyright (c) 2022 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include "GenericFaultTestEventTriggerDelegate.h"
20+
21+
#include <app/clusters/general-diagnostics-server/general-diagnostics-server.h>
22+
#include <lib/support/CodeUtils.h>
23+
24+
using namespace ::chip::DeviceLayer;
25+
26+
namespace chip {
27+
28+
bool GenericFaultTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const
29+
{
30+
return !mEnableKey.empty() && mEnableKey.data_equal(enableKey);
31+
}
32+
33+
CHIP_ERROR GenericFaultTestEventTriggerDelegate::HandleEventTrigger(uint64_t eventTrigger)
34+
{
35+
36+
if ((eventTrigger & ~kGenericFaultQueryFabricIndexMask) == kGenericFaultQueryTrigger)
37+
{
38+
// Fault injection
39+
GeneralFaults<kMaxHardwareFaults> hwFaultsPrevious;
40+
GeneralFaults<kMaxHardwareFaults> hwFaultsCurrent;
41+
ReturnErrorOnFailure(hwFaultsPrevious.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_RADIO));
42+
ReturnErrorOnFailure(hwFaultsPrevious.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_POWER_SOURCE));
43+
44+
ReturnErrorOnFailure(hwFaultsCurrent.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_RADIO));
45+
ReturnErrorOnFailure(hwFaultsCurrent.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_SENSOR));
46+
ReturnErrorOnFailure(hwFaultsCurrent.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_POWER_SOURCE));
47+
ReturnErrorOnFailure(hwFaultsCurrent.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_USER_INTERFACE_FAULT));
48+
49+
app::Clusters::GeneralDiagnosticsServer::Instance().OnHardwareFaultsDetect(hwFaultsPrevious, hwFaultsCurrent);
50+
51+
// Radio faults injection
52+
GeneralFaults<kMaxRadioFaults> radioFaultsPrevious;
53+
GeneralFaults<kMaxRadioFaults> radioFaultsCurrent;
54+
55+
ReturnErrorOnFailure(radioFaultsPrevious.add(EMBER_ZCL_RADIO_FAULT_TYPE_WI_FI_FAULT));
56+
ReturnErrorOnFailure(radioFaultsPrevious.add(EMBER_ZCL_RADIO_FAULT_TYPE_THREAD_FAULT));
57+
58+
ReturnErrorOnFailure(radioFaultsCurrent.add(EMBER_ZCL_RADIO_FAULT_TYPE_WI_FI_FAULT));
59+
ReturnErrorOnFailure(radioFaultsCurrent.add(EMBER_ZCL_RADIO_FAULT_TYPE_CELLULAR_FAULT));
60+
ReturnErrorOnFailure(radioFaultsCurrent.add(EMBER_ZCL_RADIO_FAULT_TYPE_THREAD_FAULT));
61+
ReturnErrorOnFailure(radioFaultsCurrent.add(EMBER_ZCL_RADIO_FAULT_TYPE_NFC_FAULT));
62+
63+
app::Clusters::GeneralDiagnosticsServer::Instance().OnRadioFaultsDetect(radioFaultsPrevious, radioFaultsCurrent);
64+
65+
GeneralFaults<kMaxNetworkFaults> networkFaultsPrevious;
66+
GeneralFaults<kMaxNetworkFaults> networkFaultsCurrent;
67+
68+
// Network faults injections
69+
ReturnErrorOnFailure(networkFaultsPrevious.add(EMBER_ZCL_NETWORK_FAULT_TYPE_HARDWARE_FAILURE));
70+
ReturnErrorOnFailure(networkFaultsPrevious.add(EMBER_ZCL_NETWORK_FAULT_TYPE_NETWORK_JAMMED));
71+
72+
ReturnErrorOnFailure(networkFaultsCurrent.add(EMBER_ZCL_NETWORK_FAULT_TYPE_HARDWARE_FAILURE));
73+
ReturnErrorOnFailure(networkFaultsCurrent.add(EMBER_ZCL_NETWORK_FAULT_TYPE_NETWORK_JAMMED));
74+
ReturnErrorOnFailure(networkFaultsCurrent.add(EMBER_ZCL_NETWORK_FAULT_TYPE_CONNECTION_FAILED));
75+
76+
app::Clusters::GeneralDiagnosticsServer::Instance().OnNetworkFaultsDetect(networkFaultsPrevious, networkFaultsCurrent);
77+
}
78+
79+
return CHIP_ERROR_INVALID_ARGUMENT;
80+
}
81+
82+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
*
3+
* Copyright (c) 2022 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
21+
#include <app/TestEventTriggerDelegate.h>
22+
23+
namespace chip {
24+
25+
class GenericFaultTestEventTriggerDelegate : public TestEventTriggerDelegate
26+
{
27+
public:
28+
static constexpr uint64_t kGenericFaultQueryTrigger = 0xFFFF'FFFF'10D0'0001;
29+
static constexpr uint64_t kGenericFaultQueryFabricIndexMask = 0xff;
30+
31+
explicit GenericFaultTestEventTriggerDelegate(const ByteSpan & enableKey) : mEnableKey(enableKey) {}
32+
33+
bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override;
34+
CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override;
35+
36+
private:
37+
ByteSpan mEnableKey;
38+
};
39+
40+
} // namespace chip

src/platform/qpg/ConfigurationManagerImpl.cpp

+69
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <platform/internal/CHIPDeviceLayerInternal.h>
2525

2626
#include <platform/ConfigurationManager.h>
27+
#include <platform/DiagnosticDataProvider.h>
2728
#include <platform/internal/GenericConfigurationManagerImpl.ipp>
2829

2930
#include <lib/core/CHIPVendorIdentifiers.hpp>
@@ -46,13 +47,81 @@ ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance()
4647
CHIP_ERROR ConfigurationManagerImpl::Init()
4748
{
4849
CHIP_ERROR err;
50+
uint32_t rebootCount;
4951

5052
// Initialize the generic implementation base class.
5153
err = Internal::GenericConfigurationManagerImpl<QPGConfig>::Init();
54+
SuccessOrExit(err);
55+
56+
if (QPGConfig::ConfigValueExists(QPGConfig::kCounterKey_RebootCount))
57+
{
58+
err = GetRebootCount(rebootCount);
59+
SuccessOrExit(err);
60+
61+
// Do not increment reboot count if the value is going to overflow UINT16.
62+
err = StoreRebootCount(rebootCount < UINT16_MAX ? rebootCount + 1 : rebootCount);
63+
SuccessOrExit(err);
64+
}
65+
else
66+
{
67+
// The first boot after factory reset of the Node.
68+
err = StoreRebootCount(1);
69+
SuccessOrExit(err);
70+
}
71+
if (!QPGConfig::ConfigValueExists(QPGConfig::kCounterKey_TotalOperationalHours))
72+
{
73+
err = StoreTotalOperationalHours(0);
74+
SuccessOrExit(err);
75+
}
5276

77+
if (!QPGConfig::ConfigValueExists(QPGConfig::kCounterKey_BootReason))
78+
{
79+
err = StoreBootReason(to_underlying(BootReasonType::kUnspecified));
80+
SuccessOrExit(err);
81+
}
82+
83+
err = CHIP_NO_ERROR;
84+
85+
exit:
5386
return err;
5487
}
5588

89+
CHIP_ERROR ConfigurationManagerImpl::GetRebootCount(uint32_t & rebootCount)
90+
{
91+
return ReadConfigValue(QPGConfig::kCounterKey_RebootCount, rebootCount);
92+
}
93+
94+
CHIP_ERROR ConfigurationManagerImpl::StoreRebootCount(uint32_t rebootCount)
95+
{
96+
return WriteConfigValue(QPGConfig::kCounterKey_RebootCount, rebootCount);
97+
}
98+
99+
CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours)
100+
{
101+
if (!QPGConfig::ConfigValueExists(QPGConfig::kCounterKey_TotalOperationalHours))
102+
{
103+
totalOperationalHours = 0;
104+
return CHIP_NO_ERROR;
105+
}
106+
107+
return QPGConfig::ReadConfigValue(QPGConfig::kCounterKey_TotalOperationalHours, totalOperationalHours);
108+
}
109+
110+
CHIP_ERROR ConfigurationManagerImpl::StoreTotalOperationalHours(uint32_t totalOperationalHours)
111+
{
112+
return QPGConfig::WriteConfigValue(QPGConfig::kCounterKey_TotalOperationalHours, totalOperationalHours);
113+
}
114+
115+
CHIP_ERROR ConfigurationManagerImpl::GetBootReason(uint32_t & bootReason)
116+
{
117+
return ReadConfigValue(QPGConfig::kCounterKey_BootReason, bootReason);
118+
}
119+
120+
CHIP_ERROR ConfigurationManagerImpl::StoreBootReason(uint32_t bootReason)
121+
{
122+
return WriteConfigValue(QPGConfig::kCounterKey_BootReason, bootReason);
123+
}
124+
56125
bool ConfigurationManagerImpl::CanFactoryReset()
57126
{
58127
// TODO: query the application to determine if factory reset is allowed.

src/platform/qpg/ConfigurationManagerImpl.h

+6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ namespace DeviceLayer {
3535
class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl<Internal::QPGConfig>
3636
{
3737
public:
38+
CHIP_ERROR GetRebootCount(uint32_t & rebootCount) override;
39+
CHIP_ERROR StoreRebootCount(uint32_t rebootCount) override;
40+
CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override;
41+
CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours) override;
42+
CHIP_ERROR GetBootReason(uint32_t & bootReason) override;
43+
CHIP_ERROR StoreBootReason(uint32_t bootReason) override;
3844
// This returns an instance of this class.
3945
static ConfigurationManagerImpl & GetDefaultInstance();
4046

src/platform/qpg/DiagnosticDataProviderImpl.cpp

+97
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,102 @@ DiagnosticDataProvider & GetDiagnosticDataProviderImpl()
8080
return DiagnosticDataProviderImpl::GetDefaultInstance();
8181
}
8282

83+
CHIP_ERROR DiagnosticDataProviderImpl::GetRebootCount(uint16_t & rebootCount)
84+
{
85+
uint32_t count = 0;
86+
CHIP_ERROR err = ConfigurationMgr().GetRebootCount(count);
87+
88+
if (err == CHIP_NO_ERROR)
89+
{
90+
VerifyOrReturnError(count <= UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
91+
rebootCount = static_cast<uint16_t>(count);
92+
}
93+
94+
return err;
95+
}
96+
97+
CHIP_ERROR DiagnosticDataProviderImpl::GetBootReason(BootReasonType & bootReason)
98+
{
99+
uint32_t reason = 0;
100+
CHIP_ERROR err = ConfigurationMgr().GetBootReason(reason);
101+
102+
if (err == CHIP_NO_ERROR)
103+
{
104+
VerifyOrReturnError(reason <= UINT8_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
105+
bootReason = static_cast<BootReasonType>(reason);
106+
}
107+
108+
return err;
109+
}
110+
111+
CHIP_ERROR DiagnosticDataProviderImpl::GetUpTime(uint64_t & upTime)
112+
{
113+
System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp();
114+
System::Clock::Timestamp startTime = PlatformMgrImpl().GetStartTime();
115+
116+
if (currentTime >= startTime)
117+
{
118+
upTime = std::chrono::duration_cast<System::Clock::Seconds64>(currentTime - startTime).count();
119+
return CHIP_NO_ERROR;
120+
}
121+
122+
return CHIP_ERROR_INVALID_TIME;
123+
}
124+
125+
CHIP_ERROR DiagnosticDataProviderImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours)
126+
{
127+
uint64_t upTime = 0;
128+
129+
if (GetUpTime(upTime) == CHIP_NO_ERROR)
130+
{
131+
uint32_t totalHours = 0;
132+
if (ConfigurationMgr().GetTotalOperationalHours(totalHours) == CHIP_NO_ERROR)
133+
{
134+
VerifyOrReturnError(upTime / 3600 <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
135+
totalOperationalHours = totalHours + static_cast<uint32_t>(upTime / 3600);
136+
return CHIP_NO_ERROR;
137+
}
138+
}
139+
140+
return CHIP_ERROR_INVALID_TIME;
141+
}
142+
143+
CHIP_ERROR DiagnosticDataProviderImpl::GetActiveHardwareFaults(GeneralFaults<kMaxHardwareFaults> & hardwareFaults)
144+
{
145+
ChipLogProgress(DeviceLayer, "GetActiveHardwareFaults");
146+
147+
#if CHIP_CONFIG_TEST
148+
ReturnErrorOnFailure(hardwareFaults.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_RADIO));
149+
ReturnErrorOnFailure(hardwareFaults.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_SENSOR));
150+
ReturnErrorOnFailure(hardwareFaults.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_POWER_SOURCE));
151+
ReturnErrorOnFailure(hardwareFaults.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_USER_INTERFACE_FAULT));
152+
#endif
153+
154+
return CHIP_NO_ERROR;
155+
}
156+
157+
CHIP_ERROR DiagnosticDataProviderImpl::GetActiveRadioFaults(GeneralFaults<kMaxRadioFaults> & radioFaults)
158+
{
159+
ChipLogProgress(DeviceLayer, "GetActiveRadioFaults");
160+
#if CHIP_CONFIG_TEST
161+
ReturnErrorOnFailure(radioFaults.add(EMBER_ZCL_RADIO_FAULT_TYPE_THREAD_FAULT));
162+
ReturnErrorOnFailure(radioFaults.add(EMBER_ZCL_RADIO_FAULT_TYPE_BLE_FAULT));
163+
#endif
164+
165+
return CHIP_NO_ERROR;
166+
}
167+
168+
CHIP_ERROR DiagnosticDataProviderImpl::GetActiveNetworkFaults(GeneralFaults<kMaxNetworkFaults> & networkFaults)
169+
{
170+
ChipLogProgress(DeviceLayer, "GetActiveNetworkFaults");
171+
#if CHIP_CONFIG_TEST
172+
ReturnErrorOnFailure(networkFaults.add(EMBER_ZCL_NETWORK_FAULT_TYPE_HARDWARE_FAILURE));
173+
ReturnErrorOnFailure(networkFaults.add(EMBER_ZCL_NETWORK_FAULT_TYPE_NETWORK_JAMMED));
174+
ReturnErrorOnFailure(networkFaults.add(EMBER_ZCL_NETWORK_FAULT_TYPE_CONNECTION_FAILED));
175+
#endif
176+
177+
return CHIP_NO_ERROR;
178+
}
179+
83180
} // namespace DeviceLayer
84181
} // namespace chip

src/platform/qpg/DiagnosticDataProviderImpl.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,23 @@ class DiagnosticDataProviderImpl : public DiagnosticDataProvider
3737
public:
3838
static DiagnosticDataProviderImpl & GetDefaultInstance();
3939

40-
// ===== Methods that implement the PlatformManager abstract interface.
40+
// ===== Methods that implement the DiagnosticDataProvider abstract interface.
4141

4242
bool SupportsWatermarks() override { return true; }
43+
// Heap diag
4344
CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override;
4445
CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override;
4546
CHIP_ERROR GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) override;
4647
CHIP_ERROR ResetWatermarks() override;
48+
// Uptime diag
49+
CHIP_ERROR GetRebootCount(uint16_t & rebootCount) override;
50+
CHIP_ERROR GetBootReason(BootReasonType & bootReason) override;
51+
CHIP_ERROR GetUpTime(uint64_t & upTime) override;
52+
CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override;
53+
// Fault diag
54+
CHIP_ERROR GetActiveHardwareFaults(GeneralFaults<kMaxHardwareFaults> & hardwareFaults) override;
55+
CHIP_ERROR GetActiveRadioFaults(GeneralFaults<kMaxRadioFaults> & radioFaults) override;
56+
CHIP_ERROR GetActiveNetworkFaults(GeneralFaults<kMaxNetworkFaults> & networkFaults) override;
4757
};
4858

4959
/**

0 commit comments

Comments
 (0)