Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 95b9739

Browse files
several changes on update server
-- Remove unsupported kEventChangeBegin and kEventChangeEnd -- Add kEventUpdateProcessingComplete, trigger it when updating trait version. -- Update status report using kStatus_BadRequest when update request is malformed. -- Add kStatus_InvalidValueInUpdate to represent data element value error in wdm profie. -- When processing update request, we need to skip this DE when DE generates WEAVE_ERROR_WRONG_TLV_TYPE and WEAVE_ERROR_TLV_TAG_NOT_FOUND. -- Rename BuildStatusDataHandleElement to UpdateStatusDataHandleElement -- Add InitializeStatusDataHandleList to initialize StatusDataHandleList with defaut incorrect state, whenenever the data element in list has been processed successfully, update StatusDataHandleList with sucess status. Once it hit fatal error, we end up the conditional and unconditional data list loop, and update trait version for successful DEs.
1 parent 9708816 commit 95b9739

File tree

4 files changed

+121
-63
lines changed

4 files changed

+121
-63
lines changed

src/lib/profiles/data-management/Current/MessageDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ enum
131131
kStatus_IncompatibleDataSchemaVersion = 0x2B,
132132
kStatus_MultipleFailures = 0x2C,
133133
kStatus_UpdateOutOfSequence = 0x2D,
134+
kStatus_InvalidTLVInUpdate = 0x2E,
134135
};
135136

136137
// TODO: The type is only used in a few places. We should use it everywhere.

src/lib/profiles/data-management/Current/SubscriptionEngine.cpp

Lines changed: 99 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@
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

4645
namespace 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+
15641593
void 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

20142071
exit:
2015-
20162072
if (pBuf != NULL)
20172073
{
20182074
PacketBuffer::Free(pBuf);

src/lib/profiles/data-management/Current/SubscriptionEngine.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -447,13 +447,16 @@ class SubscriptionEngine
447447

448448
static WEAVE_ERROR AllocateRightSizedBuffer(PacketBuffer *& buf, const uint32_t desiredSize, const uint32_t minSize,
449449
uint32_t & outMaxPayloadSize);
450+
static WEAVE_ERROR InitializeStatusDataHandleList(Weave::TLV::TLVReader & aReader,
451+
StatusDataHandleElement * apStatusDataHandleList, uint32_t & aNumDataElements,
452+
uint8_t * apBufEndAddr);
450453
static void ConstructStatusListVersionList(Weave::TLV::TLVWriter & aWriter, void * apContext);
451-
static void BuildStatusDataHandleElement(PacketBuffer * pBuf, TraitDataHandle aTraitDataHandle, WEAVE_ERROR & err,
452-
uint32_t aCurrentIndex);
454+
static void UpdateStatusDataHandleElement(StatusDataHandleElement * apStatusDataHandleList, TraitDataHandle aTraitDataHandle,
455+
WEAVE_ERROR & err, uint32_t aCurrentIndex);
453456
static bool IsStartingPath(StatusDataHandleElement * apStatusDataHandleList, TraitDataHandle aTraitDataHandle,
454457
uint32_t aCurrentIndex);
455-
static WEAVE_ERROR UpdateTraitVersions(PacketBuffer * apBuf, const TraitCatalogBase<TraitDataSource> * apCatalog,
456-
uint32_t aNumDataElements);
458+
static WEAVE_ERROR UpdateTraitVersions(StatusDataHandleElement * apStatusDataHandleList,
459+
const TraitCatalogBase<TraitDataSource> * apCatalog, uint32_t aNumDataElements);
457460
static WEAVE_ERROR SendFaultyUpdateResponse(Weave::ExchangeContext * apEC);
458461
static WEAVE_ERROR SendUpdateResponse(Weave::ExchangeContext * apEC, uint32_t aNumDataElements,
459462
const TraitCatalogBase<TraitDataSource> * apCatalog, PacketBuffer * apBuf,
@@ -463,12 +466,17 @@ class SubscriptionEngine
463466
const TraitCatalogBase<TraitDataSource> * apCatalog,
464467
IUpdateRequestDataElementAccessControlDelegate & acDelegate,
465468
bool aConditionalLoop, uint32_t aCurrentIndex, bool & aExistFailure,
466-
PacketBuffer * apBuf);
467-
static WEAVE_ERROR ProcessUpdateRequestDataList(Weave::TLV::TLVReader & aReader, PacketBuffer * apBuf,
469+
StatusDataHandleElement * apStatusDataHandleList);
470+
static WEAVE_ERROR ProcessUpdateRequestDataListWithConditionality(Weave::TLV::TLVReader & aReader,
471+
StatusDataHandleElement * apStatusDataHandleList,
472+
const TraitCatalogBase<TraitDataSource> * apCatalog,
473+
IUpdateRequestDataElementAccessControlDelegate & acDelegate,
474+
bool & aExistFailure, bool aConditionalLoop);
475+
static WEAVE_ERROR ProcessUpdateRequestDataList(Weave::TLV::TLVReader & aReader,
476+
StatusDataHandleElement * apStatusDataHandleList,
468477
const TraitCatalogBase<TraitDataSource> * apCatalog,
469478
IUpdateRequestDataElementAccessControlDelegate & acDelegate,
470-
bool & aExistFailure, uint32_t & aNumDataElements, bool aConditionalLoop);
471-
479+
bool & aExistFailure, uint32_t aNumDataElements);
472480
static WEAVE_ERROR ProcessUpdateRequest(Weave::ExchangeContext * apEC, Weave::TLV::TLVReader & aReader,
473481
const TraitCatalogBase<TraitDataSource> * apCatalog,
474482
IUpdateRequestDataElementAccessControlDelegate & acDelegate);

0 commit comments

Comments
 (0)