LCOV - code coverage report
Current view: top level - app/MessageDef - EventDataIB.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 151 169 89.3 %
Date: 2024-02-15 08:20:41 Functions: 20 20 100.0 %

          Line data    Source code
       1             : /**
       2             :  *
       3             :  *    Copyright (c) 2020 Project CHIP Authors
       4             :  *    Copyright (c) 2018 Google LLC.
       5             :  *    Copyright (c) 2016-2017 Nest Labs, Inc.
       6             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7             :  *    you may not use this file except in compliance with the License.
       8             :  *    You may obtain a copy of the License at
       9             :  *
      10             :  *        http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  *    Unless required by applicable law or agreed to in writing, software
      13             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  *    See the License for the specific language governing permissions and
      16             :  *    limitations under the License.
      17             :  */
      18             : /**
      19             :  *    @file
      20             :  *      This file defines EventDataIB parser and builder in CHIP interaction model
      21             :  *
      22             :  */
      23             : 
      24             : #include "EventDataIB.h"
      25             : 
      26             : #include "MessageDefHelper.h"
      27             : 
      28             : #include <inttypes.h>
      29             : #include <stdarg.h>
      30             : #include <stdio.h>
      31             : 
      32             : #include <app/AppConfig.h>
      33             : 
      34             : namespace chip {
      35             : namespace app {
      36             : #if CHIP_CONFIG_IM_PRETTY_PRINT
      37        1579 : CHIP_ERROR EventDataIB::Parser::PrettyPrint() const
      38             : {
      39        1579 :     CHIP_ERROR err = CHIP_NO_ERROR;
      40             :     TLV::TLVReader reader;
      41             : 
      42        1579 :     PRETTY_PRINT("EventDataIB =");
      43        1579 :     PRETTY_PRINT("{");
      44             : 
      45             :     // make a copy of the Path reader
      46        1579 :     reader.Init(mReader);
      47             : 
      48        9486 :     while (CHIP_NO_ERROR == (err = reader.Next()))
      49             :     {
      50        7907 :         if (!TLV::IsContextTag(reader.GetTag()))
      51             :         {
      52           0 :             continue;
      53             :         }
      54        7907 :         uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
      55        7907 :         switch (tagNum)
      56             :         {
      57        1579 :         case to_underlying(Tag::kPath): {
      58        1579 :             EventPathIB::Parser path;
      59        1579 :             ReturnErrorOnFailure(path.Init(reader));
      60             : 
      61        1579 :             PRETTY_PRINT_INCDEPTH();
      62        1579 :             ReturnErrorOnFailure(path.PrettyPrint());
      63        1579 :             PRETTY_PRINT_DECDEPTH();
      64             :         }
      65        1579 :         break;
      66        1579 :         case to_underlying(Tag::kEventNumber):
      67        1579 :             VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
      68             : 
      69             : #if CHIP_DETAIL_LOGGING
      70             :             {
      71             :                 EventNumber number;
      72        1579 :                 ReturnErrorOnFailure(reader.Get(number));
      73        1579 :                 PRETTY_PRINT("\tEventNumber = 0x" ChipLogFormatX64 ",", ChipLogValueX64(number));
      74             :             }
      75             : #endif // CHIP_DETAIL_LOGGING
      76        1579 :             break;
      77        1579 :         case to_underlying(Tag::kPriority):
      78        1579 :             VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
      79             : 
      80             : #if CHIP_DETAIL_LOGGING
      81             :             {
      82             :                 uint64_t value;
      83        1579 :                 ReturnErrorOnFailure(reader.Get(value));
      84        1579 :                 PRETTY_PRINT("\tPriorityLevel = 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
      85             :             }
      86             : #endif // CHIP_DETAIL_LOGGING
      87        1579 :             break;
      88        1579 :         case to_underlying(Tag::kEpochTimestamp):
      89        1579 :             VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
      90             : 
      91             : #if CHIP_DETAIL_LOGGING
      92             :             {
      93             :                 uint64_t value;
      94        1579 :                 ReturnErrorOnFailure(reader.Get(value));
      95        1579 :                 PRETTY_PRINT("\tEpochTimestamp = 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
      96             :             }
      97             : #endif // CHIP_DETAIL_LOGGING
      98        1579 :             break;
      99             : 
     100           4 :         case to_underlying(Tag::kSystemTimestamp):
     101           4 :             VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
     102             : 
     103             : #if CHIP_DETAIL_LOGGING
     104             :             {
     105             :                 uint64_t value;
     106           4 :                 ReturnErrorOnFailure(reader.Get(value));
     107           4 :                 PRETTY_PRINT("\tSystemTimestamp = 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
     108             :             }
     109             : #endif // CHIP_DETAIL_LOGGING
     110           4 :             break;
     111           4 :         case to_underlying(Tag::kDeltaEpochTimestamp):
     112           4 :             VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
     113             : 
     114             : #if CHIP_DETAIL_LOGGING
     115             :             {
     116             :                 uint64_t value;
     117           4 :                 ReturnErrorOnFailure(reader.Get(value));
     118           4 :                 PRETTY_PRINT("\tDeltaEpochTimestampstamp= 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
     119             :             }
     120             : #endif // CHIP_DETAIL_LOGGING
     121           4 :             break;
     122           4 :         case to_underlying(Tag::kDeltaSystemTimestamp):
     123           4 :             VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
     124             : 
     125             : #if CHIP_DETAIL_LOGGING
     126             :             {
     127             :                 uint64_t value;
     128           4 :                 ReturnErrorOnFailure(reader.Get(value));
     129           4 :                 PRETTY_PRINT("\tDeltaSystemTimestamp = 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
     130             :             }
     131             : #endif // CHIP_DETAIL_LOGGING
     132           4 :             break;
     133        1579 :         case to_underlying(Tag::kData):
     134        1579 :             PRETTY_PRINT_INCDEPTH();
     135        1579 :             ReturnErrorOnFailure(CheckIMPayload(reader, 0, "EventData"));
     136        1579 :             PRETTY_PRINT_DECDEPTH();
     137        1579 :             break;
     138           0 :         default:
     139           0 :             PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
     140           0 :             break;
     141             :         }
     142             :     }
     143        1579 :     PRETTY_PRINT("},");
     144        1579 :     PRETTY_PRINT_BLANK_LINE();
     145             : 
     146             :     // if we have exhausted this container
     147        1579 :     if (CHIP_END_OF_TLV == err)
     148             :     {
     149        1579 :         err = CHIP_NO_ERROR;
     150             :     }
     151        1579 :     ReturnErrorOnFailure(err);
     152        1579 :     return reader.ExitContainer(mOuterContainerType);
     153             : }
     154             : #endif // CHIP_CONFIG_IM_PRETTY_PRINT
     155             : 
     156        1576 : CHIP_ERROR EventDataIB::Parser::GetPath(EventPathIB::Parser * const apPath)
     157             : {
     158             :     TLV::TLVReader reader;
     159        1576 :     ReturnErrorOnFailure(mReader.FindElementWithTag(TLV::ContextTag(Tag::kPath), reader));
     160        1576 :     ReturnErrorOnFailure(apPath->Init(reader));
     161        1576 :     return CHIP_NO_ERROR;
     162             : }
     163             : 
     164        1576 : CHIP_ERROR EventDataIB::Parser::GetPriority(uint8_t * const apPriority)
     165             : {
     166        1576 :     return GetUnsignedInteger(to_underlying(Tag::kPriority), apPriority);
     167             : }
     168             : 
     169        1576 : CHIP_ERROR EventDataIB::Parser::GetEventNumber(EventNumber * const apEventNumber)
     170             : {
     171        1576 :     return GetUnsignedInteger(to_underlying(Tag::kEventNumber), apEventNumber);
     172             : }
     173             : 
     174        1576 : CHIP_ERROR EventDataIB::Parser::GetEpochTimestamp(uint64_t * const apEpochTimestamp)
     175             : {
     176        1576 :     return GetUnsignedInteger(to_underlying(Tag::kEpochTimestamp), apEpochTimestamp);
     177             : }
     178             : 
     179        1576 : CHIP_ERROR EventDataIB::Parser::GetSystemTimestamp(uint64_t * const apSystemTimestamp)
     180             : {
     181        1576 :     return GetUnsignedInteger(to_underlying(Tag::kSystemTimestamp), apSystemTimestamp);
     182             : }
     183             : 
     184        1576 : CHIP_ERROR EventDataIB::Parser::GetDeltaEpochTimestamp(uint64_t * const apDeltaEpochTimestampstamp)
     185             : {
     186        1576 :     return GetUnsignedInteger(to_underlying(Tag::kDeltaEpochTimestamp), apDeltaEpochTimestampstamp);
     187             : }
     188             : 
     189        1576 : CHIP_ERROR EventDataIB::Parser::GetDeltaSystemTimestamp(uint64_t * const apDeltaSystemTimestamp)
     190             : {
     191        1576 :     return GetUnsignedInteger(to_underlying(Tag::kDeltaSystemTimestamp), apDeltaSystemTimestamp);
     192             : }
     193             : 
     194        1576 : CHIP_ERROR EventDataIB::Parser::GetData(TLV::TLVReader * const apReader) const
     195             : {
     196        1576 :     return mReader.FindElementWithTag(TLV::ContextTag(Tag::kData), *apReader);
     197             : }
     198             : 
     199        1575 : CHIP_ERROR EventDataIB::Parser::ProcessEventPath(EventPathIB::Parser & aEventPath, ConcreteEventPath & aConcreteEventPath)
     200             : {
     201             :     // The ReportData must contain a concrete event path
     202        1575 :     CHIP_ERROR err = aEventPath.GetEndpoint(&(aConcreteEventPath.mEndpointId));
     203        1575 :     VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
     204             : 
     205        1575 :     err = aEventPath.GetCluster(&(aConcreteEventPath.mClusterId));
     206        1575 :     VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
     207             : 
     208        1575 :     err = aEventPath.GetEvent(&(aConcreteEventPath.mEventId));
     209        1575 :     VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
     210             : 
     211        1575 :     return CHIP_NO_ERROR;
     212             : }
     213             : 
     214        1575 : CHIP_ERROR EventDataIB::Parser::ProcessEventTimestamp(EventHeader & aEventHeader)
     215             : {
     216        1575 :     CHIP_ERROR err               = CHIP_NO_ERROR;
     217        1575 :     uint64_t timeStampVal        = 0;
     218        1575 :     bool hasSystemTimestamp      = false;
     219        1575 :     bool hasEpochTimestamp       = false;
     220        1575 :     bool hasDeltaSystemTimestamp = false;
     221        1575 :     bool hasDeltaEpochTimestamp  = false;
     222             : 
     223        1575 :     err = GetDeltaSystemTimestamp(&timeStampVal);
     224        1575 :     if (err == CHIP_END_OF_TLV)
     225             :     {
     226        1575 :         err = CHIP_NO_ERROR;
     227             :     }
     228           0 :     else if (err == CHIP_NO_ERROR)
     229             :     {
     230           0 :         VerifyOrReturnError(aEventHeader.mTimestamp.IsSystem(), CHIP_ERROR_IM_MALFORMED_EVENT_DATA_IB);
     231           0 :         aEventHeader.mTimestamp.mValue += timeStampVal;
     232           0 :         hasDeltaSystemTimestamp = true;
     233             :     }
     234        1575 :     ReturnErrorOnFailure(err);
     235             : 
     236        1575 :     err = GetDeltaEpochTimestamp(&timeStampVal);
     237        1575 :     if (err == CHIP_END_OF_TLV)
     238             :     {
     239        1575 :         err = CHIP_NO_ERROR;
     240             :     }
     241           0 :     else if (err == CHIP_NO_ERROR)
     242             :     {
     243           0 :         VerifyOrReturnError(aEventHeader.mTimestamp.IsEpoch(), CHIP_ERROR_IM_MALFORMED_EVENT_DATA_IB);
     244           0 :         aEventHeader.mTimestamp.mValue += timeStampVal;
     245           0 :         hasDeltaEpochTimestamp = true;
     246             :     }
     247        1575 :     ReturnErrorOnFailure(err);
     248             : 
     249        1575 :     err = GetSystemTimestamp(&timeStampVal);
     250        1575 :     if (err == CHIP_END_OF_TLV)
     251             :     {
     252        1575 :         err = CHIP_NO_ERROR;
     253             :     }
     254           0 :     else if (err == CHIP_NO_ERROR)
     255             :     {
     256           0 :         aEventHeader.mTimestamp.mType  = Timestamp::Type::kSystem;
     257           0 :         aEventHeader.mTimestamp.mValue = timeStampVal;
     258           0 :         hasSystemTimestamp             = true;
     259             :     }
     260        1575 :     ReturnErrorOnFailure(err);
     261             : 
     262        1575 :     err = GetEpochTimestamp(&timeStampVal);
     263        1575 :     if (err == CHIP_END_OF_TLV)
     264             :     {
     265           0 :         err = CHIP_NO_ERROR;
     266             :     }
     267        1575 :     else if (err == CHIP_NO_ERROR)
     268             :     {
     269        1575 :         aEventHeader.mTimestamp.mType  = Timestamp::Type::kEpoch;
     270        1575 :         aEventHeader.mTimestamp.mValue = timeStampVal;
     271        1575 :         hasEpochTimestamp              = true;
     272             :     }
     273             : 
     274        1575 :     if (hasSystemTimestamp + hasEpochTimestamp + hasDeltaSystemTimestamp + hasDeltaEpochTimestamp == 1)
     275             :     {
     276        1575 :         return CHIP_NO_ERROR;
     277             :     }
     278           0 :     return CHIP_ERROR_IM_MALFORMED_EVENT_DATA_IB;
     279             : }
     280             : 
     281        1575 : CHIP_ERROR EventDataIB::Parser::DecodeEventHeader(EventHeader & aEventHeader)
     282             : {
     283        1575 :     uint8_t priorityLevel = 0;
     284        1575 :     EventPathIB::Parser path;
     285        1575 :     ReturnErrorOnFailure(GetPath(&path));
     286        1575 :     ReturnErrorOnFailure(ProcessEventPath(path, aEventHeader.mPath));
     287        1575 :     ReturnErrorOnFailure(GetEventNumber(&(aEventHeader.mEventNumber)));
     288        1575 :     ReturnErrorOnFailure(GetPriority(&priorityLevel));
     289        1575 :     aEventHeader.mPriorityLevel = static_cast<PriorityLevel>(priorityLevel);
     290        1575 :     ReturnErrorOnFailure(ProcessEventTimestamp(aEventHeader));
     291        1575 :     return CHIP_NO_ERROR;
     292             : }
     293             : 
     294        1328 : EventPathIB::Builder & EventDataIB::Builder::CreatePath()
     295             : {
     296             :     // skip if error has already been set
     297        1328 :     if (mError == CHIP_NO_ERROR)
     298             :     {
     299        1328 :         mError = mPath.Init(mpWriter, to_underlying(Tag::kPath));
     300             :     }
     301        1328 :     return mPath;
     302             : }
     303             : 
     304        1328 : EventDataIB::Builder & EventDataIB::Builder::Priority(const uint8_t aPriority)
     305             : {
     306             :     // skip if error has already been set
     307        1328 :     if (mError == CHIP_NO_ERROR)
     308             :     {
     309        1328 :         mError = mpWriter->Put(TLV::ContextTag(Tag::kPriority), aPriority);
     310             :     }
     311        1328 :     return *this;
     312             : }
     313             : 
     314        1328 : EventDataIB::Builder & EventDataIB::Builder::EventNumber(const uint64_t aEventNumber)
     315             : {
     316             :     // skip if error has already been set
     317        1328 :     if (mError == CHIP_NO_ERROR)
     318             :     {
     319        1328 :         mError = mpWriter->Put(TLV::ContextTag(Tag::kEventNumber), aEventNumber);
     320             :     }
     321        1328 :     return *this;
     322             : }
     323             : 
     324        1304 : EventDataIB::Builder & EventDataIB::Builder::EpochTimestamp(const uint64_t aEpochTimestamp)
     325             : {
     326             :     // skip if error has already been set
     327        1304 :     if (mError == CHIP_NO_ERROR)
     328             :     {
     329        1304 :         mError = mpWriter->Put(TLV::ContextTag(Tag::kEpochTimestamp), aEpochTimestamp);
     330             :     }
     331        1304 :     return *this;
     332             : }
     333             : 
     334          28 : EventDataIB::Builder & EventDataIB::Builder::SystemTimestamp(const uint64_t aSystemTimestamp)
     335             : {
     336             :     // skip if error has already been set
     337          28 :     if (mError == CHIP_NO_ERROR)
     338             :     {
     339          28 :         mError = mpWriter->Put(TLV::ContextTag(Tag::kSystemTimestamp), aSystemTimestamp);
     340             :     }
     341          28 :     return *this;
     342             : }
     343             : 
     344           4 : EventDataIB::Builder & EventDataIB::Builder::DeltaEpochTimestamp(const uint64_t aDeltaEpochTimestamp)
     345             : {
     346             :     // skip if error has already been set
     347           4 :     if (mError == CHIP_NO_ERROR)
     348             :     {
     349           4 :         mError = mpWriter->Put(TLV::ContextTag(Tag::kDeltaEpochTimestamp), aDeltaEpochTimestamp);
     350             :     }
     351           4 :     return *this;
     352             : }
     353             : 
     354           4 : EventDataIB::Builder & EventDataIB::Builder::DeltaSystemTimestamp(const uint64_t aDeltaSystemTimestamp)
     355             : {
     356             :     // skip if error has already been set
     357           4 :     if (mError == CHIP_NO_ERROR)
     358             :     {
     359           4 :         mError = mpWriter->Put(TLV::ContextTag(Tag::kDeltaSystemTimestamp), aDeltaSystemTimestamp);
     360             :     }
     361           4 :     return *this;
     362             : }
     363             : 
     364             : // Mark the end of this element and recover the type for outer container
     365        1328 : CHIP_ERROR EventDataIB::Builder::EndOfEventDataIB()
     366             : {
     367        1328 :     EndOfContainer();
     368        1328 :     return GetError();
     369             : }
     370             : } // namespace app
     371             : } // namespace chip

Generated by: LCOV version 1.14