mirror of
https://github.com/espressif/openthread.git
synced 2026-07-27 22:37:45 +00:00
[cmd-parser] simplify ParseAsHexString() & Cli::UdpExample::ProcessSend() (#6726)
This commit enhances `CmdLineParser` methods that parse a hex string adding a new version which allows a (longer) hex string to be parsed in short segments sequentially. The unit test `test_cmd_line_parser` is also updated to verify the behavior of the newly added method. This commit also updates CLI `UdpExample` implementation to use the new method for parsing message payload data from input hex string and simplifies how `ProcessSend()` parses different arguments indicating message payload options.
This commit is contained in:
+82
-71
@@ -114,88 +114,70 @@ otError UdpExample::ProcessOpen(uint8_t aArgsLength, Arg aArgs[])
|
||||
|
||||
otError UdpExample::ProcessSend(uint8_t aArgsLength, Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otError error = OT_ERROR_NONE;
|
||||
otMessage * message = nullptr;
|
||||
otMessageInfo messageInfo;
|
||||
otMessage * message = nullptr;
|
||||
uint8_t curArg = 0;
|
||||
uint16_t payloadLength = 0;
|
||||
PayloadType payloadType = kTypeText;
|
||||
uint8_t argIndex = 0;
|
||||
otMessageSettings messageSettings = {mLinkSecurityEnabled, OT_MESSAGE_PRIORITY_NORMAL};
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
|
||||
// Possible argument formats:
|
||||
//
|
||||
// send <text>
|
||||
// send <type> <value>
|
||||
// send <ip> <port> <text>
|
||||
// send <ip> <port> <type> <value>
|
||||
|
||||
VerifyOrExit(aArgsLength >= 1 && aArgsLength <= 4, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (aArgsLength > 2)
|
||||
{
|
||||
SuccessOrExit(error = aArgs[curArg++].ParseAsIp6Address(messageInfo.mPeerAddr));
|
||||
SuccessOrExit(error = aArgs[curArg++].ParseAsUint16(messageInfo.mPeerPort));
|
||||
}
|
||||
|
||||
if (aArgsLength == 2 || aArgsLength == 4)
|
||||
{
|
||||
uint8_t typePos = curArg++;
|
||||
|
||||
if (aArgs[typePos] == "-s")
|
||||
{
|
||||
payloadType = kTypeAutoSize;
|
||||
SuccessOrExit(error = aArgs[curArg].ParseAsUint16(payloadLength));
|
||||
}
|
||||
else if (aArgs[typePos] == "-x")
|
||||
{
|
||||
payloadLength = aArgs[curArg].GetLength();
|
||||
payloadType = kTypeHexString;
|
||||
}
|
||||
else if (aArgs[typePos] == "-t")
|
||||
{
|
||||
payloadType = kTypeText;
|
||||
}
|
||||
SuccessOrExit(error = aArgs[argIndex++].ParseAsIp6Address(messageInfo.mPeerAddr));
|
||||
SuccessOrExit(error = aArgs[argIndex++].ParseAsUint16(messageInfo.mPeerPort));
|
||||
}
|
||||
|
||||
message = otUdpNewMessage(mInterpreter.mInstance, &messageSettings);
|
||||
VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
switch (payloadType)
|
||||
if (aArgs[argIndex] == "-s")
|
||||
{
|
||||
case kTypeText:
|
||||
SuccessOrExit(error = otMessageAppend(message, aArgs[curArg].GetCString(), aArgs[curArg].GetLength()));
|
||||
break;
|
||||
case kTypeAutoSize:
|
||||
SuccessOrExit(error = WriteCharToBuffer(message, payloadLength));
|
||||
break;
|
||||
case kTypeHexString:
|
||||
{
|
||||
uint8_t buf[50];
|
||||
uint16_t bufLen;
|
||||
uint16_t conversionLength = 0;
|
||||
const char *hexString = aArgs[curArg].GetCString();
|
||||
// Auto-generated payload with a given length
|
||||
|
||||
while (payloadLength > 0)
|
||||
uint16_t payloadLength;
|
||||
|
||||
argIndex++;
|
||||
VerifyOrExit(argIndex < aArgsLength, error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = aArgs[argIndex].ParseAsUint16(payloadLength));
|
||||
SuccessOrExit(error = PrepareAutoGeneratedPayload(*message, payloadLength));
|
||||
}
|
||||
else if (aArgs[argIndex] == "-x")
|
||||
{
|
||||
// Binary hex data payload
|
||||
|
||||
argIndex++;
|
||||
VerifyOrExit(argIndex < aArgsLength, error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = PrepareHexStringPaylod(*message, aArgs[argIndex].GetCString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Text payload (same as without specifying the type)
|
||||
|
||||
if (aArgs[argIndex] == "-t")
|
||||
{
|
||||
bufLen = sizeof(buf);
|
||||
SuccessOrExit(error = ParseAsHexString(hexString, bufLen, buf, Utils::CmdLineParser::kAllowTruncate));
|
||||
VerifyOrExit(bufLen > 0, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
conversionLength = static_cast<uint16_t>(bufLen * 2);
|
||||
|
||||
if ((payloadLength & 0x01) != 0)
|
||||
{
|
||||
conversionLength -= 1;
|
||||
}
|
||||
|
||||
hexString += conversionLength;
|
||||
payloadLength -= conversionLength;
|
||||
SuccessOrExit(error = otMessageAppend(message, buf, bufLen));
|
||||
argIndex++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
VerifyOrExit(argIndex < aArgsLength, error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = otMessageAppend(message, aArgs[argIndex].GetCString(), aArgs[argIndex].GetLength()));
|
||||
}
|
||||
|
||||
error = otUdpSend(mInterpreter.mInstance, &mSocket, message, &messageInfo);
|
||||
SuccessOrExit(error = otUdpSend(mInterpreter.mInstance, &mSocket, message, &messageInfo));
|
||||
|
||||
message = nullptr;
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE && message != nullptr)
|
||||
if (message != nullptr)
|
||||
{
|
||||
otMessageFree(message);
|
||||
}
|
||||
@@ -219,26 +201,28 @@ otError UdpExample::ProcessLinkSecurity(uint8_t aArgsLength, Arg aArgs[])
|
||||
return error;
|
||||
}
|
||||
|
||||
otError UdpExample::WriteCharToBuffer(otMessage *aMessage, uint16_t aMessageSize)
|
||||
otError UdpExample::PrepareAutoGeneratedPayload(otMessage &aMessage, uint16_t aPayloadLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t character = 0x30; // 0
|
||||
uint8_t character = '0';
|
||||
|
||||
for (uint16_t index = 0; index < aMessageSize; index++)
|
||||
for (; aPayloadLength != 0; aPayloadLength--)
|
||||
{
|
||||
SuccessOrExit(error = otMessageAppend(aMessage, &character, 1));
|
||||
character++;
|
||||
SuccessOrExit(error = otMessageAppend(&aMessage, &character, sizeof(character)));
|
||||
|
||||
switch (character)
|
||||
{
|
||||
case 0x3A: // 9
|
||||
character = 0x41; // A
|
||||
case '9':
|
||||
character = 'A';
|
||||
break;
|
||||
case 0x5B: // Z
|
||||
character = 0x61; // a
|
||||
case 'Z':
|
||||
character = 'a';
|
||||
break;
|
||||
case 0x7B: // z
|
||||
character = 0x30; // 0
|
||||
case 'z':
|
||||
character = '0';
|
||||
break;
|
||||
default:
|
||||
character++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -247,6 +231,33 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError UdpExample::PrepareHexStringPaylod(otMessage &aMessage, const char *aHexString)
|
||||
{
|
||||
enum : uint8_t
|
||||
{
|
||||
kBufferSize = 50,
|
||||
};
|
||||
|
||||
otError error;
|
||||
uint8_t buf[kBufferSize];
|
||||
uint16_t length;
|
||||
bool done = false;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
length = sizeof(buf);
|
||||
error = Utils::CmdLineParser::ParseAsHexStringSegment(aHexString, length, buf);
|
||||
|
||||
VerifyOrExit((error == OT_ERROR_NONE) || (error == OT_ERROR_PENDING));
|
||||
done = (error == OT_ERROR_NONE);
|
||||
|
||||
SuccessOrExit(error = otMessageAppend(&aMessage, buf, length));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError UdpExample::Process(uint8_t aArgsLength, Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_INVALID_ARGS;
|
||||
|
||||
Reference in New Issue
Block a user