Skip to content

Commit ed17bfe

Browse files
Implement separate Produce and Consume SetupPayload validation modes
In Consume mode, unknown rendevouz flags are allowed.
1 parent fcfc9bc commit ed17bfe

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

src/setup_payload/SetupPayload.cpp

+15-11
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace chip {
3636
// Check the Setup Payload for validity
3737
//
3838
// `vendor_id` and `product_id` are allowed all of uint16_t
39-
bool PayloadContents::isValidQRCodePayload() const
39+
bool PayloadContents::isValidQRCodePayload(ValidationMode mode) const
4040
{
4141
// 3-bit value specifying the QR code payload version.
4242
if (version >= 1 << kVersionFieldLengthInBits)
@@ -50,6 +50,7 @@ bool PayloadContents::isValidQRCodePayload() const
5050
}
5151

5252
// Device Commissioning Flow
53+
// Even in ValidatoinMode::kConsume we can only handle modes that we understand.
5354
// 0: Standard commissioning flow: such a device, when uncommissioned, always enters commissioning mode upon power-up, subject
5455
// to the rules in [ref_Announcement_Commencement]. 1: User-intent commissioning flow: user action required to enter
5556
// commissioning mode. 2: Custom commissioning flow: interaction with a vendor-specified means is needed before commissioning.
@@ -60,13 +61,6 @@ bool PayloadContents::isValidQRCodePayload() const
6061
return false;
6162
}
6263

63-
chip::RendezvousInformationFlags allvalid(RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kOnNetwork,
64-
RendezvousInformationFlag::kSoftAP);
65-
if (!rendezvousInformation.HasValue() || !rendezvousInformation.Value().HasOnly(allvalid))
66-
{
67-
return false;
68-
}
69-
7064
// General discriminator validity is enforced by the SetupDiscriminator class, but it can't be short for QR a code.
7165
if (discriminator.IsShortDiscriminator())
7266
{
@@ -78,13 +72,21 @@ bool PayloadContents::isValidQRCodePayload() const
7872
return false;
7973
}
8074

75+
// RendevouzInformation must be present for a QR code.
76+
VerifyOrReturnValue(rendezvousInformation.HasValue(), false);
77+
if (mode == ValidationMode::kProduce)
78+
{
79+
chip::RendezvousInformationFlags valid(RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kOnNetwork,
80+
RendezvousInformationFlag::kSoftAP);
81+
VerifyOrReturnValue(rendezvousInformation.Value().HasOnly(valid), false);
82+
}
83+
8184
return CheckPayloadCommonConstraints();
8285
}
8386

84-
bool PayloadContents::isValidManualCode() const
87+
bool PayloadContents::isValidManualCode(ValidationMode mode) const
8588
{
8689
// Discriminator validity is enforced by the SetupDiscriminator class.
87-
8890
if (setUpPINCode >= 1 << kSetupPINCodeFieldLengthInBits)
8991
{
9092
return false;
@@ -109,7 +111,9 @@ bool PayloadContents::IsValidSetupPIN(uint32_t setupPIN)
109111

110112
bool PayloadContents::CheckPayloadCommonConstraints() const
111113
{
112-
// A version not equal to 0 would be invalid for v1 and would indicate new format (e.g. version 2)
114+
// Validation rules in this method apply to all validation modes.
115+
116+
// Even in ValidationMode::kConsume we don't understand how to handle any payload version other than 0.
113117
if (version != 0)
114118
{
115119
return false;

src/setup_payload/SetupPayload.h

+14-2
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,20 @@ struct PayloadContents
128128
SetupDiscriminator discriminator;
129129
uint32_t setUpPINCode = 0;
130130

131-
bool isValidQRCodePayload() const;
132-
bool isValidManualCode() const;
131+
enum class ValidationMode : uint8_t
132+
{
133+
kProduce, ///< Only flags or values allowed by the current spec version are allowed.
134+
/// Producers of a Setup Payload should use this mode to ensure the
135+
// payload is valid according to the current spec version.
136+
kConsume, ///< Flags or values that are reserved for future use, or were allowed in
137+
/// a previous spec version may be present. Consumers of a Setup Payload
138+
/// should use this mode to ensure they are forward and backwards
139+
/// compatible with payloads from older or newer Matter devices.
140+
};
141+
142+
bool isValidQRCodePayload(ValidationMode mode = ValidationMode::kProduce) const;
143+
bool isValidManualCode(ValidationMode mode = ValidationMode::kProduce) const;
144+
133145
bool operator==(const PayloadContents & input) const;
134146

135147
static bool IsValidSetupPIN(uint32_t setupPIN);

src/setup_payload/tests/TestQRCode.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,13 @@ TEST(TestQRCode, TestSetupPayloadVerify)
307307
invalid.SetRaw(static_cast<uint8_t>(invalid.Raw() + 1));
308308
test_payload.rendezvousInformation.SetValue(invalid);
309309
EXPECT_EQ(test_payload.isValidQRCodePayload(), false);
310+
// When validating in Consume mode, unknown rendezvous flags are OK.
311+
EXPECT_TRUE(test_payload.isValidQRCodePayload(PayloadContents::ValidationMode::kConsume));
312+
test_payload.rendezvousInformation.SetValue(RendezvousInformationFlags(0xff));
313+
EXPECT_TRUE(test_payload.isValidQRCodePayload(PayloadContents::ValidationMode::kConsume));
314+
// Rendezvous information is still required even in Consume mode.
315+
test_payload.rendezvousInformation.ClearValue();
316+
EXPECT_FALSE(test_payload.isValidQRCodePayload(PayloadContents::ValidationMode::kConsume));
310317

311318
// test invalid setup PIN
312319
test_payload = payload;

0 commit comments

Comments
 (0)