add event status IB and update event path IB (#11307)

diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn
index 5817f59..d4cda3a 100644
--- a/src/app/BUILD.gn
+++ b/src/app/BUILD.gn
@@ -72,6 +72,8 @@
     "MessageDef/EventPathIB.h",
     "MessageDef/EventPaths.cpp",
     "MessageDef/EventPaths.h",
+    "MessageDef/EventStatusIB.cpp",
+    "MessageDef/EventStatusIB.h",
     "MessageDef/InvokeRequestMessage.cpp",
     "MessageDef/InvokeRequests.cpp",
     "MessageDef/InvokeResponseIB.cpp",
diff --git a/src/app/EventManagement.cpp b/src/app/EventManagement.cpp
index e588042..c328c93 100644
--- a/src/app/EventManagement.cpp
+++ b/src/app/EventManagement.cpp
@@ -318,10 +318,11 @@
     SuccessOrExit(err);
 
     // TODO: Revisit NodeId since the the encoding spec and the IM seem to disagree on how this stuff works
-    eventPathBuilder.NodeId(apOptions->mpEventSchema->mNodeId)
-        .EndpointId(apOptions->mpEventSchema->mEndpointId)
-        .ClusterId(apOptions->mpEventSchema->mClusterId)
-        .EventId(apOptions->mpEventSchema->mEventId)
+    eventPathBuilder.Node(apOptions->mpEventSchema->mNodeId)
+        .Endpoint(apOptions->mpEventSchema->mEndpointId)
+        .Cluster(apOptions->mpEventSchema->mClusterId)
+        .Event(apOptions->mpEventSchema->mEventId)
+        .IsUrgent(false)
         .EndOfEventPathIB();
     err = eventPathBuilder.GetError();
     SuccessOrExit(err);
@@ -753,10 +754,10 @@
     {
         EventPathIB::Parser path;
         ReturnErrorOnFailure(path.Init(aReader));
-        ReturnErrorOnFailure(path.GetNodeId(&(envelope->mNodeId)));
-        ReturnErrorOnFailure(path.GetEndpointId(&(envelope->mEndpointId)));
-        ReturnErrorOnFailure(path.GetClusterId(&(envelope->mClusterId)));
-        ReturnErrorOnFailure(path.GetEventId(&(envelope->mEventId)));
+        ReturnErrorOnFailure(path.GetNode(&(envelope->mNodeId)));
+        ReturnErrorOnFailure(path.GetEndpoint(&(envelope->mEndpointId)));
+        ReturnErrorOnFailure(path.GetCluster(&(envelope->mClusterId)));
+        ReturnErrorOnFailure(path.GetEvent(&(envelope->mEventId)));
         envelope->mFieldsToRead |= 1 << EventDataElement::kCsTag_EventPath;
     }
 
diff --git a/src/app/MessageDef/EventPathIB.cpp b/src/app/MessageDef/EventPathIB.cpp
index a4f8ca8..12d3506 100644
--- a/src/app/MessageDef/EventPathIB.cpp
+++ b/src/app/MessageDef/EventPathIB.cpp
@@ -31,17 +31,14 @@
 
 #include <app/AppBuildConfig.h>
 
-using namespace chip;
-using namespace chip::TLV;
-
 namespace chip {
 namespace app {
 #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
 CHIP_ERROR EventPathIB::Parser::CheckSchemaValidity() const
 {
-    CHIP_ERROR err           = CHIP_NO_ERROR;
-    uint16_t TagPresenceMask = 0;
-    chip::TLV::TLVReader reader;
+    CHIP_ERROR err      = CHIP_NO_ERROR;
+    int TagPresenceMask = 0;
+    TLV::TLVReader reader;
 
     PRETTY_PRINT("EventPath =");
     PRETTY_PRINT("{");
@@ -51,65 +48,81 @@
 
     while (CHIP_NO_ERROR == (err = reader.Next()))
     {
-        VerifyOrExit(chip::TLV::IsContextTag(reader.GetTag()), err = CHIP_ERROR_INVALID_TLV_TAG);
-        switch (chip::TLV::TagNumFromTag(reader.GetTag()))
+        VerifyOrReturnError(TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
+        uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
+        switch (tagNum)
         {
-        case kCsTag_NodeId:
+        case to_underlying(Tag::kNode):
             // check if this tag has appeared before
-            VerifyOrExit(!(TagPresenceMask & (1 << kCsTag_NodeId)), err = CHIP_ERROR_INVALID_TLV_TAG);
-            TagPresenceMask |= (1 << kCsTag_NodeId);
-            VerifyOrExit(chip::TLV::kTLVType_UnsignedInteger == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
+            VerifyOrReturnError(!(TagPresenceMask & (1 << to_underlying(Tag::kNode))), CHIP_ERROR_INVALID_TLV_TAG);
+            TagPresenceMask |= (1 << to_underlying(Tag::kNode));
+            VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
 #if CHIP_DETAIL_LOGGING
             {
-                uint64_t nodeId;
-                reader.Get(nodeId);
-                PRETTY_PRINT("\tNodeId = 0x%" PRIx64 ",", nodeId);
+                NodeId node;
+                reader.Get(node);
+                PRETTY_PRINT("\tNode = 0x%" PRIx64 ",", node);
             }
 #endif // CHIP_DETAIL_LOGGING
             break;
-        case kCsTag_EndpointId:
+        case to_underlying(Tag::kEndpoint):
             // check if this tag has appeared before
-            VerifyOrExit(!(TagPresenceMask & (1 << kCsTag_EndpointId)), err = CHIP_ERROR_INVALID_TLV_TAG);
-            TagPresenceMask |= (1 << kCsTag_EndpointId);
-            VerifyOrExit(chip::TLV::kTLVType_UnsignedInteger == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
+            VerifyOrReturnError(!(TagPresenceMask & (1 << to_underlying(Tag::kEndpoint))), CHIP_ERROR_INVALID_TLV_TAG);
+            TagPresenceMask |= (1 << to_underlying(Tag::kEndpoint));
+            VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
 #if CHIP_DETAIL_LOGGING
             {
-                uint16_t endpointId;
-                reader.Get(endpointId);
-                PRETTY_PRINT("\tEndpointId = 0x%" PRIx16 ",", endpointId);
+                EndpointId endpoint;
+                reader.Get(endpoint);
+                PRETTY_PRINT("\tEndpoint = 0x%" PRIx16 ",", endpoint);
             }
 #endif // CHIP_DETAIL_LOGGING
             break;
-        case kCsTag_ClusterId:
+        case to_underlying(Tag::kCluster):
             // check if this tag has appeared before
-            VerifyOrExit(!(TagPresenceMask & (1 << kCsTag_ClusterId)), err = CHIP_ERROR_INVALID_TLV_TAG);
-            TagPresenceMask |= (1 << kCsTag_ClusterId);
-            VerifyOrExit(chip::TLV::kTLVType_UnsignedInteger == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
+            VerifyOrReturnError(!(TagPresenceMask & (1 << to_underlying(Tag::kCluster))), CHIP_ERROR_INVALID_TLV_TAG);
+            TagPresenceMask |= (1 << to_underlying(Tag::kCluster));
+            VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
 
 #if CHIP_DETAIL_LOGGING
             {
-                chip::ClusterId clusterId;
-                reader.Get(clusterId);
-                PRETTY_PRINT("\tClusterId = 0x%" PRIx32 ",", clusterId);
+                ClusterId cluster;
+                reader.Get(cluster);
+                PRETTY_PRINT("\tCluster = 0x%" PRIx32 ",", cluster);
             }
 #endif // CHIP_DETAIL_LOGGING
             break;
-        case chip::app::EventPathIB::kCsTag_EventId:
+        case to_underlying(Tag::kEvent):
             // check if this tag has appeared before
-            VerifyOrExit(!(TagPresenceMask & (1 << chip::app::EventPathIB::kCsTag_EventId)), err = CHIP_ERROR_INVALID_TLV_TAG);
-            TagPresenceMask |= (1 << chip::app::EventPathIB::kCsTag_EventId);
-            VerifyOrExit(chip::TLV::kTLVType_UnsignedInteger == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
+            VerifyOrReturnError(!(TagPresenceMask & (1 << to_underlying(Tag::kEvent))), CHIP_ERROR_INVALID_TLV_TAG);
+            TagPresenceMask |= (1 << to_underlying(Tag::kEvent));
+            VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
 
 #if CHIP_DETAIL_LOGGING
             {
-                chip::EventId eventId;
-                reader.Get(eventId);
-                PRETTY_PRINT("\tEventId = 0x%" PRIx16 ",", eventId);
+                EventId event;
+                reader.Get(event);
+                PRETTY_PRINT("\tEvent = 0x%" PRIx16 ",", event);
+            }
+#endif // CHIP_DETAIL_LOGGING
+            break;
+        case to_underlying(Tag::kIsUrgent):
+            // check if this tag has appeared before
+            VerifyOrReturnError(!(TagPresenceMask & (1 << to_underlying(Tag::kIsUrgent))), CHIP_ERROR_INVALID_TLV_TAG);
+            TagPresenceMask |= (1 << to_underlying(Tag::kIsUrgent));
+            VerifyOrReturnError(TLV::kTLVType_Boolean == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
+
+#if CHIP_DETAIL_LOGGING
+            {
+                bool isUrgent;
+                ReturnErrorOnFailure(reader.Get(isUrgent));
+                PRETTY_PRINT("\tisUrgent = %s, ", isUrgent ? "true" : "false");
             }
 #endif // CHIP_DETAIL_LOGGING
             break;
         default:
-            ExitNow(err = CHIP_ERROR_INVALID_TLV_TAG);
+            PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
+            break;
         }
     }
 
@@ -119,83 +132,86 @@
     // if we have exhausted this container
     if (CHIP_END_OF_TLV == err)
     {
-        // check for required fields:
-        const uint16_t RequiredFields = (1 << kCsTag_EndpointId) | (1 << kCsTag_ClusterId);
-
-        if ((TagPresenceMask & RequiredFields) == RequiredFields)
-        {
-            err = CHIP_NO_ERROR;
-        }
-        else
-        {
-            err = CHIP_ERROR_IM_MALFORMED_EVENT_PATH;
-        }
+        err = CHIP_NO_ERROR;
     }
-    SuccessOrExit(err);
-    err = reader.ExitContainer(mOuterContainerType);
 
-exit:
-
+    ReturnErrorOnFailure(err);
+    ReturnErrorOnFailure(reader.ExitContainer(mOuterContainerType));
     return err;
 }
 #endif // CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
 
-CHIP_ERROR EventPathIB::Parser::GetNodeId(chip::NodeId * const apNodeId) const
+CHIP_ERROR EventPathIB::Parser::GetNode(NodeId * const apNode) const
 {
-    return GetUnsignedInteger(kCsTag_NodeId, apNodeId);
+    return GetUnsignedInteger(to_underlying(Tag::kNode), apNode);
 }
 
-CHIP_ERROR EventPathIB::Parser::GetEndpointId(chip::EndpointId * const apEndpointID) const
+CHIP_ERROR EventPathIB::Parser::GetEndpoint(EndpointId * const apEndpoint) const
 {
-    return GetUnsignedInteger(kCsTag_EndpointId, apEndpointID);
+    return GetUnsignedInteger(to_underlying(Tag::kEndpoint), apEndpoint);
 }
 
-CHIP_ERROR EventPathIB::Parser::GetClusterId(chip::ClusterId * const apClusterId) const
+CHIP_ERROR EventPathIB::Parser::GetCluster(ClusterId * const apCluster) const
 {
-    return GetUnsignedInteger(kCsTag_ClusterId, apClusterId);
+    return GetUnsignedInteger(to_underlying(Tag::kCluster), apCluster);
 }
 
-CHIP_ERROR EventPathIB::Parser::GetEventId(chip::EventId * const apEventId) const
+CHIP_ERROR EventPathIB::Parser::GetEvent(EventId * const apEvent) const
 {
-    return GetUnsignedInteger(kCsTag_EventId, apEventId);
+    return GetUnsignedInteger(to_underlying(Tag::kEvent), apEvent);
 }
 
-EventPathIB::Builder & EventPathIB::Builder::NodeId(const uint64_t aNodeId)
+CHIP_ERROR EventPathIB::Parser::GetIsUrgent(bool * const apIsUrgent) const
+{
+    return GetSimpleValue(to_underlying(Tag::kIsUrgent), TLV::kTLVType_Boolean, apIsUrgent);
+}
+
+EventPathIB::Builder & EventPathIB::Builder::Node(const NodeId aNode)
 {
     // skip if error has already been set
     if (mError == CHIP_NO_ERROR)
     {
-        mError = mpWriter->Put(chip::TLV::ContextTag(kCsTag_NodeId), aNodeId);
+        mError = mpWriter->Put(TLV::ContextTag(to_underlying(Tag::kNode)), aNode);
     }
     return *this;
 }
 
-EventPathIB::Builder & EventPathIB::Builder::EndpointId(const chip::EndpointId aEndpointId)
+EventPathIB::Builder & EventPathIB::Builder::Endpoint(const EndpointId aEndpoint)
 {
     // skip if error has already been set
     if (mError == CHIP_NO_ERROR)
     {
-        mError = mpWriter->Put(chip::TLV::ContextTag(kCsTag_EndpointId), aEndpointId);
+        mError = mpWriter->Put(TLV::ContextTag(to_underlying(Tag::kEndpoint)), aEndpoint);
     }
     return *this;
 }
 
-EventPathIB::Builder & EventPathIB::Builder::ClusterId(const chip::ClusterId aClusterId)
+EventPathIB::Builder & EventPathIB::Builder::Cluster(const ClusterId aCluster)
 {
     // skip if error has already been set
     if (mError == CHIP_NO_ERROR)
     {
-        mError = mpWriter->Put(chip::TLV::ContextTag(kCsTag_ClusterId), aClusterId);
+        mError = mpWriter->Put(TLV::ContextTag(to_underlying(Tag::kCluster)), aCluster);
     }
     return *this;
 }
 
-EventPathIB::Builder & EventPathIB::Builder::EventId(const chip::EventId aEventId)
+EventPathIB::Builder & EventPathIB::Builder::Event(const EventId aEvent)
 {
     // skip if error has already been set
     if (mError == CHIP_NO_ERROR)
     {
-        mError = mpWriter->Put(chip::TLV::ContextTag(kCsTag_EventId), aEventId);
+        mError = mpWriter->Put(TLV::ContextTag(to_underlying(Tag::kEvent)), aEvent);
+    }
+    return *this;
+}
+
+EventPathIB::Builder & EventPathIB::Builder::IsUrgent(const bool aIsUrgent)
+{
+    // skip if error has already been set
+    if (mError == CHIP_NO_ERROR)
+    {
+        mError = mpWriter->PutBoolean(TLV::ContextTag(to_underlying(Tag::kIsUrgent)), aIsUrgent);
     }
     return *this;
 }
diff --git a/src/app/MessageDef/EventPathIB.h b/src/app/MessageDef/EventPathIB.h
index e159c28..8b2d6a1 100644
--- a/src/app/MessageDef/EventPathIB.h
+++ b/src/app/MessageDef/EventPathIB.h
@@ -36,12 +36,13 @@
 namespace chip {
 namespace app {
 namespace EventPathIB {
-enum
+enum class Tag : uint8_t
 {
-    kCsTag_NodeId     = 0,
-    kCsTag_EndpointId = 1,
-    kCsTag_ClusterId  = 2,
-    kCsTag_EventId    = 3,
+    kNode     = 0,
+    kEndpoint = 1,
+    kCluster  = 2,
+    kEvent    = 3,
+    kIsUrgent = 4,
 };
 
 class Parser : public ListParser
@@ -67,24 +68,24 @@
     /**
      *  @brief Get a TLVReader for the NodeId. Next() must be called before accessing them.
      *
-     *  @param [in] apNodeId    A pointer to apNodeId
+     *  @param [in] apNode    A pointer to apNode
      *
      *  @return #CHIP_NO_ERROR on success
      *          #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
      *          #CHIP_END_OF_TLV if there is no such element
      */
-    CHIP_ERROR GetNodeId(NodeId * const apNodeId) const;
+    CHIP_ERROR GetNode(NodeId * const apNode) const;
 
     /**
      *  @brief Get a TLVReader for the EndpointId. Next() must be called before accessing them.
      *
-     *  @param [in] apEndpointId    A pointer to apEndpointId
+     *  @param [in] apEndpoint    A pointer to apEndpoint
      *
      *  @return #CHIP_NO_ERROR on success
      *          #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
      *          #CHIP_END_OF_TLV if there is no such element
      */
-    CHIP_ERROR GetEndpointId(EndpointId * const apEndpointId) const;
+    CHIP_ERROR GetEndpoint(EndpointId * const apEndpoint) const;
 
     /**
      *  @brief Get a TLVReader for the ClusterId. Next() must be called before accessing them.
@@ -95,7 +96,7 @@
      *          #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
      *          #CHIP_END_OF_TLV if there is no such element
      */
-    CHIP_ERROR GetClusterId(ClusterId * const apClusterId) const;
+    CHIP_ERROR GetCluster(ClusterId * const apCluster) const;
 
     /**
      *  @brief Get a TLVReader for the EventId. Next() must be called before accessing them.
@@ -106,38 +107,58 @@
      *          #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
      *          #CHIP_END_OF_TLV if there is no such element
      */
-    CHIP_ERROR GetEventId(EventId * const apEventId) const;
+    CHIP_ERROR GetEvent(EventId * const apEvent) const;
+
+    /**
+     *  @brief Get a TLVReader for the EventId. Next() must be called before accessing them.
+     *
+     *  @param [in] apEventId    A pointer to apEventId
+     *
+     *  @return #CHIP_NO_ERROR on success
+     *          #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
+     *          #CHIP_END_OF_TLV if there is no such element
+     */
+    CHIP_ERROR GetIsUrgent(bool * const apIsUrgent) const;
 };
 
 class Builder : public ListBuilder
 {
 public:
     /**
-     *  @brief Inject NodeId into the TLV stream.
+     *  @brief Inject Node into the TLV stream.
      *
-     *  @param [in] aNodeId NodeId for this event path
+     *  @param [in] aNode NodeId for this event path
      *
      *  @return A reference to *this
      */
-    EventPathIB::Builder & NodeId(const chip::NodeId aNodeId);
+    EventPathIB::Builder & Node(const NodeId aNode);
 
     /**
-     *  @brief Inject EndpointId into the TLV stream.
+     *  @brief Inject Endpoint into the TLV stream.
      *
-     *  @param [in] aEndpointId EndpointId for this eevent path
+     *  @param [in] aEndpoint EndpointId for this eevent path
      *
      *  @return A reference to *this
      */
-    EventPathIB::Builder & EndpointId(const chip::EndpointId aEndpointId);
+    EventPathIB::Builder & Endpoint(const EndpointId aEndpoint);
 
     /**
-     *  @brief Inject ClusterId into the TLV stream.
+     *  @brief Inject Cluster into the TLV stream.
      *
-     *  @param [in] aClusterId ClusterId for this event path
+     *  @param [in] aCluster ClusterId for this event path
      *
      *  @return A reference to *this
      */
-    EventPathIB::Builder & ClusterId(const chip::ClusterId aClusterId);
+    EventPathIB::Builder & Cluster(const ClusterId aCluster);
+
+    /**
+     *  @brief Inject Event into the TLV stream.
+     *
+     *  @param [in] aEvent ClusterId for this event path
+     *
+     *  @return A reference to *this
+     */
+    EventPathIB::Builder & Event(const EventId aEvent);
 
     /**
      *  @brief Inject EventId into the TLV stream.
@@ -146,7 +167,7 @@
      *
      *  @return A reference to *this
      */
-    EventPathIB::Builder & EventId(const chip::EventId aEventId);
+    EventPathIB::Builder & IsUrgent(const bool aIsUrgent);
 
     /**
      *  @brief Mark the end of this EventPath
@@ -155,6 +176,6 @@
      */
     EventPathIB::Builder & EndOfEventPathIB();
 };
-}; // namespace EventPathIB
-}; // namespace app
-}; // namespace chip
+} // namespace EventPathIB
+} // namespace app
+} // namespace chip
diff --git a/src/app/MessageDef/EventPaths.cpp b/src/app/MessageDef/EventPaths.cpp
index 61639ef..134e3cc 100644
--- a/src/app/MessageDef/EventPaths.cpp
+++ b/src/app/MessageDef/EventPaths.cpp
@@ -38,7 +38,7 @@
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
     size_t NumPath = 0;
-    chip::TLV::TLVReader reader;
+    TLV::TLVReader reader;
 
     PRETTY_PRINT("EventPaths =");
     PRETTY_PRINT("[");
@@ -48,17 +48,15 @@
 
     while (CHIP_NO_ERROR == (err = reader.Next()))
     {
-        VerifyOrExit(chip::TLV::AnonymousTag == reader.GetTag(), err = CHIP_ERROR_INVALID_TLV_TAG);
-        VerifyOrExit(chip::TLV::kTLVType_List == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
+        VerifyOrReturnError(TLV::AnonymousTag == reader.GetTag(), CHIP_ERROR_INVALID_TLV_TAG);
+        VerifyOrReturnError(TLV::kTLVType_List == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
 
         {
             EventPathIB::Parser path;
-            err = path.Init(reader);
-            SuccessOrExit(err);
+            ReturnErrorOnFailure(path.Init(reader));
 
             PRETTY_PRINT_INCDEPTH();
-            err = path.CheckSchemaValidity();
-            SuccessOrExit(err);
+            ReturnErrorOnFailure(path.CheckSchemaValidity());
             PRETTY_PRINT_DECDEPTH();
         }
 
@@ -73,12 +71,9 @@
     {
         err = CHIP_NO_ERROR;
     }
-    SuccessOrExit(err);
-    err = reader.ExitContainer(mOuterContainerType);
-
-exit:
-
-    return err;
+    ReturnErrorOnFailure(err);
+    ReturnErrorOnFailure(reader.ExitContainer(mOuterContainerType));
+    return CHIP_NO_ERROR;
 }
 #endif // CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
 
diff --git a/src/app/MessageDef/EventStatusIB.cpp b/src/app/MessageDef/EventStatusIB.cpp
new file mode 100644
index 0000000..536f28b
--- /dev/null
+++ b/src/app/MessageDef/EventStatusIB.cpp
@@ -0,0 +1,140 @@
+/**
+ *
+ *    Copyright (c) 2021 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.
+ */
+
+#include "EventStatusIB.h"
+#include "MessageDefHelper.h"
+#include "StructBuilder.h"
+#include "StructParser.h"
+
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <app/AppBuildConfig.h>
+
+namespace chip {
+namespace app {
+#if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
+CHIP_ERROR EventStatusIB::Parser::CheckSchemaValidity() const
+{
+    CHIP_ERROR err      = CHIP_NO_ERROR;
+    int TagPresenceMask = 0;
+    TLV::TLVReader reader;
+
+    PRETTY_PRINT("EventStatusIB =");
+    PRETTY_PRINT("{");
+
+    // make a copy of the reader
+    reader.Init(mReader);
+
+    while (CHIP_NO_ERROR == (err = reader.Next()))
+    {
+        VerifyOrReturnError(TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
+        uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
+        switch (tagNum)
+        {
+        case to_underlying(Tag::kPath):
+            // check if this tag has appeared before
+            VerifyOrReturnError(!(TagPresenceMask & (1 << to_underlying(Tag::kPath))), CHIP_ERROR_INVALID_TLV_TAG);
+            TagPresenceMask |= (1 << to_underlying(Tag::kPath));
+            {
+                EventPathIB::Parser path;
+                ReturnErrorOnFailure(path.Init(reader));
+
+                PRETTY_PRINT_INCDEPTH();
+                ReturnErrorOnFailure(path.CheckSchemaValidity());
+                PRETTY_PRINT_DECDEPTH();
+            }
+            break;
+        case to_underlying(Tag::kErrorStatus):
+            // check if this tag has appeared before
+            VerifyOrReturnError(!(TagPresenceMask & (1 << to_underlying(Tag::kErrorStatus))), CHIP_ERROR_INVALID_TLV_TAG);
+            TagPresenceMask |= (1 << to_underlying(Tag::kErrorStatus));
+            {
+                StatusIB::Parser errorStatus;
+                ReturnErrorOnFailure(errorStatus.Init(reader));
+
+                PRETTY_PRINT_INCDEPTH();
+                ReturnErrorOnFailure(errorStatus.CheckSchemaValidity());
+                PRETTY_PRINT_DECDEPTH();
+            }
+            break;
+        default:
+            PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
+            break;
+        }
+    }
+
+    PRETTY_PRINT("},");
+    PRETTY_PRINT("");
+
+    if (CHIP_END_OF_TLV == err)
+    {
+        const int RequiredFields = (1 << to_underlying(Tag::kPath)) | (1 << to_underlying(Tag::kErrorStatus));
+
+        if ((TagPresenceMask & RequiredFields) == RequiredFields)
+        {
+            err = CHIP_NO_ERROR;
+        }
+    }
+
+    ReturnErrorOnFailure(err);
+    ReturnErrorOnFailure(reader.ExitContainer(mOuterContainerType));
+    return CHIP_NO_ERROR;
+}
+#endif // CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
+
+CHIP_ERROR EventStatusIB::Parser::GetPath(EventPathIB::Parser * const apPath) const
+{
+    TLV::TLVReader reader;
+    ReturnErrorOnFailure(mReader.FindElementWithTag(TLV::ContextTag(to_underlying(Tag::kPath)), reader));
+    ReturnErrorOnFailure(apPath->Init(reader));
+    return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR EventStatusIB::Parser::GetErrorStatus(StatusIB::Parser * const apErrorStatus) const
+{
+    TLV::TLVReader reader;
+    ReturnErrorOnFailure(mReader.FindElementWithTag(TLV::ContextTag(to_underlying(Tag::kErrorStatus)), reader));
+    ReturnErrorOnFailure(apErrorStatus->Init(reader));
+    return CHIP_NO_ERROR;
+}
+
+EventPathIB::Builder & EventStatusIB::Builder::CreatePath()
+{
+    if (mError == CHIP_NO_ERROR)
+    {
+        mError = mPath.Init(mpWriter, to_underlying(Tag::kPath));
+    }
+    return mPath;
+}
+
+StatusIB::Builder & EventStatusIB::Builder::CreateErrorStatus()
+{
+    if (mError == CHIP_NO_ERROR)
+    {
+        mError = mErrorStatus.Init(mpWriter, to_underlying(Tag::kErrorStatus));
+    }
+    return mErrorStatus;
+}
+
+EventStatusIB::Builder & EventStatusIB::Builder::EndOfEventStatusIB()
+{
+    EndOfContainer();
+    return *this;
+}
+} // namespace app
+} // namespace chip
diff --git a/src/app/MessageDef/EventStatusIB.h b/src/app/MessageDef/EventStatusIB.h
new file mode 100644
index 0000000..f51eae5
--- /dev/null
+++ b/src/app/MessageDef/EventStatusIB.h
@@ -0,0 +1,114 @@
+/**
+ *
+ *    Copyright (c) 2021 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 "EventPathIB.h"
+#include "StatusIB.h"
+#include "StructBuilder.h"
+#include "StructParser.h"
+
+#include <app/AppBuildConfig.h>
+#include <app/util/basic-types.h>
+#include <lib/core/CHIPCore.h>
+#include <lib/core/CHIPTLV.h>
+#include <lib/support/CodeUtils.h>
+#include <lib/support/logging/CHIPLogging.h>
+
+namespace chip {
+namespace app {
+namespace EventStatusIB {
+enum class Tag : uint8_t
+{
+    kPath        = 0,
+    kErrorStatus = 1,
+};
+
+class Parser : public StructParser
+{
+public:
+#if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
+    /**
+     *  @brief Roughly verify the message is correctly formed
+     *   1) all mandatory tags are present
+     *   2) all elements have expected data type
+     *   3) any tag can only appear once
+     *   4) At the top level of the structure, unknown tags are ignored for forward compatibility
+     *  @note The main use of this function is to print out what we're
+     *    receiving during protocol development and debugging.
+     *    The encoding rule has changed in IM encoding spec so this
+     *    check is only "roughly" conformant now.
+     *
+     *  @return #CHIP_NO_ERROR on success
+     */
+    CHIP_ERROR CheckSchemaValidity() const;
+#endif
+
+    /**
+     *  @brief Get a TLVReader for the EventPathIB. Next() must be called before accessing them.
+     *
+     *  @param [in] apPath    A pointer to apPath
+     *
+     *  @return #CHIP_NO_ERROR on success
+     *          #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not a Path
+     *          #CHIP_END_OF_TLV if there is no such element
+     */
+    CHIP_ERROR GetPath(EventPathIB::Parser * const apPath) const;
+
+    /**
+     *  @brief Get a TLVReader for the StatusIB. Next() must be called before accessing them.
+     *
+     *  @param [in] apErrorStatus    A pointer to apErrorStatus
+     *
+     *  @return #CHIP_NO_ERROR on success
+     *          # CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not a structure
+     *          #CHIP_END_OF_TLV if there is no such element
+     */
+    CHIP_ERROR GetErrorStatus(StatusIB::Parser * const apErrorStatus) const;
+};
+
+class Builder : public StructBuilder
+{
+public:
+    /**
+     *  @brief Initialize a EventPathIB::Builder for writing into the TLV stream
+     *
+     *  @return A reference to EventPathIB::Builder
+     */
+    EventPathIB::Builder & CreatePath();
+
+    /**
+     *  @brief Initialize a StatusIB::Builder for writing into the TLV stream
+     *
+     *  @return A reference to StatusIB::Builder
+     */
+    StatusIB::Builder & CreateErrorStatus();
+
+    /**
+     *  @brief Mark the end of this EventStatusIB
+     *
+     *  @return A reference to *this
+     */
+    EventStatusIB::Builder & EndOfEventStatusIB();
+
+private:
+    EventPathIB::Builder mPath;
+    StatusIB::Builder mErrorStatus;
+};
+} // namespace EventStatusIB
+} // namespace app
+} // namespace chip
diff --git a/src/app/MessageDef/ReadRequestMessage.h b/src/app/MessageDef/ReadRequestMessage.h
index 116b5fe..66137d5 100644
--- a/src/app/MessageDef/ReadRequestMessage.h
+++ b/src/app/MessageDef/ReadRequestMessage.h
@@ -43,8 +43,8 @@
 enum
 {
     kCsTag_AttributePathList        = 0,
-    kCsTag_EventPaths               = 1,
-    kCsTag_AttributeDataVersionList = 2,
+    kCsTag_AttributeDataVersionList = 1,
+    kCsTag_EventPaths               = 2,
     kCsTag_EventNumber              = 3,
 };
 
diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp
index a77794a..d3516d1 100644
--- a/src/app/ReadClient.cpp
+++ b/src/app/ReadClient.cpp
@@ -236,10 +236,10 @@
     {
         EventPathIB::Builder eventPathBuilder = aEventPathsBuilder.CreateEventPath();
         EventPathParams eventPath             = apEventPathParamsList[eventIndex];
-        eventPathBuilder.NodeId(eventPath.mNodeId)
-            .EventId(eventPath.mEventId)
-            .EndpointId(eventPath.mEndpointId)
-            .ClusterId(eventPath.mClusterId)
+        eventPathBuilder.Node(eventPath.mNodeId)
+            .Event(eventPath.mEventId)
+            .Endpoint(eventPath.mEndpointId)
+            .Cluster(eventPath.mClusterId)
             .EndOfEventPathIB();
         SuccessOrExit(err = eventPathBuilder.GetError());
     }
diff --git a/src/app/ReadHandler.cpp b/src/app/ReadHandler.cpp
index a1589a6..c2ec72d 100644
--- a/src/app/ReadHandler.cpp
+++ b/src/app/ReadHandler.cpp
@@ -391,13 +391,13 @@
         EventPathIB::Parser path;
         err = path.Init(reader);
         SuccessOrExit(err);
-        err = path.GetNodeId(&(clusterInfo.mNodeId));
+        err = path.GetNode(&(clusterInfo.mNodeId));
         SuccessOrExit(err);
-        err = path.GetEndpointId(&(clusterInfo.mEndpointId));
+        err = path.GetEndpoint(&(clusterInfo.mEndpointId));
         SuccessOrExit(err);
-        err = path.GetClusterId(&(clusterInfo.mClusterId));
+        err = path.GetCluster(&(clusterInfo.mClusterId));
         SuccessOrExit(err);
-        err = path.GetEventId(&(clusterInfo.mEventId));
+        err = path.GetEvent(&(clusterInfo.mEventId));
         if (CHIP_NO_ERROR == err)
         {
             clusterInfo.mFlags.Set(ClusterInfo::Flags::kEventIdValid);
diff --git a/src/app/tests/TestMessageDef.cpp b/src/app/tests/TestMessageDef.cpp
index 2b2e68a..0200590 100644
--- a/src/app/tests/TestMessageDef.cpp
+++ b/src/app/tests/TestMessageDef.cpp
@@ -24,6 +24,7 @@
 
 #include <app/AppBuildConfig.h>
 #include <app/MessageDef/EventFilters.h>
+#include <app/MessageDef/EventStatusIB.h>
 #include <app/MessageDef/InvokeRequestMessage.h>
 #include <app/MessageDef/InvokeResponseMessage.h>
 #include <app/MessageDef/ReadRequestMessage.h>
@@ -190,7 +191,7 @@
 void BuildEventPath(nlTestSuite * apSuite, EventPathIB::Builder & aEventPathBuilder)
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
-    aEventPathBuilder.NodeId(1).EndpointId(2).ClusterId(3).EventId(4).EndOfEventPathIB();
+    aEventPathBuilder.Node(1).Endpoint(2).Cluster(3).Event(4).IsUrgent(true).EndOfEventPathIB();
     err = aEventPathBuilder.GetError();
     NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
 }
@@ -202,22 +203,26 @@
     chip::EndpointId endpointId = 2;
     chip::ClusterId clusterId   = 3;
     chip::EventId eventId       = 4;
+    bool isUrgent               = false;
 
 #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
     err = aEventPathParser.CheckSchemaValidity();
     NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
 #endif
-    err = aEventPathParser.GetNodeId(&nodeId);
+    err = aEventPathParser.GetNode(&nodeId);
     NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && nodeId == 1);
 
-    err = aEventPathParser.GetEndpointId(&endpointId);
+    err = aEventPathParser.GetEndpoint(&endpointId);
     NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && endpointId == 2);
 
-    err = aEventPathParser.GetClusterId(&clusterId);
+    err = aEventPathParser.GetCluster(&clusterId);
     NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && clusterId == 3);
 
-    err = aEventPathParser.GetEventId(&eventId);
+    err = aEventPathParser.GetEvent(&eventId);
     NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && eventId == 4);
+
+    err = aEventPathParser.GetIsUrgent(&isUrgent);
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR && isUrgent == true);
 }
 
 void BuildEventPaths(nlTestSuite * apSuite, EventPaths::Builder & aEventPathsBuilder)
@@ -411,6 +416,36 @@
                        !statusIB.mClusterStatus.HasValue());
 }
 
+void BuildEventStatusIB(nlTestSuite * apSuite, EventStatusIB::Builder & aEventStatusIBBuilder)
+{
+    EventPathIB::Builder eventPathBuilder = aEventStatusIBBuilder.CreatePath();
+    NL_TEST_ASSERT(apSuite, aEventStatusIBBuilder.GetError() == CHIP_NO_ERROR);
+    BuildEventPath(apSuite, eventPathBuilder);
+
+    StatusIB::Builder statusIBBuilder = aEventStatusIBBuilder.CreateErrorStatus();
+    NL_TEST_ASSERT(apSuite, statusIBBuilder.GetError() == CHIP_NO_ERROR);
+    BuildStatusIB(apSuite, statusIBBuilder);
+
+    aEventStatusIBBuilder.EndOfEventStatusIB();
+    NL_TEST_ASSERT(apSuite, aEventStatusIBBuilder.GetError() == CHIP_NO_ERROR);
+}
+
+void ParseEventStatusIB(nlTestSuite * apSuite, EventStatusIB::Parser & aEventStatusIBParser)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    EventPathIB::Parser eventPathParser;
+    StatusIB::Parser statusParser;
+#if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
+    err = aEventStatusIBParser.CheckSchemaValidity();
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+#endif
+    err = aEventStatusIBParser.GetPath(&eventPathParser);
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+
+    err = aEventStatusIBParser.GetErrorStatus(&statusParser);
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+}
+
 void BuildAttributeStatusIB(nlTestSuite * apSuite, AttributeStatusIB::Builder & aAttributeStatusIBBuilder)
 {
     AttributePath::Builder attributePathBuilder = aAttributeStatusIBBuilder.CreateAttributePathBuilder();
@@ -1450,6 +1485,30 @@
     ParseStatusIB(apSuite, StatusIBParser);
 }
 
+void EventStatusIBTest(nlTestSuite * apSuite, void * apContext)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    EventStatusIB::Builder eventStatusIBBuilder;
+    EventStatusIB::Parser eventStatusIBParser;
+    chip::System::PacketBufferTLVWriter writer;
+    chip::System::PacketBufferTLVReader reader;
+    writer.Init(chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize));
+    eventStatusIBBuilder.Init(&writer);
+    BuildEventStatusIB(apSuite, eventStatusIBBuilder);
+    chip::System::PacketBufferHandle buf;
+    err = writer.Finalize(&buf);
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+
+    DebugPrettyPrint(buf);
+
+    reader.Init(std::move(buf));
+    err = reader.Next();
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+
+    eventStatusIBParser.Init(reader);
+    ParseEventStatusIB(apSuite, eventStatusIBParser);
+}
+
 void AttributeStatusIBTest(nlTestSuite * apSuite, void * apContext)
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
@@ -1964,6 +2023,7 @@
                 NL_TEST_DEF("EventDataElementTest", EventDataElementTest),
                 NL_TEST_DEF("EventListTest", EventListTest),
                 NL_TEST_DEF("StatusIBTest", StatusIBTest),
+                NL_TEST_DEF("EventStatusIBTest", EventStatusIBTest),
                 NL_TEST_DEF("AttributeStatusIBTest", AttributeStatusIBTest),
                 NL_TEST_DEF("AttributeStatusListTest", AttributeStatusListTest),
                 NL_TEST_DEF("AttributeDataElementTest", AttributeDataElementTest),