[cli] fix GetOwner function for console cli backend (#3486)

Current implementation of GetOwner function for single-instance CLI
assumed that `cli_uart` backend is used. This caused application
crash when different backend was used and `cli_uart` was not
initialized (and in result sUartServer static pointer was not set).

This commit fixes the issue by moving static CLI Server pointer and
the mInterpreter field to the to the base Server class and providing
getter method to obtain the Interpreter instance. With this approach,
any backend derived from the Server class will be able to initialize
the static pointer and will provide a valid reference to the
Interpreter class instance.

Signed-off-by: Robert Lubos <[email protected]>
This commit is contained in:
Robert Lubos
2019-01-22 16:07:46 -08:00
committed by Jonathan Hui
parent b1686c61f4
commit 9cb48245e5
20 changed files with 99 additions and 41 deletions
+1
View File
@@ -282,6 +282,7 @@ LOCAL_SRC_FILES := \
src/cli/cli_coap.cpp \
src/cli/cli_console.cpp \
src/cli/cli_dataset.cpp \
src/cli/cli_server.cpp \
src/cli/cli_uart.cpp \
src/cli/cli_udp.cpp \
src/posix/main.c \
@@ -60,6 +60,7 @@
<ClCompile Include="..\..\src\cli\cli.cpp" />
<ClCompile Include="..\..\src\cli\cli_dataset.cpp" />
<ClCompile Include="..\..\src\cli\cli_instance.cpp" />
<ClCompile Include="..\..\src\cli\cli_server.cpp" />
<ClCompile Include="..\..\src\cli\cli_uart.cpp" />
<ClCompile Include="..\..\src\core\utils\missing_strnlen.c" />
<ClCompile Include="..\..\src\core\utils\parse_cmdline.cpp" />
@@ -16,6 +16,9 @@
<ClCompile Include="..\..\src\cli\cli_instance.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\cli\cli_server.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\cli\cli_uart.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -58,6 +58,7 @@
<ItemGroup>
<ClCompile Include="..\..\src\cli\cli.cpp" />
<ClCompile Include="..\..\src\cli\cli_dataset.cpp" />
<ClCompile Include="..\..\src\cli\cli_server.cpp" />
<ClCompile Include="..\..\src\cli\cli_uart.cpp" />
<ClCompile Include="..\..\src\cli\cli_udp.cpp" />
</ItemGroup>
@@ -12,7 +12,10 @@
</ClCompile>
<ClCompile Include="..\..\src\cli\cli_dataset.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ClCompile>
<ClCompile Include="..\..\src\cli\cli_server.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\cli\cli_uart.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+1
View File
@@ -147,6 +147,7 @@ SOURCES_COMMON = \
cli_coap_secure.cpp \
cli_console.cpp \
cli_dataset.cpp \
cli_server.cpp \
cli_uart.cpp \
cli_udp.cpp \
$(NULL)
+1 -1
View File
@@ -3916,7 +3916,7 @@ Interpreter &Interpreter::GetOwner(OwnerLocator &aOwnerLocator)
#else
OT_UNUSED_VARIABLE(aOwnerLocator);
Interpreter &interpreter = Uart::sUartServer->GetInterpreter();
Interpreter &interpreter = Server::sServer->GetInterpreter();
#endif
return interpreter;
}
+1 -1
View File
@@ -43,7 +43,6 @@
#include <openthread/udp.h>
#include "cli/cli_dataset.hpp"
#include "cli/cli_server.hpp"
#include "cli/cli_udp.hpp"
#if OPENTHREAD_ENABLE_APPLICATION_COAP
@@ -82,6 +81,7 @@ namespace ot {
namespace Cli {
class Interpreter;
class Server;
/**
* This structure represents a CLI command.
+1
View File
@@ -38,6 +38,7 @@
#include <ctype.h>
#include "cli/cli.hpp"
#include "cli/cli_server.hpp"
#include "coap/coap_message.hpp"
namespace ot {
+1
View File
@@ -39,6 +39,7 @@
#include <openthread/ip6.h>
#include "cli/cli.hpp"
#include "cli/cli_server.hpp"
// header for place your x509 certificate and private key
#include "x509_cert_key.hpp"
+6 -8
View File
@@ -45,28 +45,26 @@
namespace ot {
namespace Cli {
static Console *sServer;
static otDEFINE_ALIGNED_VAR(sCliConsoleRaw, sizeof(Console), uint64_t);
extern "C" void otCliConsoleInit(otInstance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext)
{
Instance *instance = static_cast<Instance *>(aInstance);
sServer = new (&sCliConsoleRaw) Console(instance);
sServer->SetOutputCallback(aCallback);
sServer->SetContext(aContext);
Server::sServer = new (&sCliConsoleRaw) Console(instance);
static_cast<Console *>(Server::sServer)->SetOutputCallback(aCallback);
static_cast<Console *>(Server::sServer)->SetContext(aContext);
}
extern "C" void otCliConsoleInputLine(char *aBuf, uint16_t aBufLength)
{
sServer->ReceiveTask(aBuf, aBufLength);
static_cast<Console *>(Server::sServer)->ReceiveTask(aBuf, aBufLength);
}
Console::Console(Instance *aInstance)
: mCallback(NULL)
: Server(aInstance)
, mCallback(NULL)
, mContext(NULL)
, mInterpreter(aInstance)
{
}
-2
View File
@@ -107,8 +107,6 @@ private:
otCliConsoleOutputCallback mCallback;
void * mContext;
Interpreter mInterpreter;
};
} // namespace Cli
+1
View File
@@ -40,6 +40,7 @@
#include <openthread/dataset.h>
#include "cli/cli.hpp"
#include "cli/cli_server.hpp"
namespace ot {
namespace Cli {
-2
View File
@@ -40,8 +40,6 @@
#include <openthread/dataset.h>
#include "cli/cli_server.hpp"
namespace ot {
namespace Cli {
+1
View File
@@ -37,6 +37,7 @@
#include <stdlib.h>
#include "cli.hpp"
#include "cli_server.hpp"
#include "common/debug.hpp"
#include "utils/wrap_string.h"
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2019, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file provides the static fields for CLI server.
*/
#include "cli_server.hpp"
namespace ot {
namespace Cli {
Server *Server::sServer;
} // namespace Cli
} // namespace ot
+21
View File
@@ -36,6 +36,8 @@
#include "openthread-core-config.h"
#include "cli/cli.hpp"
namespace ot {
namespace Cli {
@@ -46,6 +48,12 @@ namespace Cli {
class Server
{
public:
Server(Instance *aInstance)
: mInterpreter(aInstance)
{
;
}
/**
* This method delivers raw characters to the client.
*
@@ -80,6 +88,19 @@ public:
OT_UNUSED_VARIABLE(aFormat);
return -1;
}
/**
* This method returns a reference to the interpreter object.
*
* @returns A reference to the interpreter object.
*
*/
Interpreter &GetInterpreter(void) { return mInterpreter; }
static Server *sServer;
protected:
Interpreter mInterpreter;
};
} // namespace Cli
+12 -14
View File
@@ -87,47 +87,45 @@
namespace ot {
namespace Cli {
Uart *Uart::sUartServer;
static otDEFINE_ALIGNED_VAR(sCliUartRaw, sizeof(Uart), uint64_t);
extern "C" void otCliUartInit(otInstance *aInstance)
{
Instance *instance = static_cast<Instance *>(aInstance);
Uart::sUartServer = new (&sCliUartRaw) Uart(instance);
Server::sServer = new (&sCliUartRaw) Uart(instance);
}
extern "C" void otCliUartSetUserCommands(const otCliCommand *aUserCommands, uint8_t aLength)
{
Uart::sUartServer->GetInterpreter().SetUserCommands(aUserCommands, aLength);
Server::sServer->GetInterpreter().SetUserCommands(aUserCommands, aLength);
}
extern "C" void otCliUartOutputBytes(const uint8_t *aBytes, uint8_t aLength)
{
Uart::sUartServer->GetInterpreter().OutputBytes(aBytes, aLength);
Server::sServer->GetInterpreter().OutputBytes(aBytes, aLength);
}
extern "C" void otCliUartOutputFormat(const char *aFmt, ...)
{
va_list aAp;
va_start(aAp, aFmt);
Uart::sUartServer->OutputFormatV(aFmt, aAp);
static_cast<Uart *>(Server::sServer)->OutputFormatV(aFmt, aAp);
va_end(aAp);
}
extern "C" void otCliUartOutput(const char *aString, uint16_t aLength)
{
Uart::sUartServer->Output(aString, aLength);
Server::sServer->Output(aString, aLength);
}
extern "C" void otCliUartAppendResult(otError aError)
{
Uart::sUartServer->GetInterpreter().AppendResult(aError);
Server::sServer->GetInterpreter().AppendResult(aError);
}
Uart::Uart(Instance *aInstance)
: mInterpreter(aInstance)
: Server(aInstance)
{
mRxLength = 0;
mTxHead = 0;
@@ -139,7 +137,7 @@ Uart::Uart(Instance *aInstance)
extern "C" void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength)
{
Uart::sUartServer->ReceiveTask(aBuf, aBufLength);
static_cast<Uart *>(Server::sServer)->ReceiveTask(aBuf, aBufLength);
}
void Uart::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength)
@@ -339,7 +337,7 @@ exit:
extern "C" void otPlatUartSendDone(void)
{
Uart::sUartServer->SendDoneTask();
static_cast<Uart *>(Server::sServer)->SendDoneTask();
}
void Uart::SendDoneTask(void)
@@ -356,10 +354,10 @@ extern "C" void otCliPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, cons
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
VerifyOrExit(Uart::sUartServer != NULL);
VerifyOrExit(Server::sServer != NULL);
Uart::sUartServer->OutputFormatV(aFormat, aArgs);
Uart::sUartServer->OutputFormat("\r\n");
static_cast<Uart *>(Server::sServer)->OutputFormatV(aFormat, aArgs);
Server::sServer->OutputFormat("\r\n");
exit:
return;
-12
View File
@@ -92,19 +92,9 @@ public:
*/
int OutputFormatV(const char *aFmt, va_list aAp);
/**
* This method returns a reference to the interpreter object.
*
* @returns A reference to the interpreter object.
*
*/
Interpreter &GetInterpreter(void) { return mInterpreter; }
void ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength);
void SendDoneTask(void);
static Uart *sUartServer;
private:
enum
{
@@ -125,8 +115,6 @@ private:
uint16_t mSendLength;
Interpreter mInterpreter;
friend class Interpreter;
};
+1
View File
@@ -37,6 +37,7 @@
#include <openthread/udp.h>
#include "cli/cli.hpp"
#include "cli/cli_server.hpp"
#include "common/encoding.hpp"
using ot::Encoding::BigEndian::HostSwap16;