| /* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <assert.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| |
| #include <iostream> |
| |
| #include "SetupPayload.cpp" |
| #include "Base45.cpp" |
| #include "QRCodeSetupPayloadGenerator.cpp" |
| #include "QRCodeSetupPayloadParser.cpp" |
| |
| using namespace chip; |
| using namespace std; |
| |
| #define EXPECT_EQ(x, y) \ |
| ((x) != (y)) ? cerr << endl << __FILE__ << ":" << __LINE__ << ":error EXPECT_EQ(" << x << ", " << y << ")\n", 1 : 0 |
| |
| int testPayloadByteArrayRep() |
| { |
| SetupPayload payload; |
| |
| payload.version = 5; |
| payload.vendorID = 12; |
| payload.productID = 1; |
| payload.requiresCustomFlow = 0; |
| payload.rendezvousInformation = 1; |
| payload.discriminator = 128; |
| payload.setUpPINCode = 2048; |
| |
| QRCodeSetupPayloadGenerator generator(payload); |
| string result = generator.payloadBinaryRepresentation(); |
| string expected = "000000000000000000100000000000010000000000000000100000000000000000010000000000000011001010"; |
| |
| return EXPECT_EQ(result, expected); |
| } |
| |
| int testPayloadBase45Rep() |
| { |
| SetupPayload payload; |
| |
| payload.version = 5; |
| payload.vendorID = 12; |
| payload.productID = 1; |
| payload.requiresCustomFlow = 0; |
| payload.rendezvousInformation = 1; |
| payload.discriminator = 128; |
| payload.setUpPINCode = 2048; |
| |
| QRCodeSetupPayloadGenerator generator(payload); |
| string result = generator.payloadBase45Representation(); |
| string expected = "B20800G00G8G000"; |
| |
| return EXPECT_EQ(result, expected); |
| } |
| |
| int testBase45() |
| { |
| int surprises = 0; |
| |
| uint8_t input[] = { 10, 10, 10 }; |
| |
| surprises += EXPECT_EQ(base45Encode(input, 0), ""); |
| |
| surprises += EXPECT_EQ(base45Encode(input, 1), "A0"); |
| |
| surprises += EXPECT_EQ(base45Encode(input, 2), "5C1"); |
| |
| surprises += EXPECT_EQ(base45Encode(input, 3), "5C1A0"); |
| |
| surprises += EXPECT_EQ(base45Encode((uint8_t *) "Hello World!", sizeof("Hello World!") - 1), "8 C VDN44I3E.VD/94"); |
| |
| vector<uint8_t> decoded = vector<uint8_t>(); |
| surprises += EXPECT_EQ(base45Decode("8 C VDN44I3E.VD/94", decoded), CHIP_NO_ERROR); |
| |
| string hello_world; |
| for (size_t _ = 0; _ < decoded.size(); _++) |
| { |
| hello_world += (char) decoded[_]; |
| } |
| surprises += EXPECT_EQ(hello_world, "Hello World!"); |
| |
| // short input |
| surprises += EXPECT_EQ(base45Decode("A0", decoded), CHIP_NO_ERROR); |
| surprises += EXPECT_EQ(decoded.size(), 2); |
| |
| // empty == empty |
| surprises += EXPECT_EQ(base45Decode("", decoded), CHIP_NO_ERROR); |
| surprises += EXPECT_EQ(decoded.size(), 0); |
| // too short |
| surprises += EXPECT_EQ(base45Decode("A", decoded), CHIP_ERROR_INVALID_MESSAGE_LENGTH); |
| |
| // outside valid chars |
| surprises += EXPECT_EQ(base45Decode("0\001", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("\0010", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("[0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("0[", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| |
| // BOGUS chars |
| surprises += EXPECT_EQ(base45Decode("!0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("\"0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("#0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("&0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("'0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("(0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode(")0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode(",0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode(";0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("<0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("=0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode(">0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| surprises += EXPECT_EQ(base45Decode("@0", decoded), CHIP_ERROR_INVALID_INTEGER_VALUE); |
| |
| return surprises; |
| } |
| |
| int testBitsetLen() |
| { |
| return EXPECT_EQ(kTotalPayloadDataSizeInBits % 8, 0); |
| } |
| |
| int testSetupPayloadVerify() |
| { |
| int surprises = 0; |
| SetupPayload payload; |
| |
| payload.version = 5; |
| payload.vendorID = 12; |
| payload.productID = 1; |
| payload.requiresCustomFlow = 0; |
| payload.rendezvousInformation = 1; |
| payload.discriminator = 128; |
| payload.setUpPINCode = 2048; |
| surprises += EXPECT_EQ(payload.isValidQRCodePayload(), true); |
| |
| // test invalid version |
| SetupPayload test_payload = payload; |
| test_payload.version = 2 << kVersionFieldLengthInBits; |
| surprises += EXPECT_EQ(test_payload.isValidQRCodePayload(), false); |
| |
| // test invalid rendezvousInformation |
| test_payload = payload; |
| test_payload.rendezvousInformation = 512; |
| surprises += EXPECT_EQ(test_payload.isValidQRCodePayload(), false); |
| |
| // test invalid discriminator |
| test_payload = payload; |
| test_payload.discriminator = 2 << kPayloadDiscriminatorFieldLengthInBits; |
| surprises += EXPECT_EQ(test_payload.isValidQRCodePayload(), false); |
| |
| // test invalid stetup PIN |
| test_payload = payload; |
| test_payload.setUpPINCode = 2 << kSetupPINCodeFieldLengthInBits; |
| surprises += EXPECT_EQ(test_payload.isValidQRCodePayload(), false); |
| |
| return surprises; |
| } |
| |
| int testInvalidQRCodePayload_WrongCharacterSet() |
| { |
| int surprises = 0; |
| string invalidString = "adas12AA"; |
| |
| QRCodeSetupPayloadParser parser = QRCodeSetupPayloadParser(invalidString); |
| SetupPayload payload; |
| CHIP_ERROR err = parser.populatePayload(payload); |
| bool didFail = err != CHIP_NO_ERROR; |
| surprises = EXPECT_EQ(didFail, true); |
| surprises = EXPECT_EQ(payload.isValidQRCodePayload(), false); |
| return surprises; |
| } |
| |
| int testInvalidQRCodePayload_WrongLength() |
| { |
| int surprises = 0; |
| string invalidString = "AA12"; |
| QRCodeSetupPayloadParser parser = QRCodeSetupPayloadParser(invalidString); |
| SetupPayload payload; |
| CHIP_ERROR err = parser.populatePayload(payload); |
| bool didFail = err != CHIP_NO_ERROR; |
| surprises = EXPECT_EQ(didFail, true); |
| surprises = EXPECT_EQ(payload.isValidQRCodePayload(), false); |
| return surprises; |
| } |
| |
| int testPayloadEquality() |
| { |
| SetupPayload payload; |
| |
| payload.version = 5; |
| payload.vendorID = 12; |
| payload.productID = 1; |
| payload.requiresCustomFlow = 0; |
| payload.rendezvousInformation = 1; |
| payload.discriminator = 128; |
| payload.setUpPINCode = 2048; |
| |
| SetupPayload equalPayload; |
| equalPayload.version = 5; |
| equalPayload.vendorID = 12; |
| equalPayload.productID = 1; |
| equalPayload.requiresCustomFlow = 0; |
| equalPayload.rendezvousInformation = 1; |
| equalPayload.discriminator = 128; |
| equalPayload.setUpPINCode = 2048; |
| |
| bool result = payload == equalPayload; |
| return EXPECT_EQ(result, true); |
| } |
| |
| int testPayloadInEquality() |
| { |
| SetupPayload payload; |
| |
| payload.version = 5; |
| payload.vendorID = 12; |
| payload.productID = 1; |
| payload.requiresCustomFlow = 0; |
| payload.rendezvousInformation = 1; |
| payload.discriminator = 128; |
| payload.setUpPINCode = 2048; |
| |
| SetupPayload unequalPayload; |
| unequalPayload.version = 5; |
| unequalPayload.vendorID = 12; |
| unequalPayload.productID = 1; |
| unequalPayload.requiresCustomFlow = 0; |
| unequalPayload.rendezvousInformation = 1; |
| unequalPayload.discriminator = 28; |
| unequalPayload.setUpPINCode = 121233; |
| |
| bool result = payload == unequalPayload; |
| return EXPECT_EQ(result, false); |
| } |
| |
| int testQRCodeToPayloadGeneration() |
| { |
| int surprises = 0; |
| SetupPayload payload; |
| payload.version = 3; |
| payload.vendorID = 100; |
| payload.productID = 12; |
| payload.requiresCustomFlow = 1; |
| payload.rendezvousInformation = 4; |
| payload.discriminator = 233; |
| payload.setUpPINCode = 5221133; |
| |
| QRCodeSetupPayloadGenerator generator(payload); |
| string base45Rep = generator.payloadBase45Representation(); |
| |
| SetupPayload resultingPayload; |
| QRCodeSetupPayloadParser parser(base45Rep); |
| |
| CHIP_ERROR err = parser.populatePayload(resultingPayload); |
| bool didSucceed = err == CHIP_NO_ERROR; |
| surprises = EXPECT_EQ(didSucceed, true); |
| surprises = EXPECT_EQ(resultingPayload.isValidQRCodePayload(), true); |
| |
| bool result = payload == resultingPayload; |
| surprises += EXPECT_EQ(result, true); |
| return surprises; |
| } |
| |
| int main(int argc, char ** argv) |
| { |
| int result = testBitsetLen() + testPayloadByteArrayRep() + testPayloadBase45Rep() + testBase45() + testSetupPayloadVerify() + |
| testPayloadEquality() + testPayloadInEquality() + testQRCodeToPayloadGeneration() + |
| testInvalidQRCodePayload_WrongCharacterSet() + testInvalidQRCodePayload_WrongLength(); |
| if (result == 0) |
| { |
| printf("\n** All QRCode tests pass **\n"); |
| } |
| else |
| { |
| printf("\n**== QRCode tests FAILED ==**\n"); |
| } |
| return result; |
| } |