Skip to content

Commit

Permalink
[posix] add rcp capability diag command to check the Spinel interface…
Browse files Browse the repository at this point in the history
… speed
  • Loading branch information
zhanglongxia committed Jun 28, 2024
1 parent cc8f66c commit 2fbecc5
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/lib/spinel/radio_spinel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,12 @@ void RadioSpinel::SetDiagOutputCallback(otPlatDiagOutputCallback aCallback, void
mOutputContext = aContext;
}

void RadioSpinel::GetDiagOutputCallback(otPlatDiagOutputCallback &aCallback, void *&aContext)
{
aCallback = mOutputCallback;
aContext = mOutputContext;
}

otError RadioSpinel::PlatDiagProcess(const char *aString)
{
return Set(SPINEL_PROP_NEST_STREAM_MFG, SPINEL_DATATYPE_UTF8_S, aString);
Expand Down
9 changes: 9 additions & 0 deletions src/lib/spinel/radio_spinel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,15 @@ class RadioSpinel : private Logger
*
*/
void SetDiagOutputCallback(otPlatDiagOutputCallback aCallback, void *aContext);

/**
* Gets the diag output callback.
*
* @param[out] aCallback A reference to a function that is called on outputting diag messages.
* @param[out] aContext A reference to the user context.
*
*/
void GetDiagOutputCallback(otPlatDiagOutputCallback &aCallback, void *&aContext);
#endif

/**
Expand Down
11 changes: 11 additions & 0 deletions src/posix/platform/README_RCP_CAPS_DIAG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This module provides diag commands for checking RCP capabilities.

- [capflags](#capflags)
- [spinel](#spinel)
- [spinelspeed](#spinelspeed)

## Command Details

Expand Down Expand Up @@ -112,3 +113,13 @@ PROP_VALUE_SET PHY_TX_POWER ------------------------------- OK
PROP_VALUE_SET RADIO_COEX_ENABLE -------------------------- OK
Done
```

### spinelspeed

Check the speed of Spinel interface.

```bash
> diag rcpcaps spinelspeed
SpinelSpeed ----------------------------------------------- 34414843 bps
Done
```
86 changes: 86 additions & 0 deletions src/posix/platform/rcp_caps_diag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,10 @@ otError RcpCapsDiag::DiagProcess(char *aArgs[], uint8_t aArgsLength)
{
ProcessSpinel();
}
else if (strcmp(aArgs[1], "spinelspeed") == 0)
{
ProcessSpinelSpeed();
}
else
{
error = OT_ERROR_INVALID_COMMAND;
Expand Down Expand Up @@ -616,6 +620,88 @@ bool RcpCapsDiag::IsSpinelCapabilitySupported(const uint8_t *aCapsData, spinel_s
return ret;
}

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

void RcpCapsDiag::HandleDiagOutput(const char *aFormat, va_list aArguments)
{
int rval;

VerifyOrExit(mDiagOutput != nullptr && mDiagOutputLength != 0);
rval = vsnprintf(mDiagOutput, mDiagOutputLength, aFormat, aArguments);
VerifyOrExit(rval >= 0);

rval = (rval > mDiagOutputLength) ? mDiagOutputLength : rval;
mDiagOutput += rval;
mDiagOutputLength -= rval;

exit:
return;
}

void RcpCapsDiag::ProcessSpinelSpeed(void)
{
static constexpr uint32_t kUsPerSec = 1000000;
static constexpr uint8_t kBitsPerByte = 8;
static constexpr uint8_t kSpinelHeaderSize = 4;
static constexpr uint8_t kZeroTerminatorSize = 1;
static const char *const kEchoCmd = "echo ";
static constexpr uint8_t kEchoPayloadLength = 200;
static constexpr uint8_t kNumTests = 100;

otError error = OT_ERROR_NONE;
char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE] = {0};
char output[OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE];
uint16_t i;
uint16_t echoPayloadLength;
uint64_t startTimestamp;
uint64_t endTimestamp;
uint64_t sumTime = 0;
uint64_t sumLength = 0;
uint64_t speed;
otPlatDiagOutputCallback callback;
void *context;

mRadioSpinel.GetDiagOutputCallback(callback, context);
mRadioSpinel.SetDiagOutputCallback(HandleDiagOutput, this);

strncpy(cmd, kEchoCmd, sizeof(cmd) - 1);
echoPayloadLength = sizeof(cmd) - strlen(cmd) - 1;
echoPayloadLength = (kEchoPayloadLength < echoPayloadLength) ? kEchoPayloadLength : echoPayloadLength;
memset(cmd + strlen(cmd), '1', echoPayloadLength);

for (i = 0; i < kNumTests; i++)
{
output[0] = '\0';
mDiagOutput = output;
mDiagOutputLength = sizeof(output);
startTimestamp = otPlatTimeGet();

SuccessOrExit(error = mRadioSpinel.PlatDiagProcess(cmd));

endTimestamp = otPlatTimeGet();
sumTime += endTimestamp - startTimestamp;
sumLength += kSpinelHeaderSize + strlen(cmd) + kZeroTerminatorSize + kSpinelHeaderSize + strlen(output) +
kZeroTerminatorSize;
}

mRadioSpinel.SetDiagOutputCallback(callback, context);

exit:
if (error == OT_ERROR_NONE)
{
speed = (sumLength * kBitsPerByte * kUsPerSec) / sumTime;
snprintf(output, sizeof(output), "%lu bps", speed);
OutputFormat("SpinelSpeed", output);
}
else
{
Output("Failed to test the Spinel speed: %s", otThreadErrorToString(error));
}
}

void RcpCapsDiag::OutputFormat(const char *aName, const char *aValue)
{
static constexpr uint8_t kMaxNameLength = 56;
Expand Down
9 changes: 9 additions & 0 deletions src/posix/platform/rcp_caps_diag.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class RcpCapsDiag
: mRadioSpinel(aRadioSpinel)
, mOutputCallback(nullptr)
, mOutputContext(nullptr)
, mDiagOutput(nullptr)
, mDiagOutputLength(0)
{
}

Expand Down Expand Up @@ -109,6 +111,7 @@ class RcpCapsDiag
};

void ProcessSpinel(void);
void ProcessSpinelSpeed(void);
void ProcessCapabilityFlags(void);
void TestSpinelCommands(Category aCategory);
void TestRadioCapbilityFlags(void);
Expand All @@ -120,6 +123,10 @@ class RcpCapsDiag
const uint32_t *aFlags,
uint16_t aNumbFlags);
bool IsSpinelCapabilitySupported(const uint8_t *aCapsData, spinel_size_t aCapsLength, uint32_t aCapability);

static void HandleDiagOutput(const char *aFormat, va_list aArguments, void *aContext);
void HandleDiagOutput(const char *aFormat, va_list aArguments);

void OutputFormat(const char *aName, const char *aValue);
void OutputResult(const SpinelEntry &aEntry, otError error);
void Output(const char *aFormat, ...);
Expand All @@ -133,6 +140,8 @@ class RcpCapsDiag
Spinel::RadioSpinel &mRadioSpinel;
otPlatDiagOutputCallback mOutputCallback;
void *mOutputContext;
char *mDiagOutput;
uint16_t mDiagOutputLength;
};

} // namespace Posix
Expand Down

0 comments on commit 2fbecc5

Please sign in to comment.