diff --git a/src/app/clusters/basic/basic.cpp b/src/app/clusters/basic/basic.cpp index 88dcadf7de97a1..d01abf835f9df2 100644 --- a/src/app/clusters/basic/basic.cpp +++ b/src/app/clusters/basic/basic.cpp @@ -33,10 +33,98 @@ using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::Basic; +using namespace chip::app::Clusters::Basic::Attributes; using namespace chip::DeviceLayer; namespace { +class BasicAttrAccess : public AttributeAccessInterface +{ +public: + // Register for the Basic cluster on all endpoints. + BasicAttrAccess() : AttributeAccessInterface(Optional::Missing(), Basic::Id) {} + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override; + +private: + CHIP_ERROR ReadLocation(AttributeValueEncoder & aEncoder); + CHIP_ERROR WriteLocation(AttributeValueDecoder & aDecoder); +}; + +BasicAttrAccess gAttrAccess; + +CHIP_ERROR BasicAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + if (aPath.mClusterId != Basic::Id) + { + // We shouldn't have been called at all. + return CHIP_ERROR_INVALID_ARGUMENT; + } + + switch (aPath.mAttributeId) + { + case Location::Id: + return ReadLocation(aEncoder); + default: + break; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BasicAttrAccess::ReadLocation(AttributeValueEncoder & aEncoder) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + char location[DeviceLayer::ConfigurationManager::kMaxLocationLength + 1]; + size_t codeLen = 0; + + if (ConfigurationMgr().GetCountryCode(location, sizeof(location), codeLen) == CHIP_NO_ERROR) + { + if (codeLen == 0) + { + err = aEncoder.Encode(chip::CharSpan("XX", strlen("XX"))); + } + else + { + err = aEncoder.Encode(chip::CharSpan(location, strlen(location))); + } + } + else + { + err = aEncoder.Encode(chip::CharSpan("XX", strlen("XX"))); + } + + return err; +} + +CHIP_ERROR BasicAttrAccess::Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) +{ + VerifyOrDie(aPath.mClusterId == Basic::Id); + + switch (aPath.mAttributeId) + { + case Location::Id: + return WriteLocation(aDecoder); + default: + break; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BasicAttrAccess::WriteLocation(AttributeValueDecoder & aDecoder) +{ + chip::CharSpan location; + + ReturnErrorOnFailure(aDecoder.Decode(location)); + VerifyOrReturnError(location.size() <= DeviceLayer::ConfigurationManager::kMaxLocationLength, + CHIP_ERROR_INVALID_MESSAGE_LENGTH); + + return DeviceLayer::ConfigurationMgr().StoreCountryCode(location.data(), location.size()); +} + class PlatformMgrDelegate : public DeviceLayer::PlatformManagerDelegate { // Gets called by the current Node after completing a boot or reboot process.