From 9ff00bdbae2859341dbdcc1ee12108e8a13ef852 Mon Sep 17 00:00:00 2001 From: Shu Chen Date: Fri, 19 Aug 2016 09:00:06 +0800 Subject: [PATCH] ncp-spinel: Add STREAM_MFG property for diagnostics module (#403) It's a generic stream property which doesn't take care of the diagnostics feature details - get diags commands from the property with VALUE_SET command - return diags output to the property with VALUE_IS command --- include/openthread-diag.h | 2 ++ src/diag/diag_process.cpp | 2 ++ src/diag/openthread-diag.cpp | 25 ++++++++++++++++++++++ src/ncp/ncp_base.cpp | 41 +++++++++++++++++++++++++++++++++++- src/ncp/ncp_base.hpp | 6 ++++++ src/ncp/spinel.c | 4 ++++ src/ncp/spinel.h | 1 + tests/unit/test_diag.cpp | 21 ++---------------- 8 files changed, 82 insertions(+), 20 deletions(-) diff --git a/include/openthread-diag.h b/include/openthread-diag.h index c99857d12..d418abec3 100644 --- a/include/openthread-diag.h +++ b/include/openthread-diag.h @@ -43,6 +43,8 @@ void diagInit(); char *diagProcessCmd(int argc, char *argv[]); +char *diagProcessCmdLine(char *string); + bool isDiagEnabled(); #ifdef __cplusplus diff --git a/src/diag/diag_process.cpp b/src/diag/diag_process.cpp index bcdd8aedc..139c91fbe 100644 --- a/src/diag/diag_process.cpp +++ b/src/diag/diag_process.cpp @@ -354,6 +354,8 @@ void Diag::DiagReceiveDone(RadioPacket *aFrame, ThreadError aError) sStats.received_packets++; } + + otPlatRadioReceive(sChannel); } void Diag::AlarmFired() diff --git a/src/diag/openthread-diag.cpp b/src/diag/openthread-diag.cpp index 3d221d1a0..3594a8b96 100644 --- a/src/diag/openthread-diag.cpp +++ b/src/diag/openthread-diag.cpp @@ -56,6 +56,31 @@ char *diagProcessCmd(int argc, char *argv[]) return Diag::ProcessCmd(argc, argv); } +char *diagProcessCmdLine(char *string) +{ + char *argv[8]; + int argc = 0; + int length = static_cast(strlen(string)); + char *cmd; + + for (; *string == ' '; string++, length--); + + for (cmd = string + 1; (cmd < string + length) && (cmd != NULL); ++cmd) + { + if (*cmd == ' ' || *cmd == '\r' || *cmd == '\n') + { + *cmd = '\0'; + } + + if (*(cmd - 1) == '\0' && *cmd != ' ') + { + argv[argc++] = cmd; + } + } + + return Diag::ProcessCmd(argc, argv); +} + bool isDiagEnabled() { return Diag::isEnabled(); diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index b0427a5e7..1436a86ee 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include @@ -217,6 +217,9 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] = { SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD, &NcpBase::SetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD }, { SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY, &NcpBase::SetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY }, +#if OPENTHREAD_ENABLE_DIAG + { SPINEL_PROP_NEST_STREAM_MFG, &NcpBase::SetPropertyHandler_NEST_STREAM_MFG }, +#endif }; const NcpBase::InsertPropertyHandlerEntry NcpBase::mInsertPropertyHandlerTable[] = @@ -3342,6 +3345,42 @@ ThreadError NcpBase::SetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT(uint8_t header return errorCode; } +#if OPENTHREAD_ENABLE_DIAG +ThreadError NcpBase::SetPropertyHandler_NEST_STREAM_MFG(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) +{ + char *string(NULL); + char *output(NULL); + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_UTF8_S, + &string + ); + + if ((parsedLength > 0) && (string != NULL)) + { + // all diagnostics related features are processed within diagnostics module + output = diagProcessCmdLine(string); + + errorCode = SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + reinterpret_cast(output), + static_cast(strlen(output) + 1) + ); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} +#endif // ---------------------------------------------------------------------------- // MARK: Individual Property Inserters diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index 076ccfe6e..4275760f8 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -34,6 +34,7 @@ #define NCP_BASE_HPP_ #include +#include #include #include @@ -361,6 +362,11 @@ private: ThreadError SetPropertyHandler_CNTR_RESET(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); +#if OPENTHREAD_ENABLE_DIAG + ThreadError SetPropertyHandler_NEST_STREAM_MFG(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, + uint16_t value_len); +#endif + ThreadError InsertPropertyHandler_IPV6_ADDRESS_TABLE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError InsertPropertyHandler_THREAD_LOCAL_ROUTES(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c index 90a592390..6678cabb4 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1130,6 +1130,10 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "PROP_THREAD_CONTEXT_REUSE_DELAY"; break; + case SPINEL_PROP_NEST_STREAM_MFG: + ret = "SPINEL_PROP_NEST_STREAM_MFG"; + break; + default: break; } diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index bc5152b7f..c1669dd9a 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -639,6 +639,7 @@ typedef enum SPINEL_PROP_CNTR__END = 2048, SPINEL_PROP_NEST__BEGIN = 15296, + SPINEL_PROP_NEST_STREAM_MFG = SPINEL_PROP_NEST__BEGIN + 0, SPINEL_PROP_NEST__END = 15360, SPINEL_PROP_VENDOR__BEGIN = 15360, diff --git a/tests/unit/test_diag.cpp b/tests/unit/test_diag.cpp index 88fd8b367..ede0d42dc 100644 --- a/tests/unit/test_diag.cpp +++ b/tests/unit/test_diag.cpp @@ -155,28 +155,11 @@ void TestDiag() for (unsigned int i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { char string[50]; - int length = strlen(tests[i].command); - char *cmd; char *output = NULL; - argc = 0; + memcpy(string, tests[i].command, strlen(tests[i].command) + 1); - memcpy(string, tests[i].command, length + 1); - - for (cmd = string + 1; (cmd < string + length) && (cmd != NULL); ++cmd) - { - if (*cmd == ' ' || *cmd == '\r' || *cmd == '\n') - { - *cmd = '\0'; - } - - if (*(cmd - 1) == '\0' && *cmd != ' ') - { - argv[argc++] = cmd; - } - } - - output = diagProcessCmd(argc, argv); + output = diagProcessCmdLine(string); VerifyOrQuit(memcmp(output, tests[i].output, strlen(tests[i].output)) == 0, "Test Diagnostics module failed\r\n"); }