Skip to content

Commit

Permalink
[diag] add diag output callback
Browse files Browse the repository at this point in the history
The length of diag output messages is limited by the diag buffer size.
Developers have to change the diag buffer size to allow diag module to
output long messages. If diag output messages become longer and longer,
developers have to keep changing the diag buffer size.

This commit adds an output callback to diag module to output diag messages.
Then the length of diag output messages won't be limited by the diag buffer
size.
  • Loading branch information
zhanglongxia committed Jun 13, 2024
1 parent cb1220d commit f0379f6
Show file tree
Hide file tree
Showing 19 changed files with 488 additions and 252 deletions.
7 changes: 7 additions & 0 deletions examples/platforms/simulation/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ static bool sGpioValue = false;
static uint8_t sRawPowerSetting[OPENTHREAD_CONFIG_POWER_CALIBRATION_RAW_POWER_SETTING_SIZE];
static uint16_t sRawPowerSettingLength = 0;

void otPlatDiagSetOutputCallback(otInstance *aInstance, otPlatDiagOutputCallback aCallback, void *aContext)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aCallback);
OT_UNUSED_VARIABLE(aContext);
}

void otPlatDiagModeSet(bool aMode) { sDiagMode = aMode; }

bool otPlatDiagModeGet(void) { return sDiagMode; }
Expand Down
32 changes: 16 additions & 16 deletions include/openthread/diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#define OPENTHREAD_DIAG_H_

#include <openthread/instance.h>
#include <openthread/platform/diag.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -51,47 +52,46 @@ extern "C" {
*
*/

/* Represents the pointer to callback to output diag messages.*/
typedef otPlatDiagOutputCallback otDiagOutputCallback;

/**
* Processes a factory diagnostics command line.
* Sets the diag output callback.
*
* The output of this function (the content written to @p aOutput) MUST terminate with `\0` and the `\0` is within the
* output buffer.
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aCallback A pointer to a function that is called on outputting diag messages.
* @param[in] aContext A pointer to the user context.
*
*/
void otDiagSetOutputCallback(otInstance *aInstance, otDiagOutputCallback aCallback, void *aContext);

/**
* Processes a factory diagnostics command line.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aArgsLength The number of elements in @p aArgs.
* @param[in] aArgs An array of arguments.
* @param[out] aOutput The diagnostics execution result.
* @param[in] aOutputMaxLen The output buffer size.
*
* @retval OT_ERROR_INVALID_ARGS The command is supported but invalid arguments provided.
* @retval OT_ERROR_NONE The command is successfully process.
* @retval OT_ERROR_NOT_IMPLEMENTED The command is not supported.
*
*/
otError otDiagProcessCmd(otInstance *aInstance,
uint8_t aArgsLength,
char *aArgs[],
char *aOutput,
size_t aOutputMaxLen);
otError otDiagProcessCmd(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]);

/**
* Processes a factory diagnostics command line.
*
* The output of this function (the content written to @p aOutput) MUST terminate with `\0` and the `\0` is within the
* output buffer.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aString A NULL-terminated input string.
* @param[out] aOutput The diagnostics execution result.
* @param[in] aOutputMaxLen The output buffer size.
*
* @retval OT_ERROR_NONE The command is successfully process.
* @retval OT_ERROR_INVALID_ARGS The command is supported but invalid arguments provided.
* @retval OT_ERROR_NOT_IMPLEMENTED The command is not supported.
* @retval OT_ERROR_NO_BUFS The command string is too long.
*
*/
otError otDiagProcessCmdLine(otInstance *aInstance, const char *aString, char *aOutput, size_t aOutputMaxLen);
otError otDiagProcessCmdLine(otInstance *aInstance, const char *aString);

/**
* Indicates whether or not the factory diagnostics mode is enabled.
Expand Down
2 changes: 1 addition & 1 deletion include/openthread/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (420)
#define OPENTHREAD_API_VERSION (421)

/**
* @addtogroup api-instance
Expand Down
31 changes: 21 additions & 10 deletions include/openthread/platform/diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,27 +67,38 @@ typedef enum
} otGpioMode;

/**
* Processes a factory diagnostics command line.
* Pointer to callback to output platform diag messages.
*
* @param[in] aFormat The format string.
* @param[in] aArguments The format string arguments.
* @param[out] aContext A pointer to the user context.
*
*/
typedef void (*otPlatDiagOutputCallback)(const char *aFormat, va_list aArguments, void *aContext);

/**
* Sets the platform diag output callback.
*
* The output of this function (the content written to @p aOutput) MUST terminate with `\0` and the `\0` is within the
* output buffer.
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aCallback A pointer to a function that is called on outputting diag messages.
* @param[in] aContext A pointer to the user context.
*
*/
void otPlatDiagSetOutputCallback(otInstance *aInstance, otPlatDiagOutputCallback aCallback, void *aContext);

/**
* Processes a factory diagnostics command line.
*
* @param[in] aInstance The OpenThread instance for current request.
* @param[in] aArgsLength The number of arguments in @p aArgs.
* @param[in] aArgs The arguments of diagnostics command line.
* @param[out] aOutput The diagnostics execution result.
* @param[in] aOutputMaxLen The output buffer size.
*
* @retval OT_ERROR_INVALID_ARGS The command is supported but invalid arguments provided.
* @retval OT_ERROR_NONE The command is successfully process.
* @retval OT_ERROR_INVALID_COMMAND The command is not valid or not supported.
*
*/
otError otPlatDiagProcess(otInstance *aInstance,
uint8_t aArgsLength,
char *aArgs[],
char *aOutput,
size_t aOutputMaxLen);
otError otPlatDiagProcess(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]);

/**
* Enables/disables the factory diagnostics mode.
Expand Down
19 changes: 12 additions & 7 deletions src/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi
#if (OPENTHREAD_FTD || OPENTHREAD_MTD) && OPENTHREAD_CONFIG_CLI_REGISTER_IP6_RECV_CALLBACK
otIp6SetReceiveCallback(GetInstancePtr(), &Interpreter::HandleIp6Receive, this);
#endif
#if OPENTHREAD_CONFIG_DIAG_ENABLE
otDiagSetOutputCallback(GetInstancePtr(), &Interpreter::HandleDiagOutput, this);
#endif

ClearAllBytes(mUserCommands);

OutputPrompt();
Expand Down Expand Up @@ -210,19 +214,20 @@ void Interpreter::OutputResult(otError aError)
#if OPENTHREAD_CONFIG_DIAG_ENABLE
template <> otError Interpreter::Process<Cmd("diag")>(Arg aArgs[])
{
otError error;
char *args[kMaxArgs];
char output[OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE];
char *args[kMaxArgs];

// all diagnostics related features are processed within diagnostics module
Arg::CopyArgsToStringArray(aArgs, args);

error = otDiagProcessCmd(GetInstancePtr(), Arg::GetArgsLength(aArgs), args, output, sizeof(output));

OutputFormat("%s", output);
return otDiagProcessCmd(GetInstancePtr(), Arg::GetArgsLength(aArgs), args);
}

return error;
void Interpreter::HandleDiagOutput(const char *aFormat, va_list aArguments, void *aContext)
{
static_cast<Interpreter *>(aContext)->HandleDiagOutput(aFormat, aArguments);
}

void Interpreter::HandleDiagOutput(const char *aFormat, va_list aArguments) { OutputFormatV(aFormat, aArguments); }
#endif

template <> otError Interpreter::Process<Cmd("version")>(Arg aArgs[])
Expand Down
5 changes: 5 additions & 0 deletions src/cli/cli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,11 @@ class Interpreter : public OutputImplementer, public Utils

#endif // OPENTHREAD_FTD || OPENTHREAD_MTD

#if OPENTHREAD_CONFIG_DIAG_ENABLE
static void HandleDiagOutput(const char *aFormat, va_list aArguments, void *aContext);
void HandleDiagOutput(const char *aFormat, va_list aArguments);
#endif

void SetCommandTimeout(uint32_t aTimeoutMilli);

static void HandleTimer(Timer &aTimer);
Expand Down
12 changes: 8 additions & 4 deletions src/core/api/diags_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,22 @@

using namespace ot;

otError otDiagProcessCmdLine(otInstance *aInstance, const char *aString, char *aOutput, size_t aOutputMaxLen)
otError otDiagProcessCmdLine(otInstance *aInstance, const char *aString)
{
AssertPointerIsNotNull(aString);

return AsCoreType(aInstance).Get<FactoryDiags::Diags>().ProcessLine(aString, aOutput, aOutputMaxLen);
return AsCoreType(aInstance).Get<FactoryDiags::Diags>().ProcessLine(aString);
}

otError otDiagProcessCmd(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen)
otError otDiagProcessCmd(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[])
{
return AsCoreType(aInstance).Get<FactoryDiags::Diags>().ProcessCmd(aArgsLength, aArgs, aOutput, aOutputMaxLen);
return AsCoreType(aInstance).Get<FactoryDiags::Diags>().ProcessCmd(aArgsLength, aArgs);
}

bool otDiagIsEnabled(otInstance *aInstance) { return AsCoreType(aInstance).Get<FactoryDiags::Diags>().IsEnabled(); }

void otDiagSetOutputCallback(otInstance *aInstance, otDiagOutputCallback aCallback, void *aContext)
{
AsCoreType(aInstance).Get<FactoryDiags::Diags>().SetOutputCallback(aCallback, aContext);
}
#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
Loading

0 comments on commit f0379f6

Please sign in to comment.