Merge pull request #645 from openweave/feature/EventBeforeTraitData

Add option to pack events from eventlist in NotifyRequest before trait-data properties from datalist
diff --git a/src/lib/core/WeaveConfig.h b/src/lib/core/WeaveConfig.h
index 270bc51..bb510b6 100644
--- a/src/lib/core/WeaveConfig.h
+++ b/src/lib/core/WeaveConfig.h
@@ -2356,6 +2356,25 @@
 #endif // WEAVE_CONFIG_MAX_SOFTWARE_VERSION_LENGTH
 
 /**
+ *  @def WEAVE_CONFIG_ENABLE_OFFLOAD_EVENTS_FIRST
+ *
+ *  @brief
+ *    Enable offloading of events before trait properties
+ *
+ *  When this option is enabled, WeaveDataManagement will first
+ *  attempt to pack events from the eventlist into the NotifyRequest
+ *  message before adding modified trait data properties from
+ *  the datalist.
+ *
+ *  This feature can be useful in systems that might need
+ *  the events to be dispatched as early as possible.
+ *
+ */
+#ifndef WEAVE_CONFIG_ENABLE_OFFLOAD_EVENTS_FIRST
+#define WEAVE_CONFIG_ENABLE_OFFLOAD_EVENTS_FIRST            0
+#endif // WEAVE_CONFIG_ENABLE_OFFLOAD_EVENTS_FIRST
+
+/**
  * @def WEAVE_NON_PRODUCTION_MARKER
  *
  * @brief Defines the name of a mark symbol whose presence signals that the Weave code
diff --git a/src/lib/profiles/data-management/Current/NotificationEngine.cpp b/src/lib/profiles/data-management/Current/NotificationEngine.cpp
index 509e692..edfdcdc 100644
--- a/src/lib/profiles/data-management/Current/NotificationEngine.cpp
+++ b/src/lib/profiles/data-management/Current/NotificationEngine.cpp
@@ -1421,6 +1421,18 @@
 
             // Ensure we're in the DataList element.  May allocate memory.
             err = aNotifyRequest.MoveToState(kNotifyRequestBuilder_BuildDataList);
+
+#if WEAVE_CONFIG_ENABLE_OFFLOAD_EVENTS_FIRST
+            // if we did not have enough space for data list at all,
+            // squash the error and exit immediately. This check is necessary here
+            // when we are loading from the datalist after having loaded the event
+            // list into the buffer already.
+            if ((err == WEAVE_ERROR_NO_MEMORY) || (err == WEAVE_ERROR_BUFFER_TOO_SMALL))
+            {
+                err = WEAVE_NO_ERROR;
+                ExitNow();
+            }
+#endif // WEAVE_CONFIG_ENABLE_OFFLOAD_EVENTS_FIRST
             SuccessOrExit(err);
 
             // Make a back-up of the writer so that we can rewind back if the next retrieval fails due to the packet getting full.
@@ -1550,6 +1562,20 @@
     // Fill in the DataList.  Allocation may take place
     subClean = true;
 
+#if WEAVE_CONFIG_ENABLE_OFFLOAD_EVENTS_FIRST
+
+#if WEAVE_CONFIG_EVENT_LOGGING_WDM_OFFLOAD
+    // Fill in the EventList.  Allocation may take place
+    err = BuildSingleNotifyRequestEventList(aSubHandler, notifyRequest, subClean, neWriteInProgress);
+    SuccessOrExit(err);
+#endif
+
+    aIsSubscriptionClean &= subClean;
+    subClean = true;
+
+    err = BuildSingleNotifyRequestDataList(aSubHandler, notifyRequest, subClean, neWriteInProgress);
+    SuccessOrExit(err);
+#else
     err = BuildSingleNotifyRequestDataList(aSubHandler, notifyRequest, subClean, neWriteInProgress);
     SuccessOrExit(err);
 
@@ -1561,6 +1587,7 @@
     err = BuildSingleNotifyRequestEventList(aSubHandler, notifyRequest, subClean, neWriteInProgress);
     SuccessOrExit(err);
 #endif
+#endif // WEAVE_CONFIG_ENABLE_OFFLOAD_EVENTS_FIRST
 
     aIsSubscriptionClean &= subClean;