3939#include < SystemLayer/SystemStats.h>
4040
4141#ifndef WEAVE_WDM_ALIGNED_TYPE
42- #define WEAVE_WDM_ALIGNED_TYPE (address, type ) \
43- reinterpret_cast <type *> WEAVE_SYSTEM_ALIGN_SIZE ((size_t )(address), 4)
42+ #define WEAVE_WDM_ALIGNED_TYPE (address, type ) reinterpret_cast <type *> WEAVE_SYSTEM_ALIGN_SIZE ((size_t )(address), 4)
4443#endif
4544
4645namespace nl {
@@ -1561,6 +1560,36 @@ WEAVE_ERROR SubscriptionEngine::AllocateRightSizedBuffer(PacketBuffer *& buf, co
15611560 return err;
15621561}
15631562
1563+ /* *
1564+ * Initialize StatusDataHandleList
1565+ */
1566+ WEAVE_ERROR SubscriptionEngine::InitializeStatusDataHandleList (Weave::TLV::TLVReader & aReader,
1567+ StatusDataHandleElement * apStatusDataHandleList,
1568+ uint32_t & aNumDataElements, uint8_t * apBufEndAddr)
1569+ {
1570+ WEAVE_ERROR err = WEAVE_NO_ERROR;
1571+ Weave::TLV::TLVReader dataReader;
1572+ dataReader.Init (aReader);
1573+
1574+ for (aNumDataElements = 0 ; WEAVE_NO_ERROR == (err = dataReader.Next ()); aNumDataElements++)
1575+ {
1576+ // Check if apStatusDataHandleList[aNumDataElements] overflow the end of the buffer.
1577+ VerifyOrExit ((uint8_t *) (apStatusDataHandleList + aNumDataElements + 1 ) <= apBufEndAddr, err = WEAVE_ERROR_NO_MEMORY);
1578+ apStatusDataHandleList[aNumDataElements].mProfileId = Weave::Profiles::kWeaveProfile_Common ;
1579+ apStatusDataHandleList[aNumDataElements].mStatusCode = Weave::Profiles::Common::kStatus_InternalError ;
1580+ apStatusDataHandleList[aNumDataElements].mTraitDataHandle = 0 ;
1581+ }
1582+
1583+ // if we have exhausted this container
1584+ if (WEAVE_END_OF_TLV == err)
1585+ {
1586+ err = WEAVE_NO_ERROR;
1587+ }
1588+
1589+ exit:
1590+ return err;
1591+ }
1592+
15641593void SubscriptionEngine::ConstructStatusListVersionList (nl::Weave::TLV::TLVWriter & aWriter, void * apContext)
15651594{
15661595 WEAVE_ERROR err = WEAVE_NO_ERROR;
@@ -1631,8 +1660,8 @@ void SubscriptionEngine::ConstructStatusListVersionList(nl::Weave::TLV::TLVWrite
16311660 }
16321661}
16331662
1634- void SubscriptionEngine::BuildStatusDataHandleElement (PacketBuffer * pBuf, TraitDataHandle aTraitDataHandle, WEAVE_ERROR & err ,
1635- uint32_t aCurrentIndex)
1663+ void SubscriptionEngine::UpdateStatusDataHandleElement (StatusDataHandleElement * apStatusDataHandleList ,
1664+ TraitDataHandle aTraitDataHandle, WEAVE_ERROR & err, uint32_t aCurrentIndex)
16361665{
16371666 uint32_t profileId = 0 ;
16381667 uint16_t statusCode = 0 ;
@@ -1655,6 +1684,12 @@ void SubscriptionEngine::BuildStatusDataHandleElement(PacketBuffer * pBuf, Trait
16551684 statusCode = kStatus_VersionMismatch ;
16561685 err = WEAVE_NO_ERROR;
16571686 }
1687+ else if (WEAVE_ERROR_WRONG_TLV_TYPE == err || WEAVE_ERROR_TLV_TAG_NOT_FOUND == err)
1688+ {
1689+ profileId = Weave::Profiles::kWeaveProfile_WDM ;
1690+ statusCode = kStatus_InvalidTLVInUpdate ;
1691+ err = WEAVE_NO_ERROR;
1692+ }
16581693 else if (WEAVE_NO_ERROR == err)
16591694 {
16601695 profileId = Weave::Profiles::kWeaveProfile_Common ;
@@ -1664,13 +1699,11 @@ void SubscriptionEngine::BuildStatusDataHandleElement(PacketBuffer * pBuf, Trait
16641699 {
16651700 profileId = Weave::Profiles::kWeaveProfile_Common ;
16661701 statusCode = Weave::Profiles::Common::kStatus_InternalError ;
1667- WeaveLogError (DataManagement, " fail to process UpdateRequest with error %s at %s:%d" , nl::ErrorStr (err), __FILE__, __LINE__);
16681702 }
16691703
1670- StatusDataHandleElement * statusDataHandleList = WEAVE_WDM_ALIGNED_TYPE (pBuf->Start (), StatusDataHandleElement);
1671- statusDataHandleList[aCurrentIndex].mProfileId = profileId;
1672- statusDataHandleList[aCurrentIndex].mStatusCode = statusCode;
1673- statusDataHandleList[aCurrentIndex].mTraitDataHandle = aTraitDataHandle;
1704+ apStatusDataHandleList[aCurrentIndex].mProfileId = profileId;
1705+ apStatusDataHandleList[aCurrentIndex].mStatusCode = statusCode;
1706+ apStatusDataHandleList[aCurrentIndex].mTraitDataHandle = aTraitDataHandle;
16741707}
16751708
16761709/* *
@@ -1697,30 +1730,31 @@ bool SubscriptionEngine::IsStartingPath(StatusDataHandleElement * apStatusDataHa
16971730 * Update version for all traits according to temporary statusDataHandleList, and bump version once at starting path
16981731 * for each trait
16991732 */
1700- WEAVE_ERROR SubscriptionEngine::UpdateTraitVersions (PacketBuffer * apBuf, const TraitCatalogBase<TraitDataSource> * apCatalog ,
1701- uint32_t aNumDataElements)
1733+ WEAVE_ERROR SubscriptionEngine::UpdateTraitVersions (StatusDataHandleElement * apStatusDataHandleList ,
1734+ const TraitCatalogBase<TraitDataSource> * apCatalog, uint32_t aNumDataElements)
17021735{
17031736 WEAVE_ERROR err = WEAVE_NO_ERROR;
17041737 TraitDataSource * dataSource = NULL ;
17051738 TraitUpdatableDataSource * updatableSource = NULL ;
1706- StatusDataHandleElement * statusDataHandleList = WEAVE_WDM_ALIGNED_TYPE (apBuf->Start (), StatusDataHandleElement);
17071739
17081740 for (uint32_t index = 0 ; index < aNumDataElements; index++)
17091741 {
1710- if ((nl::Weave::Profiles::kWeaveProfile_Common == statusDataHandleList [index].mProfileId ) &&
1711- (nl::Weave::Profiles::Common::kStatus_Success == statusDataHandleList [index].mStatusCode ))
1742+ if ((nl::Weave::Profiles::kWeaveProfile_Common == apStatusDataHandleList [index].mProfileId ) &&
1743+ (nl::Weave::Profiles::Common::kStatus_Success == apStatusDataHandleList [index].mStatusCode ))
17121744 {
17131745
1714- err = apCatalog->Locate (statusDataHandleList [index].mTraitDataHandle , &dataSource);
1746+ err = apCatalog->Locate (apStatusDataHandleList [index].mTraitDataHandle , &dataSource);
17151747 SuccessOrExit (err);
17161748
17171749 updatableSource = static_cast <TraitUpdatableDataSource *>(dataSource);
17181750
1719- if (IsStartingPath (statusDataHandleList, statusDataHandleList [index].mTraitDataHandle , index))
1751+ if (IsStartingPath (apStatusDataHandleList, apStatusDataHandleList [index].mTraitDataHandle , index))
17201752 {
17211753 updatableSource->IncrementVersion ();
17221754 WeaveLogDetail (DataManagement, " <UpdateTraitVersions> [Trait %08x] bumped version: 0x%" PRIx64 " " ,
17231755 updatableSource->GetSchemaEngine ()->GetProfileId (), updatableSource->GetVersion ());
1756+
1757+ updatableSource->OnEvent (TraitUpdatableDataSource::kEventUpdateProcessingComplete , NULL );
17241758 }
17251759 else
17261760 {
@@ -1747,7 +1781,7 @@ WEAVE_ERROR SubscriptionEngine::SendFaultyUpdateResponse(Weave::ExchangeContext
17471781
17481782 p = msgBuf->Start ();
17491783 nl::Weave::Encoding::LittleEndian::Write32 (p, Weave::Profiles::kWeaveProfile_Common );
1750- nl::Weave::Encoding::LittleEndian::Write16 (p, Weave::Profiles::Common::kStatus_InternalError );
1784+ nl::Weave::Encoding::LittleEndian::Write16 (p, Weave::Profiles::Common::kStatus_BadRequest );
17511785 msgBuf->SetDataLength (statusReportLen);
17521786
17531787 err = apEC->SendMessage (Profiles::kWeaveProfile_Common , Profiles::Common::kMsgType_StatusReport , msgBuf);
@@ -1840,7 +1874,7 @@ WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequestDataElement(Weave::TLV::TLVR
18401874 const TraitCatalogBase<TraitDataSource> * apCatalog,
18411875 IUpdateRequestDataElementAccessControlDelegate & acDelegate,
18421876 bool aConditionalLoop, uint32_t aCurrentIndex, bool & aExistFailure,
1843- PacketBuffer * apBuf )
1877+ StatusDataHandleElement * apStatusDataHandleList )
18441878{
18451879 WEAVE_ERROR err = WEAVE_NO_ERROR;
18461880 Weave::TLV::TLVReader pathReader;
@@ -1879,9 +1913,10 @@ WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequestDataElement(Weave::TLV::TLVR
18791913 if (err == WEAVE_ERROR_TLV_TAG_NOT_FOUND)
18801914 {
18811915 WeaveLogDetail (DataManagement, " Ignoring un-mappable path!" );
1882- // no need to reset the value of err, it is set unconditionally below
1916+ err = WEAVE_NO_ERROR;
18831917 }
18841918#endif
1919+ SuccessOrExit (err);
18851920
18861921 traitPath.mTraitDataHandle = aHandle;
18871922 traitPath.mPropertyPathHandle = aPathHandle;
@@ -1936,7 +1971,7 @@ WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequestDataElement(Weave::TLV::TLVR
19361971
19371972 if (!needSkip)
19381973 {
1939- BuildStatusDataHandleElement (apBuf , aHandle, err, aCurrentIndex);
1974+ UpdateStatusDataHandleElement (apStatusDataHandleList , aHandle, err, aCurrentIndex);
19401975 }
19411976
19421977 return err;
@@ -1946,24 +1981,23 @@ WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequestDataElement(Weave::TLV::TLVR
19461981 * Loop through all data elements in list and process either conditional data elements or unconditional data elements in
19471982 * one loop, and build temporary statusDataHandleList. Later it would use this list to construct update response.
19481983 */
1949- WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequestDataList (Weave::TLV::TLVReader & aReader, PacketBuffer * apBuf,
1950- const TraitCatalogBase<TraitDataSource> * apCatalog,
1951- IUpdateRequestDataElementAccessControlDelegate & acDelegate,
1952- bool & aExistFailure, uint32_t & aNumDataElements,
1953- bool aConditionalLoop)
1984+ WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequestDataListWithConditionality (
1985+ Weave::TLV::TLVReader & aReader, StatusDataHandleElement * apStatusDataHandleList,
1986+ const TraitCatalogBase<TraitDataSource> * apCatalog, IUpdateRequestDataElementAccessControlDelegate & acDelegate,
1987+ bool & aExistFailure, bool aConditionalLoop)
19541988{
19551989 WEAVE_ERROR err = WEAVE_NO_ERROR;
19561990 Weave::TLV::TLVReader dataReader;
19571991 dataReader.Init (aReader);
19581992
1959- for (aNumDataElements = 0 ; WEAVE_NO_ERROR == (err = dataReader.Next ()); aNumDataElements ++)
1993+ for (uint32_t index = 0 ; WEAVE_NO_ERROR == (err = dataReader.Next ()); index ++)
19601994 {
19611995 TraitDataHandle handle;
19621996 PropertyPathHandle pathHandle;
19631997
19641998 // if it is running conditional loop, needs to skip unconditional elements, vice versa.
1965- err = ProcessUpdateRequestDataElement (dataReader, handle, pathHandle, apCatalog, acDelegate, aConditionalLoop,
1966- aNumDataElements, aExistFailure, apBuf );
1999+ err = ProcessUpdateRequestDataElement (dataReader, handle, pathHandle, apCatalog, acDelegate, aConditionalLoop, index,
2000+ aExistFailure, apStatusDataHandleList );
19672001 SuccessOrExit (err);
19682002 }
19692003
@@ -1977,6 +2011,32 @@ WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequestDataList(Weave::TLV::TLVRead
19772011 return err;
19782012}
19792013
2014+ /* *
2015+ * Process Data list in Update requests and update trait version for processed data elements
2016+ */
2017+ WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequestDataList (Weave::TLV::TLVReader & aReader,
2018+ StatusDataHandleElement * apStatusDataHandleList,
2019+ const TraitCatalogBase<TraitDataSource> * apCatalog,
2020+ IUpdateRequestDataElementAccessControlDelegate & acDelegate,
2021+ bool & aExistFailure, uint32_t aNumDataElements)
2022+ {
2023+ WEAVE_ERROR err = WEAVE_NO_ERROR;
2024+
2025+ // process conditional DEs
2026+ err =
2027+ ProcessUpdateRequestDataListWithConditionality (aReader, apStatusDataHandleList, apCatalog, acDelegate, aExistFailure, true );
2028+ SuccessOrExit (err);
2029+
2030+ // process unconditional DEs
2031+ err = ProcessUpdateRequestDataListWithConditionality (aReader, apStatusDataHandleList, apCatalog, acDelegate, aExistFailure,
2032+ false );
2033+ SuccessOrExit (err);
2034+
2035+ exit:
2036+ UpdateTraitVersions (apStatusDataHandleList, apCatalog, aNumDataElements);
2037+ return err;
2038+ }
2039+
19802040/* *
19812041 * Apply all conditional DEs first, then apply all unconditional DEs second, during loop, add status and dataHandle to
19822042 * temporary result list. Then update starting version for traits and generate update response.
@@ -1985,34 +2045,30 @@ WEAVE_ERROR SubscriptionEngine::ProcessUpdateRequest(Weave::ExchangeContext * ap
19852045 const TraitCatalogBase<TraitDataSource> * apCatalog,
19862046 IUpdateRequestDataElementAccessControlDelegate & acDelegate)
19872047{
1988- WEAVE_ERROR err = WEAVE_NO_ERROR;
1989- PacketBuffer * pBuf = NULL ;
1990- bool existFailure = false ;
1991- uint32_t numDataElements = 0 ;
1992- uint32_t maxPayloadSize = 0 ;
1993-
2048+ WEAVE_ERROR err = WEAVE_NO_ERROR;
2049+ PacketBuffer * pBuf = NULL ;
2050+ bool existFailure = false ;
2051+ uint32_t numDataElements = 0 ;
2052+ uint32_t maxPayloadSize = 0 ;
2053+ StatusDataHandleElement * statusDataHandleList = NULL ;
2054+ uint8_t * pBufEndAddr = NULL ;
19942055 VerifyOrExit (apCatalog != NULL , err = WEAVE_ERROR_INVALID_ARGUMENT);
19952056
19962057 err = AllocateRightSizedBuffer (pBuf, WDM_MAX_UPDATE_RESPONSE_SIZE, WDM_MIN_UPDATE_RESPONSE_SIZE, maxPayloadSize);
19972058 SuccessOrExit (err);
19982059
1999- // process conditional DEs
2000- err = ProcessUpdateRequestDataList (aReader, pBuf, apCatalog, acDelegate, existFailure, numDataElements, true );
2060+ statusDataHandleList = WEAVE_WDM_ALIGNED_TYPE (pBuf->Start (), StatusDataHandleElement);
2061+ pBufEndAddr = pBuf->Start () + maxPayloadSize;
2062+ err = InitializeStatusDataHandleList (aReader, statusDataHandleList, numDataElements, pBufEndAddr);
20012063 SuccessOrExit (err);
20022064
2003- // process unconditional DEs
2004- err = ProcessUpdateRequestDataList (aReader, pBuf, apCatalog, acDelegate, existFailure, numDataElements, false );
2005- SuccessOrExit (err);
2006-
2007- // update trait versions
2008- err = UpdateTraitVersions (pBuf, apCatalog, numDataElements);
2065+ err = ProcessUpdateRequestDataList (aReader, statusDataHandleList, apCatalog, acDelegate, existFailure, numDataElements);
20092066 SuccessOrExit (err);
20102067
20112068 err = SendUpdateResponse (apEC, numDataElements, apCatalog, pBuf, existFailure, maxPayloadSize);
20122069 pBuf = NULL ;
20132070
20142071exit:
2015-
20162072 if (pBuf != NULL )
20172073 {
20182074 PacketBuffer::Free (pBuf);
0 commit comments