Skip to content

Commit

Permalink
TRACE: Add transport tracing to linux example apps
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
Rob Oliver committed Apr 1, 2022
1 parent fbcaa81 commit 1649e7b
Show file tree
Hide file tree
Showing 16 changed files with 172 additions and 331 deletions.
1 change: 0 additions & 1 deletion examples/chip-tool/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "<CHIPProjectAppConfig.h>"
chip_project_config_include = "<CHIPProjectAppConfig.h>"
Expand Down
28 changes: 0 additions & 28 deletions examples/chip-tool/with_pw_trace.gni

This file was deleted.

8 changes: 1 addition & 7 deletions examples/common/tracing/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand All @@ -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" ]
}
93 changes: 33 additions & 60 deletions examples/common/tracing/TraceHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@
#include <mutex>
#include <stdint.h>
#include <string>
#include <vector>

#include "pw_trace/trace.h"
#include "pw_trace_chip/trace_chip.h"
#include "transport/TraceMessage.h"
#include <lib/support/BytesToHex.h>
#include <lib/support/CodeUtils.h>
Expand Down Expand Up @@ -130,15 +129,15 @@ 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');
// Fill a buffer long enough for the hex conversion, that will be overwritten
std::vector<char> 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);

return AsJsonString(hexBuf);
return AsJsonString(std::string(hexBuf.data(), hexBuf.size()));
}

std::string PacketHeaderToJson(const PacketHeader * packetHeader)
Expand Down Expand Up @@ -230,17 +229,9 @@ std::string PreparedSecureMessageDataToJson(const TracePreparedSecureMessageData
return jsonBody;
}

bool SecureMessageSentHandler(const TraceEventFields & eventFields, void * context)
void SecureMessageSentHandler(const TraceSecureMessageSentData * eventData)
{
TraceHandlerContext * ourContext = reinterpret_cast<TraceHandlerContext *>(context);
if ((std::string{ eventFields.dataFormat } != kTraceMessageSentDataFormat) ||
(eventFields.dataSize != sizeof(TraceSecureMessageSentData)))
{
return false;
}

const auto * eventData = reinterpret_cast<const TraceSecureMessageSentData *>(eventFields.dataBuffer);
std::string jsonBody = "{";
std::string jsonBody = "{";
jsonBody += PacketHeaderToJson(eventData->packetHeader);
jsonBody += ", ";
jsonBody += PayloadHeaderToJson(eventData->payloadHeader);
Expand All @@ -250,25 +241,14 @@ bool SecureMessageSentHandler(const TraceEventFields & eventFields, void * conte
jsonBody += AsFirstJsonKey("payload_hex", AsJsonHexString(eventData->packetPayload, eventData->packetSize));
jsonBody += "}";

TraceOutput * sink = ourContext->sink;
TraceOutput * sink = gTraceHandlerContext.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<TraceHandlerContext *>(context);
if ((std::string{ eventFields.dataFormat } != kTraceMessageReceivedDataFormat) ||
(eventFields.dataSize != sizeof(TraceSecureMessageReceivedData)))
{
return false;
}

const auto * eventData = reinterpret_cast<const TraceSecureMessageReceivedData *>(eventFields.dataBuffer);

std::string jsonBody = "{";
jsonBody += AsFirstJsonKey("peer_address", AsJsonString(eventData->peerAddress));
jsonBody += ", ";
Expand All @@ -281,50 +261,48 @@ bool SecureMessageReceivedHandler(const TraceEventFields & eventFields, void * c
jsonBody += AsFirstJsonKey("payload_hex", AsJsonHexString(eventData->packetPayload, eventData->packetSize));
jsonBody += "}";

TraceOutput * sink = ourContext->sink;
TraceOutput * sink = gTraceHandlerContext.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<TraceHandlerContext *>(context);
if ((std::string{ eventFields.dataFormat } != kTracePreparedMessageSentDataFormat) ||
(eventFields.dataSize != sizeof(TracePreparedSecureMessageData)))
{
return false;
}

const auto * eventData = reinterpret_cast<const TracePreparedSecureMessageData *>(eventFields.dataBuffer);
TraceOutput * sink = ourContext->sink;
TraceOutput * sink = gTraceHandlerContext.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<TraceHandlerContext *>(context);
if ((std::string{ eventFields.dataFormat } != kTracePreparedMessageReceivedDataFormat) ||
(eventFields.dataSize != sizeof(TracePreparedSecureMessageData)))
{
return false;
}

const auto * eventData = reinterpret_cast<const TracePreparedSecureMessageData *>(eventFields.dataBuffer);
TraceOutput * sink = ourContext->sink;
TraceOutput * sink = gTraceHandlerContext.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<const TracePreparedSecureMessageData *>(data));
}
else if ((std::string{ type } == kTracePreparedMessageSentDataFormat) && (size == sizeof(TracePreparedSecureMessageData)))
{
PreparedMessageSentHandler(reinterpret_cast<const TracePreparedSecureMessageData *>(data));
}
else if ((std::string{ type } == kTraceMessageSentDataFormat) && (size == sizeof(TraceSecureMessageSentData)))
{
SecureMessageSentHandler(reinterpret_cast<const TraceSecureMessageSentData *>(data));
}
else if ((std::string{ type } == kTraceMessageReceivedDataFormat) && (size == sizeof(TraceSecureMessageReceivedData)))
{
SecureMessageReceivedHandler(reinterpret_cast<const TraceSecureMessageReceivedData *>(data));
}
}

} // namespace
Expand All @@ -336,16 +314,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();
}

Expand Down
8 changes: 8 additions & 0 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
#include <CommonRpc.h>
#endif

#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
#include "TraceHandlers.h"
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED

#include <signal.h>

#include "AppMain.h"
Expand Down Expand Up @@ -291,6 +295,10 @@ int ChipLinuxAppInit(int argc, char ** argv, OptionSet * customOptions)

DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0);

#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
chip::trace::InitTrace();
#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);
Expand Down
5 changes: 5 additions & 0 deletions examples/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down Expand Up @@ -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" ]
}
29 changes: 29 additions & 0 deletions examples/platform/linux/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
#include <lib/core/CHIPError.h>
#include <lib/support/Base64.h>

#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
#include "TraceHandlers.h"
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED

using namespace chip;
using namespace chip::ArgParser;

Expand Down Expand Up @@ -57,6 +61,8 @@ enum
kDeviceOption_Spake2pVerifierBase64 = 0x1011,
kDeviceOption_Spake2pSaltBase64 = 0x1012,
kDeviceOption_Spake2pIterations = 0x1013,
kDeviceOption_TraceFile = 0x1014,
kDeviceOption_TraceLog = 0x1015,
};

constexpr unsigned kAppUsageLength = 64;
Expand Down Expand Up @@ -88,6 +94,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
{}
};

Expand Down Expand Up @@ -164,6 +174,13 @@ const char * sDeviceOptionHelp =
"\n"
" --interface-id <interface>\n"
" A interface id to advertise on.\n"
#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
"\n"
" --trace_file <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<uint8_t> & outVector)
Expand Down Expand Up @@ -350,6 +367,18 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier,
Inet::InterfaceId(static_cast<chip::Inet::InterfaceId::PlatformType>(atoi(aValue)));
break;

#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
case kDeviceOption_TraceFile:
chip::trace::SetTraceStream(new chip::trace::TraceStreamFile(aValue));
break;
case kDeviceOption_TraceLog:
if (atoi(aValue) == 1)
{
chip::trace::SetTraceStream(new chip::trace::TraceStreamLog());
}
break;
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED

default:
PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
retval = false;
Expand Down
38 changes: 0 additions & 38 deletions examples/platform/linux/pw_trace_chip/BUILD.gn

This file was deleted.

Loading

0 comments on commit 1649e7b

Please sign in to comment.