Skip to content

Commit 7ad1e7a

Browse files
committed
Define new JF server variables for JF Admins only
1 parent d761e1b commit 7ad1e7a

24 files changed

+420
-48
lines changed

docs/guides/joint_fabric_guide.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
- [Joint Fabric Guide](#joint-fabric-guide)
44
- [Joint Fabric Example Applications](#joint-fabric-example-applications)
5-
- [Bootstrap Joint Fabric Demo on Linux](#bootstrap-joint-fabric-demo-on-linux)
6-
- [Run Joint Fabric Demo](#run-joint-fabric-demo)
5+
- [Building the Example Application](#building-the-example-application)
6+
- [Bootstrap Joint Fabric Demo on Linux](#bootstrap-joint-fabric-demo-on-linux)
7+
- [Initialize Ecosystem A (Vendor ID = 0xFFF1)](#initialize-ecosystem-a-vendor-id--0xfff1)
8+
- [Initialize Ecosystem B (Vendor ID = 0xFFF2)](#initialize-ecosystem-b-vendor-id--0xfff2)
9+
- [Run Joint Fabric Demo](#run-joint-fabric-demo)
710

811
## Joint Fabric Example Applications
912

@@ -250,4 +253,16 @@ jf-admin-app has been installed:
250253
A `Subjects` field equal to `18446744065119551489` (`FFFFFFFDFFFF0001` in hex)
251254
should be found.
252255

256+
- Open Joint Commissioning Window on JF Admin App of Ecosystem B
257+
258+
```
259+
>>> pairing open-joint-commissioning-window 1 400 1000 1261
260+
```
261+
262+
Check for the following logs on the jf-admin-app side:
263+
264+
```
265+
>>> [DIS] Advertise commission parameter vendorID=65521 productID=32769 discriminator=1261/04 cm=2 cp=0 jf=14
266+
```
267+
253268
## Run Joint Fabric Demo

examples/chip-tool/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ static_library("chip-tool-utils") {
9191
"commands/icd/ICDCommand.h",
9292
"commands/pairing/OpenCommissioningWindowCommand.cpp",
9393
"commands/pairing/OpenCommissioningWindowCommand.h",
94+
"commands/pairing/OpenJointCommissioningWindowCommand.cpp",
95+
"commands/pairing/OpenJointCommissioningWindowCommand.h",
9496
"commands/pairing/PairingCommand.cpp",
9597
"commands/pairing/ToTLVCert.cpp",
9698
"commands/payload/AdditionalDataParseCommand.cpp",

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "commands/pairing/GetCommissionerRootCertificateCommand.h"
2424
#include "commands/pairing/IssueNOCChainCommand.h"
2525
#include "commands/pairing/OpenCommissioningWindowCommand.h"
26+
#include "commands/pairing/OpenJointCommissioningWindowCommand.h"
2627
#include "commands/pairing/PairingCommand.h"
2728

2829
#include <app/server/Dnssd.h>
@@ -272,6 +273,7 @@ void registerCommandsPairing(Commands & commands, CredentialIssuerCommands * cre
272273
// make_unique<CommissionedListCommand>(),
273274
make_unique<StartUdcServerCommand>(credsIssuerConfig),
274275
make_unique<OpenCommissioningWindowCommand>(credsIssuerConfig),
276+
make_unique<OpenJointCommissioningWindowCommand>(credsIssuerConfig),
275277
make_unique<GetCommissionerNodeIdCommand>(credsIssuerConfig),
276278
make_unique<GetCommissionerRootCertificateCommand>(credsIssuerConfig),
277279
make_unique<IssueNOCChainCommand>(credsIssuerConfig),
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2025 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
#include "OpenJointCommissioningWindowCommand.h"
20+
21+
#include <system/SystemClock.h>
22+
23+
using namespace ::chip;
24+
25+
CHIP_ERROR OpenJointCommissioningWindowCommand::RunCommand()
26+
{
27+
mWindowOpener = Platform::MakeUnique<Controller::CommissioningWindowOpener>(&CurrentCommissioner());
28+
29+
SetupPayload ignored;
30+
return mWindowOpener->OpenCommissioningWindow(Controller::CommissioningWindowPasscodeParams()
31+
.SetNodeId(mNodeId)
32+
.SetTimeout(mCommissioningWindowTimeout)
33+
.SetIteration(mIteration)
34+
.SetDiscriminator(mDiscriminator)
35+
.SetReadVIDPIDAttributes(true)
36+
.SetCallback(&mOnOpenCommissioningWindowCallback),
37+
ignored, true);
38+
}
39+
40+
void OpenJointCommissioningWindowCommand::OnOpenCommissioningWindowResponse(void * context, NodeId remoteId, CHIP_ERROR err,
41+
SetupPayload payload)
42+
{
43+
LogErrorOnFailure(err);
44+
45+
OpenJointCommissioningWindowCommand * command = reinterpret_cast<OpenJointCommissioningWindowCommand *>(context);
46+
VerifyOrReturn(command != nullptr, ChipLogError(chipTool, "OnOpenJointCommissioningWindowCommand: context is null"));
47+
command->SetCommandExitStatus(err);
48+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2025 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
#pragma once
20+
21+
#include "../common/CHIPCommand.h"
22+
23+
#include <controller/CommissioningWindowOpener.h>
24+
#include <lib/support/CHIPMem.h>
25+
26+
class OpenJointCommissioningWindowCommand : public CHIPCommand
27+
{
28+
public:
29+
OpenJointCommissioningWindowCommand(CredentialIssuerCommands * credIssuerCommands) :
30+
CHIPCommand("open-joint-commissioning-window", credIssuerCommands),
31+
mOnOpenCommissioningWindowCallback(OnOpenCommissioningWindowResponse, this)
32+
{
33+
AddArgument("node-id", 0, UINT64_MAX, &mNodeId, "Node to send command to.");
34+
AddArgument("window-timeout", 0, UINT16_MAX, &mCommissioningWindowTimeout,
35+
"Time, in seconds, before the commissioning window closes.");
36+
AddArgument("iteration", chip::Crypto::kSpake2p_Min_PBKDF_Iterations, chip::Crypto::kSpake2p_Max_PBKDF_Iterations,
37+
&mIteration, "Number of PBKDF iterations to use to derive the verifier. Ignored if 'option' is 0.");
38+
AddArgument("discriminator", 0, 4095, &mDiscriminator, "Discriminator to use for advertising. Ignored if 'option' is 0.");
39+
AddArgument("timeout", 0, UINT16_MAX, &mTimeout, "Time, in seconds, before this command is considered to have timed out.");
40+
}
41+
42+
/////////// CHIPCommand Interface /////////
43+
CHIP_ERROR RunCommand() override;
44+
// We issue multiple data model operations for this command, and the default
45+
// timeout for those is 10 seconds, so default to 20 seconds.
46+
chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(mTimeout.ValueOr(20)); }
47+
48+
private:
49+
NodeId mNodeId;
50+
uint16_t mCommissioningWindowTimeout;
51+
uint32_t mIteration;
52+
uint16_t mDiscriminator;
53+
54+
chip::Optional<uint16_t> mTimeout;
55+
56+
chip::Platform::UniquePtr<chip::Controller::CommissioningWindowOpener> mWindowOpener;
57+
58+
static void OnOpenCommissioningWindowResponse(void * context, NodeId deviceId, CHIP_ERROR status, chip::SetupPayload payload);
59+
60+
chip::Callback::Callback<chip::Controller::OnOpenCommissioningWindow> mOnOpenCommissioningWindowCallback;
61+
};

examples/jf-admin-app/linux/JFAManager.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ CHIP_ERROR JFAManager::Init(Server & server)
4040
return CHIP_NO_ERROR;
4141
}
4242

43+
CHIP_ERROR JFAManager::GetJointFabricMode(uint8_t & jointFabricMode)
44+
{
45+
jointFabricMode = ((IsDeviceCommissioned() ? 0 : 1) << 0) | (IsDeviceCommissioned() ? (IsDeviceJFAdmin() ? (1 << 1) : 0) : 0) |
46+
(IsDeviceCommissioned() ? (IsDeviceJFAnchor() ? (1 << 2) : 0) : 0) | (IsDeviceCommissioned() ? (1 << 3) : 0);
47+
return CHIP_NO_ERROR;
48+
}
49+
4350
CHIP_ERROR JFAManager::FinalizeCommissioning(NodeId nodeId)
4451
{
4552
if (jfFabricIndex == kUndefinedFabricId)
@@ -72,6 +79,46 @@ void JFAManager::HandleCommissioningCompleteEvent()
7279
}
7380
}
7481

82+
bool JFAManager::IsDeviceJFAdmin()
83+
{
84+
if (jfFabricIndex == kUndefinedFabricId)
85+
{
86+
return false;
87+
}
88+
89+
CATValues cats;
90+
91+
if (mServer->GetFabricTable().FetchCATs(jfFabricIndex, cats) == CHIP_NO_ERROR)
92+
{
93+
if (cats.ContainsIdentifier(kAdminCATIdentifier))
94+
{
95+
return true;
96+
}
97+
}
98+
99+
return false;
100+
}
101+
102+
bool JFAManager::IsDeviceJFAnchor()
103+
{
104+
if (jfFabricIndex == kUndefinedFabricId)
105+
{
106+
return false;
107+
}
108+
109+
CATValues cats;
110+
111+
if (mServer->GetFabricTable().FetchCATs(jfFabricIndex, cats) == CHIP_NO_ERROR)
112+
{
113+
if (cats.ContainsIdentifier(kAnchorCATIdentifier))
114+
{
115+
return true;
116+
}
117+
}
118+
119+
return false;
120+
}
121+
75122
void JFAManager::ReleaseSession()
76123
{
77124
auto optionalSessionHandle = mSessionHolder.Get();

examples/jf-admin-app/linux/include/JFAManager.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ class JFAManager
3838
void HandleCommissioningCompleteEvent();
3939
CHIP_ERROR FinalizeCommissioning(NodeId nodeId);
4040

41+
CHIP_ERROR GetJointFabricMode(uint8_t & jointFabricMode);
42+
43+
bool IsDeviceCommissioned() { return jfFabricIndex != kUndefinedFabricId; }
44+
bool IsDeviceJFAdmin();
45+
bool IsDeviceJFAnchor();
46+
4147
private:
4248
// Various actions to take when OnConnected callback is called
4349
enum OnConnectedAction

examples/jf-admin-app/linux/main.cpp

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,81 @@
2525
#include <app/ConcreteAttributePath.h>
2626
#include <app/server/Server.h>
2727
#include <lib/support/logging/CHIPLogging.h>
28+
#include <platform/DeviceInstanceInfoProvider.h>
2829

2930
#include <string>
3031

3132
using namespace chip;
3233
using namespace chip::app;
3334
using namespace chip::app::Clusters;
35+
using namespace chip::DeviceLayer;
36+
37+
namespace {
38+
39+
class ExampleDeviceInstanceInfoProvider : public DeviceInstanceInfoProvider
40+
{
41+
public:
42+
void Init(DeviceInstanceInfoProvider * defaultProvider) { mDefaultProvider = defaultProvider; }
43+
44+
CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override { return mDefaultProvider->GetVendorName(buf, bufSize); }
45+
CHIP_ERROR GetVendorId(uint16_t & vendorId) override { return mDefaultProvider->GetVendorId(vendorId); }
46+
CHIP_ERROR GetProductName(char * buf, size_t bufSize) override { return mDefaultProvider->GetProductName(buf, bufSize); }
47+
CHIP_ERROR GetProductId(uint16_t & productId) override { return mDefaultProvider->GetProductId(productId); }
48+
CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override { return mDefaultProvider->GetPartNumber(buf, bufSize); }
49+
CHIP_ERROR GetProductURL(char * buf, size_t bufSize) override { return mDefaultProvider->GetPartNumber(buf, bufSize); }
50+
CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override { return mDefaultProvider->GetProductLabel(buf, bufSize); }
51+
CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override { return mDefaultProvider->GetSerialNumber(buf, bufSize); }
52+
CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override
53+
{
54+
return mDefaultProvider->GetManufacturingDate(year, month, day);
55+
}
56+
CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override
57+
{
58+
return mDefaultProvider->GetHardwareVersion(hardwareVersion);
59+
}
60+
CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override
61+
{
62+
return mDefaultProvider->GetHardwareVersionString(buf, bufSize);
63+
}
64+
CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override
65+
{
66+
return mDefaultProvider->GetRotatingDeviceIdUniqueId(uniqueIdSpan);
67+
}
68+
CHIP_ERROR GetJointFabricMode(uint8_t & jointFabricMode) override { return JFAMgr().GetJointFabricMode(jointFabricMode); }
69+
70+
private:
71+
DeviceInstanceInfoProvider * mDefaultProvider;
72+
};
73+
74+
ExampleDeviceInstanceInfoProvider gExampleDeviceInstanceInfoProvider;
75+
76+
} // namespace
3477

3578
void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size,
3679
uint8_t * value)
3780
{}
3881

39-
void EventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
82+
void EventHandler(const ChipDeviceEvent * event, intptr_t arg)
4083
{
4184
(void) arg;
4285

43-
if (event->Type == DeviceLayer::DeviceEventType::kCommissioningComplete)
86+
if (event->Type == DeviceEventType::kCommissioningComplete)
4487
{
4588
JFAMgr().HandleCommissioningCompleteEvent();
4689
}
4790
}
4891

4992
void ApplicationInit()
5093
{
94+
auto * defaultProvider = GetDeviceInstanceInfoProvider();
95+
if (defaultProvider != &gExampleDeviceInstanceInfoProvider)
96+
{
97+
gExampleDeviceInstanceInfoProvider.Init(defaultProvider);
98+
SetDeviceInstanceInfoProvider(&gExampleDeviceInstanceInfoProvider);
99+
}
100+
51101
JFAMgr().Init(Server::GetInstance());
52-
DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0);
102+
PlatformMgrImpl().AddEventHandler(EventHandler, 0);
53103
}
54104

55105
void ApplicationShutdown() {}

examples/jf-control-app/BUILD.gn

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ config("config") {
6666

6767
static_library("jfc-utils") {
6868
sources = [
69-
"${chip_root}/examples/chip-tool/CHIPCommand.h",
7069
"${chip_root}/examples/chip-tool/commands/clusters/ModelCommand.cpp",
7170
"${chip_root}/examples/chip-tool/commands/clusters/ModelCommand.h",
7271
"${chip_root}/examples/chip-tool/commands/common/BDXDiagnosticLogsServerDelegate.cpp",
72+
"${chip_root}/examples/chip-tool/commands/common/CHIPCommand.h",
7373
"${chip_root}/examples/chip-tool/commands/common/Command.cpp",
7474
"${chip_root}/examples/chip-tool/commands/common/Command.h",
7575
"${chip_root}/examples/chip-tool/commands/common/Commands.cpp",
@@ -82,6 +82,8 @@ static_library("jfc-utils") {
8282
"${chip_root}/examples/chip-tool/commands/icd/ICDCommand.h",
8383
"${chip_root}/examples/chip-tool/commands/pairing/OpenCommissioningWindowCommand.cpp",
8484
"${chip_root}/examples/chip-tool/commands/pairing/OpenCommissioningWindowCommand.h",
85+
"${chip_root}/examples/chip-tool/commands/pairing/OpenJointCommissioningWindowCommand.cpp",
86+
"${chip_root}/examples/chip-tool/commands/pairing/OpenJointCommissioningWindowCommand.h",
8587
"${chip_root}/examples/chip-tool/commands/pairing/ToTLVCert.cpp",
8688
"${chip_root}/examples/platform/linux/RpcClientProcessor.cpp",
8789
"${chip_root}/examples/platform/linux/RpcClientProcessor.h",

0 commit comments

Comments
 (0)