Skip to content

Commit

Permalink
[qr-code] Align QR Code format with the spec
Browse files Browse the repository at this point in the history
1. Replace boolean requiresCustomFlow with 2-bit field with
   the following meaning:
   0 - device automatically enters paring mode upon power-up
   1 - device needs user interaction to enter pairing mode
   2 - device uses a vendor-specific flow that should be
       retrieved from the distributed ledger.
2. Replace CH: prefix with MT:
  • Loading branch information
Damian-Nordic committed Jun 2, 2021
1 parent 17f00e0 commit fc71c26
Show file tree
Hide file tree
Showing 29 changed files with 258 additions and 181 deletions.
2 changes: 1 addition & 1 deletion docs/guides/nrfconnect_examples_cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Takes no arguments.

```shell
uart:~$ chip qrcode
CH:H34.GHY00 0C9SS0
MT:W0GU2OTB00KA0648G00
```

#### `qrcodeurl`
Expand Down
4 changes: 2 additions & 2 deletions examples/all-clusters-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,8 +509,8 @@ std::string createSetupPayload()
ESP_LOGE(TAG, "Failed to get decimal setup code");
}

payload.requiresCustomFlow = 1;
generator = ManualSetupPayloadGenerator(payload);
payload.commissioningFlow = CommissioningFlow::kCustom;
generator = ManualSetupPayloadGenerator(payload);

if (generator.payloadDecimalStringRepresentation(outCode) == CHIP_NO_ERROR)
{
Expand Down
4 changes: 2 additions & 2 deletions examples/chip-tool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ and the `parse-setup-payload` command

#### QR Code

$ chip-tool payload parse-setup-payload "CH:#####"
$ chip-tool payload parse-setup-payload "MT:#####"

#### QR Code with optional Vendor Info

$ chip-tool payload parse-setup-payload "CH:#####"
$ chip-tool payload parse-setup-payload "MT:#####"

#### Manual Setup Code

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ CHIP_ERROR SetupPayloadParseCommand::Print(chip::SetupPayload payload)
std::vector<OptionalQRCodeInfo> optionalVendorData;
CHIP_ERROR err = CHIP_NO_ERROR;

ChipLogProgress(SetupPayload, "RequiresCustomFlow: %u", payload.requiresCustomFlow);
ChipLogProgress(SetupPayload, "CommissioningFlow: %u", payload.commissioningFlow);
ChipLogProgress(SetupPayload, "VendorID: %u", payload.vendorID);
ChipLogProgress(SetupPayload, "Version: %u", payload.version);
ChipLogProgress(SetupPayload, "ProductID: %u", payload.productID);
Expand Down Expand Up @@ -100,5 +100,5 @@ CHIP_ERROR SetupPayloadParseCommand::Parse(std::string codeString, chip::SetupPa

bool SetupPayloadParseCommand::IsQRCode(std::string codeString)
{
return codeString.rfind(QRCODE_PREFIX) == 0;
return codeString.rfind(kQRCodePrefix) == 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,4 @@ class SetupPayloadParseCommand : public Command
CHIP_ERROR Parse(std::string codeString, chip::SetupPayload & payload);
CHIP_ERROR Print(chip::SetupPayload payload);
bool IsQRCode(std::string codeString);
const std::string QRCODE_PREFIX = "CH:";
};
4 changes: 2 additions & 2 deletions examples/lock-app/cc13x2x7_26x2x7/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,15 @@ This is done by scanning a QR code. A URL will be displayed on the lock-app's
log ([UART terminal](#viewing-logging-output)). It will look like the following:
```
SetupQRCode: [CH:.81TM -00 0C9SS0]
SetupQRCode: [MT:.81TM -00 0C9SS0]
Copy/paste the below URL in a browser to see the QR Code:
https://dhrishi.github.io/connectedhomeip/qrcode.html?data=CH%3A.81TM%20-00%200C9SS0
```
You can directly navigate to the webpage URL displayed (which has QR payload
pre-loaded). Alternatively, you can navigate to [the QR code
generator][qr_code_generator] and enter in the payload shown in `SetupQRCode`
(in this case `CH:.81TM -00 0C9SS0`).
(in this case `MT:.81TM -00 0C9SS0`).
### CHIP Remote Commands
Expand Down
4 changes: 2 additions & 2 deletions examples/pump-app/cc13x2x7_26x2x7/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,15 @@ This is done by scanning a QR code. A URL will be displayed on the lock-app's
log ([UART terminal](#viewing-logging-output)). It will look like the following:
```
SetupQRCode: [CH:.81TM -00 0C9SS0]
SetupQRCode: [MT:.81TM -00 0C9SS0]
Copy/paste the below URL in a browser to see the QR Code:
https://dhrishi.github.io/connectedhomeip/qrcode.html?data=CH%3A.81TM%20-00%200C9SS0
```
You can directly navigate to the webpage URL displayed (which has QR payload
pre-loaded). Alternatively, you can navigate to [the QR code
generator][qr_code_generator] and enter in the payload shown in `SetupQRCode`
(in this case `CH:.81TM -00 0C9SS0`).
(in this case `MT:.81TM -00 0C9SS0`).
### CHIP Remote Commands
Expand Down
4 changes: 2 additions & 2 deletions examples/pump-controller-app/cc13x2x7_26x2x7/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,15 @@ This is done by scanning a QR code. A URL will be displayed on the lock-app's
log ([UART terminal](#viewing-logging-output)). It will look like the following:
```
SetupQRCode: [CH:.81TM -00 0C9SS0]
SetupQRCode: [MT:.81TM -00 0C9SS0]
Copy/paste the below URL in a browser to see the QR Code:
https://dhrishi.github.io/connectedhomeip/qrcode.html?data=CH%3A.81TM%20-00%200C9SS0
```
You can directly navigate to the webpage URL displayed (which has QR payload
pre-loaded). Alternatively, you can navigate to [the QR code
generator][qr_code_generator] and enter in the payload shown in `SetupQRCode`
(in this case `CH:.81TM -00 0C9SS0`).
(in this case `MT:.81TM -00 0C9SS0`).
### CHIP Remote Commands
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ class CHIPToolActivity :
val records = (messages[0] as NdefMessage).records
if (records.size != 1) return

// Require NDEF URI record starting with "ch:"
// Require NDEF URI record starting with "mt:"
val uri = records[0].toUri()
if (!uri?.scheme.equals("ch", true)) return
if (!uri?.scheme.equals("mt", true)) return

lateinit var setupPayload: SetupPayload
try {
Expand Down
8 changes: 4 additions & 4 deletions src/controller/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,11 @@ For testing
Print the commissioning information encoded in the Manual Pairing Code.

```
chip-device-ctrl > setup-payload parse-manual 35767807533
chip-device-ctrl > setup-payload parse-manual 34970112332
Version: 0
VendorID: 0
ProductID: 0
RequiresCustomFlow: 0
CommissioningFlow: 0
RendezvousInformation: 0
Discriminator: 3840
SetUpPINCode: 20202021
Expand All @@ -228,11 +228,11 @@ SetUpPINCode: 20202021
Print the commissioning information encoded in the QR Code payload.

```
chip-device-ctrl > setup-payload parse-qr "VP:vendorpayload%CH:H34.GHY00 0C9SS0"
chip-device-ctrl > setup-payload parse-qr "VP:vendorpayload%MT:W0GU2OTB00KA0648G00"
Version: 0
VendorID: 9050
ProductID: 20043
RequiresCustomFlow: 0
CommissioningFlow: 0
RendezvousInformation: 2 [BLE]
Discriminator: 3840
SetUpPINCode: 20202021
Expand Down
2 changes: 1 addition & 1 deletion src/controller/python/chip/setup_payload/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void YieldSetupPayloadAttributes(const SetupPayload & payload, AttributeVisitor
attrVisitor("Version", std::to_string(payload.version).c_str());
attrVisitor("VendorID", std::to_string(payload.vendorID).c_str());
attrVisitor("ProductID", std::to_string(payload.productID).c_str());
attrVisitor("RequiresCustomFlow", std::to_string(payload.requiresCustomFlow).c_str());
attrVisitor("CommissioningFlow", std::to_string(static_cast<uint8_t>(payload.commissioningFlow)).c_str());
attrVisitor("RendezvousInformation", std::to_string(payload.rendezvousInformation.Raw()).c_str());
attrVisitor("Discriminator", std::to_string(payload.discriminator).c_str());
attrVisitor("SetUpPINCode", std::to_string(payload.setUpPINCode).c_str());
Expand Down
4 changes: 2 additions & 2 deletions src/controller/python/chip/setup_payload/setup_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def Print(self):
decorated_value = f" [{decorated_value}]" if decorated_value else ""
print(f"{name}: {value}{decorated_value}")

for tag, value in self.vendor_attributes:
print(f"Vendor attribute '{tag:>3}': {value}")
for tag in self.vendor_attributes:
print(f"Vendor attribute '{tag:>3}': {self.vendor_attributes[tag]}")

def Clear(self):
self.attributes.clear()
Expand Down
9 changes: 8 additions & 1 deletion src/darwin/Framework/CHIP/CHIPSetupPayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ typedef NS_ENUM(NSUInteger, CHIPRendezvousInformationFlags) {
kRendezvousInformationAllMask = kRendezvousInformationSoftAP | kRendezvousInformationBLE | kRendezvousInformationOnNetwork,
};

typedef NS_ENUM(NSUInteger, CHIPCommissioningFlow) {
kCommissioningFlowStandard = 0, // Device automatically enters pairing mode upon power-up
kCommissioningFlowUserActionRequired = 1, // Device requires a user interaction to enter pairing mode
kCommissioningFlowCustom = 2, // Commissioning steps should be retrieved from the distributed compliance ledger
kCommissioningFlowInvalid = 3,
};

typedef NS_ENUM(NSUInteger, CHIPOptionalQRCodeInfoType) {
kOptionalQRCodeInfoTypeUnknown,
kOptionalQRCodeInfoTypeString,
Expand All @@ -46,7 +53,7 @@ typedef NS_ENUM(NSUInteger, CHIPOptionalQRCodeInfoType) {
@property (nonatomic, strong) NSNumber * version;
@property (nonatomic, strong) NSNumber * vendorID;
@property (nonatomic, strong) NSNumber * productID;
@property (nonatomic, assign) BOOL requiresCustomFlow;
@property (nonatomic, assign) CHIPCommissioningFlow commissioningFlow;
@property (nonatomic, assign) CHIPRendezvousInformationFlags rendezvousInformation;
@property (nonatomic, strong) NSNumber * discriminator;
@property (nonatomic, strong) NSNumber * setUpPINCode;
Expand Down
19 changes: 16 additions & 3 deletions src/darwin/Framework/CHIP/CHIPSetupPayload.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ @implementation CHIPSetupPayload {
chip::SetupPayload _chipSetupPayload;
}

- (CHIPRendezvousInformationFlags)valueOf:(chip::RendezvousInformationFlags)value
- (CHIPRendezvousInformationFlags)convertRendezvousFlags:(chip::RendezvousInformationFlags)value
{
if (value.Has(chip::RendezvousInformationFlag::kBLE)) {
return kRendezvousInformationBLE;
Expand All @@ -39,15 +39,28 @@ - (CHIPRendezvousInformationFlags)valueOf:(chip::RendezvousInformationFlags)valu
}
}

- (CHIPCommissioningFlow)convertCommissioningFlow:(chip::CommissioningFlow)value
{
if (value == chip::CommissioningFlow::kStandard) {
return kCommissioningFlowStandard;
} else if (value == chip::CommissioningFlow::kUserActionRequired) {
return kCommissioningFlowUserActionRequired;
} else if (value == chip::CommissioningFlow::kCustom) {
return kCommissioningFlowCustom;
} else {
return kCommissioningFlowInvalid;
}
}

- (id)initWithSetupPayload:(chip::SetupPayload)setupPayload
{
if (self = [super init]) {
_chipSetupPayload = setupPayload;
_version = [NSNumber numberWithUnsignedChar:setupPayload.version];
_vendorID = [NSNumber numberWithUnsignedShort:setupPayload.vendorID];
_productID = [NSNumber numberWithUnsignedShort:setupPayload.productID];
_requiresCustomFlow = setupPayload.requiresCustomFlow == 1;
_rendezvousInformation = [self valueOf:setupPayload.rendezvousInformation];
_commissioningFlow = [self convertCommissioningFlow:setupPayload.commissioningFlow];
_rendezvousInformation = [self convertRendezvousFlags:setupPayload.rendezvousInformation];
_discriminator = [NSNumber numberWithUnsignedShort:setupPayload.discriminator];
_setUpPINCode = [NSNumber numberWithUnsignedInt:setupPayload.setUpPINCode];

Expand Down
5 changes: 3 additions & 2 deletions src/darwin/Framework/CHIP/CHIPSetupPayload_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

#ifdef __cplusplus
- (id)initWithSetupPayload:(chip::SetupPayload)setupPayload;
- (CHIPRendezvousInformationFlags)valueOf:(chip::RendezvousInformationFlags)value;
- (CHIPRendezvousInformationFlags)convertRendezvousFlags:(chip::RendezvousInformationFlags)value;
- (CHIPCommissioningFlow)convertCommissioningFlow:(chip::CommissioningFlow)value;
#endif

@end
@end
30 changes: 15 additions & 15 deletions src/darwin/Framework/CHIPTests/CHIPSetupPayloadParserTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ - (void)testOnboardingPayloadParser_Manual_NoError
XCTAssertEqual(payload.setUpPINCode.unsignedIntegerValue, 123456780);
XCTAssertEqual(payload.vendorID.unsignedIntegerValue, 1);
XCTAssertEqual(payload.productID.unsignedIntegerValue, 1);
XCTAssertTrue(payload.requiresCustomFlow);
XCTAssertEqual(payload.commissioningFlow, kCommissioningFlowCustom);
XCTAssertEqual(payload.version.unsignedIntegerValue, 0);
XCTAssertEqual(payload.rendezvousInformation, kRendezvousInformationNone);
}
Expand Down Expand Up @@ -79,7 +79,7 @@ - (void)testOnboardingPayloadParser_Admin_NoError
XCTAssertEqual(payload.setUpPINCode.unsignedIntegerValue, 123456780);
XCTAssertEqual(payload.vendorID.unsignedIntegerValue, 1);
XCTAssertEqual(payload.productID.unsignedIntegerValue, 1);
XCTAssertTrue(payload.requiresCustomFlow);
XCTAssertEqual(payload.commissioningFlow, kCommissioningFlowCustom);
XCTAssertEqual(payload.version.unsignedIntegerValue, 0);
XCTAssertEqual(payload.rendezvousInformation, kRendezvousInformationNone);
}
Expand All @@ -98,7 +98,7 @@ - (void)testOnboardingPayloadParser_Admin_WrongType
- (void)testOnboardingPayloadParser_QRCode_NoError
{
NSError * error;
CHIPSetupPayload * payload = [CHIPOnboardingPayloadParser setupPayloadForOnboardingPayload:@"CH:R5L90UV200A3L900000"
CHIPSetupPayload * payload = [CHIPOnboardingPayloadParser setupPayloadForOnboardingPayload:@"MT:R5L90MP500K64J00000"
ofType:CHIPOnboardingPayloadTypeQRCode
error:&error];

Expand All @@ -109,15 +109,15 @@ - (void)testOnboardingPayloadParser_QRCode_NoError
XCTAssertEqual(payload.setUpPINCode.unsignedIntegerValue, 2048);
XCTAssertEqual(payload.vendorID.unsignedIntegerValue, 12);
XCTAssertEqual(payload.productID.unsignedIntegerValue, 1);
XCTAssertFalse(payload.requiresCustomFlow);
XCTAssertEqual(payload.commissioningFlow, kCommissioningFlowStandard);
XCTAssertEqual(payload.version.unsignedIntegerValue, 5);
XCTAssertEqual(payload.rendezvousInformation, kRendezvousInformationSoftAP);
}

- (void)testOnboardingPayloadParser_QRCode_WrongType
{
NSError * error;
CHIPSetupPayload * payload = [CHIPOnboardingPayloadParser setupPayloadForOnboardingPayload:@"CH:R5L90UV200A3L900000"
CHIPSetupPayload * payload = [CHIPOnboardingPayloadParser setupPayloadForOnboardingPayload:@"MT:R5L90MP500K64J00000"
ofType:CHIPOnboardingPayloadTypeAdmin
error:&error];

Expand All @@ -129,7 +129,7 @@ - (void)testOnboardingPayloadParser_NFC_NoError
{
NSError * error;
CHIPSetupPayload * payload =
[CHIPOnboardingPayloadParser setupPayloadForOnboardingPayload:@"CH:R5L90UV200A3L90A33P0GQ670.QT52B.E23O6DE044U1077U.3"
[CHIPOnboardingPayloadParser setupPayloadForOnboardingPayload:@"MT:R5L90MP500K64J0A33P0GQ670.QT52B.E23O6DE0Y3U10O0"
ofType:CHIPOnboardingPayloadTypeNFC
error:&error];

Expand All @@ -140,7 +140,7 @@ - (void)testOnboardingPayloadParser_NFC_NoError
XCTAssertEqual(payload.setUpPINCode.unsignedIntegerValue, 2048);
XCTAssertEqual(payload.vendorID.unsignedIntegerValue, 12);
XCTAssertEqual(payload.productID.unsignedIntegerValue, 1);
XCTAssertFalse(payload.requiresCustomFlow);
XCTAssertEqual(payload.commissioningFlow, kCommissioningFlowStandard);
XCTAssertEqual(payload.version.unsignedIntegerValue, 5);
XCTAssertEqual(payload.rendezvousInformation, kRendezvousInformationSoftAP);
}
Expand All @@ -149,7 +149,7 @@ - (void)testOnboardingPayloadParser_NFC_WrongType
{
NSError * error;
CHIPSetupPayload * payload =
[CHIPOnboardingPayloadParser setupPayloadForOnboardingPayload:@"CH:R5L90UV200A3L90A33P0GQ670.QT52B.E23O6DE044U1077U.3"
[CHIPOnboardingPayloadParser setupPayloadForOnboardingPayload:@"MT:R5L90MP500K64J0A33P0GQ670.QT52B.E23O6DE0Y3U10O0"
ofType:CHIPOnboardingPayloadTypeManualCode
error:&error];

Expand All @@ -171,7 +171,7 @@ - (void)testManualParser
XCTAssertEqual(payload.setUpPINCode.unsignedIntegerValue, 123456780);
XCTAssertEqual(payload.vendorID.unsignedIntegerValue, 1);
XCTAssertEqual(payload.productID.unsignedIntegerValue, 1);
XCTAssertTrue(payload.requiresCustomFlow);
XCTAssertEqual(payload.commissioningFlow, kCommissioningFlowCustom);
XCTAssertEqual(payload.version.unsignedIntegerValue, 0);
XCTAssertEqual(payload.rendezvousInformation, kRendezvousInformationNone);
}
Expand All @@ -190,7 +190,7 @@ - (void)testQRCodeParser_Error
{
NSError * error;
CHIPQRCodeSetupPayloadParser * parser =
[[CHIPQRCodeSetupPayloadParser alloc] initWithBase38Representation:@"CH:J5L900CK70WWI0000"];
[[CHIPQRCodeSetupPayloadParser alloc] initWithBase38Representation:@"MT:R5L90MP500K64J0000."];
CHIPSetupPayload * payload = [parser populatePayload:&error];

XCTAssertNil(payload);
Expand All @@ -201,7 +201,7 @@ - (void)testQRCodeParser
{
NSError * error;
CHIPQRCodeSetupPayloadParser * parser =
[[CHIPQRCodeSetupPayloadParser alloc] initWithBase38Representation:@"CH:R5L90UV200A3L900000"];
[[CHIPQRCodeSetupPayloadParser alloc] initWithBase38Representation:@"MT:R5L90MP500K64J00000"];
CHIPSetupPayload * payload = [parser populatePayload:&error];

XCTAssertNotNil(payload);
Expand All @@ -211,16 +211,16 @@ - (void)testQRCodeParser
XCTAssertEqual(payload.setUpPINCode.unsignedIntegerValue, 2048);
XCTAssertEqual(payload.vendorID.unsignedIntegerValue, 12);
XCTAssertEqual(payload.productID.unsignedIntegerValue, 1);
XCTAssertFalse(payload.requiresCustomFlow);
XCTAssertEqual(payload.commissioningFlow, kCommissioningFlowStandard);
XCTAssertEqual(payload.version.unsignedIntegerValue, 5);
XCTAssertEqual(payload.rendezvousInformation, kRendezvousInformationSoftAP);
}

- (void)testQRCodeParserWithOptionalData
{
NSError * error;
CHIPQRCodeSetupPayloadParser * parser = [[CHIPQRCodeSetupPayloadParser alloc]
initWithBase38Representation:@"CH:R5L90UV200A3L90A33P0GQ670.QT52B.E23O6DE044U1077U.3"];
CHIPQRCodeSetupPayloadParser * parser =
[[CHIPQRCodeSetupPayloadParser alloc] initWithBase38Representation:@"MT:R5L90MP500K64J0A33P0GQ670.QT52B.E23O6DE0Y3U10O0"];
CHIPSetupPayload * payload = [parser populatePayload:&error];

XCTAssertNotNil(payload);
Expand All @@ -231,7 +231,7 @@ - (void)testQRCodeParserWithOptionalData
XCTAssertEqual(payload.setUpPINCode.unsignedIntegerValue, 2048);
XCTAssertEqual(payload.vendorID.unsignedIntegerValue, 12);
XCTAssertEqual(payload.productID.unsignedIntegerValue, 1);
XCTAssertFalse(payload.requiresCustomFlow);
XCTAssertEqual(payload.commissioningFlow, kCommissioningFlowStandard);
XCTAssertEqual(payload.rendezvousInformation, kRendezvousInformationSoftAP);
XCTAssertTrue([payload.serialNumber isEqualToString:@"1"]);

Expand Down
9 changes: 8 additions & 1 deletion src/setup_payload/Base38.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,14 @@ CHIP_ERROR base38Decode(std::string base38, std::vector<uint8_t> & result)

for (int i = 0; i < bytesInDecodedChunk; i++)
{
result.push_back(static_cast<uint8_t>(value >> (8 * i)));
result.push_back(static_cast<uint8_t>(value));
value >>= 8;
}

if (value > 0)
{
// encoded value is too big to represent a correct chunk of size 1, 2 or 3 bytes
return CHIP_ERROR_INVALID_ARGUMENT;
}
}
return CHIP_NO_ERROR;
Expand Down
Loading

0 comments on commit fc71c26

Please sign in to comment.