Failedto customize Cluster as per document

Hello, Nordic Team!

I followed this document and used the XML file mentioned in the document. custom_clusters


I did regenerate the files under the zap-generated folder, but the ExtendedCommandResponse in MyCluster.xml was not generated, which caused the compilation error.

Here are my steps:

1. Copy the Mycluster.xml file from the document and place it under src/default_zap in project directory.

2. Copy the file `ncs/v3.0.0-rc1/modules/lib/matter/src/app/zap-templates/zcl/zcl.json` to the `src/default_zap` directory in project.

3. west zap-append -o src/default_zap/zcl.json src/default_zap/MyCluster.xml

4. west zap-gui -j src/default_zap/zcl.json --clusters src/default_zap/MyCluster.xml

5. west zap-generate --full

I didn't modify any code.

ncs 3.0.0, nrf54l15dk

Best regards,


Wang Xiongwei

Parents
  • Hi,

    If ExtendedCommandResponse is not generated, it is most likely missing from the XML file. I see that the example XML in the documentation is missing this.

    Here is an example of how to implement it:

    <command source="server" code="0x01" name="ExtendedCommandResponse" optional="false" disableDefaultResponse="true">
       <description>Response to ExtendedCommand.</description>
       <arg name="arg1" type="int8u"/>
    </command>

    And this is what the complete MyCluster.xml will look like with this included:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <configurator>
       <cluster>
          <domain>General</domain>
          <name>MyNewCluster</name>
          <code>0xFFF1FC01</code>
          <define>MY_NEW_CLUSTER</define>
          <description>The MyNewCluster cluster showcases a cluster manufacturer extensions</description>
          <attribute side="server" code="0xFFF10000" define="MY_ATTRIBUTE" type="boolean" writable="true" default="false" optional="false">MyAttribute</attribute>
          <command source="client" code="0xFFF10000" name="MyCommand" optional="false">
             <description>Command that takes two uint8 arguments and returns their sum.</description>
             <arg name="arg1" type="int8u"/>
             <arg name="arg2" type="int8u"/>
          </command>
          <event side="server" code="0xFFF10000" name="MyEvent" priority="info" optional="false">
             <description>Event that is generated by the server.</description>
             <arg name="arg1" type="int8u"/>
          </event>
       </cluster>
       <clusterExtension code="0x0028">
          <attribute side="server" code="0x17" define="EXTENDED_ATTRIBUTE" type="boolean" writable="true" default="false" optional="false">ExtendedAttribute</attribute>
          <command source="client" code="0x00" name="ExtendedCommand" response="ExtendedCommandResponse" optional="false">
             <description>Command that takes two uint8 arguments and returns their sum.</description>
             <arg name="arg1" type="int8u"/>
             <arg name="arg2" type="int8u"/>
          </command>
          <command source="server" code="0x01" name="ExtendedCommandResponse" optional="false" disableDefaultResponse="true">
             <description>Response to ExtendedCommand.</description>
             <arg name="arg1" type="int8u"/>
          </command>
          <event side="server" code="0x04" name="ExtendedEvent" priority="info" optional="false">
             <description>Event that is generated by the server.</description>
             <arg name="arg1" type="int8u"/>
          </event>
       </clusterExtension>
       <enum name="MyNewEnum" type="int8u">
          <cluster code="0xFFF1FC01" />
          <item name="EnumValue1" value="0" />
          <item name="EnumValue2" value="1" />
       </enum>
       <struct name="MyStruct" isFabricScoped="true">
          <cluster code="0xFFF1FC01"/>
          <item fieldId="1" name="Data" type="octet_string" length="128" isFabricSensitive="true"/>
       </struct>
       <deviceType>
          <name>my-new-device</name>
          <domain>CHIP</domain>
          <typeName>My new device</typeName>
          <profileId editable="false">0x0104</profileId>
          <deviceId editable="false">0xfff10001</deviceId>
          <class>Simple</class>
          <scope>Endpoint</scope>
          <clusters lockOthers="true">
             <include cluster="MyNewCluster" client="true" server="true" clientLocked="false" serverLocked="false"/>
          </clusters>
       </deviceType>
    </configurator>

    I will notify the developers that ExtendedCommandResponse is missing from the example file.

    Best regards,
    Marte

  • Thank you, Marte. Additionally, I need to point out that the tutorial I mentioned earlier doesn't seem to provide complete steps. Compilation results in some errors, which are easy to fix, but if Nordic could provide explanations in the documentation, it would greatly help developers. Regardless, thank you.

  • Hi,

    Thank you for the feedback. I have forwarded it internally.

    You say that you fixed these issues on your side, but since this is a public ticket, I will provide instructions on how to fix them in case anyone else finds this ticket.

    I assume the errors you got were due to missing implementations of functions for the custom cluster and the Basic Cluster Extended Command generated by the ZAP tool. At least when I tested, I saw undefined references to these functions.

    To fix this, create the file zcl_callbacks.cpp in the src directory (if one does not already exist) and add the following:

    /*
     * Copyright (c) 2025 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
     #include <lib/support/logging/CHIPLogging.h>
    
    #include "app_task.h"
    #include "board/board.h"
    
    #include <zap-generated/PluginApplicationCallbacks.h>
    #include <app-common/zap-generated/callback.h>
    #include <app-common/zap-generated/attributes/Accessors.h>
    #include <app/ConcreteAttributePath.h>
    
    using namespace ::chip;
    using namespace ::chip::app;
    using namespace ::chip::app::Clusters;
    using namespace ::chip::app::Clusters::MyNewCluster::Commands;
    using namespace ::chip::app::Clusters::BasicInformation::Commands;
    
    
    bool emberAfMyNewClusterClusterMyCommandCallback(CommandHandler *commandObj,
    						     const ConcreteCommandPath &commandPath,
    						     const MyCommand::DecodableType &commandData)
    {
    	/* Intentionally empty */
    	return true;
    }
    
    
    void MatterMyNewClusterPluginServerInitCallback()
    {
    	/* Intentionally empty */
    }
    
    /** @brief MyNewCluster Cluster Init
     *
     * This function is called when a specific cluster is initialized. It gives the
     * application an opportunity to take care of cluster initialization procedures.
     * It is called exactly once for each endpoint where cluster is present.
     *
     * @param endpoint   Ver.: always
     *
     */
    void emberAfMyNewClusterClusterInitCallback(EndpointId endpoint)
    {
        /* Intentionally empty */
    }
    
    
    bool emberAfBasicInformationClusterExtendedCommandCallback(CommandHandler *commandObj,
                                 const ConcreteCommandPath &commandPath,
                                 const ExtendedCommand::DecodableType & /* unused */)
    {
        /* Intentionally empty */
        return true;
    }
    

    Make sure also to add this file to target_sources in CMakeLists.txt:

    target_sources(app PRIVATE
        src/app_task.cpp
        src/zcl_callbacks.cpp
        src/main.cpp
    )

    Please note that I have left the functions empty, so this only fixes the build issue. To implement these functions, I recommend looking at other Matter samples, such as the manufacturer-specific sample.

    Best regards,
    Marte

Reply
  • Hi,

    Thank you for the feedback. I have forwarded it internally.

    You say that you fixed these issues on your side, but since this is a public ticket, I will provide instructions on how to fix them in case anyone else finds this ticket.

    I assume the errors you got were due to missing implementations of functions for the custom cluster and the Basic Cluster Extended Command generated by the ZAP tool. At least when I tested, I saw undefined references to these functions.

    To fix this, create the file zcl_callbacks.cpp in the src directory (if one does not already exist) and add the following:

    /*
     * Copyright (c) 2025 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
     #include <lib/support/logging/CHIPLogging.h>
    
    #include "app_task.h"
    #include "board/board.h"
    
    #include <zap-generated/PluginApplicationCallbacks.h>
    #include <app-common/zap-generated/callback.h>
    #include <app-common/zap-generated/attributes/Accessors.h>
    #include <app/ConcreteAttributePath.h>
    
    using namespace ::chip;
    using namespace ::chip::app;
    using namespace ::chip::app::Clusters;
    using namespace ::chip::app::Clusters::MyNewCluster::Commands;
    using namespace ::chip::app::Clusters::BasicInformation::Commands;
    
    
    bool emberAfMyNewClusterClusterMyCommandCallback(CommandHandler *commandObj,
    						     const ConcreteCommandPath &commandPath,
    						     const MyCommand::DecodableType &commandData)
    {
    	/* Intentionally empty */
    	return true;
    }
    
    
    void MatterMyNewClusterPluginServerInitCallback()
    {
    	/* Intentionally empty */
    }
    
    /** @brief MyNewCluster Cluster Init
     *
     * This function is called when a specific cluster is initialized. It gives the
     * application an opportunity to take care of cluster initialization procedures.
     * It is called exactly once for each endpoint where cluster is present.
     *
     * @param endpoint   Ver.: always
     *
     */
    void emberAfMyNewClusterClusterInitCallback(EndpointId endpoint)
    {
        /* Intentionally empty */
    }
    
    
    bool emberAfBasicInformationClusterExtendedCommandCallback(CommandHandler *commandObj,
                                 const ConcreteCommandPath &commandPath,
                                 const ExtendedCommand::DecodableType & /* unused */)
    {
        /* Intentionally empty */
        return true;
    }
    

    Make sure also to add this file to target_sources in CMakeLists.txt:

    target_sources(app PRIVATE
        src/app_task.cpp
        src/zcl_callbacks.cpp
        src/main.cpp
    )

    Please note that I have left the functions empty, so this only fixes the build issue. To implement these functions, I recommend looking at other Matter samples, such as the manufacturer-specific sample.

    Best regards,
    Marte

Children
No Data
Related