From 10739278be6982d13b44d60bc9d302d25c43f969 Mon Sep 17 00:00:00 2001
From: Yufeng Wang <yufengwang@google.com>
Date: Tue, 4 Jan 2022 07:28:32 -0800
Subject: [PATCH] Fix TestGroupMessaging test failure (#12960)

---
 src/app/clusters/basic/basic.cpp | 88 ++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

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<EndpointId>::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.