mirror of
https://github.com/espressif/openthread.git
synced 2026-08-02 09:07:47 +00:00
Replace CLI response buffer with direct output via CLI server. (#75)
* Added new Output method that allows format strings. * Added an output FIFO to the CLI serial server.
This commit is contained in:
+59
-75
@@ -76,8 +76,6 @@ const struct Command Interpreter::sCommands[] =
|
||||
{ "whitelist", &ProcessWhitelist },
|
||||
};
|
||||
|
||||
ResponseBuffer Interpreter::sResponse;
|
||||
|
||||
otNetifAddress Interpreter::sAddress;
|
||||
|
||||
Ip6::IcmpEcho Interpreter::sIcmpEcho(&HandleEchoResponse, NULL);
|
||||
@@ -139,11 +137,11 @@ void Interpreter::AppendResult(ThreadError error)
|
||||
{
|
||||
if (error == kThreadError_None)
|
||||
{
|
||||
sResponse.Append("Done\r\n");
|
||||
sServer->OutputFormat("Done\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sResponse.Append("Error %d\r\n", error);
|
||||
sServer->OutputFormat("Error %d\r\n", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +156,7 @@ void Interpreter::ProcessHelp(int argc, char *argv[])
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof(sCommands) / sizeof(sCommands[0]); i++)
|
||||
{
|
||||
sResponse.Append("%s\r\n", sCommands[i].mName);
|
||||
sServer->OutputFormat("%s\r\n", sCommands[i].mName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +167,7 @@ void Interpreter::ProcessChannel(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%d\r\n", otGetChannel());
|
||||
sServer->OutputFormat("%d\r\n", otGetChannel());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -188,7 +186,7 @@ void Interpreter::ProcessChildTimeout(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%d\r\n", otGetChildTimeout());
|
||||
sServer->OutputFormat("%d\r\n", otGetChildTimeout());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -207,7 +205,7 @@ void Interpreter::ProcessContextIdReuseDelay(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%d\r\n", otGetContextIdReuseDelay());
|
||||
sServer->OutputFormat("%d\r\n", otGetContextIdReuseDelay());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -222,9 +220,9 @@ exit:
|
||||
void Interpreter::ProcessExtAddress(int argc, char *argv[])
|
||||
{
|
||||
const uint8_t *extAddress = otGetExtendedAddress();
|
||||
sResponse.Append("%02x%02x%02x%02x%02x%02x%02x%02x\r\n",
|
||||
extAddress[0], extAddress[1], extAddress[2], extAddress[3],
|
||||
extAddress[4], extAddress[5], extAddress[6], extAddress[7]);
|
||||
sServer->OutputFormat("%02x%02x%02x%02x%02x%02x%02x%02x\r\n",
|
||||
extAddress[0], extAddress[1], extAddress[2], extAddress[3],
|
||||
extAddress[4], extAddress[5], extAddress[6], extAddress[7]);
|
||||
AppendResult(kThreadError_None);
|
||||
}
|
||||
|
||||
@@ -235,9 +233,9 @@ void Interpreter::ProcessExtPanId(int argc, char *argv[])
|
||||
if (argc == 0)
|
||||
{
|
||||
const uint8_t *extPanId = otGetExtendedPanId();
|
||||
sResponse.Append("%02x%02x%02x%02x%02x%02x%02x%02x\r\n",
|
||||
extPanId[0], extPanId[1], extPanId[2], extPanId[3],
|
||||
extPanId[4], extPanId[5], extPanId[6], extPanId[7]);
|
||||
sServer->OutputFormat("%02x%02x%02x%02x%02x%02x%02x%02x\r\n",
|
||||
extPanId[0], extPanId[1], extPanId[2], extPanId[3],
|
||||
extPanId[4], extPanId[5], extPanId[6], extPanId[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -291,11 +289,11 @@ void Interpreter::ProcessIpAddr(int argc, char *argv[])
|
||||
{
|
||||
for (const otNetifAddress *addr = otGetUnicastAddresses(); addr; addr = addr->mNext)
|
||||
{
|
||||
sResponse.Append("%x:%x:%x:%x:%x:%x:%x:%x\r\n",
|
||||
HostSwap16(addr->mAddress.m16[0]), HostSwap16(addr->mAddress.m16[1]),
|
||||
HostSwap16(addr->mAddress.m16[2]), HostSwap16(addr->mAddress.m16[3]),
|
||||
HostSwap16(addr->mAddress.m16[4]), HostSwap16(addr->mAddress.m16[5]),
|
||||
HostSwap16(addr->mAddress.m16[6]), HostSwap16(addr->mAddress.m16[7]));
|
||||
sServer->OutputFormat("%x:%x:%x:%x:%x:%x:%x:%x\r\n",
|
||||
HostSwap16(addr->mAddress.m16[0]), HostSwap16(addr->mAddress.m16[1]),
|
||||
HostSwap16(addr->mAddress.m16[2]), HostSwap16(addr->mAddress.m16[3]),
|
||||
HostSwap16(addr->mAddress.m16[4]), HostSwap16(addr->mAddress.m16[5]),
|
||||
HostSwap16(addr->mAddress.m16[6]), HostSwap16(addr->mAddress.m16[7]));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -321,7 +319,7 @@ void Interpreter::ProcessKeySequence(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%d\r\n", otGetKeySequenceCounter());
|
||||
sServer->OutputFormat("%d\r\n", otGetKeySequenceCounter());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -340,7 +338,7 @@ void Interpreter::ProcessLeaderWeight(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%d\r\n", otGetLocalLeaderWeight());
|
||||
sServer->OutputFormat("%d\r\n", otGetLocalLeaderWeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -363,10 +361,10 @@ void Interpreter::ProcessMasterKey(int argc, char *argv[])
|
||||
|
||||
for (int i = 0; i < keyLength; i++)
|
||||
{
|
||||
sResponse.Append("%02x", key[i]);
|
||||
sServer->OutputFormat("%02x", key[i]);
|
||||
}
|
||||
|
||||
sResponse.Append("\r\n");
|
||||
sServer->OutputFormat("\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -391,25 +389,25 @@ void Interpreter::ProcessMode(int argc, char *argv[])
|
||||
|
||||
if (linkMode.mRxOnWhenIdle)
|
||||
{
|
||||
sResponse.Append("r");
|
||||
sServer->OutputFormat("r");
|
||||
}
|
||||
|
||||
if (linkMode.mSecureDataRequests)
|
||||
{
|
||||
sResponse.Append("s");
|
||||
sServer->OutputFormat("s");
|
||||
}
|
||||
|
||||
if (linkMode.mDeviceType)
|
||||
{
|
||||
sResponse.Append("d");
|
||||
sServer->OutputFormat("d");
|
||||
}
|
||||
|
||||
if (linkMode.mNetworkData)
|
||||
{
|
||||
sResponse.Append("n");
|
||||
sServer->OutputFormat("n");
|
||||
}
|
||||
|
||||
sResponse.Append("\r\n");
|
||||
sServer->OutputFormat("\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -461,7 +459,7 @@ void Interpreter::ProcessNetworkIdTimeout(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%d\r\n", otGetNetworkIdTimeout());
|
||||
sServer->OutputFormat("%d\r\n", otGetNetworkIdTimeout());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -479,7 +477,7 @@ void Interpreter::ProcessNetworkName(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%.*s\r\n", OT_NETWORK_NAME_SIZE, otGetNetworkName());
|
||||
sServer->OutputFormat("%.*s\r\n", OT_NETWORK_NAME_SIZE, otGetNetworkName());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -497,7 +495,7 @@ void Interpreter::ProcessPanId(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%d\r\n", otGetPanId());
|
||||
sServer->OutputFormat("%d\r\n", otGetPanId());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -515,16 +513,13 @@ void Interpreter::HandleEchoResponse(void *aContext, Message &aMessage, const Ip
|
||||
|
||||
aMessage.Read(aMessage.GetOffset(), sizeof(icmp6Header), &icmp6Header);
|
||||
|
||||
sResponse.Init();
|
||||
sResponse.Append("%d bytes from ", aMessage.GetLength() - aMessage.GetOffset());
|
||||
sResponse.Append("%x:%x:%x:%x:%x:%x:%x:%x",
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().m16[0]), HostSwap16(aMessageInfo.GetPeerAddr().m16[1]),
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().m16[2]), HostSwap16(aMessageInfo.GetPeerAddr().m16[3]),
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().m16[4]), HostSwap16(aMessageInfo.GetPeerAddr().m16[5]),
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().m16[6]), HostSwap16(aMessageInfo.GetPeerAddr().m16[7]));
|
||||
sResponse.Append(": icmp_seq=%d hlim=%d\r\n", icmp6Header.GetSequence(), aMessageInfo.mHopLimit);
|
||||
|
||||
sServer->Output(sResponse.GetResponse(), sResponse.GetResponseLength());
|
||||
sServer->OutputFormat("%d bytes from ", aMessage.GetLength() - aMessage.GetOffset());
|
||||
sServer->OutputFormat("%x:%x:%x:%x:%x:%x:%x:%x",
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().m16[0]), HostSwap16(aMessageInfo.GetPeerAddr().m16[1]),
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().m16[2]), HostSwap16(aMessageInfo.GetPeerAddr().m16[3]),
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().m16[4]), HostSwap16(aMessageInfo.GetPeerAddr().m16[5]),
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().m16[6]), HostSwap16(aMessageInfo.GetPeerAddr().m16[7]));
|
||||
sServer->OutputFormat(": icmp_seq=%d hlim=%d\r\n", icmp6Header.GetSequence(), aMessageInfo.mHopLimit);
|
||||
}
|
||||
|
||||
void Interpreter::ProcessPing(int argc, char *argv[])
|
||||
@@ -545,8 +540,6 @@ void Interpreter::ProcessPing(int argc, char *argv[])
|
||||
|
||||
sIcmpEcho.SendEchoRequest(sSockAddr, sEchoRequest, length);
|
||||
|
||||
sResponse.Init();
|
||||
|
||||
return;
|
||||
|
||||
exit:
|
||||
@@ -710,8 +703,8 @@ exit:
|
||||
|
||||
void Interpreter::ProcessRloc16(int argc, char *argv[])
|
||||
{
|
||||
sResponse.Append("%04x\r\n", otGetRloc16());
|
||||
sResponse.Append("Done\r\n");
|
||||
sServer->OutputFormat("%04x\r\n", otGetRloc16());
|
||||
sServer->OutputFormat("Done\r\n");
|
||||
}
|
||||
|
||||
ThreadError Interpreter::ProcessRouteAdd(int argc, char *argv[])
|
||||
@@ -834,7 +827,7 @@ void Interpreter::ProcessRouterUpgradeThreshold(int argc, char *argv[])
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sResponse.Append("%d\r\n", otGetRouterUpgradeThreshold());
|
||||
sServer->OutputFormat("%d\r\n", otGetRouterUpgradeThreshold());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -859,8 +852,8 @@ void Interpreter::ProcessScan(int argc, char *argv[])
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otActiveScan(scanChannels, 0, &HandleActiveScanResult));
|
||||
sResponse.Append("| J | Network Name | Extended PAN | PAN | MAC Address | Ch | dBm |\r\n");
|
||||
sResponse.Append("+---+------------------+------------------+------+------------------+----+-----+\r\n");
|
||||
sServer->OutputFormat("| J | Network Name | Extended PAN | PAN | MAC Address | Ch | dBm |\r\n");
|
||||
sServer->OutputFormat("+---+------------------+------------------+------+------------------+----+-----+\r\n");
|
||||
|
||||
return;
|
||||
|
||||
@@ -872,46 +865,44 @@ void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult)
|
||||
{
|
||||
const uint8_t *bytes;
|
||||
|
||||
sResponse.Init();
|
||||
|
||||
if (aResult == NULL)
|
||||
{
|
||||
sResponse.Append("Done\r\n");
|
||||
sServer->OutputFormat("Done\r\n");
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
sResponse.Append("| %d ", aResult->mIsJoinable);
|
||||
sServer->OutputFormat("| %d ", aResult->mIsJoinable);
|
||||
|
||||
if (aResult->mNetworkName != NULL)
|
||||
{
|
||||
sResponse.Append("| %-16s ", aResult->mNetworkName);
|
||||
sServer->OutputFormat("| %-16s ", aResult->mNetworkName);
|
||||
}
|
||||
else
|
||||
{
|
||||
sResponse.Append("| ---------------- ");
|
||||
sServer->OutputFormat("| ---------------- ");
|
||||
}
|
||||
|
||||
if (aResult->mExtPanId != NULL)
|
||||
{
|
||||
bytes = aResult->mExtPanId;
|
||||
sResponse.Append("| %02x%02x%02x%02x%02x%02x%02x%02x ",
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]);
|
||||
sServer->OutputFormat("| %02x%02x%02x%02x%02x%02x%02x%02x ",
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sResponse.Append("| ---------------- ");
|
||||
sServer->OutputFormat("| ---------------- ");
|
||||
}
|
||||
|
||||
sResponse.Append("| %04x ", aResult->mPanId);
|
||||
sServer->OutputFormat("| %04x ", aResult->mPanId);
|
||||
|
||||
bytes = aResult->mExtAddress.m8;
|
||||
sResponse.Append("| %02x%02x%02x%02x%02x%02x%02x%02x ",
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]);
|
||||
sResponse.Append("| %02d ", aResult->mChannel);
|
||||
sResponse.Append("| %03d |\r\n", aResult->mRssi);
|
||||
sServer->OutputFormat("| %02x%02x%02x%02x%02x%02x%02x%02x ",
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]);
|
||||
sServer->OutputFormat("| %02d ", aResult->mChannel);
|
||||
sServer->OutputFormat("| %03d |\r\n", aResult->mRssi);
|
||||
|
||||
exit:
|
||||
sServer->Output(sResponse.GetResponse(), sResponse.GetResponseLength());
|
||||
return;
|
||||
}
|
||||
|
||||
void Interpreter::ProcessStart(int argc, char *argv[])
|
||||
@@ -933,23 +924,23 @@ void Interpreter::ProcessState(int argc, char *argv[])
|
||||
switch (otGetDeviceRole())
|
||||
{
|
||||
case kDeviceRoleDisabled:
|
||||
sResponse.Append("disabled\r\n");
|
||||
sServer->OutputFormat("disabled\r\n");
|
||||
break;
|
||||
|
||||
case kDeviceRoleDetached:
|
||||
sResponse.Append("detached\r\n");
|
||||
sServer->OutputFormat("detached\r\n");
|
||||
break;
|
||||
|
||||
case kDeviceRoleChild:
|
||||
sResponse.Append("child\r\n");
|
||||
sServer->OutputFormat("child\r\n");
|
||||
break;
|
||||
|
||||
case kDeviceRoleRouter:
|
||||
sResponse.Append("router\r\n");
|
||||
sServer->OutputFormat("router\r\n");
|
||||
break;
|
||||
|
||||
case kDeviceRoleLeader:
|
||||
sResponse.Append("leader\r\n");
|
||||
sServer->OutputFormat("leader\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1060,8 +1051,6 @@ void Interpreter::ProcessLine(char *aBuf, uint16_t aBufLength, Server &aServer)
|
||||
}
|
||||
}
|
||||
|
||||
sResponse.Init();
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(sCommands) / sizeof(sCommands[0]); i++)
|
||||
{
|
||||
if (strcmp(cmd, sCommands[i].mName) == 0)
|
||||
@@ -1071,11 +1060,6 @@ void Interpreter::ProcessLine(char *aBuf, uint16_t aBufLength, Server &aServer)
|
||||
}
|
||||
}
|
||||
|
||||
if (sResponse.GetResponseLength() > 0)
|
||||
{
|
||||
aServer.Output(sResponse.GetResponse(), sResponse.GetResponseLength());
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,55 +50,6 @@ namespace Thread {
|
||||
*/
|
||||
namespace Cli {
|
||||
|
||||
/**
|
||||
* This class implements the response buffer for CLI command results.
|
||||
*
|
||||
*/
|
||||
class ResponseBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the response buffer.
|
||||
*
|
||||
*/
|
||||
void Init(void) { mEnd = mBuffer; }
|
||||
|
||||
/**
|
||||
* This method appends output according to the format string.
|
||||
*
|
||||
* @param[in] fmt A pointer to the NULL-terminated format string.
|
||||
* @param[in] ... Arguments for the format specification.
|
||||
*
|
||||
*/
|
||||
void Append(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(mEnd, sizeof(mBuffer) - (mEnd - mBuffer), fmt, ap);
|
||||
va_end(ap);
|
||||
mEnd += strlen(mEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the response string.
|
||||
*
|
||||
* @returns A pointer to the response string.
|
||||
*
|
||||
*/
|
||||
const char *GetResponse(void) { return mBuffer; }
|
||||
|
||||
/**
|
||||
* This method returns the length of the response string.
|
||||
*
|
||||
* @returns The length to the response string.
|
||||
*
|
||||
*/
|
||||
uint16_t GetResponseLength(void) { return mEnd - mBuffer; }
|
||||
|
||||
private:
|
||||
char mBuffer[512];
|
||||
char *mEnd;
|
||||
};
|
||||
|
||||
/**
|
||||
* This structure represents a CLI command.
|
||||
*
|
||||
@@ -173,8 +124,6 @@ private:
|
||||
static ThreadError ParseLong(char *argv, long &value);
|
||||
|
||||
static const struct Command sCommands[];
|
||||
static ResponseBuffer sResponse;
|
||||
|
||||
static otNetifAddress sAddress;
|
||||
|
||||
static Ip6::SockAddr sSockAddr;
|
||||
|
||||
+82
-11
@@ -31,6 +31,7 @@
|
||||
* This file implements the CLI server on the serial service.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -45,11 +46,12 @@
|
||||
namespace Thread {
|
||||
namespace Cli {
|
||||
|
||||
static const uint8_t sEraseString[] = {'\b', ' ', '\b'};
|
||||
static const uint8_t CRNL[] = {'\r', '\n'};
|
||||
static const char sEraseString[] = {'\b', ' ', '\b'};
|
||||
static const char CRNL[] = {'\r', '\n'};
|
||||
static Serial *sServer;
|
||||
|
||||
Tasklet Serial::sReceiveTask(&ReceiveTask, NULL);
|
||||
Tasklet Serial::sSendDoneTask(&SendDoneTask, NULL);
|
||||
|
||||
Serial::Serial(void)
|
||||
{
|
||||
@@ -59,14 +61,13 @@ Serial::Serial(void)
|
||||
ThreadError Serial::Start(void)
|
||||
{
|
||||
mRxLength = 0;
|
||||
mTxHead = 0;
|
||||
mTxLength = 0;
|
||||
mSendLength = 0;
|
||||
otPlatSerialEnable();
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
extern "C" void otPlatSerialSignalSendDone(void)
|
||||
{
|
||||
}
|
||||
|
||||
extern "C" void otPlatSerialSignalReceive(void)
|
||||
{
|
||||
Serial::sReceiveTask.Post();
|
||||
@@ -92,7 +93,7 @@ void Serial::ReceiveTask(void)
|
||||
{
|
||||
case '\r':
|
||||
case '\n':
|
||||
otPlatSerialSend(CRNL, sizeof(CRNL));
|
||||
Output(CRNL, sizeof(CRNL));
|
||||
|
||||
if (mRxLength > 0)
|
||||
{
|
||||
@@ -104,7 +105,7 @@ void Serial::ReceiveTask(void)
|
||||
|
||||
case '\b':
|
||||
case 127:
|
||||
otPlatSerialSend(sEraseString, sizeof(sEraseString));
|
||||
Output(sEraseString, sizeof(sEraseString));
|
||||
|
||||
if (mRxLength > 0)
|
||||
{
|
||||
@@ -114,7 +115,7 @@ void Serial::ReceiveTask(void)
|
||||
break;
|
||||
|
||||
default:
|
||||
otPlatSerialSend(buf, 1);
|
||||
Output(reinterpret_cast<const char *>(buf), 1);
|
||||
mRxBuffer[mRxLength++] = *buf;
|
||||
break;
|
||||
}
|
||||
@@ -144,9 +145,79 @@ ThreadError Serial::ProcessCommand(void)
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Serial::Output(const char *aBuf, uint16_t aBufLength)
|
||||
int Serial::Output(const char *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
return otPlatSerialSend(reinterpret_cast<const uint8_t *>(aBuf), aBufLength);
|
||||
uint16_t remaining = kTxBufferSize - mTxLength;
|
||||
uint16_t tail = (mTxHead + mTxLength) % kTxBufferSize;
|
||||
|
||||
if (aBufLength > remaining)
|
||||
{
|
||||
aBufLength = remaining;
|
||||
}
|
||||
|
||||
for (int i = 0; i < aBufLength; i++)
|
||||
{
|
||||
tail = (mTxHead + mTxLength) % kTxBufferSize;
|
||||
mTxBuffer[tail] = *aBuf++;
|
||||
mTxLength++;
|
||||
}
|
||||
|
||||
Send();
|
||||
|
||||
return aBufLength;
|
||||
}
|
||||
|
||||
int Serial::OutputFormat(const char *fmt, ...)
|
||||
{
|
||||
char buf[kMaxLineLength];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return Output(buf, strlen(buf));
|
||||
}
|
||||
|
||||
void Serial::Send(void)
|
||||
{
|
||||
VerifyOrExit(mSendLength == 0, ;);
|
||||
|
||||
if (mTxHead + mTxLength > kTxBufferSize)
|
||||
{
|
||||
mSendLength = kTxBufferSize - mTxHead;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSendLength = mTxLength;
|
||||
}
|
||||
|
||||
if (mSendLength > 0)
|
||||
{
|
||||
otPlatSerialSend(reinterpret_cast<uint8_t *>(mTxBuffer + mTxHead), mSendLength);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
extern "C" void otPlatSerialSignalSendDone(void)
|
||||
{
|
||||
Serial::sSendDoneTask.Post();
|
||||
}
|
||||
|
||||
void Serial::SendDoneTask(void *aContext)
|
||||
{
|
||||
sServer->SendDoneTask();
|
||||
}
|
||||
|
||||
void Serial::SendDoneTask(void)
|
||||
{
|
||||
mTxHead = (mTxHead + mSendLength) % kTxBufferSize;
|
||||
mTxLength -= mSendLength;
|
||||
mSendLength = 0;
|
||||
|
||||
Send();
|
||||
}
|
||||
|
||||
} // namespace Cli
|
||||
|
||||
+26
-3
@@ -59,31 +59,54 @@ public:
|
||||
ThreadError Start(void);
|
||||
|
||||
/**
|
||||
* This method delivers output to the client.
|
||||
* This method delivers raw characters to the client.
|
||||
*
|
||||
* @param[in] aBuf A pointer to a buffer.
|
||||
* @param[in] aBufLength Number of bytes in the buffer.
|
||||
*
|
||||
* @retval kThreadError_None Successfully delivered output the client.
|
||||
* @returns The number of bytes placed in the output queue.
|
||||
*
|
||||
*/
|
||||
ThreadError Output(const char *aBuf, uint16_t aBufLength);
|
||||
int Output(const char *aBuf, uint16_t aBufLength);
|
||||
|
||||
/**
|
||||
* This method delivers formatted output to the client.
|
||||
*
|
||||
* @param[in] aFmt A pointer to the format string.
|
||||
* @param[in] ... A variable list of arguments to format.
|
||||
*
|
||||
* @returns The number of bytes placed in the output queue.
|
||||
*
|
||||
*/
|
||||
int OutputFormat(const char *fmt, ...);
|
||||
|
||||
static Tasklet sReceiveTask;
|
||||
static Tasklet sSendDoneTask;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kRxBufferSize = 128,
|
||||
kTxBufferSize = 512,
|
||||
kMaxLineLength = 80,
|
||||
};
|
||||
|
||||
static void ReceiveTask(void *aContext);
|
||||
static void SendDoneTask(void *aContext);
|
||||
|
||||
ThreadError ProcessCommand(void);
|
||||
void ReceiveTask(void);
|
||||
void SendDoneTask(void);
|
||||
void Send(void);
|
||||
|
||||
char mRxBuffer[kRxBufferSize];
|
||||
uint16_t mRxLength;
|
||||
|
||||
char mTxBuffer[kTxBufferSize];
|
||||
uint16_t mTxHead;
|
||||
uint16_t mTxLength;
|
||||
|
||||
uint16_t mSendLength;
|
||||
};
|
||||
|
||||
} // namespace Cli
|
||||
|
||||
+14
-3
@@ -55,15 +55,26 @@ public:
|
||||
virtual ThreadError Start() = 0;
|
||||
|
||||
/**
|
||||
* This method delivers output to the client.
|
||||
* This method delivers raw characters to the client.
|
||||
*
|
||||
* @param[in] aBuf A pointer to a buffer.
|
||||
* @param[in] aBufLength Number of bytes in the buffer.
|
||||
*
|
||||
* @retval kThreadError_None Successfully delivered output the client.
|
||||
* @returns The number of bytes placed in the output queue.
|
||||
*
|
||||
*/
|
||||
virtual ThreadError Output(const char *aBuf, uint16_t aBufLength) = 0;
|
||||
virtual int Output(const char *aBuf, uint16_t aBufLength) = 0;
|
||||
|
||||
/**
|
||||
* This method delivers formatted output to the client.
|
||||
*
|
||||
* @param[in] aFmt A pointer to the format string.
|
||||
* @param[in] ... A variable list of arguments to format.
|
||||
*
|
||||
* @returns The number of bytes placed in the output queue.
|
||||
*
|
||||
*/
|
||||
virtual int OutputFormat(const char *fmt, ...) = 0;
|
||||
};
|
||||
|
||||
} // namespace Cli
|
||||
|
||||
+16
-2
@@ -31,6 +31,7 @@
|
||||
* This file implements the CLI server on a UDP socket.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -87,7 +88,7 @@ exit:
|
||||
{}
|
||||
}
|
||||
|
||||
ThreadError Udp::Output(const char *aBuf, uint16_t aBufLength)
|
||||
int Udp::Output(const char *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
otMessage message;
|
||||
@@ -102,9 +103,22 @@ exit:
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
otFreeMessage(message);
|
||||
aBufLength = 0;
|
||||
}
|
||||
|
||||
return error;
|
||||
return aBufLength;
|
||||
}
|
||||
|
||||
int Udp::OutputFormat(const char *fmt, ...)
|
||||
{
|
||||
char buf[kMaxLineLength];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return Output(buf, strlen(buf));
|
||||
}
|
||||
|
||||
} // namespace Cli
|
||||
|
||||
+19
-3
@@ -56,17 +56,33 @@ public:
|
||||
ThreadError Start(void);
|
||||
|
||||
/**
|
||||
* This method delivers output to the client.
|
||||
* This method delivers raw characters to the client.
|
||||
*
|
||||
* @param[in] aBuf A pointer to a buffer.
|
||||
* @param[in] aBufLength Number of bytes in the buffer.
|
||||
*
|
||||
* @retval kThreadError_None Successfully delivered output the client.
|
||||
* @returns The number of bytes placed in the output queue.
|
||||
*
|
||||
*/
|
||||
ThreadError Output(const char *aBuf, uint16_t aBufLength);
|
||||
int Output(const char *aBuf, uint16_t aBufLength);
|
||||
|
||||
/**
|
||||
* This method delivers formatted output to the client.
|
||||
*
|
||||
* @param[in] aFmt A pointer to the format string.
|
||||
* @param[in] ... A variable list of arguments to format.
|
||||
*
|
||||
* @returns The number of bytes placed in the output queue.
|
||||
*
|
||||
*/
|
||||
int OutputFormat(const char *fmt, ...);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMaxLineLength = 80,
|
||||
};
|
||||
|
||||
static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleUdpReceive(otMessage aMessage, const otMessageInfo *aMessageInfo);
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ class Node:
|
||||
|
||||
def get_key_sequence(self):
|
||||
self.send_command('keysequence')
|
||||
i = self.pexpect.expect('(\d+)')
|
||||
i = self.pexpect.expect('(\d+)\r\n')
|
||||
if i == 0:
|
||||
key_sequence = int(self.pexpect.match.groups()[0])
|
||||
self.pexpect.expect('Done')
|
||||
@@ -205,7 +205,7 @@ class Node:
|
||||
|
||||
def get_timeout(self):
|
||||
self.send_command('childtimeout')
|
||||
i = self.pexpect.expect('(\d+)')
|
||||
i = self.pexpect.expect('(\d+)\r\n')
|
||||
if i == 0:
|
||||
timeout = self.pexpect.match.groups()[0]
|
||||
self.pexpect.expect('Done')
|
||||
@@ -218,7 +218,7 @@ class Node:
|
||||
|
||||
def get_weight(self):
|
||||
self.send_command('leaderweight')
|
||||
i = self.pexpect.expect('(\d+)')
|
||||
i = self.pexpect.expect('(\d+)\r\n')
|
||||
if i == 0:
|
||||
weight = self.pexpect.match.groups()[0]
|
||||
self.pexpect.expect('Done')
|
||||
@@ -239,7 +239,7 @@ class Node:
|
||||
self.send_command('ipaddr')
|
||||
|
||||
while True:
|
||||
i = self.pexpect.expect(['(\S+:\S+)', 'Done'])
|
||||
i = self.pexpect.expect(['(\S+:\S+)\r\n', 'Done'])
|
||||
if i == 0:
|
||||
addrs.append(self.pexpect.match.groups()[0])
|
||||
elif i == 1:
|
||||
@@ -249,7 +249,7 @@ class Node:
|
||||
|
||||
def get_context_reuse_delay(self):
|
||||
self.send_command('contextreusedelay')
|
||||
i = self.pexpect.expect('(\d+)')
|
||||
i = self.pexpect.expect('(\d+)\r\n')
|
||||
if i == 0:
|
||||
timeout = self.pexpect.match.groups()[0]
|
||||
self.pexpect.expect('Done')
|
||||
@@ -289,7 +289,7 @@ class Node:
|
||||
|
||||
results = []
|
||||
while True:
|
||||
i = self.pexpect.expect(['\|\s(\S+)\s+\|\s(\S+)\s+\|\s([0-9a-fA-F]{4})\s\|\s([0-9a-fA-F]{16})\s\|\s(\d+)',
|
||||
i = self.pexpect.expect(['\|\s(\S+)\s+\|\s(\S+)\s+\|\s([0-9a-fA-F]{4})\s\|\s([0-9a-fA-F]{16})\s\|\s(\d+)\r\n',
|
||||
'Done'])
|
||||
if i == 0:
|
||||
results.append(self.pexpect.match.groups())
|
||||
|
||||
Reference in New Issue
Block a user