blob: 6b5c0234b28825a6a97ddc0964c88b5e925dea0c [file] [log] [blame]
/*
*
* Copyright (c) 2013-2017 Nest Labs, Inc.
* All rights reserved.
*
* 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.
*/
/**
* @file
* This file implements methods for the Nest Weave Status Report
* profile.
*/
#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveMessageLayer.h>
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Support/CodeUtils.h>
using namespace ::nl::Weave;
using namespace ::nl::Weave::TLV;
using namespace ::nl::Weave::Profiles;
using namespace ::nl::Weave::Profiles::Common;
using namespace ::nl::Weave::Profiles::StatusReporting;
StatusReport::StatusReport(void)
{
mProfileId = 0;
mStatusCode = 0;
mError = WEAVE_NO_ERROR;
}
StatusReport::~StatusReport(void)
{
mProfileId = 0;
mStatusCode = 0;
mError = WEAVE_NO_ERROR;
}
WEAVE_ERROR StatusReport::init(uint32_t aProfileId, uint16_t aCode, ReferencedTLVData *aInfo)
{
mProfileId = aProfileId;
mStatusCode = aCode;
mError = WEAVE_NO_ERROR;
if (aInfo)
mAdditionalInfo = *aInfo;
return WEAVE_NO_ERROR;
}
WEAVE_ERROR StatusReport::init(WEAVE_ERROR aError)
{
if (aError == WEAVE_NO_ERROR)
{
mProfileId = kWeaveProfile_Common;
mStatusCode = kStatus_Success;
}
else
{
mProfileId = kWeaveProfile_Common;
mStatusCode = kStatus_InternalError;
mError = aError;
}
return WEAVE_NO_ERROR;
}
WEAVE_ERROR StatusReport::pack(PacketBuffer *aBuffer)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
MessageIterator i(aBuffer);
TLVWriter writer;
i.append();
err = i.write32(mProfileId);
SuccessOrExit(err);
err = i.write16(mStatusCode);
SuccessOrExit(err);
/*
* the assumption here is that EITHER there's
* an error code that wants to be included as
* metadata OR there's additional info passed
* in at initialization time, which may include
* an error, OR there's none of the above, in
* which case the else clause her writes nothing
*/
if (mError != WEAVE_NO_ERROR)
{
writer.Init(aBuffer);
err = StartMetaData(writer);
SuccessOrExit(err);
err = AddErrorCode(writer, mError);
SuccessOrExit(err);
err = EndMetaData(writer);
SuccessOrExit(err);
/*
* this is a bit of a hack. we basically set this
* so that packedLength() below will return the right
* number at least if we call it AFTER the thing has
* been packed. it's not clear we ever use this.
*/
mAdditionalInfo.theLength = writer.GetLengthWritten();
}
else
{
err = mAdditionalInfo.pack(i);
}
exit:
return err;
}
inline uint16_t StatusReport::packedLength(void)
{
return sizeof(mProfileId)+sizeof(mStatusCode)+mAdditionalInfo.theLength;
}
WEAVE_ERROR StatusReport::parse(PacketBuffer *aBuffer, StatusReport &aDestination)
{
WEAVE_ERROR err;
MessageIterator i(aBuffer);
err = i.read32(&aDestination.mProfileId);
SuccessOrExit(err);
err = i.read16(&aDestination.mStatusCode);
SuccessOrExit(err);
err = ReferencedTLVData::parse(i, aDestination.mAdditionalInfo);
exit:
return err;
}
bool StatusReport::operator == (const StatusReport &another) const
{
return ((mProfileId == another.mProfileId) && (mStatusCode == another.mStatusCode));
}
/*
* the universal, gold standard for success is
* <Nest Labs> : <Common Profile> : <Success>
*/
bool StatusReport::success(void)
{
return(mProfileId == kWeaveProfile_Common && mStatusCode == kStatus_Success);
}
WEAVE_ERROR StatusReport::StartMetaData(nl::Weave::TLV::TLVWriter &aWriter)
{
TLVType metaDataContainer;
return aWriter.StartContainer(AnonymousTag, kTLVType_Structure, metaDataContainer);
}
WEAVE_ERROR StatusReport::EndMetaData(nl::Weave::TLV::TLVWriter &aWriter)
{
WEAVE_ERROR err;
TLVType metaDataContainer = kTLVType_Structure;
err = aWriter.EndContainer(metaDataContainer);
SuccessOrExit(err);
err = aWriter.Finalize();
exit:
return err;
}
WEAVE_ERROR StatusReport::AddErrorCode(nl::Weave::TLV::TLVWriter &aWriter, WEAVE_ERROR aError)
{
return aWriter.Put(CommonTag(kTag_SystemErrorCode), aError);
}