Skip to content

Commit

Permalink
[chip-tool] Get logging code to have a dedicated non-generated class …
Browse files Browse the repository at this point in the history
…that includes generated code (project-chip#13704)

* [chip-tool] Get logging code to have a dedicated non-generated class that includes generated code

* Update generated code
  • Loading branch information
vivien-apple authored Jan 26, 2022
1 parent 1154b85 commit e45f0a1
Show file tree
Hide file tree
Showing 11 changed files with 5,378 additions and 4,530 deletions.
1 change: 1 addition & 0 deletions examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static_library("chip-tool-utils") {
sources = [
"${chip_root}/src/app/tests/suites/include/ConstraintsChecker.h",
"${chip_root}/src/app/tests/suites/include/ValueChecker.h",
"${chip_root}/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp",
"commands/clusters/ModelCommand.cpp",
"commands/common/CHIPCommand.cpp",
"commands/common/CHIPCommand.h",
Expand Down
155 changes: 155 additions & 0 deletions examples/chip-tool/commands/clusters/DataModelLogger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2022 Project CHIP Authors
* 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.
*
*/

#pragma once

#include <string>

#include <app-common/zap-generated/cluster-objects.h>
#include <lib/support/BytesToHex.h>

class DataModelLogger
{
public:
static CHIP_ERROR LogValue(const char * label, size_t indent, bool value)
{
DataModelLogger::LogString(label, indent, value ? "TRUE" : "FALSE");
return CHIP_NO_ERROR;
}

static CHIP_ERROR LogValue(const char * label, size_t indent, chip::CharSpan value)
{
DataModelLogger::LogString(label, indent, std::string(value.data(), value.size()));
return CHIP_NO_ERROR;
}

static CHIP_ERROR LogValue(const char * label, size_t indent, chip::ByteSpan value)
{
char buffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
if (CHIP_NO_ERROR ==
chip::Encoding::BytesToUppercaseHexString(value.data(), value.size(), &buffer[0], CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE))
{
DataModelLogger::LogString(label, indent, buffer);
}
else
{
DataModelLogger::LogString(label, indent,
std::string("Elided value too large of size ") + std::to_string(value.size()));
}

return CHIP_NO_ERROR;
}

template <typename X,
typename std::enable_if_t<
std::is_integral<X>::value && !std::is_same<std::remove_cv_t<std::remove_reference_t<X>>, bool>::value, int> = 0>
static CHIP_ERROR LogValue(const char * label, size_t indent, X value)
{
DataModelLogger::LogString(label, indent, std::to_string(value));
return CHIP_NO_ERROR;
}

template <typename X, typename std::enable_if_t<std::is_floating_point<X>::value, int> = 0>
static CHIP_ERROR LogValue(const char * label, size_t indent, X value)
{
DataModelLogger::LogString(label, indent, std::to_string(value));
return CHIP_NO_ERROR;
}

template <typename X, typename std::enable_if_t<std::is_enum<X>::value, int> = 0>
static CHIP_ERROR LogValue(const char * label, size_t indent, X value)
{
DataModelLogger::LogValue(label, indent, chip::to_underlying(value));
return CHIP_NO_ERROR;
}

template <typename X>
static CHIP_ERROR LogValue(const char * label, size_t indent, chip::BitFlags<X> value)
{
DataModelLogger::LogValue(label, indent, value.Raw());
return CHIP_NO_ERROR;
}

template <typename T>
static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::DataModel::DecodableList<T> & value)
{
size_t count = 0;
CHIP_ERROR err = value.ComputeSize(&count);
if (err != CHIP_NO_ERROR)
{
return err;
}
DataModelLogger::LogString(label, indent, std::to_string(count) + " entries");

auto iter = value.begin();
size_t i = 0;
while (iter.Next())
{
++i;
std::string itemLabel = std::string("[") + std::to_string(i) + "]";
ReturnErrorOnFailure(DataModelLogger::LogValue(itemLabel.c_str(), indent + 1, iter.GetValue()));
}
if (iter.GetStatus() != CHIP_NO_ERROR)
{
DataModelLogger::LogString(indent + 1, "List truncated due to invalid value");
}
return iter.GetStatus();
}

template <typename T>
static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::DataModel::Nullable<T> & value)
{
if (value.IsNull())
{
DataModelLogger::LogString(label, indent, "null");
}
else
{
DataModelLogger::LogValue(label, indent, value.Value());
}

return CHIP_NO_ERROR;
}

template <typename T>
static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::Optional<T> & value)
{
if (value.HasValue())
{
DataModelLogger::LogValue(label, indent, value.Value());
}

return CHIP_NO_ERROR;
}

#include <zap-generated/cluster/logging/DataModelLogger.h>

private:
static void LogString(size_t indent, const std::string string) { LogString("", indent, string); }

static void LogString(const std::string label, size_t indent, const std::string string)
{
std::string indentation;
for (size_t i = 0; i < indent; ++i)
{
indentation.append(" ");
}

ChipLogProgress(chipTool, "%s%s%s %s", indentation.c_str(), label.c_str(), label.size() ? ":" : "", string.c_str());
}
};
184 changes: 7 additions & 177 deletions examples/chip-tool/templates/commands.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <app-common/zap-generated/cluster-objects.h>
#include <app/data-model/DecodableList.h>
#include <app/data-model/Nullable.h>
#include <commands/clusters/DataModelLogger.h>
#include <commands/clusters/ModelCommand.h>
#include <commands/common/CommandInvoker.h>
#include <lib/core/CHIPSafeCasts.h>
Expand All @@ -18,178 +19,6 @@
#include <zap-generated/CHIPClientCallbacks.h>
#include <zap-generated/CHIPClusters.h>

// Value logging functions. The non-generated ones depend on the
// generated ones, so are placed here.
namespace {

{{#zcl_structs}}
{{#if has_more_than_one_cluster}}
CHIP_ERROR LogValue(const char * label, size_t indent, {{zapTypeToDecodableClusterObjectType name ns="detail" isArgument=true}} value);
{{/if}}
{{/zcl_structs}}

{{#zcl_clusters}}
{{#zcl_structs}}
{{#unless has_more_than_one_cluster}}
CHIP_ERROR LogValue(const char * label, size_t indent, {{zapTypeToDecodableClusterObjectType name ns=parent.name isArgument=true}} value);
{{/unless}}
{{/zcl_structs}}
{{/zcl_clusters}}

{{#zcl_clusters}}
{{#zcl_events}}
{{#unless has_more_than_one_cluster}}
CHIP_ERROR LogValue(const char * label, size_t indent, chip::app::Clusters::{{asUpperCamelCase parent.name}}::Events::{{asUpperCamelCase name}}::DecodableType value);
{{/unless}}
{{/zcl_events}}
{{/zcl_clusters}}

#if CHIP_PROGRESS_LOGGING
std::string IndentStr(size_t indent)
{
std::string str;
for (size_t i = 0; i < indent; ++i) {
str.append(" ");
}
return str;
}
#endif // CHIP_PROGRESS_LOGGING

template <typename X, typename std::enable_if_t<std::is_integral<X>::value && !std::is_same<std::remove_cv_t<std::remove_reference_t<X>>, bool>::value, int> = 0>
CHIP_ERROR LogValue(const char * label, size_t indent, X value)
{
ChipLogProgress(chipTool, "%s%s: %s", IndentStr(indent).c_str(), label, std::to_string(value).c_str());
return CHIP_NO_ERROR;
}

template <typename X, typename std::enable_if_t<std::is_floating_point<X>::value, int> = 0>
CHIP_ERROR LogValue(const char * label, size_t indent, X value)
{
ChipLogProgress(chipTool, "%s%s: %s", IndentStr(indent).c_str(), label, std::to_string(value).c_str());
return CHIP_NO_ERROR;
}

CHIP_ERROR LogValue(const char * label, size_t indent, bool value)
{
ChipLogProgress(chipTool, "%s%s: %s", IndentStr(indent).c_str(), label, value ? "TRUE" : "FALSE");
return CHIP_NO_ERROR;
}

template <typename X, typename std::enable_if_t<std::is_enum<X>::value, int> = 0>
CHIP_ERROR LogValue(const char * label, size_t indent, X value)
{
return LogValue(label, indent, chip::to_underlying(value));
}


CHIP_ERROR LogValue(const char * label, size_t indent, chip::CharSpan value)
{
ChipLogProgress(chipTool, "%s%s: %.*s", IndentStr(indent).c_str(), label, static_cast<int>(value.size()), value.data());
return CHIP_NO_ERROR;
}

CHIP_ERROR LogValue(const char * label, size_t indent, chip::ByteSpan value)
{
char buffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
if (CHIP_NO_ERROR == chip::Encoding::BytesToUppercaseHexString(value.data(), value.size(), &buffer[0], CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE))
{
ChipLogProgress(chipTool, "%s%s: %s", IndentStr(indent).c_str(), label, buffer);
}
else
{
ChipLogProgress(chipTool, "%s%s: %zu", IndentStr(indent).c_str(), label, value.size());
}
return CHIP_NO_ERROR;
}

template <typename X>
CHIP_ERROR LogValue(const char * label, size_t indent, chip::BitFlags<X> value)
{
return LogValue(label, indent, value.Raw());
}

template <typename T>
CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::DataModel::DecodableList<T> & value)
{
size_t count = 0;
CHIP_ERROR err = value.ComputeSize(&count);
if (err != CHIP_NO_ERROR)
{
return err;
}
ChipLogProgress(chipTool, "%s%s: %zu entries", IndentStr(indent).c_str(), label, count);

auto iter = value.begin();
size_t i = 0;
while (iter.Next())
{
++i;
std::string itemLabel = std::string("[") + std::to_string(i) + "]";
ReturnErrorOnFailure(LogValue(itemLabel.c_str(), indent + 1, iter.GetValue()));
}
if (iter.GetStatus() != CHIP_NO_ERROR)
{
ChipLogProgress(chipTool, "%sList truncated due to invalid value", IndentStr(indent+1).c_str());
}
return iter.GetStatus();
}


template <typename T>
CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::DataModel::Nullable<T> & value)
{
if (!value.IsNull())
{
return LogValue(label, indent, value.Value());
}
ChipLogProgress(chipTool, "%s%s: null", IndentStr(indent).c_str(), label);
return CHIP_NO_ERROR;
}

template <typename T>
CHIP_ERROR LogValue(const char * label, size_t indent, const chip::Optional<T> & value)
{
if (value.HasValue())
{
return LogValue(label, indent, value.Value());
}

return CHIP_NO_ERROR;
}

// We output helpers for all structs here, including ones we might not actually
// be logging.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
{{#zcl_structs}}
{{#if has_more_than_one_cluster}}
{{> log_struct_value ns="detail"}}
{{/if}}
{{/zcl_structs}}

{{#zcl_clusters}}
{{#zcl_structs}}
{{#unless has_more_than_one_cluster}}
{{> log_struct_value ns=parent.name}}
{{/unless}}
{{/zcl_structs}}
{{/zcl_clusters}}
#pragma GCC diagnostic pop

// We output helpers for all events here, including ones we might not actually
// be logging.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
{{#zcl_clusters}}
{{#zcl_events}}
{{#unless has_more_than_one_cluster}}
{{> log_event_value ns=parent.name}}
{{/unless}}
{{/zcl_events}}
{{/zcl_clusters}}
#pragma GCC diagnostic pop
} // anonymous namespace

static void OnDefaultSuccessResponseWithoutExit(void * context)
{
ChipLogProgress(chipTool, "Default Success Response");
Expand Down Expand Up @@ -219,7 +48,7 @@ static void OnDefaultSuccess(void * context, const chip::app::DataModel::NullObj
template <typename T>
static void OnGeneralAttributeEventResponse(void * context, const char * label, T value)
{
CHIP_ERROR err = LogValue(label, 0, value);
CHIP_ERROR err = DataModelLogger::LogValue(label, 0, value);

auto * command = static_cast<ModelCommand *>(context);
command->SetCommandExitStatus(err);
Expand All @@ -232,8 +61,9 @@ static void On{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}Success(v
ChipLogProgress(Zcl, "Received {{asUpperCamelCase name}}:");
CHIP_ERROR err = CHIP_NO_ERROR;
{{#chip_cluster_response_arguments}}
if (err == CHIP_NO_ERROR) {
err = LogValue("{{asLowerCamelCase label}}", 1, data.{{asLowerCamelCase label}});
if (err == CHIP_NO_ERROR)
{
err = DataModelLogger::LogValue("{{asLowerCamelCase label}}", 1, data.{{asLowerCamelCase label}});
}
{{/chip_cluster_response_arguments}}

Expand Down Expand Up @@ -371,7 +201,7 @@ public:

static void OnValueReport(void * context, chip::app::Clusters::{{asUpperCamelCase parent.name}}::Events::{{asUpperCamelCase name}}::DecodableType value)
{
LogValue("{{asUpperCamelCase parent.name}}.{{asUpperCamelCase name}} report", 0, value);
DataModelLogger::LogValue("{{asUpperCamelCase parent.name}}.{{asUpperCamelCase name}} report", 0, value);
}

private:
Expand Down Expand Up @@ -493,7 +323,7 @@ public:

static void OnValueReport(void * context, {{zapTypeToDecodableClusterObjectType type ns=parent.name isArgument=true}} value)
{
LogValue("{{asUpperCamelCase parent.name}}.{{asUpperCamelCase name}} report", 0, value);
DataModelLogger::LogValue("{{asUpperCamelCase parent.name}}.{{asUpperCamelCase name}} report", 0, value);
}

private:
Expand Down
Loading

0 comments on commit e45f0a1

Please sign in to comment.