Skip to content

Commit

Permalink
[app] Allow to define external clusters in chip_data_model.* (#27886)
Browse files Browse the repository at this point in the history
zap_cluster_list.py raises an error when the ZAP file
enables a cluster that is not implemented in the SDK. This
forces users to patch the SDK in order to use custom,
vendor-specific clusters.

Add EXTERNAL_CLUSTERS argument to chip_configure_data_model()
CMake function that takes a list of external cluster names
for which the default implementation should not included nor
required.

Usage example:
chip_configure_data_model(app
    INCLUDE_SERVER
    ZAP_FILE lock-app.zap
    EXTERNAL_CLUSTERS BASIC_INFORMATION_CLUSTER MY_CUSTOM_CLUSTER
)

Replace the existing zap_clusters_with_custom_implementation
argument of chip_data_model() GN template with new one:
external_clusters. The previous argument took a list of
cluster implementation directories to be skipped, so it was
only useful for bypassing the default implementations, but
could not be used for custom, vendor-specific clusters.
The new argument addresses both scenarios.

Usage example:
chip_data_model("lock-common") {
  zap_file = "lock-app.zap"
  ...
  external_clusters = [
    "BASIC_INFORMATION_CLUSTER",
    "MY_CUSTOM_CLUSTER",
  ]
}
  • Loading branch information
Damian-Nordic authored and pull[bot] committed Jul 22, 2023
1 parent 9fd5e43 commit 74ee23c
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 37 deletions.
30 changes: 19 additions & 11 deletions src/app/chip_data_model.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,16 @@ endfunction()
#
# Configure ${APP_TARGET} with source files associated with clusters enabled in the ${ZAP_FILE}
#
function(chip_configure_zap_file APP_TARGET ZAP_FILE)
function(chip_configure_zap_file APP_TARGET ZAP_FILE EXTERNAL_CLUSTERS)
find_package(Python3 REQUIRED)
set(args --zap_file ${ZAP_FILE})

if (EXTERNAL_CLUSTERS)
list(APPEND args --external-clusters ${EXTERNAL_CLUSTERS})
endif()

execute_process(
COMMAND ${Python3_EXECUTABLE} ${CHIP_APP_BASE_DIR}/zap_cluster_list.py --zap_file ${ZAP_FILE}
COMMAND ${Python3_EXECUTABLE} ${CHIP_APP_BASE_DIR}/zap_cluster_list.py ${args}
OUTPUT_VARIABLE CLUSTER_LIST
ERROR_VARIABLE ERROR_MESSAGE
RESULT_VARIABLE RC
Expand All @@ -57,17 +62,20 @@ endfunction()
#
# Configure ${APP_TARGET} based on the selected data model configuration.
# Available options are:
# SCOPE Cmake scope keyword that defines the scope of included sources
# The default is PRIVATE scope.
# INCLUDE_SERVER Include source files from src/app/server directory
# ZAP_FILE Path to the ZAP file, used to determine the list of clusters
# supported by the application.
# IDL .matter IDL file to use for codegen. Inferred from ZAP_FILE
# if not provided
# SCOPE CMake scope keyword that defines the scope of included sources.
# The default is PRIVATE scope.
# INCLUDE_SERVER Include source files from src/app/server directory.
# ZAP_FILE Path to the ZAP file, used to determine the list of clusters
# supported by the application.
# IDL .matter IDL file to use for codegen. Inferred from ZAP_FILE
# if not provided
# EXTERNAL_CLUSTERS Clusters with external implementations. The default implementations
# will not be used nor required for these clusters.
# Format: MY_CUSTOM_CLUSTER'.
#
function(chip_configure_data_model APP_TARGET)
set(SCOPE PRIVATE)
cmake_parse_arguments(ARG "INCLUDE_SERVER" "SCOPE" "ZAP_FILE;IDL" "" ${ARGN})
cmake_parse_arguments(ARG "INCLUDE_SERVER" "SCOPE;ZAP_FILE;IDL" "EXTERNAL_CLUSTERS" ${ARGN})

if (ARG_SCOPE)
set(SCOPE ${ARG_SCOPE})
Expand All @@ -90,7 +98,7 @@ function(chip_configure_data_model APP_TARGET)
endif()

if (ARG_ZAP_FILE)
chip_configure_zap_file(${APP_TARGET} ${ARG_ZAP_FILE})
chip_configure_zap_file(${APP_TARGET} ${ARG_ZAP_FILE} "${ARG_EXTERNAL_CLUSTERS}")
if (NOT ARG_IDL)
string(REPLACE ".zap" ".matter" ARG_IDL ${ARG_ZAP_FILE})
endif()
Expand Down
34 changes: 11 additions & 23 deletions src/app/chip_data_model.gni
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ template("chip_data_model") {
"*",
[
"zap_pregenerated_dir",
"zap_clusters_with_custom_implementation",
"zap_file",
"is_server",
"external_clusters",
])

if (!defined(sources)) {
Expand Down Expand Up @@ -183,34 +183,22 @@ template("chip_data_model") {

if (defined(invoker.zap_file)) {
_zap_file = rebase_path(invoker.zap_file, root_build_dir)
_script_args = [
"--zap_file",
_zap_file,
]
if (defined(invoker.external_clusters)) {
_script_args += [ "--external-clusters" ]
_script_args += invoker.external_clusters
}
_cluster_sources = exec_script("${_app_root}/zap_cluster_list.py",
[ "--zap_file=" + _zap_file ],
_script_args,
"list lines",
[ invoker.zap_file ])
}

_custom_impl_clusters = []
if (defined(invoker.zap_clusters_with_custom_implementation)) {
_custom_impl_clusters = invoker.zap_clusters_with_custom_implementation
}

if (_cluster_sources == []) {
# The variable is only used within the nested foreach-loop and will be
# unused before it goes out of scope when the outter-loop is not entered.
not_needed([ "_custom_impl_clusters" ])
}

foreach(cluster, _cluster_sources) {
_custom_impl = false
foreach(ci, _custom_impl_clusters) {
if (cluster == ci) {
_custom_impl = true
}
}

if (_custom_impl) {
# do not include any sources, we have a custom implementation for this cluster
} else if (cluster == "door-lock-server") {
if (cluster == "door-lock-server") {
sources += [
"${_app_root}/clusters/${cluster}/door-lock-server-callback.cpp",
"${_app_root}/clusters/${cluster}/door-lock-server.cpp",
Expand Down
1 change: 0 additions & 1 deletion src/app/zap_cluster_list.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@
"WATER_TANK_MONITORING_CLUSTER": [],
"WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"],
"WINDOW_COVERING_CLUSTER": ["window-covering-server"],
"TEMPERATURE_CONTROL_CLUSTER": ["temperature-control-server"],
"ZEOLITE_FILTER_MONITORING_CLUSTER": [],
"ZLL_COMMISSIONING_CLUSTER": []
}
Expand Down
15 changes: 13 additions & 2 deletions src/app/zap_cluster_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ def get_cluster_sources(clusters: typing.Set[str],
return cluster_sources


def dump_zapfile_clusters(zap_file_path: pathlib.Path, implementation_data_path: pathlib.Path):
def dump_zapfile_clusters(zap_file_path: pathlib.Path,
implementation_data_path: pathlib.Path,
external_clusters: typing.List[str]):
"""Prints all of the source directories to build for a given ZAP file.
Arguments:
Expand All @@ -56,6 +58,8 @@ def dump_zapfile_clusters(zap_file_path: pathlib.Path, implementation_data_path:

for endpoint_type in zap_json.get('endpointTypes'):
for cluster in endpoint_type.get('clusters'):
if cluster.get('define') in external_clusters:
continue
side: str = cluster.get('side')
if side == 'client':
clusters_set = client_clusters
Expand Down Expand Up @@ -90,10 +94,17 @@ def main():
required=False,
type=pathlib.Path,
default=os.path.join(os.path.dirname(__file__), "zap_cluster_list.json"))
parser.add_argument('--external-clusters',
help='Clusters with external implementations. ' +
'The default implementations will not be used nor required for these clusters. ' +
'Format: MY_CUSTOM_CLUSTER',
nargs='+',
metavar='EXTERNAL_CLUSTER',
default=[])

args = parser.parse_args()

dump_zapfile_clusters(args.zap_file, args.cluster_implementation_data)
dump_zapfile_clusters(args.zap_file, args.cluster_implementation_data, args.external_clusters)

sys.exit(0)

Expand Down

0 comments on commit 74ee23c

Please sign in to comment.