/* * * Copyright (c) 2022 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. */ #pragma once #include #include #include #include #include namespace chip { /// File signature (aka magic number) of a valid Matter OTA image inline constexpr uint32_t kOTAImageFileIdentifier = 0x1BEEF11E; enum class OTAImageDigestType : uint8_t { kSha256 = 1, kSha256_128 = 2, kSha256_120 = 3, kSha256_96 = 4, kSha256_64 = 5, kSha256_32 = 6, kSha384 = 7, kSha512 = 8, kSha3_224 = 9, kSha3_256 = 10, kSha3_384 = 11, kSha3_512 = 12, }; struct OTAImageHeader { uint16_t mVendorId; uint16_t mProductId; uint32_t mSoftwareVersion; CharSpan mSoftwareVersionString; uint64_t mPayloadSize; Optional mMinApplicableVersion; Optional mMaxApplicableVersion; CharSpan mReleaseNotesURL; OTAImageDigestType mImageDigestType; ByteSpan mImageDigest; }; class OTAImageHeaderParser { public: /** * @brief Prepare the parser for accepting Matter OTA image chunks. * * The method can be called many times to reset the parser state. */ void Init(); /** * @brief Clear all resources associated with the parser. */ void Clear(); /** * @brief Returns if the parser is ready to accept subsequent Matter OTA image chunks. */ bool IsInitialized() const { return mState != State::kNotInitialized; } /** * @brief Decode Matter OTA image header * * The method takes subsequent chunks of the Matter OTA image file and decodes the header when * enough data has been provided. If more image chunks are needed, CHIP_ERROR_BUFFER_TOO_SMALL * error is returned. Other error codes indicate that the header is invalid. * * @param buffer Byte span containing a subsequent Matter OTA image chunk. When the method * returns CHIP_NO_ERROR, the byte span is used to return a remaining part * of the chunk, not used by the header. * @param header Structure to store results of the operation. Note that the results must not be * referenced after the parser is cleared since string members of the structure * are only shallow-copied by the method. * * @retval CHIP_NO_ERROR Header has been decoded successfully. * @retval CHIP_ERROR_BUFFER_TOO_SMALL Provided buffers are insufficient to decode the * header. A user is expected call the method again * when the next image chunk is available. * @retval CHIP_ERROR_INVALID_FILE_IDENTIFIER Not a Matter OTA image file. * @retval Error code Encoded header is invalid. */ CHIP_ERROR AccumulateAndDecode(ByteSpan & buffer, OTAImageHeader & header); private: enum State { kNotInitialized, kInitialized, kTlv }; void Append(ByteSpan & buffer, uint32_t numBytes); CHIP_ERROR DecodeFixed(); CHIP_ERROR DecodeTlv(OTAImageHeader & header); State mState; uint32_t mHeaderTlvSize; uint32_t mBufferOffset; Platform::ScopedMemoryBuffer mBuffer; }; } // namespace chip