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

Commit 14524ee

Browse files
authored
Merge pull request #487 from openweave/feature/fix_update_server
several changes on update server
2 parents 315d18a + 95b9739 commit 14524ee

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)