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 : /**
19 : * @file
20 : * This file describes a QRCode Setup Payload generator based on the
21 : * CHIP specification.
22 : *
23 : * The encoding of the binary data to a base38 string is as follows:
24 : * - Every 2 bytes (16 bits) of binary source data are encoded to 3
25 : * characters of the Base-38 alphabet.
26 : * - If an odd number of bytes are to be encoded, the remaining
27 : * single byte is encoded to 2 characters of the Base-38 alphabet.
28 : */
29 :
30 : #include "SetupPayload.h"
31 :
32 : #include <lib/support/Span.h>
33 :
34 : #include <string>
35 :
36 : #pragma once
37 :
38 : namespace chip {
39 :
40 : class QRCodeSetupPayloadGenerator
41 : {
42 : private:
43 : SetupPayload mPayload;
44 :
45 : public:
46 35 : QRCodeSetupPayloadGenerator(const SetupPayload & setupPayload) : mPayload(setupPayload) {}
47 :
48 : /**
49 : * This function is called to encode the binary data of a payload to a
50 : * base38 null-terminated string.
51 : *
52 : * If the payload has any optional data that needs to be TLV encoded, this
53 : * function will fail.
54 : *
55 : * @param[out] base38Representation
56 : * The string to copy the base38 to.
57 : *
58 : * @retval #CHIP_NO_ERROR if the method succeeded.
59 : * @retval #CHIP_ERROR_INVALID_ARGUMENT if the payload is invalid.
60 : * @retval other Other CHIP or platform-specific error codes indicating
61 : * that an error occurred preventing the function from
62 : * producing the requested string.
63 : */
64 : CHIP_ERROR payloadBase38Representation(std::string & base38Representation);
65 :
66 : /**
67 : * This function is called to encode the binary data of a payload to a
68 : * base38 null-terminated string.
69 : *
70 : * If the payload has any optional data that needs to be TLV encoded, this
71 : * function will allocate a scratch heap buffer to hold the TLV data while
72 : * encoding.
73 : *
74 : * @param[out] base38Representation
75 : * The string to copy the base38 to.
76 : *
77 : * @retval #CHIP_NO_ERROR if the method succeeded.
78 : * @retval #CHIP_ERROR_INVALID_ARGUMENT if the payload is invalid.
79 : * @retval other Other CHIP or platform-specific error codes indicating
80 : * that an error occurred preventing the function from
81 : * producing the requested string.
82 : */
83 : CHIP_ERROR payloadBase38RepresentationWithAutoTLVBuffer(std::string & base38Representation);
84 :
85 : /**
86 : * This function is called to encode the binary data of a payload to a
87 : * base38 null-terminated string, using the caller-provided buffer as
88 : * temporary scratch space for optional data that needs to be TLV-encoded.
89 : * If that buffer is not big enough to hold the TLV-encoded part of the
90 : * payload, this function will fail.
91 : *
92 : * @param[out] base38Representation
93 : * The string to copy the base38 to.
94 : * @param[in] tlvDataStart
95 : * A pointer to an uint8_t buffer into which the TLV
96 : * should be written.
97 : * @param[in] tlvDataStartSize
98 : * The maximum number of bytes that should be written to
99 : * the output buffer.
100 : *
101 : * @retval #CHIP_NO_ERROR if the method succeeded.
102 : * @retval #CHIP_ERROR_INVALID_ARGUMENT if the payload is invalid.
103 : * @retval other Other CHIP or platform-specific error codes indicating
104 : * that an error occurred preventing the function from
105 : * producing the requested string.
106 : */
107 : CHIP_ERROR payloadBase38Representation(std::string & base38Representation, uint8_t * tlvDataStart, uint32_t tlvDataStartSize);
108 :
109 : /**
110 : * This function disables internal checks about the validity of the generated payload.
111 : * It allows using the generator to generate invalid payloads.
112 : * Default is false.
113 : */
114 26 : void SetAllowInvalidPayload(bool allow) { mAllowInvalidPayload = allow; }
115 :
116 : /**
117 : * When set to true, the encoded payload will start with the delimiter character ('*')
118 : * instead of the QR code prefix ("MT:"), suitable for generating concatenated QR codes.
119 : * Default is false
120 : */
121 : void SetAsConcatenation(bool concatenation) { mAsConcatenation = concatenation; }
122 :
123 : private:
124 : CHIP_ERROR generateTLVFromOptionalData(SetupPayload & outPayload, uint8_t * tlvDataStart, uint32_t maxLen,
125 : size_t & tlvDataLengthInBytes);
126 :
127 : bool mAllowInvalidPayload = false;
128 : bool mAsConcatenation = false;
129 : };
130 :
131 : /**
132 : * A minimal QR code setup payload generator that omits any optional data,
133 : * for compatibility with devices that don't support std::string or STL.
134 : */
135 : class QRCodeBasicSetupPayloadGenerator
136 : {
137 : private:
138 : PayloadContents mPayload;
139 :
140 : public:
141 0 : QRCodeBasicSetupPayloadGenerator(const PayloadContents & payload) : mPayload(payload) {}
142 :
143 : /**
144 : * This function is called to encode the binary data of a payload to a
145 : * base38 null-terminated string.
146 : *
147 : * The resulting size of the out_buf span will be the size of data written
148 : * and not including the null terminator.
149 : *
150 : * This function will fail if the payload has any optional data requiring
151 : * TLV encoding.
152 : *
153 : * @param[out] outBuffer
154 : * The buffer to copy the base38 to.
155 : *
156 : * @retval #CHIP_NO_ERROR if the method succeeded.
157 : * @retval #CHIP_ERROR_INVALID_ARGUMENT if the payload is invalid.
158 : * @retval #CHIP_ERROR_BUFFER_TOO_SMALL if outBuffer has insufficient size.
159 : * @retval other Other CHIP or platform-specific error codes indicating
160 : * that an error occurred preventing the function from
161 : * producing the requested string.
162 : */
163 : CHIP_ERROR payloadBase38Representation(MutableCharSpan & outBuffer);
164 :
165 : // TODO - Find the optimal value for maximum length of QR Code Base38 string
166 : static constexpr uint16_t kMaxQRCodeBase38RepresentationLength = 128;
167 : };
168 :
169 : } // namespace chip
|