From 7abbcfe6344df1a2e0b3f96d48fbd39754ed6fdf Mon Sep 17 00:00:00 2001 From: rgoliver Date: Fri, 1 Apr 2022 18:04:35 -0400 Subject: [PATCH] TRACE: Add transport tracing to linux example apps (#16893) * TRACE: Add transport tracing to linux example apps - Add tracing to the linux example platform for linux apps. - Separate message tracing from pigweed trace, to support handling the trace messages without enabling full pigweed tracing. - Enable just the transport trace by default for linux. * Fix trace failure on standalone ack * Restyled by clang-format Co-authored-by: Tennessee Carmel-Veilleux Co-authored-by: Restyled.io --- examples/chip-tool/args.gni | 1 - examples/chip-tool/with_pw_trace.gni | 28 ----- examples/common/tracing/BUILD.gn | 8 +- examples/common/tracing/TraceHandlers.cpp | 109 ++++++++++-------- examples/platform/linux/AppMain.cpp | 46 +++++++- examples/platform/linux/BUILD.gn | 5 + examples/platform/linux/Options.cpp | 25 ++++ examples/platform/linux/Options.h | 3 + .../platform/linux/pw_trace_chip/BUILD.gn | 38 ------ .../public/pw_trace_chip/trace_chip.h | 92 --------------- .../pw_trace_backend/trace_backend.h | 20 ---- .../platform/linux/pw_trace_chip/trace.cc | 71 ------------ src/lib/core/BUILD.gn | 1 + src/lib/core/core.gni | 7 +- src/transport/BUILD.gn | 5 +- src/transport/TraceMessage.cpp | 47 ++++++++ src/transport/TraceMessage.h | 50 ++++++-- 17 files changed, 233 insertions(+), 323 deletions(-) delete mode 100644 examples/chip-tool/with_pw_trace.gni delete mode 100644 examples/platform/linux/pw_trace_chip/BUILD.gn delete mode 100644 examples/platform/linux/pw_trace_chip/public/pw_trace_chip/trace_chip.h delete mode 100644 examples/platform/linux/pw_trace_chip/public_overrides/pw_trace_backend/trace_backend.h delete mode 100644 examples/platform/linux/pw_trace_chip/trace.cc create mode 100644 src/transport/TraceMessage.cpp diff --git a/examples/chip-tool/args.gni b/examples/chip-tool/args.gni index 32852e06139527..a76f3e8996ce3c 100644 --- a/examples/chip-tool/args.gni +++ b/examples/chip-tool/args.gni @@ -15,7 +15,6 @@ import("//build_overrides/chip.gni") import("${chip_root}/config/standalone/args.gni") -import("${chip_root}/examples/chip-tool/with_pw_trace.gni") chip_device_project_config_include = "" chip_project_config_include = "" diff --git a/examples/chip-tool/with_pw_trace.gni b/examples/chip-tool/with_pw_trace.gni deleted file mode 100644 index e43329163aaa7a..00000000000000 --- a/examples/chip-tool/with_pw_trace.gni +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# 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. - -# add this gni as import in your build args to use pigweed in the example -# 'import("//with_pw_rpc.gni")' - -import("//build_overrides/chip.gni") - -import("${chip_root}/config/standalone/args.gni") - -import("//build_overrides/pigweed.gni") - -cpp_standard = "gnu++17" - -pw_trace_BACKEND = "${chip_root}/examples/platform/linux/pw_trace_chip" - -chip_enable_transport_trace = true diff --git a/examples/common/tracing/BUILD.gn b/examples/common/tracing/BUILD.gn index c05f8695c95251..0ec67ae4e07a5e 100644 --- a/examples/common/tracing/BUILD.gn +++ b/examples/common/tracing/BUILD.gn @@ -12,11 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build_overrides/pigweed.gni") - import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("$dir_pw_build/target_types.gni") import("${chip_root}/src/lib/lib.gni") config("default_config") { @@ -26,10 +23,7 @@ config("default_config") { source_set("trace_handlers") { sources = [ "TraceHandlers.cpp" ] - deps = [ - "$dir_pw_trace", - "${chip_root}/src/lib", - ] + deps = [ "${chip_root}/src/lib" ] public_configs = [ ":default_config" ] } diff --git a/examples/common/tracing/TraceHandlers.cpp b/examples/common/tracing/TraceHandlers.cpp index d0c54d07c7c7a1..96be5808c65c54 100644 --- a/examples/common/tracing/TraceHandlers.cpp +++ b/examples/common/tracing/TraceHandlers.cpp @@ -20,9 +20,8 @@ #include #include #include +#include -#include "pw_trace/trace.h" -#include "pw_trace_chip/trace_chip.h" #include "transport/TraceMessage.h" #include #include @@ -82,8 +81,14 @@ class TraceOutput } } + bool HasStreamAvailable() const + { + std::lock_guard guard(mLock); + return (mStream != nullptr); + } + private: - std::mutex mLock; + mutable std::mutex mLock; TraceStream * mStream = nullptr; }; @@ -130,15 +135,25 @@ std::string AsJsonBool(bool isTrue) std::string AsJsonHexString(const uint8_t * buf, size_t bufLen) { - // Fill a string long enough for the hex conversion, that will be overwritten - std::string hexBuf(2 * bufLen, '0'); + // Avoid hex conversion that would fail on empty + if (bufLen == 0) + { + return AsJsonString(""); + } + + // Fill a buffer long enough for the hex conversion, that will be overwritten + std::vector hexBuf(2 * bufLen, '\0'); CHIP_ERROR status = Encoding::BytesToLowercaseHexBuffer(buf, bufLen, hexBuf.data(), hexBuf.size()); // Static conditions exist that should ensure never failing. Catch failure in an assert. - VerifyOrDie(status == CHIP_NO_ERROR); + if (status != CHIP_NO_ERROR) + { + ChipLogError(Support, "Unexpected failure: %" CHIP_ERROR_FORMAT, status.Format()); + VerifyOrDie(status == CHIP_NO_ERROR); + } - return AsJsonString(hexBuf); + return AsJsonString(std::string(hexBuf.data(), hexBuf.size())); } std::string PacketHeaderToJson(const PacketHeader * packetHeader) @@ -230,17 +245,15 @@ std::string PreparedSecureMessageDataToJson(const TracePreparedSecureMessageData return jsonBody; } -bool SecureMessageSentHandler(const TraceEventFields & eventFields, void * context) +void SecureMessageSentHandler(const TraceSecureMessageSentData * eventData) { - TraceHandlerContext * ourContext = reinterpret_cast(context); - if ((std::string{ eventFields.dataFormat } != kTraceMessageSentDataFormat) || - (eventFields.dataSize != sizeof(TraceSecureMessageSentData))) + TraceOutput * sink = gTraceHandlerContext.sink; + if (!sink->HasStreamAvailable()) { - return false; + return; } - const auto * eventData = reinterpret_cast(eventFields.dataBuffer); - std::string jsonBody = "{"; + std::string jsonBody = "{"; jsonBody += PacketHeaderToJson(eventData->packetHeader); jsonBody += ", "; jsonBody += PayloadHeaderToJson(eventData->payloadHeader); @@ -250,25 +263,19 @@ bool SecureMessageSentHandler(const TraceEventFields & eventFields, void * conte jsonBody += AsFirstJsonKey("payload_hex", AsJsonHexString(eventData->packetPayload, eventData->packetSize)); jsonBody += "}"; - TraceOutput * sink = ourContext->sink; sink->StartEvent(std::string{ kTraceMessageEvent } + "." + kTraceMessageSentDataFormat); sink->AddField("json", jsonBody); sink->FinishEvent(); - - return true; } -bool SecureMessageReceivedHandler(const TraceEventFields & eventFields, void * context) +void SecureMessageReceivedHandler(const TraceSecureMessageReceivedData * eventData) { - TraceHandlerContext * ourContext = reinterpret_cast(context); - if ((std::string{ eventFields.dataFormat } != kTraceMessageReceivedDataFormat) || - (eventFields.dataSize != sizeof(TraceSecureMessageReceivedData))) + TraceOutput * sink = gTraceHandlerContext.sink; + if (!sink->HasStreamAvailable()) { - return false; + return; } - const auto * eventData = reinterpret_cast(eventFields.dataBuffer); - std::string jsonBody = "{"; jsonBody += AsFirstJsonKey("peer_address", AsJsonString(eventData->peerAddress)); jsonBody += ", "; @@ -281,50 +288,57 @@ bool SecureMessageReceivedHandler(const TraceEventFields & eventFields, void * c jsonBody += AsFirstJsonKey("payload_hex", AsJsonHexString(eventData->packetPayload, eventData->packetSize)); jsonBody += "}"; - TraceOutput * sink = ourContext->sink; sink->StartEvent(std::string{ kTraceMessageEvent } + "." + kTraceMessageReceivedDataFormat); sink->AddField("json", jsonBody); sink->FinishEvent(); // Note that `eventData->session` is currently ignored. - - return true; } -bool PreparedMessageSentHandler(const TraceEventFields & eventFields, void * context) +void PreparedMessageSentHandler(const TracePreparedSecureMessageData * eventData) { - TraceHandlerContext * ourContext = reinterpret_cast(context); - if ((std::string{ eventFields.dataFormat } != kTracePreparedMessageSentDataFormat) || - (eventFields.dataSize != sizeof(TracePreparedSecureMessageData))) + TraceOutput * sink = gTraceHandlerContext.sink; + if (!sink->HasStreamAvailable()) { - return false; + return; } - const auto * eventData = reinterpret_cast(eventFields.dataBuffer); - TraceOutput * sink = ourContext->sink; sink->StartEvent(std::string{ kTraceMessageEvent } + "." + kTracePreparedMessageSentDataFormat); sink->AddField("json", PreparedSecureMessageDataToJson(eventData, "destination")); sink->FinishEvent(); - - return true; } -bool PreparedMessageReceivedHandler(const TraceEventFields & eventFields, void * context) +void PreparedMessageReceivedHandler(const TracePreparedSecureMessageData * eventData) { - TraceHandlerContext * ourContext = reinterpret_cast(context); - if ((std::string{ eventFields.dataFormat } != kTracePreparedMessageReceivedDataFormat) || - (eventFields.dataSize != sizeof(TracePreparedSecureMessageData))) + TraceOutput * sink = gTraceHandlerContext.sink; + if (!sink->HasStreamAvailable()) { - return false; + return; } - const auto * eventData = reinterpret_cast(eventFields.dataBuffer); - TraceOutput * sink = ourContext->sink; sink->StartEvent(std::string{ kTraceMessageEvent } + "." + kTracePreparedMessageReceivedDataFormat); sink->AddField("json", PreparedSecureMessageDataToJson(eventData, "source")); sink->FinishEvent(); +} - return true; +void TraceHandler(const char * type, const void * data, size_t size) +{ + if ((std::string{ type } == kTracePreparedMessageReceivedDataFormat) && (size == sizeof(TracePreparedSecureMessageData))) + { + PreparedMessageReceivedHandler(reinterpret_cast(data)); + } + else if ((std::string{ type } == kTracePreparedMessageSentDataFormat) && (size == sizeof(TracePreparedSecureMessageData))) + { + PreparedMessageSentHandler(reinterpret_cast(data)); + } + else if ((std::string{ type } == kTraceMessageSentDataFormat) && (size == sizeof(TraceSecureMessageSentData))) + { + SecureMessageSentHandler(reinterpret_cast(data)); + } + else if ((std::string{ type } == kTraceMessageReceivedDataFormat) && (size == sizeof(TraceSecureMessageReceivedData))) + { + SecureMessageReceivedHandler(reinterpret_cast(data)); + } } } // namespace @@ -336,16 +350,11 @@ void SetTraceStream(TraceStream * stream) void InitTrace() { - void * context = &gTraceHandlerContext; - RegisterTraceHandler(SecureMessageSentHandler, context); - RegisterTraceHandler(SecureMessageReceivedHandler, context); - RegisterTraceHandler(PreparedMessageSentHandler, context); - RegisterTraceHandler(PreparedMessageReceivedHandler, context); + SetTransportTraceHook(TraceHandler); } void DeInitTrace() { - UnregisterAllTraceHandlers(); gTraceOutput.DeleteStream(); } diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index 596629efaea7d5..0876bba0d4a831 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -60,6 +60,10 @@ #include #endif +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED +#include "TraceHandlers.h" +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + #include #include "AppMain.h" @@ -89,6 +93,13 @@ static constexpr uint8_t kWiFiStartCheckAttempts = 5; #endif namespace { +// To hold SPAKE2+ verifier, discriminator, passcode +LinuxCommissionableDataProvider gCommissionableDataProvider; + +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED +chip::trace::TraceStream * gTraceStream = nullptr; +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + void EventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) { (void) arg; @@ -208,8 +219,18 @@ CHIP_ERROR InitCommissionableDataProvider(LinuxCommissionableDataProvider & prov options.payload.discriminator); } -// To hold SPAKE2+ verifier, discriminator, passcode -LinuxCommissionableDataProvider gCommissionableDataProvider; +void Cleanup() +{ +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + if (gTraceStream != nullptr) + { + delete gTraceStream; + gTraceStream = nullptr; + } + chip::trace::DeInitTrace(); +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED +} + } // namespace #if CHIP_DEVICE_CONFIG_ENABLE_WPA @@ -291,6 +312,23 @@ int ChipLinuxAppInit(int argc, char ** argv, OptionSet * customOptions) DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0); +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + if (LinuxDeviceOptions::GetInstance().traceStreamFilename.HasValue()) + { + const char * traceFilename = LinuxDeviceOptions::GetInstance().traceStreamFilename.Value().c_str(); + gTraceStream = new chip::trace::TraceStreamFile(traceFilename); + } + else if (LinuxDeviceOptions::GetInstance().traceStreamToLogEnabled) + { + gTraceStream = new chip::trace::TraceStreamLog(); + } + chip::trace::InitTrace(); + if (gTraceStream != nullptr) + { + chip::trace::SetTraceStream(gTraceStream); + } +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + #if CONFIG_NETWORK_LAYER_BLE DeviceLayer::ConnectivityMgr().SetBLEDeviceName(nullptr); // Use default device name (CHIP-XXXX) DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(LinuxDeviceOptions::GetInstance().mBleDevice, false); @@ -320,6 +358,8 @@ int ChipLinuxAppInit(int argc, char ** argv, OptionSet * customOptions) if (err != CHIP_NO_ERROR) { ChipLogProgress(NotSpecified, "Failed to init Linux App: %s ", ErrorStr(err)); + Cleanup(); + // End the program with non zero error code to indicate a error. return 1; } @@ -704,4 +744,6 @@ void ChipLinuxAppMainLoop() Server::GetInstance().Shutdown(); DeviceLayer::PlatformMgr().Shutdown(); + + Cleanup(); } diff --git a/examples/platform/linux/BUILD.gn b/examples/platform/linux/BUILD.gn index 7c8c9d666fa508..1db7f364e8ba4d 100644 --- a/examples/platform/linux/BUILD.gn +++ b/examples/platform/linux/BUILD.gn @@ -15,6 +15,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") import("${chip_root}/src/app/common_flags.gni") +import("${chip_root}/src/lib/core/core.gni") import("${chip_root}/src/lib/lib.gni") config("app-main-config") { @@ -53,5 +54,9 @@ source_set("app-main") { "${chip_root}/src/lib/shell:shell_core", ] + if (chip_enable_transport_trace) { + public_deps += [ "${chip_root}/examples/common/tracing:trace_handlers" ] + } + public_configs = [ ":app-main-config" ] } diff --git a/examples/platform/linux/Options.cpp b/examples/platform/linux/Options.cpp index 4f1f5348ca8ff6..fabf4dc1b84137 100644 --- a/examples/platform/linux/Options.cpp +++ b/examples/platform/linux/Options.cpp @@ -57,6 +57,8 @@ enum kDeviceOption_Spake2pVerifierBase64 = 0x1011, kDeviceOption_Spake2pSaltBase64 = 0x1012, kDeviceOption_Spake2pIterations = 0x1013, + kDeviceOption_TraceFile = 0x1014, + kDeviceOption_TraceLog = 0x1015, }; constexpr unsigned kAppUsageLength = 64; @@ -88,6 +90,10 @@ OptionDef sDeviceOptionDefs[] = { { "PICS", kArgumentRequired, kDeviceOption_PICS }, { "KVS", kArgumentRequired, kDeviceOption_KVS }, { "interface-id", kArgumentRequired, kDeviceOption_InterfaceId }, +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + { "trace_file", kArgumentRequired, kDeviceOption_TraceFile }, + { "trace_log", kArgumentRequired, kDeviceOption_TraceLog }, +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED {} }; @@ -164,6 +170,13 @@ const char * sDeviceOptionHelp = "\n" " --interface-id \n" " A interface id to advertise on.\n" +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + "\n" + " --trace_file \n" + " Output trace data to the provided file.\n" + " --trace_log <1/0>\n" + " A value of 1 enables traces to go to the log, 0 disables this (default 0).\n" +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED "\n"; bool Base64ArgToVector(const char * arg, size_t maxSize, std::vector & outVector) @@ -350,6 +363,18 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier, Inet::InterfaceId(static_cast(atoi(aValue))); break; +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + case kDeviceOption_TraceFile: + LinuxDeviceOptions::GetInstance().traceStreamFilename.SetValue(std::string{ aValue }); + break; + case kDeviceOption_TraceLog: + if (atoi(aValue) != 0) + { + LinuxDeviceOptions::GetInstance().traceStreamToLogEnabled = true; + } + break; +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + default: PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName); retval = false; diff --git a/examples/platform/linux/Options.h b/examples/platform/linux/Options.h index c0c02b8f7fad3f..833cc3bf5a3b63 100644 --- a/examples/platform/linux/Options.h +++ b/examples/platform/linux/Options.h @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include @@ -50,6 +51,8 @@ struct LinuxDeviceOptions const char * PICS = nullptr; const char * KVS = nullptr; chip::Inet::InterfaceId interfaceId = chip::Inet::InterfaceId::Null(); + bool traceStreamToLogEnabled = false; + chip::Optional traceStreamFilename; static LinuxDeviceOptions & GetInstance(); }; diff --git a/examples/platform/linux/pw_trace_chip/BUILD.gn b/examples/platform/linux/pw_trace_chip/BUILD.gn deleted file mode 100644 index 91d4bbb816f2ab..00000000000000 --- a/examples/platform/linux/pw_trace_chip/BUILD.gn +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# 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. - -import("//build_overrides/chip.gni") -import("//build_overrides/pigweed.gni") - -import("$dir_pw_build/target_types.gni") - -config("public_include_path") { - include_dirs = [ "public" ] -} - -config("backend_config") { - include_dirs = [ "public_overrides" ] -} - -pw_source_set("pw_trace_chip") { - public_configs = [ - ":backend_config", - ":public_include_path", - ] - include_dirs = [ "${chip_root}/src" ] - public_deps = [ "$dir_pw_status" ] - deps = [ "$dir_pw_trace:facade" ] - sources = [ "trace.cc" ] - public = [ "public_overrides/pw_trace_backend/trace_backend.h" ] -} diff --git a/examples/platform/linux/pw_trace_chip/public/pw_trace_chip/trace_chip.h b/examples/platform/linux/pw_trace_chip/public/pw_trace_chip/trace_chip.h deleted file mode 100644 index c65899c29b0e0e..00000000000000 --- a/examples/platform/linux/pw_trace_chip/public/pw_trace_chip/trace_chip.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2021 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 -#include - -// Enable these trace types -#define PW_TRACE_TYPE_INSTANT ::chip::trace::PW_TRACE_EVENT_TYPE_INSTANT -#define PW_TRACE_TYPE_INSTANT_GROUP ::chip::trace::PW_TRACE_EVENT_TYPE_INSTANT_GROUP - -#define PW_TRACE_TYPE_DURATION_START ::chip::trace::PW_TRACE_EVENT_TYPE_DURATION_START -#define PW_TRACE_TYPE_DURATION_END ::chip::trace::PW_TRACE_EVENT_TYPE_DURATION_END - -#define PW_TRACE_TYPE_DURATION_GROUP_START ::chip::trace::PW_TRACE_EVENT_TYPE_DURATION_GROUP_START -#define PW_TRACE_TYPE_DURATION_GROUP_END ::chip::trace::PW_TRACE_EVENT_TYPE_DURATION_GROUP_END - -#define PW_TRACE_TYPE_ASYNC_START ::chip::trace::PW_TRACE_EVENT_TYPE_ASYNC_START -#define PW_TRACE_TYPE_ASYNC_INSTANT ::chip::trace::PW_TRACE_EVENT_TYPE_ASYNC_STEP -#define PW_TRACE_TYPE_ASYNC_END ::chip::trace::PW_TRACE_EVENT_TYPE_ASYNC_END - -namespace chip { -namespace trace { - -typedef enum -{ - PW_TRACE_EVENT_TYPE_INVALID = 0, - PW_TRACE_EVENT_TYPE_INSTANT = 1, - PW_TRACE_EVENT_TYPE_INSTANT_GROUP = 2, - PW_TRACE_EVENT_TYPE_ASYNC_START = 3, - PW_TRACE_EVENT_TYPE_ASYNC_STEP = 4, - PW_TRACE_EVENT_TYPE_ASYNC_END = 5, - PW_TRACE_EVENT_TYPE_DURATION_START = 6, - PW_TRACE_EVENT_TYPE_DURATION_END = 7, - PW_TRACE_EVENT_TYPE_DURATION_GROUP_START = 8, - PW_TRACE_EVENT_TYPE_DURATION_GROUP_END = 9, -} TraceEventType; - -// This should not be called directly, instead use the PW_TRACE_* macros. -void TraceEvent(const char * module, const char * label, TraceEventType eventType, const char * group, uint32_t traceId, - uint8_t flags, const char * dataFormat, const void * dataBuffer, size_t dataSize); - -struct TraceEventFields -{ - const char * module; - const char * label; - TraceEventType eventType; - const char * group; - uint32_t traceId; - uint8_t flags; - const char * dataFormat; - const void * dataBuffer; - size_t dataSize; -}; - -typedef bool (*TraceHandlerCallback)(const TraceEventFields & eventFields, void * context); - -// Register an additional trace handler which gets called for all data trace events with the given context -void RegisterTraceHandler(TraceHandlerCallback callback, void * context); -void UnregisterAllTraceHandlers(); - -// These are what the facade actually calls. -#define PW_TRACE(eventType, flags, label, group, traceId) \ - do \ - { \ - ::chip::trace::TraceEvent(PW_TRACE_MODULE_NAME, label, eventType, group, traceId, flags, NULL, NULL, 0); \ - } while (0) - -#define PW_TRACE_DATA(eventType, flags, label, group, traceId, dataFormat, data, size) \ - do \ - { \ - ::chip::trace::TraceEvent(PW_TRACE_MODULE_NAME, label, eventType, group, traceId, flags, dataFormat, data, size); \ - } while (0) - -} // namespace trace -} // namespace chip diff --git a/examples/platform/linux/pw_trace_chip/public_overrides/pw_trace_backend/trace_backend.h b/examples/platform/linux/pw_trace_chip/public_overrides/pw_trace_backend/trace_backend.h deleted file mode 100644 index cf6e094d8ebde3..00000000000000 --- a/examples/platform/linux/pw_trace_chip/public_overrides/pw_trace_backend/trace_backend.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2021 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 "pw_trace_chip/trace_chip.h" diff --git a/examples/platform/linux/pw_trace_chip/trace.cc b/examples/platform/linux/pw_trace_chip/trace.cc deleted file mode 100644 index bf005c518933fd..00000000000000 --- a/examples/platform/linux/pw_trace_chip/trace.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2021 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. - * - */ - -#include -#include - -#include "pw_trace_chip/trace_chip.h" - -#include "pw_trace/trace.h" - -namespace chip { -namespace trace { - -namespace { - -struct TraceHandlerEntry -{ - // Handler callback that will receive the event - TraceHandlerCallback callback; - // Registration-time context provided for the given handler - void * context; -}; - -std::mutex handlerLock; -std::vector traceHandlers; - -} // namespace - -void TraceEvent(const char * module, const char * label, TraceEventType eventType, const char * group, uint32_t traceId, - uint8_t flags, const char * dataFormat, const void * dataBuffer, size_t dataSize) -{ - TraceEventFields eventFields = { module, label, eventType, group, traceId, flags, dataFormat, dataBuffer, dataSize }; - std::lock_guard guard(handlerLock); - for (const auto & handler : traceHandlers) - { - if (handler.callback(eventFields, handler.context)) - { - return; - } - } -} - -void RegisterTraceHandler(TraceHandlerCallback callback, void * context) -{ - std::lock_guard guard(handlerLock); - traceHandlers.push_back(TraceHandlerEntry{ callback, context }); -} - -void UnregisterAllTraceHandlers() -{ - std::lock_guard guard(handlerLock); - traceHandlers.clear(); -} - -} // namespace trace -} // namespace chip diff --git a/src/lib/core/BUILD.gn b/src/lib/core/BUILD.gn index 156d79fa5a52b2..94fc8db703c077 100644 --- a/src/lib/core/BUILD.gn +++ b/src/lib/core/BUILD.gn @@ -59,6 +59,7 @@ buildconfig_header("chip_buildconfig") { "CHIP_CONFIG_MEMORY_DEBUG_DMALLOC=${chip_config_memory_debug_dmalloc}", "CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES=false", "CHIP_CONFIG_TRANSPORT_TRACE_ENABLED=${chip_enable_transport_trace}", + "CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED=${chip_enable_transport_pw_trace}", "CHIP_CONFIG_MINMDNS_DYNAMIC_OPERATIONAL_RESPONDER_LIST=${chip_config_minmdns_dynamic_operational_responder_list}", ] } diff --git a/src/lib/core/core.gni b/src/lib/core/core.gni index 44654616b415ba..f2e78db68a14dc 100644 --- a/src/lib/core/core.gni +++ b/src/lib/core/core.gni @@ -51,8 +51,11 @@ declare_args() { # Memory management debug option: use dmalloc chip_config_memory_debug_dmalloc = false - # When enabled traces messages using pw_trace. - chip_enable_transport_trace = false + # When enabled trace messages using tansport trace hook. + chip_enable_transport_trace = current_os == "linux" || current_os == "mac" + + # When this is enabled trace messages will be sent to pw_trace. + chip_enable_transport_pw_trace = false # Enables using dynamic memory for minmdns tracking of operational # responders. diff --git a/src/transport/BUILD.gn b/src/transport/BUILD.gn index 75828b62480068..42ea4dcd73b839 100644 --- a/src/transport/BUILD.gn +++ b/src/transport/BUILD.gn @@ -72,6 +72,9 @@ static_library("transport") { ] if (chip_enable_transport_trace) { - deps = [ "$dir_pw_trace" ] + sources += [ "TraceMessage.cpp" ] + } + if (chip_enable_transport_pw_trace) { + public_deps += [ "$dir_pw_trace" ] } } diff --git a/src/transport/TraceMessage.cpp b/src/transport/TraceMessage.cpp new file mode 100644 index 00000000000000..461f17989bc5ff --- /dev/null +++ b/src/transport/TraceMessage.cpp @@ -0,0 +1,47 @@ +/* + * + * 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. + */ + +#include + +namespace chip { +namespace trace { +namespace { + +TransportTraceHandler gTransportTraceHandler = nullptr; + +} // namespace + +void SetTransportTraceHook(TransportTraceHandler handler) +{ + gTransportTraceHandler = handler; +} + +namespace internal { + +void HandleTransportTrace(const char * type, const void * data, size_t size) +{ + if (gTransportTraceHandler) + { + gTransportTraceHandler(type, data, size); + } +} + +} // namespace internal + +} // namespace trace +} // namespace chip diff --git a/src/transport/TraceMessage.h b/src/transport/TraceMessage.h index 93cdfa6dd77927..f7d23697296091 100644 --- a/src/transport/TraceMessage.h +++ b/src/transport/TraceMessage.h @@ -24,15 +24,28 @@ #include #include -#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED +#if CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED #include "pw_trace/trace.h" +#endif // CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED + +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED || CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED + +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED && CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED +#define _CHIP_TRACE_MESSAGE_INTERNAL(type, data, size) \ + ::chip::trace::internal::HandleTransportTrace(type, data, size); \ + PW_TRACE_INSTANT_DATA(::chip::trace::kTraceMessageEvent, type, data, size); +#elif CHIP_CONFIG_TRANSPORT_TRACE_ENABLED +#define _CHIP_TRACE_MESSAGE_INTERNAL(type, data, size) ::chip::trace::internal::HandleTransportTrace(type, data, size); +#else // CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED +#define _CHIP_TRACE_MESSAGE_INTERNAL(type, data, size) PW_TRACE_INSTANT_DATA(::chip::trace::kTraceMessageEvent, type, data, size); +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED && CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED #define CHIP_TRACE_MESSAGE_SENT(payloadHeader, packetHeader, data, dataLen) \ do \ { \ const ::chip::trace::TraceSecureMessageSentData _trace_data{ &payloadHeader, &packetHeader, data, dataLen }; \ - PW_TRACE_INSTANT_DATA(::chip::trace::kTraceMessageEvent, ::chip::trace::kTraceMessageSentDataFormat, \ - reinterpret_cast(&_trace_data), sizeof(_trace_data)); \ + _CHIP_TRACE_MESSAGE_INTERNAL(::chip::trace::kTraceMessageSentDataFormat, reinterpret_cast(&_trace_data), \ + sizeof(_trace_data)); \ } while (0) #define CHIP_TRACE_MESSAGE_RECEIVED(payloadHeader, packetHeader, session, peerAddress, data, dataLen) \ @@ -40,27 +53,27 @@ { \ const ::chip::trace::TraceSecureMessageReceivedData _trace_data{ &payloadHeader, &packetHeader, session, \ &peerAddress, data, dataLen }; \ - PW_TRACE_INSTANT_DATA(::chip::trace::kTraceMessageEvent, ::chip::trace::kTraceMessageReceivedDataFormat, \ - reinterpret_cast(&_trace_data), sizeof(_trace_data)); \ + _CHIP_TRACE_MESSAGE_INTERNAL(::chip::trace::kTraceMessageReceivedDataFormat, reinterpret_cast(&_trace_data), \ + sizeof(_trace_data)); \ } while (0) #define CHIP_TRACE_PREPARED_MESSAGE_SENT(destination, packetBuffer) \ do \ { \ const ::chip::trace::TracePreparedSecureMessageData _trace_data{ destination, packetBuffer }; \ - PW_TRACE_INSTANT_DATA(::chip::trace::kTraceMessageEvent, ::chip::trace::kTracePreparedMessageSentDataFormat, \ - reinterpret_cast(&_trace_data), sizeof(_trace_data)); \ + _CHIP_TRACE_MESSAGE_INTERNAL(::chip::trace::kTracePreparedMessageSentDataFormat, \ + reinterpret_cast(&_trace_data), sizeof(_trace_data)); \ } while (0) #define CHIP_TRACE_PREPARED_MESSAGE_RECEIVED(source, packetBuffer) \ do \ { \ const ::chip::trace::TracePreparedSecureMessageData _trace_data{ source, packetBuffer }; \ - PW_TRACE_INSTANT_DATA(::chip::trace::kTraceMessageEvent, ::chip::trace::kTracePreparedMessageReceivedDataFormat, \ - reinterpret_cast(&_trace_data), sizeof(_trace_data)); \ + _CHIP_TRACE_MESSAGE_INTERNAL(::chip::trace::kTracePreparedMessageReceivedDataFormat, \ + reinterpret_cast(&_trace_data), sizeof(_trace_data)); \ } while (0) -#else +#else // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED || CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED #define CHIP_TRACE_MESSAGE_SENT(payloadHeader, packetHeader, data, dataLen) \ do \ { \ @@ -80,7 +93,7 @@ do \ { \ } while (0) -#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED || CHIP_CONFIG_TRANSPORT_PW_TRACE_ENABLED namespace chip { namespace trace { @@ -115,5 +128,20 @@ struct TracePreparedSecureMessageData const System::PacketBufferHandle * packetBuffer; }; +#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + +typedef void (*TransportTraceHandler)(const char * type, const void * data, size_t size); + +// Configure the transport trace events to be sent to the provided handler. +void SetTransportTraceHook(TransportTraceHandler); + +namespace internal { + +void HandleTransportTrace(const char * type, const void * data, size_t size); + +} // namespace internal + +#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED + } // namespace trace } // namespace chip