| /* |
| * Copyright (c) 2022 Project CHIP Authors |
| * All rights reserved. |
| * |
| * 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 "Decoder.h" |
| #include "../logging/Log.h" |
| |
| #include <lib/support/BufferReader.h> |
| #include <protocols/secure_channel/Constants.h> |
| #include <protocols/secure_channel/PASESession.h> |
| |
| namespace { |
| constexpr const char * kProtocolName = "Secure Channel"; |
| |
| constexpr const char * kUnknown = "Unknown"; |
| constexpr const char * kMsgCounterSyncReq = "Message Counter Sync Request"; |
| constexpr const char * kMsgCounterSyncResp = "Message Counter Sync Response"; |
| constexpr const char * kStandaloneAck = "Standalone Ack"; |
| constexpr const char * kPBKDFParamRequest = "Password-Based Key Derivation Parameters Request"; |
| constexpr const char * kPBKDFParamResponse = "Password-Based Key Derivation Parameters Response"; |
| constexpr const char * kPASE_Pake1 = "Password Authenticated Session Establishment '1'"; |
| constexpr const char * kPASE_Pake2 = "Password Authenticated Session Establishment '2'"; |
| constexpr const char * kPASE_Pake3 = "Password Authenticated Session Establishment '3'"; |
| constexpr const char * kCASE_Sigma1 = "Certificate Authenticated Session Establishment Sigma '1'"; |
| constexpr const char * kCASE_Sigma2 = "Certificate Authenticated Session Establishment Sigma '2'"; |
| constexpr const char * kCASE_Sigma3 = "Certificate Authenticated Session Establishment Sigma '3'"; |
| constexpr const char * kCASE_Sigma2Resume = "Certificate Authenticated Session Establishment Sigma '2' Resume"; |
| constexpr const char * kStatusReport = "Status Report"; |
| } // namespace |
| |
| using MessageType = chip::Protocols::SecureChannel::MsgType; |
| |
| namespace chip { |
| namespace trace { |
| namespace secure_channel { |
| |
| using namespace logging; |
| |
| CHIP_ERROR DecodeSEDParams(TLV::TLVReader & reader); |
| CHIP_ERROR DecodeMessageCounterSyncRequest(TLV::TLVReader & reader); |
| CHIP_ERROR DecodeMessageCounterSyncResponse(TLV::TLVReader & reader); |
| CHIP_ERROR DecodeStandaloneAck(TLV::TLVReader & reader); |
| CHIP_ERROR DecodePBDFKParamRequest(TLV::TLVReader & reader); |
| CHIP_ERROR DecodePBDFKParamResponse(TLV::TLVReader & reader); |
| CHIP_ERROR DecodePASEPake1(TLV::TLVReader & reader); |
| CHIP_ERROR DecodePASEPake2(TLV::TLVReader & reader); |
| CHIP_ERROR DecodePASEPake3(TLV::TLVReader & reader); |
| CHIP_ERROR DecodeCASESigma1(TLV::TLVReader & reader); |
| CHIP_ERROR DecodeCASESigma2(TLV::TLVReader & reader); |
| CHIP_ERROR DecodeCASESigma3(TLV::TLVReader & reader); |
| CHIP_ERROR DecodeCASESigma2Resume(TLV::TLVReader & reader); |
| CHIP_ERROR DecodeStatusReport(const uint8_t * data, size_t len); // TODO StatusReport does not use TLV Encoding |
| |
| const char * ToProtocolName() |
| { |
| return kProtocolName; |
| } |
| |
| const char * ToProtocolMessageTypeName(uint8_t protocolCode) |
| { |
| switch (protocolCode) |
| { |
| case to_underlying(MessageType::MsgCounterSyncReq): |
| return kMsgCounterSyncReq; |
| case to_underlying(MessageType::MsgCounterSyncRsp): |
| return kMsgCounterSyncResp; |
| case to_underlying(MessageType::StandaloneAck): |
| return kStandaloneAck; |
| case to_underlying(MessageType::PBKDFParamRequest): |
| return kPBKDFParamRequest; |
| case to_underlying(MessageType::PBKDFParamResponse): |
| return kPBKDFParamResponse; |
| case to_underlying(MessageType::PASE_Pake1): |
| return kPASE_Pake1; |
| case to_underlying(MessageType::PASE_Pake2): |
| return kPASE_Pake2; |
| case to_underlying(MessageType::PASE_Pake3): |
| return kPASE_Pake3; |
| case to_underlying(MessageType::CASE_Sigma1): |
| return kCASE_Sigma1; |
| case to_underlying(MessageType::CASE_Sigma2): |
| return kCASE_Sigma2; |
| case to_underlying(MessageType::CASE_Sigma3): |
| return kCASE_Sigma3; |
| case to_underlying(MessageType::CASE_Sigma2Resume): |
| return kCASE_Sigma2Resume; |
| case to_underlying(MessageType::StatusReport): |
| return kStatusReport; |
| default: |
| return kUnknown; |
| } |
| } |
| |
| CHIP_ERROR LogAsProtocolMessage(uint8_t protocolCode, const uint8_t * data, size_t len) |
| { |
| TLV::TLVReader reader; |
| reader.Init(data, len); |
| |
| switch (protocolCode) |
| { |
| case to_underlying(MessageType::MsgCounterSyncReq): |
| return DecodeMessageCounterSyncRequest(reader); |
| case to_underlying(MessageType::MsgCounterSyncRsp): |
| return DecodeMessageCounterSyncResponse(reader); |
| case to_underlying(MessageType::StandaloneAck): |
| return DecodeStandaloneAck(reader); |
| case to_underlying(MessageType::PBKDFParamRequest): |
| return DecodePBDFKParamRequest(reader); |
| case to_underlying(MessageType::PBKDFParamResponse): |
| return DecodePBDFKParamResponse(reader); |
| case to_underlying(MessageType::PASE_Pake1): |
| return DecodePASEPake1(reader); |
| case to_underlying(MessageType::PASE_Pake2): |
| return DecodePASEPake2(reader); |
| case to_underlying(MessageType::PASE_Pake3): |
| return DecodePASEPake3(reader); |
| case to_underlying(MessageType::CASE_Sigma1): |
| return DecodeCASESigma1(reader); |
| case to_underlying(MessageType::CASE_Sigma2): |
| return DecodeCASESigma2(reader); |
| case to_underlying(MessageType::CASE_Sigma3): |
| return DecodeCASESigma3(reader); |
| case to_underlying(MessageType::CASE_Sigma2Resume): |
| return DecodeCASESigma2Resume(reader); |
| case to_underlying(MessageType::StatusReport): |
| return DecodeStatusReport(data, len); |
| default: |
| return CHIP_ERROR_NOT_IMPLEMENTED; |
| } |
| } |
| |
| CHIP_ERROR DecodeMessageCounterSyncRequest(TLV::TLVReader & reader) |
| { |
| return CHIP_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| CHIP_ERROR DecodeMessageCounterSyncResponse(TLV::TLVReader & reader) |
| { |
| return CHIP_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| CHIP_ERROR DecodeStandaloneAck(TLV::TLVReader & reader) |
| { |
| // Standalone Ack does not contains any data. Something wrong is ongoing if this code is reached. |
| return CHIP_ERROR_INCORRECT_STATE; |
| } |
| |
| CHIP_ERROR DecodePBDFKParamRequest(TLV::TLVReader & reader) |
| { |
| constexpr uint8_t kInitiatorRandomTag = 1; |
| constexpr uint8_t kInitiatorSessionIdTag = 2; |
| constexpr uint8_t kPasscodeIdTag = 3; |
| constexpr uint8_t kHasPBKDFParametersTag = 4; |
| constexpr uint8_t kInitiatorSEDParamsTag = 5; |
| |
| ByteSpan initiatorRandom; |
| uint16_t initiatorSessionId; |
| PasscodeId passcodeId; |
| bool hasPBKDFParameters; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kInitiatorRandomTag))); |
| ReturnErrorOnFailure(reader.Get(initiatorRandom)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kInitiatorSessionIdTag))); |
| ReturnErrorOnFailure(reader.Get(initiatorSessionId)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kPasscodeIdTag))); |
| ReturnErrorOnFailure(reader.Get(passcodeId)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kHasPBKDFParametersTag))); |
| ReturnErrorOnFailure(reader.Get(hasPBKDFParameters)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("Initiator Random", initiatorRandom); |
| Log("Initiator Session Id", initiatorSessionId); |
| Log("Passcode Id", passcodeId); |
| Log("hasPBKDFParameters", hasPBKDFParameters ? "true" : "false"); |
| |
| CHIP_ERROR err = reader.Next(); |
| if (err == CHIP_END_OF_TLV) |
| { |
| return reader.ExitContainer(containerType); |
| } |
| ReturnErrorOnFailure(err); |
| |
| VerifyOrReturnError(reader.GetTag() == TLV::ContextTag(kInitiatorSEDParamsTag), CHIP_ERROR_INVALID_TLV_TAG); |
| ReturnErrorOnFailure(DecodeSEDParams(reader)); |
| |
| return reader.ExitContainer(containerType); |
| } |
| |
| CHIP_ERROR DecodePBDFKParamResponse(TLV::TLVReader & reader) |
| { |
| constexpr uint8_t kInitiatorRandomTag = 1; |
| constexpr uint8_t kResponderRandomTag = 2; |
| constexpr uint8_t kResponderSessionIdTag = 3; |
| constexpr uint8_t kPBKDFParametersTag = 4; |
| constexpr uint8_t kInitiatorSEDParamsTag = 5; |
| |
| ByteSpan initiatorRandom; |
| ByteSpan responderRandom; |
| uint16_t responderSessionId; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kInitiatorRandomTag))); |
| ReturnErrorOnFailure(reader.Get(initiatorRandom)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kResponderRandomTag))); |
| ReturnErrorOnFailure(reader.Get(responderRandom)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kResponderSessionIdTag))); |
| ReturnErrorOnFailure(reader.Get(responderSessionId)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("Initiator Random", initiatorRandom); |
| Log("Responder Random", responderRandom); |
| Log("Responder Session Id", responderSessionId); |
| |
| CHIP_ERROR err = reader.Next(); |
| if (err == CHIP_END_OF_TLV) |
| { |
| return reader.ExitContainer(containerType); |
| } |
| ReturnErrorOnFailure(err); |
| |
| if (TLV::TagNumFromTag(reader.GetTag()) == kPBKDFParametersTag) |
| { |
| uint32_t iterationCount; |
| ByteSpan salt; |
| |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next()); |
| ReturnErrorOnFailure(reader.Get(iterationCount)); |
| Log("Iteration Count", iterationCount); |
| ReturnErrorOnFailure(reader.Next()); |
| ReturnErrorOnFailure(reader.Get(salt)); |
| Log("Salt", salt); |
| ReturnErrorOnFailure(reader.ExitContainer(containerType)); |
| err = reader.Next(); |
| } |
| |
| if (err == CHIP_END_OF_TLV) |
| { |
| return reader.ExitContainer(containerType); |
| } |
| ReturnErrorOnFailure(err); |
| |
| VerifyOrReturnError(reader.GetTag() == TLV::ContextTag(kInitiatorSEDParamsTag), CHIP_ERROR_INVALID_TLV_TAG); |
| ReturnErrorOnFailure(DecodeSEDParams(reader)); |
| |
| return reader.ExitContainer(containerType); |
| } |
| |
| CHIP_ERROR DecodePASEPake1(TLV::TLVReader & reader) |
| { |
| ByteSpan pA; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next()); |
| ReturnErrorOnFailure(reader.Get(pA)); |
| ReturnErrorOnFailure(reader.ExitContainer(containerType)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("pA", pA); |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR DecodePASEPake2(TLV::TLVReader & reader) |
| { |
| ByteSpan pB; |
| ByteSpan cB; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next()); |
| ReturnErrorOnFailure(reader.Get(pB)); |
| ReturnErrorOnFailure(reader.Next()); |
| ReturnErrorOnFailure(reader.Get(cB)); |
| ReturnErrorOnFailure(reader.ExitContainer(containerType)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("pB", pB); |
| Log("cB", cB); |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR DecodePASEPake3(TLV::TLVReader & reader) |
| { |
| ByteSpan cA; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next()); |
| ReturnErrorOnFailure(reader.Get(cA)); |
| ReturnErrorOnFailure(reader.ExitContainer(containerType)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("cA", cA); |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR DecodeCASESigma1(TLV::TLVReader & reader) |
| { |
| constexpr uint8_t kInitiatorRandomTag = 1; |
| constexpr uint8_t kInitiatorSessionIdTag = 2; |
| constexpr uint8_t kDestinationIdTag = 3; |
| constexpr uint8_t kInitiatorEphPubKeyTag = 4; |
| constexpr uint8_t kInitiatorSEDParamsTag = 5; |
| constexpr uint8_t kResumptionIDTag = 6; |
| constexpr uint8_t kResume1MICTag = 7; |
| |
| ByteSpan initiatorRandom; |
| uint16_t initiatorSessionId; |
| ByteSpan destinationId; |
| ByteSpan initiatorEphPubKey; |
| ByteSpan resumptionId; |
| ByteSpan initiatorResumeMIC; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kInitiatorRandomTag))); |
| ReturnErrorOnFailure(reader.Get(initiatorRandom)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kInitiatorSessionIdTag))); |
| ReturnErrorOnFailure(reader.Get(initiatorSessionId)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kDestinationIdTag))); |
| ReturnErrorOnFailure(reader.Get(destinationId)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kInitiatorEphPubKeyTag))); |
| ReturnErrorOnFailure(reader.Get(initiatorEphPubKey)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("InitiatorRandom", initiatorRandom); |
| Log("InitiatorSessionId", initiatorSessionId); |
| Log("DestinationId", destinationId); |
| Log("InitiatorEphPubKey", initiatorEphPubKey); |
| |
| CHIP_ERROR err = reader.Next(); |
| if (err == CHIP_NO_ERROR && reader.GetTag() == TLV::ContextTag(kInitiatorSEDParamsTag)) |
| { |
| ReturnErrorOnFailure(DecodeSEDParams(reader)); |
| err = reader.Next(); |
| } |
| |
| if (err == CHIP_NO_ERROR && reader.GetTag() == TLV::ContextTag(kResumptionIDTag)) |
| { |
| ReturnErrorOnFailure(reader.Get(resumptionId)); |
| Log("ResumptionID", resumptionId); |
| err = reader.Next(); |
| } |
| |
| if (err == CHIP_NO_ERROR && reader.GetTag() == TLV::ContextTag(kResume1MICTag)) |
| { |
| ReturnErrorOnFailure(reader.Get(initiatorResumeMIC)); |
| Log("InitiatorResumeMIC", initiatorResumeMIC); |
| err = reader.Next(); |
| } |
| |
| if (err == CHIP_END_OF_TLV) |
| { |
| err = CHIP_NO_ERROR; |
| } |
| ReturnErrorOnFailure(err); |
| |
| return reader.ExitContainer(containerType); |
| } |
| |
| CHIP_ERROR DecodeCASESigma2(TLV::TLVReader & reader) |
| { |
| constexpr uint8_t kResponderRandomTag = 1; |
| constexpr uint8_t kResponderSessionIdTag = 2; |
| constexpr uint8_t kResponderEphPubKeyTag = 3; |
| constexpr uint8_t kEncrypted2Tag = 4; |
| constexpr uint8_t kResponderSEDParamsTag = 5; |
| |
| ByteSpan responderRandom; |
| uint16_t responderSessionId; |
| ByteSpan responderEphPubKey; |
| ByteSpan encrypted2; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kResponderRandomTag))); |
| ReturnErrorOnFailure(reader.Get(responderRandom)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kResponderSessionIdTag))); |
| ReturnErrorOnFailure(reader.Get(responderSessionId)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kResponderEphPubKeyTag))); |
| ReturnErrorOnFailure(reader.Get(responderEphPubKey)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kEncrypted2Tag))); |
| ReturnErrorOnFailure(reader.Get(encrypted2)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("ResponderRandom", responderRandom); |
| Log("ResponderSessionId", responderSessionId); |
| Log("ResponderEphPubKey", responderEphPubKey); |
| Log("Encrypted2", encrypted2); |
| |
| CHIP_ERROR err = reader.Next(); |
| if (err == CHIP_NO_ERROR && reader.GetTag() == TLV::ContextTag(kResponderSEDParamsTag)) |
| { |
| ReturnErrorOnFailure(DecodeSEDParams(reader)); |
| err = reader.Next(); |
| } |
| |
| if (err == CHIP_END_OF_TLV) |
| { |
| err = CHIP_NO_ERROR; |
| } |
| ReturnErrorOnFailure(err); |
| |
| return reader.ExitContainer(containerType); |
| } |
| |
| CHIP_ERROR DecodeCASESigma3(TLV::TLVReader & reader) |
| { |
| constexpr uint8_t kEncrypted3Tag = 1; |
| |
| ByteSpan encrypted3; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kEncrypted3Tag))); |
| ReturnErrorOnFailure(reader.Get(encrypted3)); |
| ReturnErrorOnFailure(reader.ExitContainer(containerType)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("Encrypted3", encrypted3); |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR DecodeCASESigma2Resume(TLV::TLVReader & reader) |
| { |
| constexpr uint8_t kResumptionIDTag = 1; |
| constexpr uint8_t kSigma2ResumeMICTag = 2; |
| constexpr uint8_t kResponderSessionIdTag = 3; |
| constexpr uint8_t kResponderSEDParamsTag = 4; |
| |
| ByteSpan resumptionId; |
| ByteSpan sigma2ResumeMIC; |
| uint16_t responderSessionId; |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag())); |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kResumptionIDTag))); |
| ReturnErrorOnFailure(reader.Get(resumptionId)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kSigma2ResumeMICTag))); |
| ReturnErrorOnFailure(reader.Get(sigma2ResumeMIC)); |
| ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kResponderSessionIdTag))); |
| ReturnErrorOnFailure(reader.Get(responderSessionId)); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("ResumptionID", resumptionId); |
| Log("Sigma2ResumeMIC", sigma2ResumeMIC); |
| Log("ResponderSessionId", responderSessionId); |
| |
| CHIP_ERROR err = reader.Next(); |
| if (err == CHIP_NO_ERROR && reader.GetTag() == TLV::ContextTag(kResponderSEDParamsTag)) |
| { |
| ReturnErrorOnFailure(DecodeSEDParams(reader)); |
| err = reader.Next(); |
| } |
| |
| if (err == CHIP_END_OF_TLV) |
| { |
| err = CHIP_NO_ERROR; |
| } |
| ReturnErrorOnFailure(err); |
| |
| return reader.ExitContainer(containerType); |
| } |
| |
| CHIP_ERROR DecodeStatusReport(const uint8_t * data, size_t len) |
| { |
| uint16_t statusGeneralStatusCode; |
| uint32_t statusProtocolId; |
| uint16_t statusProtocolCode; |
| |
| Encoding::LittleEndian::Reader bufReader(data, len); |
| ReturnErrorOnFailure( |
| bufReader.Read16(&statusGeneralStatusCode).Read32(&statusProtocolId).Read16(&statusProtocolCode).StatusCode()); |
| |
| auto scopedIndent = ScopedLogIndent("Parameters"); |
| Log("GeneralStatusCode", statusGeneralStatusCode); |
| Log("ProtocolId", statusProtocolId); |
| Log("ProtocolCode", statusProtocolCode); |
| |
| if (bufReader.Remaining()) |
| { |
| ByteSpan statusProtocolData(data + bufReader.OctetsRead(), bufReader.Remaining()); |
| Log("Data", statusProtocolData); |
| } |
| |
| return CHIP_NO_ERROR; |
| } |
| |
| CHIP_ERROR DecodeSEDParams(TLV::TLVReader & reader) |
| { |
| constexpr uint8_t kIdleRetransmitTimeoutTag = 1; |
| constexpr uint8_t kActiveRetransmitTimeoutTag = 2; |
| |
| auto scopedIndent = ScopedLogIndent("SED"); |
| |
| TLV::TLVType containerType = TLV::kTLVType_Structure; |
| ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
| ReturnErrorOnFailure(reader.Next()); |
| |
| if (TLV::TagNumFromTag(reader.GetTag()) == kIdleRetransmitTimeoutTag) |
| { |
| uint32_t idleRetransmitTimeout; |
| ReturnErrorOnFailure(reader.Get(idleRetransmitTimeout)); |
| Log("Idle Retransmit Timeout", idleRetransmitTimeout); |
| |
| CHIP_ERROR err = reader.Next(); |
| if (err == CHIP_END_OF_TLV) |
| { |
| return reader.ExitContainer(containerType); |
| } |
| ReturnErrorOnFailure(err); |
| } |
| |
| VerifyOrReturnError(TLV::TagNumFromTag(reader.GetTag()) == kActiveRetransmitTimeoutTag, CHIP_ERROR_INVALID_TLV_TAG); |
| |
| uint32_t activeRetransmitTimeout; |
| ReturnErrorOnFailure(reader.Get(activeRetransmitTimeout)); |
| Log("Active Retransmit Timeout", activeRetransmitTimeout); |
| |
| ReturnErrorOnFailure(reader.ExitContainer(containerType)); |
| |
| return CHIP_NO_ERROR; |
| } |
| |
| } // namespace secure_channel |
| } // namespace trace |
| } // namespace chip |