Skip to content

Commit 3693095

Browse files
committed
Initial version of Joint Fabric implementation
1 parent 7a129d8 commit 3693095

File tree

73 files changed

+6319
-11
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+6319
-11
lines changed

.github/workflows/tests.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ jobs:
142142
src/app/zap-templates/zcl/data-model/chip/group-key-mgmt-cluster.xml \
143143
src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml \
144144
src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml \
145+
src/app/zap-templates/zcl/data-model/chip/joint-fabric-pki-cluster.xml \
145146
src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml \
146147
src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml \
147148
src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml \

docs/zap_clusters.md

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Generally regenerate using one of:
4343
| 57 | 0x39 | BridgedDeviceBasicInformation |
4444
| 59 | 0x3B | Switch |
4545
| 60 | 0x3C | AdministratorCommissioning |
46+
| 61 | 0x3D | JointFabricPki |
4647
| 62 | 0x3E | OperationalCredentials |
4748
| 63 | 0x3F | GroupKeyManagement |
4849
| 64 | 0x40 | FixedLabel |

examples/all-clusters-app/all-clusters-common/all-clusters-app.matter

+71
Original file line numberDiff line numberDiff line change
@@ -2444,6 +2444,68 @@ cluster AdministratorCommissioning = 60 {
24442444
timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2;
24452445
}
24462446

2447+
/** Joint Fabric Pki Cluster. */
2448+
cluster JointFabricPki = 61 {
2449+
revision 1; // NOTE: Default/not specifically set
2450+
2451+
enum JointFabricStatusEnum : enum8 {
2452+
kOK = 0;
2453+
kInvalidPublicKey = 1;
2454+
kInvalidNodeOpId = 2;
2455+
kInvalidNOC = 3;
2456+
kMissingCsr = 4;
2457+
kTableFull = 5;
2458+
kInvalidAdminSubject = 6;
2459+
kFabricConflict = 9;
2460+
kLabelConflict = 10;
2461+
kInvalidFabricIndex = 11;
2462+
}
2463+
2464+
enum SignNOCIssuerRequestStatusEnum : enum8 {
2465+
kOK = 0;
2466+
kFailSafeRequired = 1;
2467+
kInvalidNOCIssuerCSR = 2;
2468+
kChainValidationFailed = 3;
2469+
kTrustQuotientThreshold = 4;
2470+
kSignNOCIssuerFailed = 5;
2471+
}
2472+
2473+
readonly attribute command_id generatedCommandList[] = 65528;
2474+
readonly attribute command_id acceptedCommandList[] = 65529;
2475+
readonly attribute event_id eventList[] = 65530;
2476+
readonly attribute attrib_id attributeList[] = 65531;
2477+
readonly attribute bitmap32 featureMap = 65532;
2478+
readonly attribute int16u clusterRevision = 65533;
2479+
2480+
request struct JointFabricRequestRequest {
2481+
int64u fabricIndex = 0;
2482+
}
2483+
2484+
response struct SignNOCIssuerRequest = 1 {
2485+
octet_string<400> NOCIssuerCSR = 0;
2486+
}
2487+
2488+
request struct SignNOCIssuerResponseRequest {
2489+
SignNOCIssuerRequestStatusEnum statusCode = 0;
2490+
octet_string<400> NOCIssuerCert = 1;
2491+
node_id nodeId = 2;
2492+
fabric_id fabricId = 3;
2493+
vendor_id adminVendorId = 4;
2494+
int64u caseAdminSubject = 5;
2495+
}
2496+
2497+
response struct JointFabricResponse = 3 {
2498+
JointFabricStatusEnum statusCode = 0;
2499+
optional fabric_idx fabricIndex = 1;
2500+
optional char_string<128> debugText = 2;
2501+
}
2502+
2503+
/** Client requests Server's ICA CSR and CA Chain. */
2504+
command access(invoke: administer) JointFabricRequest(JointFabricRequestRequest): SignNOCIssuerRequest = 0;
2505+
/** Joint Fabric ICA generated. */
2506+
command access(invoke: administer) SignNOCIssuerResponse(SignNOCIssuerResponseRequest): JointFabricResponse = 2;
2507+
}
2508+
24472509
/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */
24482510
cluster OperationalCredentials = 62 {
24492511
revision 1; // NOTE: Default/not specifically set
@@ -7863,6 +7925,15 @@ endpoint 0 {
78637925
handle command RevokeCommissioning;
78647926
}
78657927

7928+
server cluster JointFabricPki {
7929+
ram attribute clusterRevision default = 1;
7930+
7931+
handle command JointFabricRequest;
7932+
handle command SignNOCIssuerRequest;
7933+
handle command SignNOCIssuerResponse;
7934+
handle command JointFabricResponse;
7935+
}
7936+
78667937
server cluster OperationalCredentials {
78677938
callback attribute NOCs;
78687939
callback attribute fabrics;

examples/all-clusters-app/all-clusters-common/all-clusters-app.zap

+60
Original file line numberDiff line numberDiff line change
@@ -5368,6 +5368,66 @@
53685368
}
53695369
]
53705370
},
5371+
{
5372+
"name": "Joint Fabric Pki",
5373+
"code": 61,
5374+
"mfgCode": null,
5375+
"define": "JOINT_FABRIC_PKI_CLUSTER",
5376+
"side": "server",
5377+
"enabled": 1,
5378+
"commands": [
5379+
{
5380+
"name": "JointFabricRequest",
5381+
"code": 0,
5382+
"mfgCode": null,
5383+
"source": "client",
5384+
"isIncoming": 1,
5385+
"isEnabled": 1
5386+
},
5387+
{
5388+
"name": "SignNOCIssuerRequest",
5389+
"code": 1,
5390+
"mfgCode": null,
5391+
"source": "server",
5392+
"isIncoming": 0,
5393+
"isEnabled": 1
5394+
},
5395+
{
5396+
"name": "SignNOCIssuerResponse",
5397+
"code": 2,
5398+
"mfgCode": null,
5399+
"source": "client",
5400+
"isIncoming": 1,
5401+
"isEnabled": 1
5402+
},
5403+
{
5404+
"name": "JointFabricResponse",
5405+
"code": 3,
5406+
"mfgCode": null,
5407+
"source": "server",
5408+
"isIncoming": 0,
5409+
"isEnabled": 1
5410+
}
5411+
],
5412+
"attributes": [
5413+
{
5414+
"name": "ClusterRevision",
5415+
"code": 65533,
5416+
"mfgCode": null,
5417+
"side": "server",
5418+
"type": "int16u",
5419+
"included": 1,
5420+
"storageOption": "RAM",
5421+
"singleton": 0,
5422+
"bounded": 0,
5423+
"defaultValue": "1",
5424+
"reportable": 1,
5425+
"minInterval": 0,
5426+
"maxInterval": 65344,
5427+
"reportableChange": 0
5428+
}
5429+
]
5430+
},
53715431
{
53725432
"name": "Operational Credentials",
53735433
"code": 62,

examples/chip-tool/commands/pairing/PairingCommand.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ CommissioningParameters PairingCommand::GetCommissioningParameters()
103103
{
104104
auto params = CommissioningParameters();
105105
params.SetSkipCommissioningComplete(mSkipCommissioningComplete.ValueOr(false));
106+
params.SetJointFabric(mJointFabric.ValueOr(false));
106107
if (mBypassAttestationVerifier.ValueOr(false))
107108
{
108109
params.SetDeviceAttestationDelegate(this);

examples/chip-tool/commands/pairing/PairingCommand.h

+2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class PairingCommand : public CHIPCommand,
8282
AddArgument("icd-symmetric-key", &mICDSymmetricKey, "The 16 bytes ICD symmetric key, default: randomly generated.");
8383
AddArgument("icd-stay-active-duration", 0, UINT32_MAX, &mICDStayActiveDurationMsec,
8484
"If set, a LIT ICD that is commissioned will be requested to stay active for this many milliseconds");
85+
AddArgument("joint-fabric", 0, 1, &mJointFabric, "Enable Joint Fabric commissioning mode.");
8586
switch (networkType)
8687
{
8788
case PairingNetworkType::None:
@@ -265,6 +266,7 @@ class PairingCommand : public CHIPCommand,
265266
chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type> mDSTOffsetList;
266267
TypedComplexArgument<chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type>>
267268
mComplex_DSTOffsets;
269+
chip::Optional<bool> mJointFabric;
268270

269271
uint16_t mRemotePort;
270272
// mDiscriminator is only used for some situations, but in those situations

examples/platform/linux/AppMain.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <platform/PlatformManager.h>
2121

2222
#include <app/InteractionModelEngine.h>
23+
#include <app/clusters/joint-fabric-pki-server/joint-fabric-pki-server.h>
2324
#include <app/clusters/network-commissioning/network-commissioning.h>
2425
#include <app/server/Dnssd.h>
2526
#include <app/server/OnboardingCodesUtil.h>
@@ -114,8 +115,12 @@
114115
#include <platform/Linux/NetworkCommissioningDriver.h>
115116
#endif // CHIP_DEVICE_LAYER_TARGET_LINUX
116117

118+
#include <controller/ExampleOperationalCredentialsIssuer.h>
119+
#include <controller/ExamplePersistentStorage.h>
120+
117121
using namespace chip;
118122
using namespace chip::ArgParser;
123+
using namespace chip::Controller;
119124
using namespace chip::Credentials;
120125
using namespace chip::DeviceLayer;
121126
using namespace chip::Inet;
@@ -509,6 +514,21 @@ int ChipLinuxAppInit(int argc, char * const argv[], OptionSet * customOptions,
509514
return 0;
510515
}
511516

517+
namespace {
518+
static constexpr size_t kFabricId = 1;
519+
520+
ExampleOperationalCredentialsIssuer gOpCredsIssuer(kFabricId);
521+
PersistentStorage gStorage;
522+
523+
CHIP_ERROR PrepareJointFabricCluster()
524+
{
525+
SetPersistentStorageDelegate(&gStorage);
526+
SetOperationalCredentialsIssuer(&gOpCredsIssuer);
527+
SetChipToolKvs(LinuxDeviceOptions::GetInstance().chipToolKvs);
528+
return CHIP_NO_ERROR;
529+
}
530+
} // namespace
531+
512532
void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl)
513533
{
514534
gMainLoopImplementation = impl;
@@ -596,6 +616,8 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl)
596616
// Init ZCL Data Model and CHIP App Server
597617
Server::GetInstance().Init(initParams);
598618

619+
VerifyOrDie(PrepareJointFabricCluster() == CHIP_NO_ERROR);
620+
599621
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
600622
// Set ReadHandler Capacity for Subscriptions
601623
chip::app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(

examples/platform/linux/Options.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ enum
109109
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
110110
kDeviceOption_WiFi_PAF,
111111
#endif
112+
kDeviceOption_ChipToolKvs,
112113
};
113114

114115
constexpr unsigned kAppUsageLength = 64;
@@ -177,6 +178,7 @@ OptionDef sDeviceOptionDefs[] = {
177178
#if CHIP_WITH_NLFAULTINJECTION
178179
{ "faults", kArgumentRequired, kDeviceOption_FaultInjection },
179180
#endif
181+
{ "chip-tool-kvs", kArgumentRequired, kDeviceOption_ChipToolKvs },
180182
{}
181183
};
182184

@@ -318,6 +320,8 @@ const char * sDeviceOptionHelp =
318320
" --faults <fault-string,...>\n"
319321
" Inject specified fault(s) at runtime.\n"
320322
#endif
323+
" --chip-tool-kvs <filepath>\n"
324+
" A file to sync Key Value Store items with chip-tool.\n"
321325
"\n";
322326

323327
bool Base64ArgToVector(const char * arg, size_t maxSize, std::vector<uint8_t> & outVector)
@@ -608,6 +612,9 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier,
608612
break;
609613
}
610614
#endif
615+
case kDeviceOption_ChipToolKvs:
616+
LinuxDeviceOptions::GetInstance().chipToolKvs = aValue;
617+
break;
611618
default:
612619
PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
613620
retval = false;

examples/platform/linux/Options.h

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct LinuxDeviceOptions
8282
int32_t subscriptionCapacity = CHIP_IM_MAX_NUM_SUBSCRIPTIONS;
8383
int32_t subscriptionResumptionRetryIntervalSec = -1;
8484
#endif
85+
const char * chipToolKvs = nullptr;
8586
static LinuxDeviceOptions & GetInstance();
8687
};
8788

scripts/rules.matterlint

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/groups-cluster.xml";
4949
load "../src/app/zap-templates/zcl/data-model/chip/group-key-mgmt-cluster.xml";
5050
load "../src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml";
5151
load "../src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml";
52+
load "../src/app/zap-templates/zcl/data-model/chip/joint-fabric-pki-cluster.xml";
5253
load "../src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml";
5354
load "../src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml";
5455
load "../src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml";
@@ -152,6 +153,7 @@ endpoint 0 {
152153
require server cluster GeneralCommissioning;
153154
require server cluster AdministratorCommissioning;
154155
require server cluster OperationalCredentials;
156+
require server cluster JointFabricPki
155157
require server cluster GeneralDiagnostics;
156158

157159
// Example rejection of clusters:

src/app/BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ static_library("app") {
427427
output_name = "libCHIPDataModel"
428428

429429
sources = [
430+
"${chip_root}/src/controller/ExamplePersistentStorage.cpp",
430431
"AttributePathExpandIterator.h",
431432
"AttributePersistenceProvider.h",
432433
"ChunkedWriteCallback.cpp",
@@ -473,6 +474,7 @@ static_library("app") {
473474
"${chip_root}/src/messaging",
474475
"${chip_root}/src/protocols/interaction_model",
475476
"${chip_root}/src/system",
477+
"${chip_root}/third_party/inipp",
476478
]
477479

478480
if (chip_use_data_model_interface == "disabled") {

0 commit comments

Comments
 (0)