Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
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 : #include "SetupPayloadHelper.h"
19 : #include "ManualSetupPayloadGenerator.h"
20 : #include "QRCodeSetupPayloadGenerator.h"
21 : #include "SetupPayload.h"
22 : #include <fstream>
23 : #include <utility>
24 :
25 : #include <lib/support/CodeUtils.h>
26 : #include <lib/support/logging/CHIPLogging.h>
27 :
28 : using namespace chip;
29 :
30 : namespace chip {
31 :
32 : enum SetupPayloadKey
33 : {
34 : SetupPayloadKey_Version,
35 : SetupPayloadKey_VendorID,
36 : SetupPayloadKey_ProductID,
37 : SetupPayloadKey_CommissioningFlow,
38 : SetupPayloadKey_RendezVousInformation,
39 : SetupPayloadKey_Discriminator,
40 : SetupPayloadKey_SetupPINCode,
41 : };
42 :
43 : struct SetupPayloadParameter
44 : {
45 : SetupPayloadKey key;
46 : std::string stringValue;
47 : uint64_t uintValue;
48 : };
49 :
50 0 : static CHIP_ERROR resolveSetupPayloadParameter(SetupPayloadParameter & parameter, const std::string & key,
51 : const std::string & value)
52 : {
53 0 : bool isUnsignedInt = true;
54 0 : bool shouldHaveValue = true;
55 0 : if (key == "version")
56 : {
57 0 : parameter.key = SetupPayloadKey_Version;
58 : }
59 0 : else if (key == "vendorID")
60 : {
61 0 : parameter.key = SetupPayloadKey_VendorID;
62 : }
63 0 : else if (key == "productID")
64 : {
65 0 : parameter.key = SetupPayloadKey_ProductID;
66 : }
67 0 : else if (key == "commissioningFlow")
68 : {
69 0 : parameter.key = SetupPayloadKey_CommissioningFlow;
70 : }
71 0 : else if (key == "rendezVousInformation")
72 : {
73 0 : parameter.key = SetupPayloadKey_RendezVousInformation;
74 : }
75 0 : else if (key == "discriminator")
76 : {
77 0 : parameter.key = SetupPayloadKey_Discriminator;
78 : }
79 0 : else if (key == "setUpPINCode")
80 : {
81 0 : parameter.key = SetupPayloadKey_SetupPINCode;
82 : }
83 : else
84 : {
85 0 : return CHIP_ERROR_INVALID_ARGUMENT;
86 : }
87 0 : if (shouldHaveValue && value.length() > 0)
88 : {
89 0 : if (isUnsignedInt)
90 : {
91 0 : parameter.uintValue = stoul(value, nullptr, 10);
92 : }
93 : else
94 : {
95 0 : parameter.stringValue = value;
96 : }
97 : }
98 0 : else if (shouldHaveValue)
99 : {
100 0 : return CHIP_ERROR_INVALID_ARGUMENT;
101 : }
102 0 : return CHIP_NO_ERROR;
103 : }
104 :
105 0 : static CHIP_ERROR addParameter(SetupPayload & setupPayload, const SetupPayloadParameter & parameter)
106 : {
107 0 : switch (parameter.key)
108 : {
109 0 : case SetupPayloadKey_Version:
110 0 : ChipLogDetail(SetupPayload, "Loaded version: %u", (uint8_t) parameter.uintValue);
111 0 : setupPayload.version = static_cast<uint8_t>(parameter.uintValue);
112 0 : break;
113 0 : case SetupPayloadKey_VendorID:
114 0 : ChipLogDetail(SetupPayload, "Loaded vendorID: %u", (uint16_t) parameter.uintValue);
115 0 : setupPayload.vendorID = static_cast<uint16_t>(parameter.uintValue);
116 0 : break;
117 0 : case SetupPayloadKey_ProductID:
118 0 : ChipLogDetail(SetupPayload, "Loaded productID: %u", (uint16_t) parameter.uintValue);
119 0 : setupPayload.productID = static_cast<uint16_t>(parameter.uintValue);
120 0 : break;
121 0 : case SetupPayloadKey_CommissioningFlow:
122 0 : ChipLogDetail(SetupPayload, "Commissioning flow: %u", (uint8_t) parameter.uintValue);
123 0 : setupPayload.commissioningFlow = static_cast<CommissioningFlow>(parameter.uintValue);
124 0 : break;
125 0 : case SetupPayloadKey_RendezVousInformation:
126 0 : ChipLogDetail(SetupPayload, "Loaded rendezvousInfo: %u", (uint16_t) parameter.uintValue);
127 0 : setupPayload.rendezvousInformation.SetValue(RendezvousInformationFlags().SetRaw(
128 0 : static_cast<std::underlying_type_t<RendezvousInformationFlag>>(parameter.uintValue)));
129 0 : break;
130 0 : case SetupPayloadKey_Discriminator:
131 0 : ChipLogDetail(SetupPayload, "Loaded discriminator: %u", (uint16_t) parameter.uintValue);
132 0 : setupPayload.discriminator.SetLongValue(static_cast<uint16_t>(parameter.uintValue));
133 0 : break;
134 0 : case SetupPayloadKey_SetupPINCode:
135 0 : ChipLogDetail(SetupPayload, "Loaded setupPinCode: %lu", (unsigned long) parameter.uintValue);
136 0 : setupPayload.setUpPINCode = static_cast<uint32_t>(parameter.uintValue);
137 0 : break;
138 0 : default:
139 0 : return CHIP_ERROR_INVALID_ARGUMENT;
140 : }
141 0 : return CHIP_NO_ERROR;
142 : }
143 :
144 0 : CHIP_ERROR loadPayloadFromFile(SetupPayload & setupPayload, const std::string & filePath)
145 : {
146 0 : std::ifstream fileStream(filePath);
147 0 : VerifyOrReturnError(!fileStream.fail(), CHIP_ERROR_INVALID_ARGUMENT);
148 :
149 0 : while (fileStream)
150 : {
151 0 : std::string key;
152 0 : std::string value;
153 0 : SetupPayloadParameter parameter;
154 :
155 0 : getline(fileStream, key, ' ');
156 0 : fileStream >> value;
157 0 : fileStream.ignore();
158 :
159 0 : if (key.length() == 0)
160 : {
161 0 : continue;
162 : }
163 0 : ReturnErrorOnFailure(resolveSetupPayloadParameter(parameter, key, value));
164 :
165 0 : ReturnErrorOnFailure(addParameter(setupPayload, parameter));
166 0 : }
167 0 : return CHIP_NO_ERROR;
168 0 : }
169 :
170 0 : CHIP_ERROR generateQRCodeFromFilePath(std::string filePath, std::string & outCode)
171 : {
172 0 : SetupPayload setupPayload;
173 0 : CHIP_ERROR err = loadPayloadFromFile(setupPayload, std::move(filePath));
174 0 : if (err != CHIP_NO_ERROR)
175 : {
176 0 : return err;
177 : }
178 0 : QRCodeSetupPayloadGenerator generator(setupPayload);
179 0 : err = generator.payloadBase38Representation(outCode);
180 0 : return err;
181 0 : }
182 :
183 0 : CHIP_ERROR generateManualCodeFromFilePath(std::string filePath, std::string & outCode)
184 : {
185 0 : SetupPayload setupPayload;
186 0 : CHIP_ERROR err = loadPayloadFromFile(setupPayload, std::move(filePath));
187 0 : if (err != CHIP_NO_ERROR)
188 : {
189 0 : return err;
190 : }
191 0 : ManualSetupPayloadGenerator generator(setupPayload);
192 0 : err = generator.payloadDecimalStringRepresentation(outCode);
193 0 : return err;
194 0 : }
195 : } // namespace chip
|