diff --git a/Android.mk b/Android.mk index f2392faf1..0346ab60f 100644 --- a/Android.mk +++ b/Android.mk @@ -340,6 +340,7 @@ LOCAL_SRC_FILES := \ src/lib/url/url.cpp \ src/posix/platform/alarm.cpp \ src/posix/platform/backbone.cpp \ + src/posix/platform/daemon.cpp \ src/posix/platform/entropy.cpp \ src/posix/platform/hdlc_interface.cpp \ src/posix/platform/infra_if.cpp \ @@ -353,7 +354,6 @@ LOCAL_SRC_FILES := \ src/posix/platform/settings.cpp \ src/posix/platform/spi_interface.cpp \ src/posix/platform/system.cpp \ - src/posix/platform/uart.cpp \ src/posix/platform/udp.cpp \ third_party/mbedtls/repo/library/aes.c \ third_party/mbedtls/repo/library/asn1parse.c \ @@ -420,7 +420,6 @@ LOCAL_C_INCLUDES := \ LOCAL_CFLAGS := \ $(OPENTHREAD_PUBLIC_CFLAGS) \ $(OPENTHREAD_PRIVATE_CFLAGS) \ - -DOPENTHREAD_CONFIG_UART_CLI_RAW=1 \ $(OPENTHREAD_PROJECT_CFLAGS) \ $(NULL) @@ -434,13 +433,11 @@ LOCAL_SRC_FILES := \ src/cli/cli_coap.cpp \ src/cli/cli_coap_secure.cpp \ src/cli/cli_commissioner.cpp \ - src/cli/cli_console.cpp \ src/cli/cli_dataset.cpp \ src/cli/cli_joiner.cpp \ src/cli/cli_network_data.cpp \ src/cli/cli_srp_client.cpp \ src/cli/cli_srp_server.cpp \ - src/cli/cli_uart.cpp \ src/cli/cli_udp.cpp \ $(NULL) @@ -484,97 +481,13 @@ LOCAL_LDLIBS := \ -lutil LOCAL_SRC_FILES := \ + src/posix/cli.cpp \ src/posix/main.c \ $(NULL) LOCAL_STATIC_LIBRARIES = libopenthread-cli ot-core include $(BUILD_EXECUTABLE) -include $(CLEAR_VARS) - -LOCAL_MODULE := libopenthread-ncp -LOCAL_MODULE_TAGS := eng - -LOCAL_C_INCLUDES := \ - $(OPENTHREAD_PROJECT_INCLUDES) \ - $(LOCAL_PATH)/include \ - $(LOCAL_PATH)/src \ - $(LOCAL_PATH)/src/core \ - $(LOCAL_PATH)/src/ncp \ - $(LOCAL_PATH)/src/posix/platform \ - $(LOCAL_PATH)/src/posix/platform/include \ - $(LOCAL_PATH)/third_party/mbedtls \ - $(LOCAL_PATH)/third_party/mbedtls/repo/include \ - $(NULL) - -LOCAL_CFLAGS := \ - $(OPENTHREAD_PUBLIC_CFLAGS) \ - $(OPENTHREAD_PRIVATE_CFLAGS) \ - $(OPENTHREAD_PROJECT_CFLAGS) \ - $(NULL) - -LOCAL_CPPFLAGS := \ - -std=c++11 \ - -pedantic-errors \ - $(NULL) - -LOCAL_SRC_FILES := \ - src/lib/spinel/spinel_buffer.cpp \ - src/ncp/changed_props_set.cpp \ - src/ncp/ncp_base.cpp \ - src/ncp/ncp_base_mtd.cpp \ - src/ncp/ncp_base_ftd.cpp \ - src/ncp/ncp_base_dispatcher.cpp \ - src/ncp/ncp_uart.cpp \ - $(NULL) - -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) - -LOCAL_MODULE := ot-ncp -LOCAL_MODULE_TAGS := eng - -ifneq ($(ANDROID_NDK),1) -LOCAL_SHARED_LIBRARIES := libcutils -endif - -LOCAL_C_INCLUDES := \ - $(OPENTHREAD_PROJECT_INCLUDES) \ - $(LOCAL_PATH)/include \ - $(LOCAL_PATH)/src \ - $(LOCAL_PATH)/src/core \ - $(LOCAL_PATH)/src/ncp \ - $(LOCAL_PATH)/src/posix/platform \ - $(LOCAL_PATH)/src/posix/platform/include \ - $(LOCAL_PATH)/third_party/mbedtls \ - $(LOCAL_PATH)/third_party/mbedtls/repo/include \ - $(NULL) - -LOCAL_CFLAGS := \ - $(OPENTHREAD_PUBLIC_CFLAGS) \ - $(OPENTHREAD_PRIVATE_CFLAGS) \ - -DOPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_NCP \ - $(OPENTHREAD_PROJECT_CFLAGS) \ - $(NULL) - -LOCAL_CPPFLAGS := \ - -std=c++11 \ - -pedantic-errors \ - $(NULL) - -LOCAL_SRC_FILES := \ - src/posix/main.c \ - $(NULL) - -LOCAL_LDLIBS := \ - -lrt \ - -lutil - -LOCAL_STATIC_LIBRARIES = libopenthread-ncp ot-core - -include $(BUILD_EXECUTABLE) - ifeq ($(USE_OTBR_DAEMON), 1) include $(CLEAR_VARS) diff --git a/doc/site/en/guides/porting/implement-platform-abstraction-layer-apis.md b/doc/site/en/guides/porting/implement-platform-abstraction-layer-apis.md index 140ae05d9..147d4fd99 100644 --- a/doc/site/en/guides/porting/implement-platform-abstraction-layer-apis.md +++ b/doc/site/en/guides/porting/implement-platform-abstraction-layer-apis.md @@ -46,13 +46,13 @@ There are two alarm service types, and [microsecond](https://github.com/openthread/openthread/blob/main/include/openthread/platform/alarm-micro.h). Millisecond is required for a new hardware platform. Microsecond is optional. -## Step 2: UART +## Step 2: UART > Note: This API is optional. API declaration: -[`/openthread/include/openthread/platform/uart.h`](https://github.com/openthread/openthread/blob/main/include/openthread/platform/uart.h) +[`/openthread/examples/platforms/utils/uart.h`](https://github.com/openthread/openthread/blob/main/examples/platforms/utils/uart.h) The UART API implements fundamental serial port communication via the UART interface. diff --git a/etc/gn/openthread.gni b/etc/gn/openthread.gni index ecdb886e9..bf0adf0c5 100644 --- a/etc/gn/openthread.gni +++ b/etc/gn/openthread.gni @@ -219,8 +219,8 @@ if (openthread_enable_core_config_args) { # Enable NCP SPI support openthread_config_ncp_spi_enable = false - # Enable NCP UART support - openthread_config_ncp_uart_enable = false + # Enable NCP HDLC support + openthread_config_ncp_hdlc_enable = false # Enable builtin mbedtls management openthread_config_enable_builtin_mbedtls_management = diff --git a/examples/Makefile-nrf52811 b/examples/Makefile-nrf52811 index 37cd78da3..6e38b3062 100644 --- a/examples/Makefile-nrf52811 +++ b/examples/Makefile-nrf52811 @@ -97,7 +97,7 @@ COMMONCFLAGS += -DSPIS_AS_SERIAL_TRANSPORT=1 COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1 else COMMONCFLAGS += -DUART_AS_SERIAL_TRANSPORT=1 -COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1 +COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 configure_OPTIONS += --enable-cli endif # NCP_SPI == 1 endif # DISABLE_TRANSPORTS diff --git a/examples/Makefile-nrf52833 b/examples/Makefile-nrf52833 index 5f6ad35c2..9a5bb5360 100644 --- a/examples/Makefile-nrf52833 +++ b/examples/Makefile-nrf52833 @@ -113,7 +113,7 @@ ifeq ($(NCP_SPI),1) COMMONCFLAGS += -DSPIS_AS_SERIAL_TRANSPORT=1 COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1 else -COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1 +COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 configure_OPTIONS += --enable-cli ifeq ($(USB),1) COMMONCFLAGS += -DUSB_CDC_AS_SERIAL_TRANSPORT=1 diff --git a/examples/Makefile-nrf52840 b/examples/Makefile-nrf52840 index e0b15761b..8ea88f382 100644 --- a/examples/Makefile-nrf52840 +++ b/examples/Makefile-nrf52840 @@ -149,7 +149,7 @@ ifeq ($(NCP_SPI),1) COMMONCFLAGS += -DSPIS_AS_SERIAL_TRANSPORT=1 COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1 else -COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1 +COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 configure_OPTIONS += --enable-cli ifeq ($(USB),1) COMMONCFLAGS += -DUSB_CDC_AS_SERIAL_TRANSPORT=1 diff --git a/examples/Makefile-simulation b/examples/Makefile-simulation index 1127ed482..f3a8acf14 100644 --- a/examples/Makefile-simulation +++ b/examples/Makefile-simulation @@ -93,7 +93,7 @@ endif ifeq ($(NCP_SPI),1) COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1 else -COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1 +COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 endif # NCP_SPI == 1 ifeq ($(OTNS),1) diff --git a/examples/README.md b/examples/README.md index 89305595d..f7bf638e2 100644 --- a/examples/README.md +++ b/examples/README.md @@ -14,7 +14,6 @@ This page lists the available common switches with description. Unless stated ot | CHANNEL_MANAGER | OT_CHANNEL_MANAGER | Enables support for channel manager. Enable this switch on devices that are supposed to request a Thread network channel change. This switch should be used only with an FTD build. | | CHANNEL_MONITOR | OT_CHANNEL_MONITOR | Enables support for channel monitor. Enable this switch on devices that are supposed to determine the cleaner channels. | | CHILD_SUPERVISION | OT_CHILD_SUPERVISION | Enables support for [child supervision](https://openthread.io/guides/build/features/child-supervision). Enable this switch on a parent or child node with custom OpenThread application that manages the supervision, checks timeout intervals, and verifies connectivity between parent and child. | -| CLI_TRANSPORT | not implemented | Selects the transport of CLI. You can set this switch to UART (default) or CONSOLE. | | COAP | OT_COAP | Enables support for the CoAP API. Enable this switch if you want to control Constrained Application Protocol communication. | | COAP_OBSERVE | OT_COAP_OBSERVE | Enables support for CoAP Observe (RFC7641) API. | | COAPS | OT_COAPS | Enables support for the secure CoAP API. Enable this switch if you want to control Constrained Application Protocol Secure (CoAP over DTLS) communication. | diff --git a/examples/apps/cli/Makefile.am b/examples/apps/cli/Makefile.am index 0d3e74115..f5ba445b5 100644 --- a/examples/apps/cli/Makefile.am +++ b/examples/apps/cli/Makefile.am @@ -49,6 +49,7 @@ LIBTOOLFLAGS_COMMON += \ $(NULL) SOURCES_COMMON += \ + cli_uart.cpp \ main.c \ $(NULL) diff --git a/src/cli/cli_uart.cpp b/examples/apps/cli/cli_uart.cpp similarity index 51% rename from src/cli/cli_uart.cpp rename to examples/apps/cli/cli_uart.cpp index 944548a60..0f3e54197 100644 --- a/src/cli/cli_uart.cpp +++ b/examples/apps/cli/cli_uart.cpp @@ -25,37 +25,77 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - -/** - * @file - * This file implements the CLI interpreter on the UART service. - */ - -#include "cli_uart.hpp" - -#if OPENTHREAD_CONFIG_CLI_TRANSPORT == OT_CLI_TRANSPORT_UART +#include "openthread-core-config.h" #include #include -#include +#include + +#include +#include + +#include "cli/cli_config.h" +#include "common/code_utils.hpp" +#include "common/debug.hpp" +#include "common/logging.hpp" +#include "utils/uart.h" + #if OPENTHREAD_POSIX #include #include #endif -#include -#include -#include -#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART -#include +/** + * @def OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE + * + * The size of CLI UART RX buffer in bytes. + * + */ +#ifndef OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE +#define OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE 640 +#else +#define OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE 512 +#endif #endif -#include "cli/cli.hpp" -#include "common/code_utils.hpp" -#include "common/encoding.hpp" -#include "common/logging.hpp" -#include "common/new.hpp" -#include "common/tasklet.hpp" +/** + * @def OPENTHREAD_CONFIG_CLI_TX_BUFFER_SIZE + * + * The size of CLI message buffer in bytes. + * + */ +#ifndef OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE +#define OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE 1024 +#endif + +#if OPENTHREAD_CONFIG_DIAG_ENABLE +#if OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE > OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE +#error "diag output buffer should be smaller than CLI UART tx buffer" +#endif +#if OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE > OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE +#error "diag command line should be smaller than CLI UART rx buffer" +#endif +#endif + +#if OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH > OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE +#error "command line should be should be smaller than CLI rx buffer" +#endif + +enum +{ + kRxBufferSize = OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE, + kTxBufferSize = OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE, +}; + +char sRxBuffer[kRxBufferSize]; +uint16_t sRxLength; + +char sTxBuffer[kTxBufferSize]; +uint16_t sTxHead; +uint16_t sTxLength; + +uint16_t sSendLength; #ifdef OT_CLI_UART_LOCK_HDR_FILE @@ -89,44 +129,13 @@ #endif // OT_CLI_UART_LOCK_HDR_FILE -#if OPENTHREAD_CONFIG_DIAG_ENABLE -static_assert(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <= OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE, - "diag output buffer should be smaller than CLI UART tx buffer"); -static_assert(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE, - "diag command line should be smaller than CLI UART rx buffer"); -#endif +static int Output(const char *aBuf, uint16_t aBufLength); +static otError ProcessCommand(void); -static_assert(OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH <= OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE, - "command line should be should be smaller than CLI rx buffer"); - -namespace ot { -namespace Cli { - -static OT_DEFINE_ALIGNED_VAR(sCliUartRaw, sizeof(Uart), uint64_t); - -void Uart::Initialize(otInstance *aInstance) +static void ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength) { - Instance *instance = static_cast(aInstance); - Interpreter::sInterpreter = new (&sCliUartRaw) Uart(instance); -} - -Uart::Uart(Instance *aInstance) - : Interpreter(aInstance) -{ - mRxLength = 0; - mTxHead = 0; - mTxLength = 0; - mSendLength = 0; - - IgnoreError(otPlatUartEnable()); -} - -void Uart::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength) -{ -#if !OPENTHREAD_CONFIG_UART_CLI_RAW - static const char sEraseString[] = {'\b', ' ', '\b'}; - static const char CRNL[] = {'\r', '\n'}; -#endif + static const char sEraseString[] = {'\b', ' ', '\b'}; + static const char CRNL[] = {'\r', '\n'}; static const char sCommandPrompt[] = {'>', ' '}; const uint8_t * end; @@ -138,12 +147,10 @@ void Uart::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength) { case '\r': case '\n': -#if !OPENTHREAD_CONFIG_UART_CLI_RAW Output(CRNL, sizeof(CRNL)); -#endif - if (mRxLength > 0) + if (sRxLength > 0) { - mRxBuffer[mRxLength] = '\0'; + sRxBuffer[sRxLength] = '\0'; IgnoreError(ProcessCommand()); } @@ -151,9 +158,7 @@ void Uart::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength) break; -#if !OPENTHREAD_CONFIG_UART_CLI_RAW #if OPENTHREAD_POSIX && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) - case 0x03: // ASCII for Ctrl-C kill(0, SIGINT); break; @@ -165,22 +170,19 @@ void Uart::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength) case '\b': case 127: - if (mRxLength > 0) + if (sRxLength > 0) { Output(sEraseString, sizeof(sEraseString)); - mRxBuffer[--mRxLength] = '\0'; + sRxBuffer[--sRxLength] = '\0'; } break; -#endif // !OPENTHREAD_CONFIG_UART_CLI_RAW default: - if (mRxLength < kRxBufferSize - 1) + if (sRxLength < kRxBufferSize - 1) { -#if !OPENTHREAD_CONFIG_UART_CLI_RAW Output(reinterpret_cast(aBuf), 1); -#endif - mRxBuffer[mRxLength++] = static_cast(*aBuf); + sRxBuffer[sRxLength++] = static_cast(*aBuf); } break; @@ -188,13 +190,13 @@ void Uart::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength) } } -otError Uart::ProcessCommand(void) +static otError ProcessCommand(void) { otError error = OT_ERROR_NONE; - while (mRxBuffer[mRxLength - 1] == '\n' || mRxBuffer[mRxLength - 1] == '\r') + while (sRxBuffer[sRxLength - 1] == '\n' || sRxBuffer[sRxLength - 1] == '\r') { - mRxBuffer[--mRxLength] = '\0'; + sRxBuffer[--sRxLength] = '\0'; } #if OPENTHREAD_CONFIG_LOG_OUTPUT != OPENTHREAD_CONFIG_LOG_OUTPUT_NONE @@ -222,32 +224,62 @@ otError Uart::ProcessCommand(void) #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE /* TODO: how exactly do we get the instance here? */ #else - otLogInfoCli("execute command: %s", mRxBuffer); + otLogInfoCli("execute command: %s", sRxBuffer); #endif #endif - if (mRxLength > 0) + if (sRxLength > 0) { - ProcessLine(mRxBuffer); + otCliInputLine(sRxBuffer); } - mRxLength = 0; + sRxLength = 0; return error; } -int Interpreter::Output(const char *aBuf, uint16_t aBufLength) +static void Send(void) { - return static_cast(this)->Output(aBuf, aBufLength); + VerifyOrExit(sSendLength == 0); + + if (sTxLength > kTxBufferSize - sTxHead) + { + sSendLength = kTxBufferSize - sTxHead; + } + else + { + sSendLength = sTxLength; + } + + if (sSendLength > 0) + { +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART + /* duplicate the output to the debug uart */ + otSysDebugUart_write_bytes(reinterpret_cast(sTxBuffer + sTxHead), sSendLength); +#endif + IgnoreError(otPlatUartSend(reinterpret_cast(sTxBuffer + sTxHead), sSendLength)); + } + +exit: + return; } -int Uart::Output(const char *aBuf, uint16_t aBufLength) +static void SendDoneTask(void) +{ + sTxHead = (sTxHead + sSendLength) % kTxBufferSize; + sTxLength -= sSendLength; + sSendLength = 0; + + Send(); +} + +static int Output(const char *aBuf, uint16_t aBufLength) { OT_CLI_UART_OUTPUT_LOCK(); uint16_t sent = 0; while (aBufLength > 0) { - uint16_t remaining = kTxBufferSize - mTxLength; + uint16_t remaining = kTxBufferSize - sTxLength; uint16_t tail; uint16_t sendLength = aBufLength; @@ -258,10 +290,10 @@ int Uart::Output(const char *aBuf, uint16_t aBufLength) for (uint16_t i = 0; i < sendLength; i++) { - tail = (mTxHead + mTxLength) % kTxBufferSize; - mTxBuffer[tail] = *aBuf++; + tail = (sTxHead + sTxLength) % kTxBufferSize; + sTxBuffer[tail] = *aBuf++; aBufLength--; - mTxLength++; + sTxLength++; } Send(); @@ -291,57 +323,98 @@ int Uart::Output(const char *aBuf, uint16_t aBufLength) return sent; } -void Uart::Send(void) +static int CliUartOutput(void *aContext, const char *aFormat, va_list aArguments) { - VerifyOrExit(mSendLength == 0); + OT_UNUSED_VARIABLE(aContext); - if (mTxLength > kTxBufferSize - mTxHead) + int rval; + + if (sTxLength == 0) { - mSendLength = kTxBufferSize - mTxHead; + rval = vsnprintf(sTxBuffer, kTxBufferSize, aFormat, aArguments); + VerifyOrExit(rval > 0 && rval < kTxBufferSize, otLogWarnPlat("Failed to format CLI output `%s`", aFormat)); + sTxHead = 0; + sTxLength = static_cast(rval); + sSendLength = 0; } else { - mSendLength = mTxLength; + va_list retryArguments; + uint16_t tail = (sTxHead + sTxLength) % kTxBufferSize; + uint16_t remaining = (sTxHead > tail ? (sTxHead - tail) : (kTxBufferSize - tail)); + + va_copy(retryArguments, aArguments); + + rval = vsnprintf(&sTxBuffer[tail], remaining, aFormat, aArguments); + + if (rval < 0) + { + otLogWarnPlat("Failed to format CLI output `%s`", aFormat); + } + else if (rval < remaining) + { + sTxLength += rval; + } + else if (rval < kTxBufferSize) + { + while (sTxLength != 0) + { + otError error; + + Send(); + + error = otPlatUartFlush(); + + if (error == OT_ERROR_NONE) + { + // Flush successful, reset the pointers + SendDoneTask(); + } + else + { + // Flush did not succeed, so abort here. + otLogWarnPlat("Failed to output CLI: %s", otThreadErrorToString(error)); + ExitNow(); + } + } + rval = vsnprintf(sTxBuffer, kTxBufferSize, aFormat, retryArguments); + OT_ASSERT(rval > 0); + sTxLength = static_cast(rval); + sTxHead = 0; + sSendLength = 0; + } + else + { + otLogWarnPlat("CLI output `%s` truncated", aFormat); + } + + va_end(retryArguments); } - if (mSendLength > 0) - { -#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART - /* duplicate the output to the debug uart */ - otPlatDebugUart_write_bytes(reinterpret_cast(mTxBuffer + mTxHead), mSendLength); -#endif - IgnoreError(otPlatUartSend(reinterpret_cast(mTxBuffer + mTxHead), mSendLength)); - } - -exit: - return; -} - -void Uart::SendDoneTask(void) -{ - mTxHead = (mTxHead + mSendLength) % kTxBufferSize; - mTxLength -= mSendLength; - mSendLength = 0; - Send(); + +exit: + return rval; } -extern "C" void otCliUartInit(otInstance *aInstance) +void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength) { - Uart::Initialize(aInstance); + ReceiveTask(aBuf, aBufLength); } -extern "C" void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength) +void otPlatUartSendDone(void) { - static_cast(Interpreter::GetInterpreter()).ReceiveTask(aBuf, aBufLength); + SendDoneTask(); } -extern "C" void otPlatUartSendDone(void) +extern "C" void otAppCliInit(otInstance *aInstance) { - static_cast(Interpreter::GetInterpreter()).SendDoneTask(); + sRxLength = 0; + sTxHead = 0; + sTxLength = 0; + sSendLength = 0; + + IgnoreError(otPlatUartEnable()); + + otCliInit(aInstance, CliUartOutput, aInstance); } - -} // namespace Cli -} // namespace ot - -#endif // OPENTHREAD_CONFIG_CLI_TRANSPORT == OT_CLI_TRANSPORT_UART diff --git a/examples/apps/cli/ftd.cmake b/examples/apps/cli/ftd.cmake index 5a55455cc..237215367 100644 --- a/examples/apps/cli/ftd.cmake +++ b/examples/apps/cli/ftd.cmake @@ -27,6 +27,7 @@ # add_executable(ot-cli-ftd + cli_uart.cpp main.c ) @@ -37,6 +38,7 @@ target_link_libraries(ot-cli-ftd PRIVATE ${OT_PLATFORM_LIB} openthread-ftd ${OT_PLATFORM_LIB} + openthread-cli-ftd ${OT_MBEDTLS} ot-config ) diff --git a/examples/apps/cli/main.c b/examples/apps/cli/main.c index c9ef70fc2..e03d51fd3 100644 --- a/examples/apps/cli/main.c +++ b/examples/apps/cli/main.c @@ -38,6 +38,14 @@ #include "openthread-system.h" #include "cli/cli_config.h" +/** + * This function initializes the CLI app. + * + * @param[in] aInstance The OpenThread instance structure. + * + */ +extern void otAppCliInit(otInstance *aInstance); + #if OPENTHREAD_EXAMPLES_SIMULATION #include #include @@ -107,9 +115,7 @@ pseudo_reset: #endif assert(instance); -#if OPENTHREAD_CONFIG_CLI_TRANSPORT == OT_CLI_TRANSPORT_UART - otCliUartInit(instance); -#endif + otAppCliInit(instance); while (!otSysPseudoResetWasRequested()) { diff --git a/examples/apps/cli/mtd.cmake b/examples/apps/cli/mtd.cmake index 45b8923fe..2d758db5f 100644 --- a/examples/apps/cli/mtd.cmake +++ b/examples/apps/cli/mtd.cmake @@ -27,6 +27,7 @@ # add_executable(ot-cli-mtd + cli_uart.cpp main.c ) @@ -37,6 +38,7 @@ target_link_libraries(ot-cli-mtd PRIVATE ${OT_PLATFORM_LIB} openthread-mtd ${OT_PLATFORM_LIB} + openthread-cli-mtd ${OT_MBEDTLS} ot-config ) diff --git a/examples/apps/ncp/Makefile.am b/examples/apps/ncp/Makefile.am index 7db30e851..9cf17e43e 100644 --- a/examples/apps/ncp/Makefile.am +++ b/examples/apps/ncp/Makefile.am @@ -34,6 +34,7 @@ bin_PROGRAMS = \ CPPFLAGS_COMMON += \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/src \ -I$(top_srcdir)/src/core \ -I$(top_srcdir)/examples/platforms \ $(NULL) @@ -49,6 +50,7 @@ LIBTOOLFLAGS_COMMON += \ SOURCES_COMMON += \ main.c \ + ncp.c \ $(NULL) LDADD_MBEDTLS = \ diff --git a/examples/apps/ncp/ftd.cmake b/examples/apps/ncp/ftd.cmake index d822b4a4a..f09e9db5c 100644 --- a/examples/apps/ncp/ftd.cmake +++ b/examples/apps/ncp/ftd.cmake @@ -28,6 +28,7 @@ add_executable(ot-ncp-ftd main.c + ncp.c ) target_include_directories(ot-ncp-ftd PRIVATE ${COMMON_INCLUDES}) @@ -37,6 +38,7 @@ target_link_libraries(ot-ncp-ftd PRIVATE ${OT_PLATFORM_LIB} openthread-ftd ${OT_PLATFORM_LIB} + openthread-ncp-ftd ${OT_MBEDTLS} ot-config ) diff --git a/examples/apps/ncp/main.c b/examples/apps/ncp/main.c index aba562edc..fa2558c1e 100644 --- a/examples/apps/ncp/main.c +++ b/examples/apps/ncp/main.c @@ -36,6 +36,14 @@ #include "openthread-system.h" +/** + * This function initializes the NCP app. + * + * @param[in] aInstance The OpenThread instance structure. + * + */ +extern void otAppNcpInit(otInstance *aInstance); + #if OPENTHREAD_EXAMPLES_SIMULATION #include #include @@ -105,7 +113,7 @@ pseudo_reset: #endif assert(instance); - otNcpInit(instance); + otAppNcpInit(instance); while (!otSysPseudoResetWasRequested()) { diff --git a/examples/apps/ncp/mtd.cmake b/examples/apps/ncp/mtd.cmake index 2cb9faddc..b25eedfa0 100644 --- a/examples/apps/ncp/mtd.cmake +++ b/examples/apps/ncp/mtd.cmake @@ -28,6 +28,7 @@ add_executable(ot-ncp-mtd main.c + ncp.c ) target_include_directories(ot-ncp-mtd PRIVATE ${COMMON_INCLUDES}) @@ -37,6 +38,7 @@ target_link_libraries(ot-ncp-mtd PRIVATE ${OT_PLATFORM_LIB} openthread-mtd ${OT_PLATFORM_LIB} + openthread-ncp-mtd ${OT_MBEDTLS} ot-config ) diff --git a/src/posix/console_cli.h b/examples/apps/ncp/ncp.c similarity index 51% rename from src/posix/console_cli.h rename to examples/apps/ncp/ncp.c index 16682d508..ee7ccf7d1 100644 --- a/src/posix/console_cli.h +++ b/examples/apps/ncp/ncp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, The OpenThread Authors. + * Copyright (c) 2021, The OpenThread Authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,69 +26,45 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef OPENTHREAD_CONSOLE_CLI_H_ -#define OPENTHREAD_CONSOLE_CLI_H_ +#include "openthread-core-config.h" -#include "platform/openthread-posix-config.h" +#include -#include +#include "common/code_utils.hpp" -#include +#include "ncp/ncp_config.h" -#include "cli/cli_config.h" +#if !OPENTHREAD_CONFIG_NCP_SPI_ENABLE +#include "utils/uart.h" -#ifndef HAVE_LIBEDIT -#define HAVE_LIBEDIT 0 -#endif +void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength) +{ + otNcpHdlcReceive(aBuf, aBufLength); +} -#ifndef HAVE_LIBREADLINE -#define HAVE_LIBREADLINE 0 -#endif - -#if OPENTHREAD_CONFIG_CLI_TRANSPORT == OT_CLI_TRANSPORT_CONSOLE -#define OPENTHREAD_USE_CONSOLE 1 -#if !(HAVE_LIBEDIT || HAVE_LIBREADLINE) || OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE -#error \ - "When OPENTHREAD_CONFIG_CLI_TRANSPORT=OT_CLI_TRANSPORT_CONSOLE, HAVE_LIBEDIT or HAVE_LIBREADLINE MUST be defined and OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE MUST be 0" -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * This function initializes CLI console. - * - * @param[in] aInstance A pointer to the OpenThread instance. - * - */ -void otxConsoleInit(otInstance *aInstance); - -/** - * This function deinitializes CLI console - * - */ -void otxConsoleDeinit(void); - -/** - * This function updates the file descriptor sets with file descriptors used by console. - * - * @param[inout] aMainloop A pointer to the mainloop context. - * - */ -void otxConsoleUpdate(otSysMainloopContext *aMainloop); - -/** - * This function performs console driver processing. - * - * @param[in] aMainloop A pointer to the mainloop context. - * - */ -void otxConsoleProcess(const otSysMainloopContext *aMainloop); - -#ifdef __cplusplus +void otPlatUartSendDone(void) +{ + otNcpHdlcSendDone(); } #endif -#endif // OPENTHREAD_CONSOLE_CLI_H_ +#if !OPENTHREAD_ENABLE_NCP_VENDOR_HOOK +#if !OPENTHREAD_CONFIG_NCP_SPI_ENABLE +static int NcpSend(const uint8_t *aBuf, uint16_t aBufLength) +{ + IgnoreError(otPlatUartSend(aBuf, aBufLength)); + return aBufLength; +} +#endif + +void otAppNcpInit(otInstance *aInstance) +{ +#if OPENTHREAD_CONFIG_NCP_SPI_ENABLE + otNcpSpiInit(aInstance); +#else + IgnoreError(otPlatUartEnable()); + + otNcpHdlcInit(aInstance, NcpSend); +#endif +} +#endif // !OPENTHREAD_ENABLE_NCP_VENDOR_HOOK diff --git a/examples/apps/ncp/rcp.cmake b/examples/apps/ncp/rcp.cmake index 0298df755..923d31a00 100644 --- a/examples/apps/ncp/rcp.cmake +++ b/examples/apps/ncp/rcp.cmake @@ -28,6 +28,7 @@ add_executable(ot-rcp main.c + ncp.c ) target_include_directories(ot-rcp PRIVATE ${COMMON_INCLUDES}) @@ -37,6 +38,7 @@ target_link_libraries(ot-rcp PRIVATE ${OT_PLATFORM_LIB} openthread-radio ${OT_PLATFORM_LIB} + openthread-rcp ot-config ) diff --git a/examples/common-switches.mk b/examples/common-switches.mk index 2e8e94e61..2f774bcee 100644 --- a/examples/common-switches.mk +++ b/examples/common-switches.mk @@ -42,7 +42,6 @@ COVERAGE ?= 0 CHANNEL_MANAGER ?= 0 CHANNEL_MONITOR ?= 0 CHILD_SUPERVISION ?= 0 -CLI_TRANSPORT ?= UART DATASET_UPDATER ?= 0 DEBUG ?= 0 DHCP6_CLIENT ?= 0 @@ -143,10 +142,6 @@ ifeq ($(CHILD_SUPERVISION),1) COMMONCFLAGS += -DOPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE=1 endif -ifneq ($(CLI_TRANSPORT),) -COMMONCFLAGS += -DOPENTHREAD_CONFIG_CLI_TRANSPORT=OT_CLI_TRANSPORT_$(CLI_TRANSPORT) -endif - ifeq ($(CSL_RECEIVER),1) COMMONCFLAGS += -DOPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE=1 endif diff --git a/examples/platforms/cc1352/openthread-core-cc1352-config.h b/examples/platforms/cc1352/openthread-core-cc1352-config.h index ad737009c..449ed8c67 100644 --- a/examples/platforms/cc1352/openthread-core-cc1352-config.h +++ b/examples/platforms/cc1352/openthread-core-cc1352-config.h @@ -48,11 +48,11 @@ #define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 #endif /* OPENTHREAD_CORE_CC1352_CONFIG_H_ */ diff --git a/examples/platforms/cc1352/uart.c b/examples/platforms/cc1352/uart.c index 34cd86504..c4cb87fed 100644 --- a/examples/platforms/cc1352/uart.c +++ b/examples/platforms/cc1352/uart.c @@ -41,11 +41,9 @@ #include #include -#include #include "utils/code_utils.h" - -#include +#include "utils/uart.h" #include #include @@ -116,7 +114,7 @@ static void uart_power_control(uint32_t who_base, int turnon) } /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartEnable(void) { @@ -138,7 +136,7 @@ otError otPlatUartEnable(void) } /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartDisable(void) { @@ -154,7 +152,7 @@ otError otPlatUartDisable(void) } /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength) { diff --git a/examples/platforms/cc2538/CMakeLists.txt b/examples/platforms/cc2538/CMakeLists.txt index 341c5f134..c69d1e576 100644 --- a/examples/platforms/cc2538/CMakeLists.txt +++ b/examples/platforms/cc2538/CMakeLists.txt @@ -35,7 +35,7 @@ endif() list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_CORE_CONFIG_PLATFORM_CHECK_FILE=\"openthread-core-cc2538-config-check.h\"" - "OPENTHREAD_CONFIG_NCP_UART_ENABLE=1" + "OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1" ) set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE) diff --git a/examples/platforms/cc2538/openthread-core-cc2538-config.h b/examples/platforms/cc2538/openthread-core-cc2538-config.h index fabb6faae..1f262173e 100644 --- a/examples/platforms/cc2538/openthread-core-cc2538-config.h +++ b/examples/platforms/cc2538/openthread-core-cc2538-config.h @@ -83,12 +83,12 @@ #define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 /** * @def OPENTHREAD_CONFIG_CC2538_USE_RADIO_RX_INTERRUPT diff --git a/examples/platforms/cc2538/uart.c b/examples/platforms/cc2538/uart.c index 992af65d5..3325c9904 100644 --- a/examples/platforms/cc2538/uart.c +++ b/examples/platforms/cc2538/uart.c @@ -41,10 +41,10 @@ #include #include -#include #include "platform-cc2538.h" #include "utils/code_utils.h" +#include "utils/uart.h" enum { diff --git a/examples/platforms/cc2650/openthread-core-cc2650-config.h b/examples/platforms/cc2650/openthread-core-cc2650-config.h index 31d2fb1ac..94de3b5a6 100644 --- a/examples/platforms/cc2650/openthread-core-cc2650-config.h +++ b/examples/platforms/cc2650/openthread-core-cc2650-config.h @@ -45,12 +45,12 @@ #define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 32 /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 /** * @def OPENTHREAD_SETTINGS_RAM diff --git a/examples/platforms/cc2650/uart.c b/examples/platforms/cc2650/uart.c index d6f048325..44515fa44 100644 --- a/examples/platforms/cc2650/uart.c +++ b/examples/platforms/cc2650/uart.c @@ -34,7 +34,8 @@ #include #include -#include + +#include "utils/uart.h" /** * \note this will configure the uart for 115200 baud 8-N-1, no HW flow control @@ -58,7 +59,7 @@ static uint16_t sReceiveTailIdx = 0; void UART0_intHandler(void); /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartEnable(void) { @@ -86,7 +87,7 @@ otError otPlatUartEnable(void) } /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartDisable(void) { @@ -109,7 +110,7 @@ otError otPlatUartDisable(void) } /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength) { diff --git a/examples/platforms/cc2652/openthread-core-cc2652-config.h b/examples/platforms/cc2652/openthread-core-cc2652-config.h index 352c32207..b9dccf636 100644 --- a/examples/platforms/cc2652/openthread-core-cc2652-config.h +++ b/examples/platforms/cc2652/openthread-core-cc2652-config.h @@ -48,11 +48,11 @@ #define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 #endif /* OPENTHREAD_CORE_CC2650_CONFIG_H_ */ diff --git a/examples/platforms/cc2652/uart.c b/examples/platforms/cc2652/uart.c index b342a5275..c8d951a2c 100644 --- a/examples/platforms/cc2652/uart.c +++ b/examples/platforms/cc2652/uart.c @@ -41,11 +41,9 @@ #include #include -#include #include "utils/code_utils.h" - -#include +#include "utils/uart.h" #include #include @@ -116,7 +114,7 @@ static void uart_power_control(uint32_t who_base, int turnon) } /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartEnable(void) { @@ -138,7 +136,7 @@ otError otPlatUartEnable(void) } /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartDisable(void) { @@ -154,7 +152,7 @@ otError otPlatUartDisable(void) } /** - * Function documented in platform/uart.h + * Function documented in utils/uart.h */ otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength) { diff --git a/examples/platforms/efr32/src/openthread-core-efr32-config.h b/examples/platforms/efr32/src/openthread-core-efr32-config.h index f3da00278..49410853d 100644 --- a/examples/platforms/efr32/src/openthread-core-efr32-config.h +++ b/examples/platforms/efr32/src/openthread-core-efr32-config.h @@ -141,12 +141,12 @@ #define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0 /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 /** * @def OPENTHREAD_CONFIG_MIN_SLEEP_DURATION_MS diff --git a/examples/platforms/efr32/src/system.c b/examples/platforms/efr32/src/system.c index 4b9baced6..90fd7245d 100644 --- a/examples/platforms/efr32/src/system.c +++ b/examples/platforms/efr32/src/system.c @@ -39,7 +39,6 @@ #include #include "openthread-system.h" -#include #include "common/logging.hpp" diff --git a/examples/platforms/efr32/src/uart.c b/examples/platforms/efr32/src/uart.c index ed195953a..638bf9e8b 100644 --- a/examples/platforms/efr32/src/uart.c +++ b/examples/platforms/efr32/src/uart.c @@ -36,9 +36,9 @@ #include "openthread-system.h" #include -#include #include "utils/code_utils.h" +#include "utils/uart.h" #include "ecode.h" #include "em_core.h" diff --git a/examples/platforms/gp712/openthread-core-gp712-config.h b/examples/platforms/gp712/openthread-core-gp712-config.h index 87c96332c..0988e6d6c 100644 --- a/examples/platforms/gp712/openthread-core-gp712-config.h +++ b/examples/platforms/gp712/openthread-core-gp712-config.h @@ -124,13 +124,13 @@ #endif /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * * Define as 1 to enable UART NCP interface. * */ -#ifndef OPENTHREAD_CONFIG_NCP_UART_ENABLE -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_NCP_HDLC_ENABLE +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 #endif #endif // OPENTHREAD_CORE_GP712_CONFIG_H_ diff --git a/examples/platforms/gp712/system.c b/examples/platforms/gp712/system.c index 175b8fdcf..147421a37 100644 --- a/examples/platforms/gp712/system.c +++ b/examples/platforms/gp712/system.c @@ -38,7 +38,6 @@ #include "stdlib.h" #include -#include #include "alarm_qorvo.h" #include "platform_qorvo.h" diff --git a/examples/platforms/gp712/uart-posix.c b/examples/platforms/gp712/uart-posix.c index e0b2c10e3..2b37685c0 100644 --- a/examples/platforms/gp712/uart-posix.c +++ b/examples/platforms/gp712/uart-posix.c @@ -40,9 +40,8 @@ #include #include -#include - #include "utils/code_utils.h" +#include "utils/uart.h" #ifdef __linux__ #include diff --git a/examples/platforms/k32w/jn5189/openthread-core-jn5189-config.h b/examples/platforms/k32w/jn5189/openthread-core-jn5189-config.h index 51f7d27e6..0d01e7d8e 100755 --- a/examples/platforms/k32w/jn5189/openthread-core-jn5189-config.h +++ b/examples/platforms/k32w/jn5189/openthread-core-jn5189-config.h @@ -102,12 +102,12 @@ /* TODO */ /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 /** * @def OPENTHREAD_SETTINGS_RAM diff --git a/examples/platforms/k32w/k32w061/openthread-core-k32w061-config.h b/examples/platforms/k32w/k32w061/openthread-core-k32w061-config.h index c6e877b46..874bc8a06 100755 --- a/examples/platforms/k32w/k32w061/openthread-core-k32w061-config.h +++ b/examples/platforms/k32w/k32w061/openthread-core-k32w061-config.h @@ -102,12 +102,12 @@ /* TODO */ /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 /** * @def OPENTHREAD_SETTINGS_RAM diff --git a/examples/platforms/k32w/src/logging.c b/examples/platforms/k32w/src/logging.c index af55c2d59..39a82c793 100755 --- a/examples/platforms/k32w/src/logging.c +++ b/examples/platforms/k32w/src/logging.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "stdio.h" #include "string.h" diff --git a/examples/platforms/k32w/src/system.c b/examples/platforms/k32w/src/system.c index 2ba808f47..9843719e9 100644 --- a/examples/platforms/k32w/src/system.c +++ b/examples/platforms/k32w/src/system.c @@ -35,7 +35,6 @@ #include "clock_config.h" #include "pin_mux.h" #include "platform-k32w.h" -#include "openthread/platform/uart.h" #include #include diff --git a/examples/platforms/k32w/src/uart.c b/examples/platforms/k32w/src/uart.c index 53ad84d31..55493fa4e 100755 --- a/examples/platforms/k32w/src/uart.c +++ b/examples/platforms/k32w/src/uart.c @@ -40,7 +40,7 @@ /* Openthread general includes */ #include -#include "openthread/platform/uart.h" +#include #if USE_RTOS #include "UART_Serial_Adapter.h" diff --git a/examples/platforms/kw41z/openthread-core-kw41z-config.h b/examples/platforms/kw41z/openthread-core-kw41z-config.h index 923dc037b..7e24b8a7b 100644 --- a/examples/platforms/kw41z/openthread-core-kw41z-config.h +++ b/examples/platforms/kw41z/openthread-core-kw41z-config.h @@ -95,11 +95,11 @@ #define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 #endif // OPENTHREAD_CORE_KW41Z_CONFIG_H_ diff --git a/examples/platforms/kw41z/system.c b/examples/platforms/kw41z/system.c index 8e0dc274a..777bb38b7 100644 --- a/examples/platforms/kw41z/system.c +++ b/examples/platforms/kw41z/system.c @@ -38,7 +38,8 @@ #include "fsl_port.h" #include "platform-kw41z.h" #include -#include "openthread/platform/uart.h" + +#include "utils/uart.h" otInstance *sInstance; diff --git a/examples/platforms/kw41z/uart.c b/examples/platforms/kw41z/uart.c index 226e04e16..9b59057a8 100644 --- a/examples/platforms/kw41z/uart.c +++ b/examples/platforms/kw41z/uart.c @@ -37,7 +37,7 @@ #include #include -#include "openthread/platform/uart.h" +#include #include "fsl_clock.h" #include "fsl_lpuart.h" diff --git a/examples/platforms/nrf528xx/src/transport/uart.c b/examples/platforms/nrf528xx/src/transport/uart.c index 8fc18fbe1..7c1c607e6 100644 --- a/examples/platforms/nrf528xx/src/transport/uart.c +++ b/examples/platforms/nrf528xx/src/transport/uart.c @@ -39,8 +39,8 @@ #include #include +#include #include -#include #include "openthread-system.h" diff --git a/examples/platforms/nrf528xx/src/transport/usb-cdc-uart.c b/examples/platforms/nrf528xx/src/transport/usb-cdc-uart.c index ec3a0060f..a05c41a86 100644 --- a/examples/platforms/nrf528xx/src/transport/usb-cdc-uart.c +++ b/examples/platforms/nrf528xx/src/transport/usb-cdc-uart.c @@ -46,10 +46,10 @@ #include #include #include +#include #include #include #include -#include #include "platform-nrf5-transport.h" diff --git a/examples/platforms/qpg6095/platform.c b/examples/platforms/qpg6095/platform.c index e00c17c25..53aafb2bb 100644 --- a/examples/platforms/qpg6095/platform.c +++ b/examples/platforms/qpg6095/platform.c @@ -38,7 +38,6 @@ #include "random_qorvo.h" #include "uart_qorvo.h" #include -#include #include "stdio.h" #include "stdlib.h" diff --git a/examples/platforms/qpg6095/uart.c b/examples/platforms/qpg6095/uart.c index 295daa640..5f3d1aa28 100644 --- a/examples/platforms/qpg6095/uart.c +++ b/examples/platforms/qpg6095/uart.c @@ -41,7 +41,8 @@ #define HAVE__BOOL 1 #include -#include + +#include "utils/uart.h" otError otPlatUartEnable(void) { diff --git a/examples/platforms/qpg7015m/openthread-core-qpg7015m-config.h b/examples/platforms/qpg7015m/openthread-core-qpg7015m-config.h index 711edaf81..74c466dd5 100755 --- a/examples/platforms/qpg7015m/openthread-core-qpg7015m-config.h +++ b/examples/platforms/qpg7015m/openthread-core-qpg7015m-config.h @@ -124,13 +124,13 @@ #endif /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * * Define as 1 to enable UART NCP interface. * */ -#ifndef OPENTHREAD_CONFIG_NCP_UART_ENABLE -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_NCP_HDLC_ENABLE +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 #endif #endif // OPENTHREAD_CORE_QPG7015M_CONFIG_H_ diff --git a/examples/platforms/samr21/openthread-core-samr21-config.h b/examples/platforms/samr21/openthread-core-samr21-config.h index 0397a42f9..54b22a948 100644 --- a/examples/platforms/samr21/openthread-core-samr21-config.h +++ b/examples/platforms/samr21/openthread-core-samr21-config.h @@ -75,11 +75,11 @@ extern uint32_t __d_nv_mem_end; #define OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER 5 /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 #endif // OPENTHREAD_CORE_SAMR21_CONFIG_H_ diff --git a/examples/platforms/samr21/uart.c b/examples/platforms/samr21/uart.c index 8f8aa1eaa..6a5ebc6d3 100644 --- a/examples/platforms/samr21/uart.c +++ b/examples/platforms/samr21/uart.c @@ -34,7 +34,7 @@ #include "asf.h" -#include +#include "utils/uart.h" enum { diff --git a/examples/platforms/simulation/CMakeLists.txt b/examples/platforms/simulation/CMakeLists.txt index 4a08b9e02..fb670f442 100644 --- a/examples/platforms/simulation/CMakeLists.txt +++ b/examples/platforms/simulation/CMakeLists.txt @@ -52,7 +52,7 @@ list(APPEND OT_PLATFORM_DEFINES "_BSD_SOURCE=1" "_DEFAULT_SOURCE=1" "OPENTHREAD_EXAMPLES_SIMULATION=1" - "OPENTHREAD_CONFIG_NCP_UART_ENABLE=1" + "OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1" ) set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE) diff --git a/examples/platforms/simulation/spi-stubs.c b/examples/platforms/simulation/spi-stubs.c index 7c0dd629c..585bca7b0 100644 --- a/examples/platforms/simulation/spi-stubs.c +++ b/examples/platforms/simulation/spi-stubs.c @@ -33,7 +33,6 @@ #include #include -#include #if OPENTHREAD_CONFIG_NCP_SPI_ENABLE diff --git a/examples/platforms/simulation/uart.c b/examples/platforms/simulation/uart.c index 777bbedd1..3bbcface5 100644 --- a/examples/platforms/simulation/uart.c +++ b/examples/platforms/simulation/uart.c @@ -39,9 +39,9 @@ #include #include -#include #include "utils/code_utils.h" +#include "utils/uart.h" #if OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART == 0 diff --git a/examples/platforms/simulation/virtual_time/platform-sim.c b/examples/platforms/simulation/virtual_time/platform-sim.c index dfe759926..819a460ba 100644 --- a/examples/platforms/simulation/virtual_time/platform-sim.c +++ b/examples/platforms/simulation/virtual_time/platform-sim.c @@ -48,7 +48,8 @@ #include #include -#include + +#include "utils/uart.h" uint32_t gNodeId = 1; @@ -168,7 +169,7 @@ otError otPlatUartSend(const uint8_t *aData, uint16_t aLength) otError otPlatUartFlush(void) { - return OT_ERROR_NOT_IMPLEMENTED; + return OT_ERROR_NONE; } #endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART diff --git a/examples/platforms/utils/Makefile.am b/examples/platforms/utils/Makefile.am index 24e42bb7f..53cd3db4c 100644 --- a/examples/platforms/utils/Makefile.am +++ b/examples/platforms/utils/Makefile.am @@ -64,6 +64,7 @@ libopenthread_platform_utils_a_SOURCES = \ settings_ram.c \ soft_source_match_table.c \ soft_source_match_table.h \ + uart.h \ $(NULL) libopenthread_platform_utils_a_LIBADD = \ diff --git a/include/openthread/platform/uart.h b/examples/platforms/utils/uart.h similarity index 100% rename from include/openthread/platform/uart.h rename to examples/platforms/utils/uart.h diff --git a/include/Makefile.am b/include/Makefile.am index 4b3cd3b4d..c107e73ce 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -106,7 +106,6 @@ ot_platform_headers = \ openthread/platform/time.h \ openthread/platform/toolchain.h \ openthread/platform/trel-udp6.h \ - openthread/platform/uart.h \ openthread/platform/udp.h \ $(NULL) diff --git a/include/openthread-config-android.h b/include/openthread-config-android.h index 10f7abf41..9b07c8135 100644 --- a/include/openthread-config-android.h +++ b/include/openthread-config-android.h @@ -57,8 +57,8 @@ /* Define to 1 if you want to use legacy network support */ #define OPENTHREAD_CONFIG_LEGACY_ENABLE 1 -/* Define to 1 to enable the NCP UART interface. */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +/* Define to 1 to enable the NCP HDLC interface. */ +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 /* Define to 1 to enable posix platform. */ #define OPENTHREAD_PLATFORM_POSIX 1 diff --git a/include/openthread/BUILD.gn b/include/openthread/BUILD.gn index 54a0d19f8..2e7cabf7a 100644 --- a/include/openthread/BUILD.gn +++ b/include/openthread/BUILD.gn @@ -111,7 +111,6 @@ source_set("openthread") { "platform/time.h", "platform/toolchain.h", "platform/trel-udp6.h", - "platform/uart.h", "platform/udp.h", "random_crypto.h", "random_noncrypto.h", diff --git a/include/openthread/cli.h b/include/openthread/cli.h index c13657796..56c986828 100644 --- a/include/openthread/cli.h +++ b/include/openthread/cli.h @@ -74,20 +74,20 @@ typedef struct otCliCommand * @param[in] aBufLength A length of the output data stored in the buffer. * @param[out] aContext A user context pointer. * - * @returns Number of bytes processed by the callback. + * @returns Number of bytes written by the callback. * */ -typedef int (*otCliConsoleOutputCallback)(const char *aBuf, uint16_t aBufLength, void *aContext); +typedef int (*otCliOutputCallback)(void *aContext, const char *aFormat, va_list aArguments); /** - * Initialize the CLI CONSOLE module. + * Initialize the CLI module. * * @param[in] aInstance The OpenThread instance structure. - * @param[in] aCallback A callback method called to process console output. + * @param[in] aCallback A callback method called to process CLI output. * @param[in] aContext A user context pointer. * */ -void otCliConsoleInit(otInstance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext); +void otCliInit(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext); /** * This method is called to feed in a console input line. @@ -95,15 +95,7 @@ void otCliConsoleInit(otInstance *aInstance, otCliConsoleOutputCallback aCallbac * @param[in] aBuf A pointer to a null-terminated string. * */ -void otCliConsoleInputLine(char *aBuf); - -/** - * Initialize the CLI UART module. - * - * @param[in] aInstance The OpenThread instance structure. - * - */ -void otCliUartInit(otInstance *aInstance); +void otCliInputLine(char *aBuf); /** * Set a user command table. @@ -133,15 +125,6 @@ void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength); */ void otCliOutputFormat(const char *aFmt, ...); -/** - * Write string to the CLI console - * - * @param[in] aString A pointer to the string, which may not be null-terminated. - * @param[in] aLength Number of bytes. - * - */ -void otCliOutput(const char *aString, uint16_t aLength); - /** * Write error code to the CLI console * diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 3f7713d82..569012f24 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (84) +#define OPENTHREAD_API_VERSION (85) /** * @addtogroup api-instance diff --git a/include/openthread/ncp.h b/include/openthread/ncp.h index b5f07fe79..72896723c 100644 --- a/include/openthread/ncp.h +++ b/include/openthread/ncp.h @@ -55,12 +55,47 @@ extern "C" { */ /** - * Initialize the NCP. + * This function pointer is called to send HDLC encoded NCP data. + * + * @param[in] aBuf A pointer to a buffer with an output. + * @param[in] aBufLength A length of the output data stored in the buffer. + * + * @returns Number of bytes processed by the callback. + * + */ +typedef int (*otNcpHdlcSendCallback)(const uint8_t *aBuf, uint16_t aBufLength); + +/** + * This function is called after NCP send finished. + * + */ +void otNcpHdlcSendDone(void); + +/** + * This function is called after HDLC encoded NCP data received. + * + * @param[in] aBuf A pointer to a buffer. + * @param[in] aBufLength The length of the data stored in the buffer. + * + */ +void otNcpHdlcReceive(const uint8_t *aBuf, uint16_t aBufLength); + +/** + * Initialize the NCP based on HDLC framing. + * + * @param[in] aInstance The OpenThread instance structure. + * @param[in] aSendCallback The function pointer used to send NCP data. + * + */ +void otNcpHdlcInit(otInstance *aInstance, otNcpHdlcSendCallback aSendCallback); + +/** + * Initialize the NCP based on SPI framing. * * @param[in] aInstance The OpenThread instance structure. * */ -void otNcpInit(otInstance *aInstance); +void otNcpSpiInit(otInstance *aInstance); /** * @brief Send data to the host via a specific stream. diff --git a/script/check-android-build b/script/check-android-build index 790cbefa0..8587fde94 100755 --- a/script/check-android-build +++ b/script/check-android-build @@ -47,8 +47,8 @@ check_targets() main() { - OPENTHREAD_ENABLE_ANDROID_MK=1 ANDROID_NDK=1 USE_OTBR_DAEMON=1 check_targets ot-cli ot-ctl ot-ncp - OPENTHREAD_ENABLE_ANDROID_MK=1 ANDROID_NDK=1 check_targets ot-cli ot-ncp spi-hdlc-adapter + OPENTHREAD_ENABLE_ANDROID_MK=1 ANDROID_NDK=1 USE_OTBR_DAEMON=1 check_targets ot-cli ot-ctl + OPENTHREAD_ENABLE_ANDROID_MK=1 ANDROID_NDK=1 check_targets ot-cli spi-hdlc-adapter } main "$@" diff --git a/script/check-scan-build b/script/check-scan-build index e1980b805..b444f0b42 100755 --- a/script/check-scan-build +++ b/script/check-scan-build @@ -102,7 +102,7 @@ do_scan_build() scan-build-9 ./configure "${configure_options[@]}" scan-build-9 --status-bugs -analyze-headers -v make -j"${OT_BUILD_JOBS}" - export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1" + export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1" scan-build-9 ./configure "${configure_options[@]}" scan-build-9 --status-bugs -analyze-headers -v make -j"${OT_BUILD_JOBS}" } diff --git a/script/check-simulation-build-autotools b/script/check-simulation-build-autotools index 636248f32..8862b380d 100755 --- a/script/check-simulation-build-autotools +++ b/script/check-simulation-build-autotools @@ -73,8 +73,8 @@ build_all_features() "-DOPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE=1" "-DOPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE=1" "-DOPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE" + "-DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1" "-DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1" - "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1" @@ -154,7 +154,7 @@ build_nest_common() "-DOPENTHREAD_CONFIG_ANOUNCE_SENDER_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1" "-DOPENTHREAD_CONFIG_TIME_SYNC_ENABLE=1" - "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1" + "-DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1" ) export CPPFLAGS="${options[*]}" @@ -173,7 +173,7 @@ build_nest_common() cd .. options=( - "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1" + "-DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1" ) export CPPFLAGS="${options[*]}" @@ -197,7 +197,7 @@ build_multi_radio_links() { # TREL radio link only. local options=( - "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1" + "-DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1" "-DOPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_DEBG" "-DOPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE=0" @@ -221,7 +221,7 @@ build_multi_radio_links() # Multi radio link - 15.4 and TREL. options=( - "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1" + "-DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1" "-DOPENTHREAD_CONFIG_DIAG_ENABLE=1" "-DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1" diff --git a/src/cli/BUILD.gn b/src/cli/BUILD.gn index 3fbd6b021..cce57689d 100644 --- a/src/cli/BUILD.gn +++ b/src/cli/BUILD.gn @@ -37,8 +37,6 @@ openthread_cli_sources = [ "cli_commissioner.cpp", "cli_commissioner.hpp", "cli_config.h", - "cli_console.cpp", - "cli_console.hpp", "cli_dataset.cpp", "cli_dataset.hpp", "cli_joiner.cpp", @@ -49,8 +47,6 @@ openthread_cli_sources = [ "cli_srp_client.hpp", "cli_srp_server.cpp", "cli_srp_server.hpp", - "cli_uart.cpp", - "cli_uart.hpp", "cli_udp.cpp", "cli_udp.hpp", "x509_cert_key.hpp", diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 31de6aa23..c60eb051e 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -26,13 +26,6 @@ # POSSIBILITY OF SUCH DAMAGE. # -set(OT_CLI_TRANSPORT "UART" CACHE STRING "set the CLI transport") -set(OT_CLI_TRANSPORT_VALUES - "UART" - "CONSOLE" -) -set_property(CACHE OT_CLI_TRANSPORT PROPERTY STRINGS ${OT_CLI_TRANSPORT_VALUES}) - set(COMMON_INCLUDES ${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/core @@ -43,13 +36,11 @@ set(COMMON_SOURCES cli_coap.cpp cli_coap_secure.cpp cli_commissioner.cpp - cli_console.cpp cli_dataset.cpp cli_joiner.cpp cli_network_data.cpp cli_srp_client.cpp cli_srp_server.cpp - cli_uart.cpp cli_udp.cpp ) diff --git a/src/cli/Makefile.am b/src/cli/Makefile.am index f4c1032f3..060ff156f 100644 --- a/src/cli/Makefile.am +++ b/src/cli/Makefile.am @@ -144,13 +144,11 @@ SOURCES_COMMON = \ cli_coap.cpp \ cli_coap_secure.cpp \ cli_commissioner.cpp \ - cli_console.cpp \ cli_dataset.cpp \ cli_joiner.cpp \ cli_network_data.cpp \ cli_srp_client.cpp \ cli_srp_server.cpp \ - cli_uart.cpp \ cli_udp.cpp \ $(NULL) @@ -168,13 +166,11 @@ noinst_HEADERS = \ cli_coap_secure.hpp \ cli_commissioner.hpp \ cli_config.h \ - cli_console.hpp \ cli_dataset.hpp \ cli_joiner.hpp \ cli_network_data.hpp \ cli_srp_client.hpp \ cli_srp_server.hpp \ - cli_uart.hpp \ cli_udp.hpp \ x509_cert_key.hpp \ $(NULL) diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 3c99c916f..c72653968 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -44,7 +44,6 @@ #include #include #include -#include #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE #include #endif @@ -110,9 +109,12 @@ namespace Cli { constexpr Interpreter::Command Interpreter::sCommands[]; Interpreter *Interpreter::sInterpreter = nullptr; +static OT_DEFINE_ALIGNED_VAR(sInterpreterRaw, sizeof(Interpreter), uint64_t); -Interpreter::Interpreter(Instance *aInstance) +Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, void *aContext) : mInstance(aInstance) + , mOutputCallback(aCallback) + , mOutputContext(aContext) , mUserCommands(nullptr) , mUserCommandsLength(0) , mPingLength(kDefaultPingLength) @@ -4777,7 +4779,7 @@ otError Interpreter::ProcessDiag(uint8_t aArgsLength, char *aArgs[]) output[sizeof(output) - 1] = '\0'; error = otDiagProcessCmd(mInstance, aArgsLength, aArgs, output, sizeof(output) - 1); - Output(output, static_cast(strlen(output))); + OutputFormat("%s", output); return error; } @@ -5161,24 +5163,33 @@ void Interpreter::OutputLine(uint8_t aIndentSize, const char *aFormat, ...) void Interpreter::OutputSpaces(uint8_t aCount) { - static const char kSpaces[] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}; + char format[sizeof("%256s")]; - while (aCount > 0) - { - uint8_t len = OT_MIN(aCount, sizeof(kSpaces)); + snprintf(format, sizeof(format), "%%%us", aCount); - Output(kSpaces, len); - aCount -= len; - } + OutputFormat(format, ""); } int Interpreter::OutputFormatV(const char *aFormat, va_list aArguments) { - char buf[kMaxLineLength]; + return mOutputCallback(mOutputContext, aFormat, aArguments); +} - vsnprintf(buf, sizeof(buf), aFormat, aArguments); +void Interpreter::Initialize(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext) +{ + Instance *instance = static_cast(aInstance); - return Output(buf, static_cast(strlen(buf))); + Interpreter::sInterpreter = new (&sInterpreterRaw) Interpreter(instance, aCallback, aContext); +} + +extern "C" void otCliInit(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext) +{ + Interpreter::Initialize(aInstance, aCallback, aContext); +} + +extern "C" void otCliInputLine(char *aBuf) +{ + Interpreter::GetInterpreter().ProcessLine(aBuf); } extern "C" void otCliSetUserCommands(const otCliCommand *aUserCommands, uint8_t aLength, void *aContext) @@ -5199,11 +5210,6 @@ extern "C" void otCliOutputFormat(const char *aFmt, ...) va_end(aAp); } -extern "C" void otCliOutput(const char *aString, uint16_t aLength) -{ - Interpreter::GetInterpreter().Output(aString, aLength); -} - extern "C" void otCliAppendResult(otError aError) { Interpreter::GetInterpreter().OutputResult(aError); diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index c5d1b95f0..4638f17e4 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -96,9 +96,11 @@ public: /** * Constructor * - * @param[in] aInstance The OpenThread instance structure. + * @param[in] aInstance The OpenThread instance structure. + * @param[in] aCallback A callback method called to process CLI output. + * @param[in] aContext A user context pointer. */ - explicit Interpreter(Instance *aInstance); + explicit Interpreter(Instance *aInstance, otCliOutputCallback aCallback, void *aContext); /** * This method returns a reference to the interpreter object. @@ -113,6 +115,16 @@ public: return *sInterpreter; } + /** + * This method initializes the Console interpreter. + * + * @param[in] aInstance The OpenThread instance structure. + * @param[in] aCallback A pointer to a callback method. + * @param[in] aContext A pointer to a user context. + * + */ + static void Initialize(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext); + /** * This method returns whether the interpreter is initialized. * @@ -792,6 +804,9 @@ private: static_assert(Utils::LookupTable::IsSorted(sCommands), "Command Table is not sorted"); Instance * mInstance; + otCliOutputCallback mOutputCallback; + void * mOutputContext; + const otCliCommand *mUserCommands; uint8_t mUserCommandsLength; void * mUserCommandsContext; diff --git a/src/cli/cli_config.h b/src/cli/cli_config.h index cbab807a3..7c8fda0df 100644 --- a/src/cli/cli_config.h +++ b/src/cli/cli_config.h @@ -56,58 +56,6 @@ #define OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH 384 #endif -/** - * @def OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE - * - * The size of CLI UART RX buffer in bytes. - * - */ -#ifndef OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE -#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE -#define OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE 640 -#else -#define OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE 512 -#endif -#endif - -/** - * @def OPENTHREAD_CONFIG_CLI_TX_BUFFER_SIZE - * - * The size of CLI message buffer in bytes. - * - */ -#ifndef OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE -#define OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE 1024 -#endif - -/** - * @def OPENTHREAD_CONFIG_UART_CLI_RAW - * - * TODO: complete. - * - */ -#ifndef OPENTHREAD_CONFIG_UART_CLI_RAW -#define OPENTHREAD_CONFIG_UART_CLI_RAW 0 -#endif - -#define OT_CLI_TRANSPORT_UART (1) -#define OT_CLI_TRANSPORT_CONSOLE (2) - -/** - * @def OPENTHREAD_CONFIG_CLI_TRANSPORT - * - * The transport of the CLI. - * - */ -#ifndef OPENTHREAD_CONFIG_CLI_TRANSPORT -#define OPENTHREAD_CONFIG_CLI_TRANSPORT OT_CLI_TRANSPORT_UART -#endif - -#if OPENTHREAD_CONFIG_CLI_TRANSPORT != OT_CLI_TRANSPORT_UART && \ - OPENTHREAD_CONFIG_CLI_TRANSPORT != OT_CLI_TRANSPORT_CONSOLE -#error "Unsupported CLI transport!" -#endif - /** * @def OPENTHREAD_CONFIG_CLI_SRP_CLIENT_MAX_SERVICES * diff --git a/src/cli/cli_console.cpp b/src/cli/cli_console.cpp deleted file mode 100644 index ab7f7499d..000000000 --- a/src/cli/cli_console.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016, 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 implements the CLI interpreter on the CONSOLE service. - */ - -#include "cli_console.hpp" - -#if OPENTHREAD_CONFIG_CLI_TRANSPORT == OT_CLI_TRANSPORT_CONSOLE - -#include -#include -#include - -#include "cli/cli.hpp" -#include "common/instance.hpp" -#include "common/new.hpp" - -namespace ot { -namespace Cli { - -static OT_DEFINE_ALIGNED_VAR(sCliConsoleRaw, sizeof(Console), uint64_t); - -extern "C" void otCliConsoleInit(otInstance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext) -{ - Console::Initialize(aInstance, aCallback, aContext); -} - -extern "C" void otCliConsoleInputLine(char *aBuf) -{ - Interpreter::GetInterpreter().ProcessLine(aBuf); -} - -// Add stubs for simulation -extern "C" void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength) -{ - OT_UNUSED_VARIABLE(aBuf); - OT_UNUSED_VARIABLE(aBufLength); -} - -extern "C" void otPlatUartSendDone(void) -{ -} - -void Console::Initialize(otInstance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext) -{ - Instance *instance = static_cast(aInstance); - - Interpreter::sInterpreter = new (&sCliConsoleRaw) Console(instance, aCallback, aContext); -} - -Console::Console(Instance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext) - : Interpreter(aInstance) - , mCallback(aCallback) - , mContext(aContext) -{ -} - -int Interpreter::Output(const char *aBuf, uint16_t aBufLength) -{ - return static_cast(this)->Output(aBuf, aBufLength); -} - -int Console::Output(const char *aBuf, uint16_t aBufLength) -{ - return mCallback(aBuf, aBufLength, mContext); -} - -} // namespace Cli -} // namespace ot - -#endif // OPENTHREAD_CONFIG_CLI_TRANSPORT == OT_CLI_TRANSPORT_CONSOLE diff --git a/src/cli/cli_console.hpp b/src/cli/cli_console.hpp deleted file mode 100644 index a197b45bb..000000000 --- a/src/cli/cli_console.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016, 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 contains definitions for a CLI interpreter on the CONSOLE service. - */ - -#ifndef CLI_CONSOLE_HPP_ -#define CLI_CONSOLE_HPP_ - -#include "cli_config.h" - -#include - -#include "cli/cli.hpp" - -namespace ot { -namespace Cli { - -/** - * This class implements the CLI interpreter on top of the CONSOLE platform abstraction. - * - */ -class Console : public Interpreter -{ -public: - /** - * This method initializes the Console interpreter. - * - * @param[in] aInstance The OpenThread instance structure. - * @param[in] aCallback A pointer to a callback method. - * @param[in] aContext A pointer to a user context. - * - */ - static void Initialize(otInstance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext); - - /** - * 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. - * - * @returns The number of bytes placed in the output queue. - * - */ - int Output(const char *aBuf, uint16_t aBufLength); - -private: - explicit Console(Instance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext); - - otCliConsoleOutputCallback mCallback; - void * mContext; - - static Console *sConsole; - - friend class Interpreter; -}; - -} // namespace Cli -} // namespace ot - -#endif // CLI_CONSOLE_HPP_ diff --git a/src/cli/cli_uart.hpp b/src/cli/cli_uart.hpp deleted file mode 100644 index 33164d530..000000000 --- a/src/cli/cli_uart.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2016, 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 contains definitions for a CLI interpreter on the UART service. - */ - -#ifndef CLI_UART_HPP_ -#define CLI_UART_HPP_ - -#include "openthread-core-config.h" - -#include "cli/cli.hpp" -#include "common/instance.hpp" -#include "common/tasklet.hpp" - -namespace ot { -namespace Cli { - -/** - * This class implements the CLI interpreter on top of the UART platform abstraction. - * - */ -class Uart : public Interpreter -{ -public: - static void Initialize(otInstance *aInstance); - - /** - * 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. - * - * @returns The number of bytes placed in the output queue. - * - */ - int Output(const char *aBuf, uint16_t aBufLength); - - void ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength); - void SendDoneTask(void); - -private: - /** - * Constructor - * - * @param[in] aInstance The OpenThread instance structure. - * - */ - explicit Uart(Instance *aInstance); - - enum - { - kRxBufferSize = OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE, - kTxBufferSize = OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE, - }; - - otError ProcessCommand(void); - void Send(void); - - char mRxBuffer[kRxBufferSize]; - uint16_t mRxLength; - - char mTxBuffer[kTxBufferSize]; - uint16_t mTxHead; - uint16_t mTxLength; - - uint16_t mSendLength; - static Uart *sUart; - - friend class Interpreter; -}; - -} // namespace Cli -} // namespace ot - -#endif // CLI_UART_HPP_ diff --git a/src/cli/ftd.cmake b/src/cli/ftd.cmake index e0385bbe7..3d50d0c29 100644 --- a/src/cli/ftd.cmake +++ b/src/cli/ftd.cmake @@ -38,8 +38,6 @@ set_target_properties( target_compile_definitions(openthread-cli-ftd PRIVATE OPENTHREAD_FTD=1 - PUBLIC - "OPENTHREAD_CONFIG_CLI_TRANSPORT=OT_CLI_TRANSPORT_${OT_CLI_TRANSPORT}" ) target_compile_options(openthread-cli-ftd PRIVATE diff --git a/src/cli/mtd.cmake b/src/cli/mtd.cmake index dabb8b155..9c06fb35f 100644 --- a/src/cli/mtd.cmake +++ b/src/cli/mtd.cmake @@ -38,8 +38,6 @@ set_target_properties( target_compile_definitions(openthread-cli-mtd PRIVATE OPENTHREAD_MTD=1 - PUBLIC - "OPENTHREAD_CONFIG_CLI_TRANSPORT=OT_CLI_TRANSPORT_${OT_CLI_TRANSPORT}" ) target_compile_options(openthread-cli-mtd PRIVATE diff --git a/src/core/config/openthread-core-config-check.h b/src/core/config/openthread-core-config-check.h index aca59dadd..5308cf712 100644 --- a/src/core/config/openthread-core-config-check.h +++ b/src/core/config/openthread-core-config-check.h @@ -73,8 +73,12 @@ #error "OPENTHREAD_ENABLE_MULTIPLE_INSTANCES was replaced by OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE." #endif +#ifdef OPENTHREAD_CONFIG_NCP_UART_ENABLE +#error "OPENTHREAD_ENABLE_NCP_UART_ENABLE was replaced by OPENTHREAD_CONFIG_NCP_HDLC_ENABLE." +#endif + #ifdef OPENTHREAD_ENABLE_NCP_UART -#error "OPENTHREAD_ENABLE_NCP_UART was replaced by OPENTHREAD_CONFIG_NCP_UART_ENABLE." +#error "OPENTHREAD_ENABLE_NCP_UART was replaced by OPENTHREAD_CONFIG_NCP_HDLC_ENABLE." #endif #ifdef OPENTHREAD_ENABLE_NCP_SPI diff --git a/src/lib/spinel/CMakeLists.txt b/src/lib/spinel/CMakeLists.txt index f7b24baba..1f2dd8dad 100644 --- a/src/lib/spinel/CMakeLists.txt +++ b/src/lib/spinel/CMakeLists.txt @@ -38,13 +38,13 @@ set_target_properties( target_compile_definitions(openthread-spinel-ncp PRIVATE OPENTHREAD_FTD=1 - OPENTHREAD_CONFIG_NCP_UART_ENABLE=1 + OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 PUBLIC OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1 ) target_compile_definitions(openthread-spinel-rcp PRIVATE OPENTHREAD_RADIO=1 - OPENTHREAD_CONFIG_NCP_UART_ENABLE=1 + OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 PUBLIC OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=0 ) diff --git a/src/ncp/BUILD.gn b/src/ncp/BUILD.gn index 5e25ecc96..2adfdecaf 100644 --- a/src/ncp/BUILD.gn +++ b/src/ncp/BUILD.gn @@ -38,10 +38,10 @@ openthread_ncp_sources = [ "ncp_base_mtd.cpp", "ncp_base_radio.cpp", "ncp_config.h", + "ncp_hdlc.cpp", + "ncp_hdlc.hpp", "ncp_spi.cpp", "ncp_spi.hpp", - "ncp_uart.cpp", - "ncp_uart.hpp", ] config("ncp_config") { diff --git a/src/ncp/CMakeLists.txt b/src/ncp/CMakeLists.txt index 86f8a54d3..76bf8d3f0 100644 --- a/src/ncp/CMakeLists.txt +++ b/src/ncp/CMakeLists.txt @@ -37,7 +37,7 @@ set(COMMON_SOURCES ncp_base_dispatcher.cpp ncp_base_radio.cpp ncp_spi.cpp - ncp_uart.cpp + ncp_hdlc.cpp ) set(OT_NCP_VENDOR_HOOK_SOURCE "" CACHE STRING "set vendor hook source file for NCP") @@ -55,7 +55,7 @@ option(OT_NCP_SPI "enable NCP SPI support") if(OT_NCP_SPI) target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_NCP_SPI_ENABLE=1") else() - target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_NCP_UART_ENABLE=1") + target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1") endif() if(OT_FTD) diff --git a/src/ncp/Makefile.am b/src/ncp/Makefile.am index 69308d212..fff99afec 100644 --- a/src/ncp/Makefile.am +++ b/src/ncp/Makefile.am @@ -112,8 +112,8 @@ COMMON_SOURCES = \ ncp_config.h \ ncp_spi.cpp \ ncp_spi.hpp \ - ncp_uart.cpp \ - ncp_uart.hpp \ + ncp_hdlc.cpp \ + ncp_hdlc.hpp \ $(NULL) if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK diff --git a/src/ncp/example_vendor_hook.cpp b/src/ncp/example_vendor_hook.cpp index 195e08400..4c0b72db1 100644 --- a/src/ncp/example_vendor_hook.cpp +++ b/src/ncp/example_vendor_hook.cpp @@ -118,20 +118,27 @@ otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey) //------------------------------------------------------------------------------------------------------------------- // When OPENTHREAD_ENABLE_NCP_VENDOR_HOOK is enabled, vendor code is -// expected to provide the `otNcpInit()` function. The reason behind +// expected to provide the `otAppNcpInit()` function. The reason behind // this is to enable vendor code to define its own sub-class of -// `NcpBase` or `NcpUart`/`NcpSpi`. +// `NcpBase` or `NcpHdlc`/`NcpSpi`. // -// Example below show how to add a vendor sub-class over `NcpUart`. +// Example below show how to add a vendor sub-class over `NcpHdlc`. -#include "ncp_uart.hpp" +#include "ncp_hdlc.hpp" #include "common/new.hpp" -class NcpVendorUart : public ot::Ncp::NcpUart +class NcpVendorUart : public ot::Ncp::NcpHdlc { + static int SendHdlc(const uint8_t *aBuf, uint16_t aBufLength) + { + OT_UNUSED_VARIABLE(aBuf); + OT_UNUSED_VARIABLE(aBufLength); + return 0; + } + public: NcpVendorUart(ot::Instance *aInstance) - : ot::Ncp::NcpUart(aInstance) + : ot::Ncp::NcpHdlc(aInstance, &NcpVendorUart::SendHdlc) { } @@ -140,7 +147,7 @@ public: static OT_DEFINE_ALIGNED_VAR(sNcpVendorRaw, sizeof(NcpVendorUart), uint64_t); -extern "C" void otNcpInit(otInstance *aInstance) +extern "C" void otAppNcpInit(otInstance *aInstance) { NcpVendorUart *ncpVendor = nullptr; ot::Instance * instance = static_cast(aInstance); diff --git a/src/ncp/ftd.cmake b/src/ncp/ftd.cmake index afa685ca4..020c4d271 100644 --- a/src/ncp/ftd.cmake +++ b/src/ncp/ftd.cmake @@ -37,7 +37,7 @@ set_target_properties( target_compile_definitions(openthread-ncp-ftd PRIVATE OPENTHREAD_FTD=1 - OPENTHREAD_CONFIG_NCP_UART_ENABLE=1 + OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 ) target_compile_options(openthread-ncp-ftd PRIVATE diff --git a/src/ncp/mtd.cmake b/src/ncp/mtd.cmake index aa4f274b3..81a377c0c 100644 --- a/src/ncp/mtd.cmake +++ b/src/ncp/mtd.cmake @@ -37,7 +37,7 @@ set_target_properties( target_compile_definitions(openthread-ncp-mtd PRIVATE OPENTHREAD_MTD=1 - OPENTHREAD_CONFIG_NCP_UART_ENABLE=1 + OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 ) target_compile_options(openthread-ncp-mtd PRIVATE diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index 8a65f3744..990c514db 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -436,7 +436,7 @@ protected: #if OPENTHREAD_CONFIG_DIAG_ENABLE static_assert(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE - kSpinelCmdHeaderSize - kSpinelPropIdSize, - "diag output buffer should be smaller than NCP UART tx buffer"); + "diag output buffer should be smaller than NCP HDLC tx buffer"); otError HandlePropertySet_SPINEL_PROP_NEST_STREAM_MFG(uint8_t aHeader); #endif diff --git a/src/ncp/ncp_config.h b/src/ncp/ncp_config.h index 2d1ac2636..60ab9c64a 100644 --- a/src/ncp/ncp_config.h +++ b/src/ncp/ncp_config.h @@ -50,13 +50,13 @@ #endif /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#ifndef OPENTHREAD_CONFIG_NCP_UART_ENABLE -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 0 +#ifndef OPENTHREAD_CONFIG_NCP_HDLC_ENABLE +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 0 #endif /** @@ -70,28 +70,28 @@ #endif /** - * @def OPENTHREAD_CONFIG_NCP_UART_TX_CHUNK_SIZE + * @def OPENTHREAD_CONFIG_NCP_HDLC_TX_CHUNK_SIZE * - * The size of NCP UART TX chunk in bytes. + * The size of NCP HDLC TX chunk in bytes. * */ -#ifndef OPENTHREAD_CONFIG_NCP_UART_TX_CHUNK_SIZE -#define OPENTHREAD_CONFIG_NCP_UART_TX_CHUNK_SIZE 2048 +#ifndef OPENTHREAD_CONFIG_NCP_HDLC_TX_CHUNK_SIZE +#define OPENTHREAD_CONFIG_NCP_HDLC_TX_CHUNK_SIZE 2048 #endif /** - * @def OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE + * @def OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE * - * The size of NCP UART RX buffer in bytes. + * The size of NCP HDLC RX buffer in bytes. * */ -#ifndef OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE +#ifndef OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE #if OPENTHREAD_RADIO -#define OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE 512 +#define OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE 512 #else -#define OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE 1300 +#define OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE 1300 #endif -#endif // OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE +#endif // OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE /** * @def OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE diff --git a/src/ncp/ncp_uart.cpp b/src/ncp/ncp_hdlc.cpp similarity index 74% rename from src/ncp/ncp_uart.cpp rename to src/ncp/ncp_hdlc.cpp index 29547b44c..b1a56c344 100644 --- a/src/ncp/ncp_uart.cpp +++ b/src/ncp/ncp_hdlc.cpp @@ -27,17 +27,16 @@ /** * @file - * This file contains definitions for a UART based NCP interface to the OpenThread stack. + * This file contains definitions for a HDLC based NCP interface to the OpenThread stack. */ -#include "ncp_uart.hpp" +#include "ncp_hdlc.hpp" #include #include #include #include -#include #include "openthread-core-config.h" #include "common/code_utils.hpp" @@ -46,16 +45,16 @@ #include "common/new.hpp" #include "net/ip6.hpp" -#if OPENTHREAD_CONFIG_NCP_UART_ENABLE +#if OPENTHREAD_CONFIG_NCP_HDLC_ENABLE #if OPENTHREAD_CONFIG_DIAG_ENABLE -static_assert(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE - +static_assert(OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE - ot::Ncp::NcpBase::kSpinelCmdHeaderSize - ot::Ncp::NcpBase::kSpinelPropIdSize, - "diag output should be smaller than NCP UART rx buffer"); + "diag output should be smaller than NCP HDLC rx buffer"); -static_assert(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE, - "diag command line should be smaller than NCP UART rx buffer"); +static_assert(OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE <= OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE, + "diag command line should be smaller than NCP HDLC rx buffer"); #endif namespace ot { @@ -63,16 +62,16 @@ namespace Ncp { #if OPENTHREAD_ENABLE_NCP_VENDOR_HOOK == 0 -static OT_DEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpUart), uint64_t); +static OT_DEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpHdlc), uint64_t); -extern "C" void otNcpInit(otInstance *aInstance) +extern "C" void otNcpHdlcInit(otInstance *aInstance, otNcpHdlcSendCallback aSendCallback) { - NcpUart * ncpUart = nullptr; + NcpHdlc * ncpHdlc = nullptr; Instance *instance = static_cast(aInstance); - ncpUart = new (&sNcpRaw) NcpUart(instance); + ncpHdlc = new (&sNcpRaw) NcpHdlc(instance, aSendCallback); - if (ncpUart == nullptr || ncpUart != NcpBase::GetNcpInstance()) + if (ncpHdlc == nullptr || ncpHdlc != NcpBase::GetNcpInstance()) { OT_ASSERT(false); } @@ -80,24 +79,23 @@ extern "C" void otNcpInit(otInstance *aInstance) #endif // OPENTHREAD_ENABLE_NCP_VENDOR_HOOK == 0 -NcpUart::NcpUart(Instance *aInstance) +NcpHdlc::NcpHdlc(Instance *aInstance, otNcpHdlcSendCallback aSendCallback) : NcpBase(aInstance) - , mFrameEncoder(mUartBuffer) - , mFrameDecoder(mRxBuffer, &NcpUart::HandleFrame, this) + , mSendCallback(aSendCallback) + , mFrameEncoder(mHdlcBuffer) + , mFrameDecoder(mRxBuffer, &NcpHdlc::HandleFrame, this) , mState(kStartingFrame) , mByte(0) - , mUartSendImmediate(false) - , mUartSendTask(*aInstance, EncodeAndSendToUart) + , mHdlcSendImmediate(false) + , mHdlcSendTask(*aInstance, EncodeAndSend) #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER , mTxFrameBufferEncrypterReader(mTxFrameBuffer) #endif // OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER { mTxFrameBuffer.SetFrameAddedCallback(HandleFrameAddedToNcpBuffer, this); - - IgnoreError(otPlatUartEnable()); } -void NcpUart::HandleFrameAddedToNcpBuffer(void * aContext, +void NcpHdlc::HandleFrameAddedToNcpBuffer(void * aContext, Spinel::Buffer::FrameTag aTag, Spinel::Buffer::Priority aPriority, Spinel::Buffer * aBuffer) @@ -106,27 +104,27 @@ void NcpUart::HandleFrameAddedToNcpBuffer(void * aContext, OT_UNUSED_VARIABLE(aTag); OT_UNUSED_VARIABLE(aPriority); - static_cast(aContext)->HandleFrameAddedToNcpBuffer(); + static_cast(aContext)->HandleFrameAddedToNcpBuffer(); } -void NcpUart::HandleFrameAddedToNcpBuffer(void) +void NcpHdlc::HandleFrameAddedToNcpBuffer(void) { - if (mUartBuffer.IsEmpty()) + if (mHdlcBuffer.IsEmpty()) { - mUartSendTask.Post(); + mHdlcSendTask.Post(); } } -void NcpUart::EncodeAndSendToUart(Tasklet &aTasklet) +void NcpHdlc::EncodeAndSend(Tasklet &aTasklet) { OT_UNUSED_VARIABLE(aTasklet); - static_cast(GetNcpInstance())->EncodeAndSendToUart(); + static_cast(GetNcpInstance())->EncodeAndSend(); } // This method encodes a frame from the tx frame buffer (mTxFrameBuffer) into the uart buffer and sends it over uart. // If the uart buffer gets full, it sends the current encoded portion. This method remembers current state, so on // sub-sequent calls, it restarts encoding the bytes from where it left of in the frame . -void NcpUart::EncodeAndSendToUart(void) +void NcpHdlc::EncodeAndSend(void) { uint16_t len; bool prevHostPowerState; @@ -175,10 +173,10 @@ void NcpUart::EncodeAndSendToUart(void) { // If mHostPowerStateInProgress transitioned from true -> false // in the call to OutFrameRemove, then the frame should be sent - // out the UART without attempting to push any new frames into - // the mUartBuffer. This is necessary to avoid prematurely calling + // out without attempting to push any new frames into the + // mHdlcBuffer. This is necessary to avoid prematurely calling // otPlatWakeHost. - mUartSendImmediate = true; + mHdlcSendImmediate = true; } mState = kFinalizingFrame; @@ -191,64 +189,63 @@ void NcpUart::EncodeAndSendToUart(void) mState = kStartingFrame; - if (mUartSendImmediate) + if (mHdlcSendImmediate) { // clear state and break; - mUartSendImmediate = false; + mHdlcSendImmediate = false; break; } } } exit: - len = mUartBuffer.GetLength(); + len = mHdlcBuffer.GetLength(); if (len > 0) { - if (otPlatUartSend(mUartBuffer.GetFrame(), len) != OT_ERROR_NONE) - { - OT_ASSERT(false); - } + int rval = mSendCallback(mHdlcBuffer.GetFrame(), len); + OT_UNUSED_VARIABLE(rval); + OT_ASSERT(rval == static_cast(len)); } } -extern "C" void otPlatUartSendDone(void) +extern "C" void otNcpHdlcSendDone(void) { - NcpUart *ncpUart = static_cast(NcpBase::GetNcpInstance()); + NcpHdlc *ncpHdlc = static_cast(NcpBase::GetNcpInstance()); - if (ncpUart != nullptr) + if (ncpHdlc != nullptr) { - ncpUart->HandleUartSendDone(); + ncpHdlc->HandleHdlcSendDone(); } } -void NcpUart::HandleUartSendDone(void) +void NcpHdlc::HandleHdlcSendDone(void) { - mUartBuffer.Clear(); - mUartSendTask.Post(); + mHdlcBuffer.Clear(); + mHdlcSendTask.Post(); } -extern "C" void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength) +extern "C" void otNcpHdlcReceive(const uint8_t *aBuf, uint16_t aBufLength) { - NcpUart *ncpUart = static_cast(NcpBase::GetNcpInstance()); + NcpHdlc *ncpHdlc = static_cast(NcpBase::GetNcpInstance()); - if (ncpUart != nullptr) + if (ncpHdlc != nullptr) { - ncpUart->HandleUartReceiveDone(aBuf, aBufLength); + ncpHdlc->HandleHdlcReceiveDone(aBuf, aBufLength); } } -void NcpUart::HandleUartReceiveDone(const uint8_t *aBuf, uint16_t aBufLength) +void NcpHdlc::HandleHdlcReceiveDone(const uint8_t *aBuf, uint16_t aBufLength) { mFrameDecoder.Decode(aBuf, aBufLength); } -void NcpUart::HandleFrame(void *aContext, otError aError) +void NcpHdlc::HandleFrame(void *aContext, otError aError) { - static_cast(aContext)->HandleFrame(aError); + static_cast(aContext)->HandleFrame(aError); } -void NcpUart::HandleFrame(otError aError) +void NcpHdlc::HandleFrame(otError aError) { uint8_t *buf = mRxBuffer.GetFrame(); uint16_t bufLength = mRxBuffer.GetLength(); @@ -273,7 +270,7 @@ void NcpUart::HandleFrame(otError aError) mRxBuffer.Clear(); } -void NcpUart::HandleError(otError aError, uint8_t *aBuf, uint16_t aBufLength) +void NcpHdlc::HandleError(otError aError, uint8_t *aBuf, uint16_t aBufLength) { char hexbuf[128]; uint16_t i = 0; @@ -308,19 +305,19 @@ void NcpUart::HandleError(otError aError, uint8_t *aBuf, uint16_t aBufLength) #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER -NcpUart::BufferEncrypterReader::BufferEncrypterReader(Spinel::Buffer &aTxFrameBuffer) +NcpHdlc::BufferEncrypterReader::BufferEncrypterReader(Spinel::Buffer &aTxFrameBuffer) : mTxFrameBuffer(aTxFrameBuffer) , mDataBufferReadIndex(0) , mOutputDataLength(0) { } -bool NcpUart::BufferEncrypterReader::IsEmpty(void) const +bool NcpHdlc::BufferEncrypterReader::IsEmpty(void) const { return mTxFrameBuffer.IsEmpty() && !mOutputDataLength; } -otError NcpUart::BufferEncrypterReader::OutFrameBegin(void) +otError NcpHdlc::BufferEncrypterReader::OutFrameBegin(void) { otError status = OT_ERROR_FAILED; @@ -350,22 +347,22 @@ otError NcpUart::BufferEncrypterReader::OutFrameBegin(void) return status; } -bool NcpUart::BufferEncrypterReader::OutFrameHasEnded(void) +bool NcpHdlc::BufferEncrypterReader::OutFrameHasEnded(void) { return (mDataBufferReadIndex >= mOutputDataLength); } -uint8_t NcpUart::BufferEncrypterReader::OutFrameReadByte(void) +uint8_t NcpHdlc::BufferEncrypterReader::OutFrameReadByte(void) { return mDataBuffer[mDataBufferReadIndex++]; } -otError NcpUart::BufferEncrypterReader::OutFrameRemove(void) +otError NcpHdlc::BufferEncrypterReader::OutFrameRemove(void) { return mTxFrameBuffer.OutFrameRemove(); } -void NcpUart::BufferEncrypterReader::Reset(void) +void NcpHdlc::BufferEncrypterReader::Reset(void) { mOutputDataLength = 0; mDataBufferReadIndex = 0; @@ -376,4 +373,4 @@ void NcpUart::BufferEncrypterReader::Reset(void) } // namespace Ncp } // namespace ot -#endif // OPENTHREAD_CONFIG_NCP_UART_ENABLE +#endif // OPENTHREAD_CONFIG_NCP_HDLC_ENABLE diff --git a/src/ncp/ncp_uart.hpp b/src/ncp/ncp_hdlc.hpp similarity index 76% rename from src/ncp/ncp_uart.hpp rename to src/ncp/ncp_hdlc.hpp index 5892c2f38..e3c489f76 100644 --- a/src/ncp/ncp_uart.hpp +++ b/src/ncp/ncp_hdlc.hpp @@ -27,11 +27,11 @@ /** * @file - * This file contains definitions for a UART based NCP interface to the OpenThread stack. + * This file contains definitions for a HDLC based NCP interface to the OpenThread stack. */ -#ifndef NCP_UART_HPP_ -#define NCP_UART_HPP_ +#ifndef NCP_HDLC_HPP_ +#define NCP_HDLC_HPP_ #include "openthread-core-config.h" @@ -45,7 +45,7 @@ namespace ot { namespace Ncp { -class NcpUart : public NcpBase +class NcpHdlc : public NcpBase { typedef NcpBase super_t; @@ -56,29 +56,29 @@ public: * @param[in] aInstance The OpenThread instance structure. * */ - explicit NcpUart(Instance *aInstance); + explicit NcpHdlc(Instance *aInstance, otNcpHdlcSendCallback aSendCallback); /** * This method is called when uart tx is finished. It prepares and sends the next data chunk (if any) to uart. * */ - void HandleUartSendDone(void); + void HandleHdlcSendDone(void); /** * This method is called when uart received a data buffer. * */ - void HandleUartReceiveDone(const uint8_t *aBuf, uint16_t aBufLength); + void HandleHdlcReceiveDone(const uint8_t *aBuf, uint16_t aBufLength); private: enum { - kUartTxBufferSize = OPENTHREAD_CONFIG_NCP_UART_TX_CHUNK_SIZE, // Uart tx buffer size. - kRxBufferSize = OPENTHREAD_CONFIG_NCP_UART_RX_BUFFER_SIZE + // Rx buffer size (should be large enough to fit + kHdlcTxBufferSize = OPENTHREAD_CONFIG_NCP_HDLC_TX_CHUNK_SIZE, // HDLC tx buffer size. + kRxBufferSize = OPENTHREAD_CONFIG_NCP_HDLC_RX_BUFFER_SIZE + // Rx buffer size (should be large enough to fit OPENTHREAD_CONFIG_NCP_SPINEL_ENCRYPTER_EXTRA_DATA_SIZE, // one whole (decoded) received frame). }; - enum UartTxState + enum HdlcTxState { kStartingFrame, // Starting a new frame. kEncodingFrame, // In middle of encoding a frame. @@ -114,27 +114,28 @@ private: }; #endif // OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER - void EncodeAndSendToUart(void); + void EncodeAndSend(void); void HandleFrame(otError aError); void HandleError(otError aError, uint8_t *aBuf, uint16_t aBufLength); void TxFrameBufferHasData(void); void HandleFrameAddedToNcpBuffer(void); - static void EncodeAndSendToUart(Tasklet &aTasklet); - static void HandleFrame(void *aContext, otError aError); - static void HandleFrameAddedToNcpBuffer(void * aContext, - Spinel::Buffer::FrameTag aTag, - Spinel::Buffer::Priority aPriority, - Spinel::Buffer * aBuffer); + static void EncodeAndSend(Tasklet &aTasklet); + static void HandleFrame(void *aContext, otError aError); + static void HandleFrameAddedToNcpBuffer(void * aContext, + Spinel::Buffer::FrameTag aTag, + Spinel::Buffer::Priority aPriority, + Spinel::Buffer * aBuffer); + otNcpHdlcSendCallback mSendCallback; Hdlc::Encoder mFrameEncoder; Hdlc::Decoder mFrameDecoder; - Hdlc::FrameBuffer mUartBuffer; - UartTxState mState; + Hdlc::FrameBuffer mHdlcBuffer; + HdlcTxState mState; uint8_t mByte; Hdlc::FrameBuffer mRxBuffer; - bool mUartSendImmediate; - Tasklet mUartSendTask; + bool mHdlcSendImmediate; + Tasklet mHdlcSendTask; #if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER BufferEncrypterReader mTxFrameBufferEncrypterReader; @@ -144,4 +145,4 @@ private: } // namespace Ncp } // namespace ot -#endif // NCP_UART_HPP_ +#endif // NCP_HDLC_HPP_ diff --git a/src/ncp/ncp_spi.cpp b/src/ncp/ncp_spi.cpp index 0f4257066..618769bc3 100644 --- a/src/ncp/ncp_spi.cpp +++ b/src/ncp/ncp_spi.cpp @@ -62,7 +62,7 @@ namespace Ncp { static OT_DEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpSpi), uint64_t); -extern "C" void otNcpInit(otInstance *aInstance) +extern "C" void otNcpSpiInit(otInstance *aInstance) { NcpSpi * ncpSpi = nullptr; Instance *instance = static_cast(aInstance); diff --git a/src/ncp/radio.cmake b/src/ncp/radio.cmake index 212a8c082..502961afb 100644 --- a/src/ncp/radio.cmake +++ b/src/ncp/radio.cmake @@ -37,7 +37,7 @@ set_target_properties( target_compile_definitions(openthread-rcp PRIVATE OPENTHREAD_RADIO=1 - OPENTHREAD_CONFIG_NCP_UART_ENABLE=1 + OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1 ) target_compile_options(openthread-rcp PRIVATE diff --git a/src/posix/CMakeLists.txt b/src/posix/CMakeLists.txt index 06940093d..575271a8f 100644 --- a/src/posix/CMakeLists.txt +++ b/src/posix/CMakeLists.txt @@ -26,10 +26,6 @@ # POSSIBILITY OF SUCH DAMAGE. # -target_compile_definitions(ot-config INTERFACE - OPENTHREAD_CONFIG_UART_CLI_RAW=1 -) - set(COMMON_INCLUDES ${OT_PUBLIC_INCLUDES} ${PROJECT_SOURCE_DIR}/src diff --git a/src/posix/Makefile-posix b/src/posix/Makefile-posix index 19cc1e53b..80201a38f 100644 --- a/src/posix/Makefile-posix +++ b/src/posix/Makefile-posix @@ -74,7 +74,6 @@ endif COMMONCFLAGS := \ -g \ - -DOPENTHREAD_CONFIG_UART_CLI_RAW=1 \ $(NULL) # If the user has asserted COVERAGE, alter the configuration options @@ -113,7 +112,6 @@ endif ifneq ($(READLINE),) configure_OPTIONS += --with-readline=$(READLINE) -CLI_TRANSPORT = $(if $(and $(filter-out no,$(READLINE)),$(filter 0,$(DAEMON))),CONSOLE,UART) endif ifeq ($(RCP_BUS),spi) diff --git a/src/posix/Makefile.am b/src/posix/Makefile.am index d9e17d4fd..e20aa6c30 100644 --- a/src/posix/Makefile.am +++ b/src/posix/Makefile.am @@ -82,6 +82,7 @@ ot_ncp_CPPFLAGS = \ ot_ncp_SOURCES = \ main.c \ + ncp.cpp \ $(NULL) ot_ncp_LDADD = \ @@ -162,7 +163,7 @@ ot_cli_CPPFLAGS = \ ot_cli_SOURCES = \ main.c \ - console_cli.cpp \ + cli.cpp \ $(NULL) ot_cli_LDADD = \ @@ -198,8 +199,4 @@ CLEANFILES = $(wildc endif # OPENTHREAD_BUILD_COVERAGE endif # OPENTHREAD_ENABLE_EXECUTABLE -noinst_HEADERS = \ - console_cli.h \ - $(NULL) - include $(abs_top_nlbuild_autotools_dir)/automake/post.am diff --git a/src/posix/cli.cmake b/src/posix/cli.cmake index eef034e34..cfb5dc380 100644 --- a/src/posix/cli.cmake +++ b/src/posix/cli.cmake @@ -28,7 +28,7 @@ add_executable(ot-cli main.c - $<$:console_cli.cpp> + cli.cpp ) set_target_properties( @@ -40,10 +40,6 @@ set_target_properties( target_include_directories(ot-cli PRIVATE ${COMMON_INCLUDES}) -if(OT_READLINE) - set(OT_CLI_TRANSPORT "CONSOLE" CACHE STRING "set CLI to use console interpreter" FORCE) -endif() - target_compile_definitions(ot-cli PRIVATE $<$:HAVE_LIB$=1> OPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_CLI diff --git a/src/posix/console_cli.cpp b/src/posix/cli.cpp similarity index 63% rename from src/posix/console_cli.cpp rename to src/posix/cli.cpp index b98ea8851..4949de51a 100644 --- a/src/posix/console_cli.cpp +++ b/src/posix/cli.cpp @@ -26,13 +26,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "console_cli.h" +#include "platform/openthread-posix-config.h" -#if OPENTHREAD_CONFIG_CLI_TRANSPORT == OT_CLI_TRANSPORT_CONSOLE +#if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE #include +#include #include +#include #include #include #include @@ -46,17 +48,20 @@ #endif #if HAVE_LIBEDIT || HAVE_LIBREADLINE +#define OPENTHREAD_USE_READLINE 1 #if HAVE_LIBEDIT #include #elif HAVE_LIBREADLINE #include #include +#endif #else -#error "Missing readline library" +#define OPENTHREAD_USE_READLINE 0 #endif #include +#include "cli/cli_config.h" #include "common/code_utils.hpp" #include "openthread-core-config.h" @@ -64,8 +69,7 @@ static const char sPrompt[] = "> "; -static int sReadFd; - +#if OPENTHREAD_USE_READLINE static void InputCallback(char *aLine) { if (aLine != nullptr) @@ -73,7 +77,7 @@ static void InputCallback(char *aLine) if (aLine[0] != '\0') { add_history(aLine); - otCliConsoleInputLine(aLine); + otCliInputLine(aLine); } free(aLine); } @@ -82,57 +86,72 @@ static void InputCallback(char *aLine) exit(OT_EXIT_SUCCESS); } } +#endif -static int OutputCallback(const char *aBuffer, uint16_t aLength, void *aContext) +static int OutputCallback(void *aContext, const char *aFormat, va_list aArguments) { - (void)aContext; + OT_UNUSED_VARIABLE(aContext); - return (int)write(STDOUT_FILENO, aBuffer, aLength); + return vdprintf(STDOUT_FILENO, aFormat, aArguments); } -void otxConsoleInit(otInstance *aInstance) +extern "C" void otAppCliInit(otInstance *aInstance) { +#if OPENTHREAD_USE_READLINE rl_instream = stdin; rl_outstream = stdout; rl_inhibit_completion = true; - rl_set_screen_size(0, OT_MAX(OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH, OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE)); + rl_set_screen_size(0, OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH); - sReadFd = fileno(rl_instream); rl_callback_handler_install(sPrompt, InputCallback); - otCliConsoleInit(aInstance, OutputCallback, nullptr); +#endif + otCliInit(aInstance, OutputCallback, nullptr); } -void otxConsoleDeinit(void) +extern "C" void otAppCliDeinit(void) { +#if OPENTHREAD_USE_READLINE rl_callback_handler_remove(); +#endif } -void otxConsoleUpdate(otSysMainloopContext *aMainloop) +extern "C" void otAppCliUpdate(otSysMainloopContext *aMainloop) { - FD_SET(sReadFd, &aMainloop->mReadFdSet); - FD_SET(sReadFd, &aMainloop->mErrorFdSet); + FD_SET(STDIN_FILENO, &aMainloop->mReadFdSet); + FD_SET(STDIN_FILENO, &aMainloop->mErrorFdSet); - if (aMainloop->mMaxFd < sReadFd) + if (aMainloop->mMaxFd < STDIN_FILENO) { - aMainloop->mMaxFd = sReadFd; + aMainloop->mMaxFd = STDIN_FILENO; } } -void otxConsoleProcess(const otSysMainloopContext *aMainloop) +extern "C" void otAppCliProcess(const otSysMainloopContext *aMainloop) { - if (FD_ISSET(sReadFd, &aMainloop->mErrorFdSet)) + if (FD_ISSET(STDIN_FILENO, &aMainloop->mErrorFdSet)) { - perror("console error"); exit(OT_EXIT_FAILURE); } - if (FD_ISSET(sReadFd, &aMainloop->mReadFdSet)) + if (FD_ISSET(STDIN_FILENO, &aMainloop->mReadFdSet)) { +#if OPENTHREAD_USE_READLINE rl_callback_read_char(); +#else + char buffer[OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH]; + + if (fgets(buffer, sizeof(buffer), stdin) != nullptr) + { + otCliInputLine(buffer); + dprintf(STDOUT_FILENO, "%s", sPrompt); + } + else + { + exit(OT_EXIT_SUCCESS); + } +#endif } } -#endif // HAVE_LIBEDIT || HAVE_LIBREADLINE - -#endif // OPENTHREAD_CONFIG_CLI_TRANSPORT == OT_CLI_TRANSPORT_CONSOLE +#endif // !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE diff --git a/src/posix/main.c b/src/posix/main.c index dc6148593..da5006ae0 100644 --- a/src/posix/main.c +++ b/src/posix/main.c @@ -67,7 +67,6 @@ #elif OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_CLI #include -#include "console_cli.h" #include "cli/cli_config.h" #else #error "Unknown posix app type!" @@ -82,6 +81,58 @@ #define OPENTHREAD_ENABLE_COVERAGE 0 #endif +/** + * This function initializes NCP app. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * + */ +void otAppNcpInit(otInstance *aInstance); + +/** + * This function deinitializes NCP app. + * + */ +void otAppNcpUpdate(otSysMainloopContext *aContext); + +/** + * This function updates the file descriptor sets with file descriptors used by console. + * + * @param[inout] aMainloop A pointer to the mainloop context. + * + */ +void otAppNcpProcess(const otSysMainloopContext *aContext); + +/** + * This function initializes CLI app. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * + */ +void otAppCliInit(otInstance *aInstance); + +/** + * This function deinitializes CLI app. + * + */ +void otAppCliDeinit(void); + +/** + * This function updates the file descriptor sets with file descriptors used by console. + * + * @param[inout] aMainloop A pointer to the mainloop context. + * + */ +void otAppCliUpdate(otSysMainloopContext *aMainloop); + +/** + * This function performs console driver processing. + * + * @param[in] aMainloop A pointer to the mainloop context. + * + */ +void otAppCliProcess(const otSysMainloopContext *aMainloop); + typedef struct PosixConfig { otPlatformConfig mPlatformConfig; ///< Platform configuration. @@ -330,12 +381,10 @@ int main(int argc, char *argv[]) instance = InitInstance(&config); #if OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_NCP - otNcpInit(instance); + otAppNcpInit(instance); #elif OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_CLI -#ifdef OPENTHREAD_USE_CONSOLE - otxConsoleInit(instance); -#else - otCliUartInit(instance); +#if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + otAppCliInit(instance); #endif otCliSetUserCommands(&radioUrlCommand, 1, &config.mPlatformConfig); #endif @@ -354,8 +403,12 @@ int main(int argc, char *argv[]) mainloop.mTimeout.tv_sec = 10; mainloop.mTimeout.tv_usec = 0; -#ifdef OPENTHREAD_USE_CONSOLE - otxConsoleUpdate(&mainloop); +#if OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_NCP + otAppNcpUpdate(&mainloop); +#elif OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_CLI +#if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + otAppCliUpdate(&mainloop); +#endif #endif otSysMainloopUpdate(instance, &mainloop); @@ -363,8 +416,12 @@ int main(int argc, char *argv[]) if (otSysMainloopPoll(&mainloop) >= 0) { otSysMainloopProcess(instance, &mainloop); -#ifdef OPENTHREAD_USE_CONSOLE - otxConsoleProcess(&mainloop); +#if OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_NCP + otAppNcpProcess(&mainloop); +#elif OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_CLI +#if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + otAppCliProcess(&mainloop); +#endif #endif } else if (errno != EINTR) @@ -374,8 +431,12 @@ int main(int argc, char *argv[]) } } -#ifdef OPENTHREAD_USE_CONSOLE - otxConsoleDeinit(); +#if OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_NCP + // disable ncp +#elif OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_CLI +#if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + otAppCliDeinit(); +#endif #endif exit: diff --git a/src/posix/ncp.cmake b/src/posix/ncp.cmake index 651b80b34..e313059bf 100644 --- a/src/posix/ncp.cmake +++ b/src/posix/ncp.cmake @@ -28,6 +28,7 @@ add_executable(ot-ncp main.c + ncp.cpp ) set_target_properties( diff --git a/src/posix/ncp.cpp b/src/posix/ncp.cpp new file mode 100644 index 000000000..868b71c6e --- /dev/null +++ b/src/posix/ncp.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2021, 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. + */ + +#include "openthread-posix-config.h" +#include "platform-posix.h" + +#include +#include +#include +#include + +#include +#include + +#include "common/code_utils.hpp" + +#if OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_NCP +static const uint8_t *sWriteBuffer = nullptr; +static uint16_t sWriteLength = 0; + +static int ncpHdlcSend(const uint8_t *aBuf, uint16_t aBufLength) +{ + sWriteBuffer = aBuf; + sWriteLength = aBufLength; + + return aBufLength; +} + +extern "C" void otAppNcpInit(otInstance *aInstance) +{ + otNcpHdlcInit(aInstance, ncpHdlcSend); +} + +extern "C" void otAppNcpUpdate(otSysMainloopContext *aContext) +{ + FD_SET(STDIN_FILENO, &aContext->mReadFdSet); + FD_SET(STDIN_FILENO, &aContext->mErrorFdSet); + + if (aContext->mMaxFd < STDIN_FILENO) + { + aContext->mMaxFd = STDIN_FILENO; + } + + if (sWriteLength > 0) + { + FD_SET(STDOUT_FILENO, &aContext->mWriteFdSet); + FD_SET(STDOUT_FILENO, &aContext->mErrorFdSet); + + if (aContext->mMaxFd < STDOUT_FILENO) + { + aContext->mMaxFd = STDOUT_FILENO; + } + } +} + +extern "C" void otAppNcpProcess(const otSysMainloopContext *aContext) +{ + ssize_t rval; + + if (FD_ISSET(STDIN_FILENO, &aContext->mErrorFdSet)) + { + DieNowWithMessage("stdin", OT_EXIT_FAILURE); + } + + if (FD_ISSET(STDOUT_FILENO, &aContext->mErrorFdSet)) + { + DieNowWithMessage("stdout", OT_EXIT_FAILURE); + } + + if (FD_ISSET(STDIN_FILENO, &aContext->mReadFdSet)) + { + uint8_t buffer[256]; + + rval = read(STDIN_FILENO, buffer, sizeof(buffer)); + + if (rval > 0) + { + otNcpHdlcReceive(buffer, static_cast(rval)); + } + else if (rval <= 0) + { + DieNowWithMessage("UART read", (rval < 0) ? OT_EXIT_ERROR_ERRNO : OT_EXIT_FAILURE); + } + } + + if ((FD_ISSET(STDOUT_FILENO, &aContext->mWriteFdSet))) + { + if (sWriteLength > 0) + { + rval = write(STDOUT_FILENO, sWriteBuffer, sWriteLength); + + if (rval < 0) + { + DieNow(OT_EXIT_ERROR_ERRNO); + } + + sWriteBuffer += rval; + sWriteLength -= static_cast(rval); + } + + if (sWriteLength == 0) + { + otNcpHdlcSendDone(); + } + } +} +#endif // OPENTHREAD_POSIX_APP_TYPE == OT_POSIX_APP_TYPE_NCP diff --git a/src/posix/platform/CMakeLists.txt b/src/posix/platform/CMakeLists.txt index 2056a531f..33dbebf7e 100644 --- a/src/posix/platform/CMakeLists.txt +++ b/src/posix/platform/CMakeLists.txt @@ -60,6 +60,7 @@ list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"${OT_CONF add_library(openthread-posix alarm.cpp backbone.cpp + daemon.cpp entropy.cpp hdlc_interface.cpp infra_if.cpp @@ -74,7 +75,6 @@ add_library(openthread-posix spi_interface.cpp system.cpp trel_udp6.cpp - uart.cpp udp.cpp virtual_time.cpp ) diff --git a/src/posix/platform/Makefile.am b/src/posix/platform/Makefile.am index 4cd44cf62..24c39a644 100644 --- a/src/posix/platform/Makefile.am +++ b/src/posix/platform/Makefile.am @@ -46,6 +46,7 @@ libopenthread_posix_a_CPPFLAGS = \ libopenthread_posix_a_SOURCES = \ alarm.cpp \ backbone.cpp \ + daemon.cpp \ entropy.cpp \ hdlc_interface.cpp \ infra_if.cpp \ @@ -60,7 +61,6 @@ libopenthread_posix_a_SOURCES = \ spi_interface.cpp \ system.cpp \ trel_udp6.cpp \ - uart.cpp \ udp.cpp \ virtual_time.cpp \ $(NULL) diff --git a/src/posix/platform/daemon.cpp b/src/posix/platform/daemon.cpp new file mode 100644 index 000000000..b62df3a2c --- /dev/null +++ b/src/posix/platform/daemon.cpp @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2021, 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. + */ + +#include "openthread-posix-config.h" +#include "platform-posix.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "cli/cli_config.h" +#include "common/code_utils.hpp" + +#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + +#define OPENTHREAD_POSIX_DAEMON_SOCKET_LOCK OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME ".lock" +static_assert(sizeof(OPENTHREAD_POSIX_DAEMON_SOCKET_NAME) < sizeof(sockaddr_un::sun_path), + "OpenThread daemon socket name too long!"); + +static int sListenSocket = -1; +static int sUartLock = -1; +static int sSessionSocket = -1; + +static int OutputFormatV(void *aContext, const char *aFormat, va_list aArguments) +{ + OT_UNUSED_VARIABLE(aContext); + + char buf[OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH + 1]; + int rval; + + buf[OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH] = '\0'; + + rval = vsnprintf(buf, sizeof(buf) - 1, aFormat, aArguments); + + VerifyOrExit(rval >= 0, otLogWarnPlat("Failed to format CLI output: %s", strerror(errno))); + + VerifyOrExit(sSessionSocket != -1, otLogDebgPlat("%s", buf)); + +#if defined(__linux__) + // Don't die on SIGPIPE + rval = send(sSessionSocket, buf, static_cast(rval), MSG_NOSIGNAL); +#else + rval = write(sSessionSocket, buf, static_cast(rval)); +#endif + + if (rval < 0) + { + otLogWarnPlat("Failed to write CLI output: %s", strerror(errno)); + close(sSessionSocket); + sSessionSocket = -1; + } + +exit: + return rval; +} + +static void InitializeSessionSocket(void) +{ + int newSessionSocket; + int rval; + + VerifyOrExit((newSessionSocket = accept(sListenSocket, nullptr, nullptr)) != -1, rval = -1); + + VerifyOrExit((rval = fcntl(newSessionSocket, F_GETFD, 0)) != -1); + + rval |= FD_CLOEXEC; + + VerifyOrExit((rval = fcntl(newSessionSocket, F_SETFD, rval)) != -1); + +#ifndef __linux__ + // some platforms (macOS, Solaris) don't have MSG_NOSIGNAL + // SOME of those (macOS, but NOT Solaris) support SO_NOSIGPIPE + // if we have SO_NOSIGPIPE, then set it. Otherwise, we're going + // to simply ignore it. +#if defined(SO_NOSIGPIPE) + rval = setsockopt(newSessionSocket, SOL_SOCKET, SO_NOSIGPIPE, &rval, sizeof(rval)); + VerifyOrExit(rval != -1); +#else +#warning "no support for MSG_NOSIGNAL or SO_NOSIGPIPE" +#endif +#endif // __linux__ + + if (sSessionSocket != -1) + { + close(sSessionSocket); + } + sSessionSocket = newSessionSocket; + +exit: + if (rval == -1) + { + otLogWarnPlat("Failed to initialize session socket: %s", strerror(errno)); + if (newSessionSocket != -1) + { + close(newSessionSocket); + } + } + else + { + otLogInfoPlat("Session socket is ready", strerror(errno)); + } +} + +void platformDaemonEnable(otInstance *aInstance) +{ + struct sockaddr_un sockname; + int ret; + + // This allows implementing pseudo reset. + VerifyOrExit(sListenSocket == -1); + + sListenSocket = SocketWithCloseExec(AF_UNIX, SOCK_STREAM, 0, kSocketNonBlock); + + if (sListenSocket == -1) + { + DieNow(OT_EXIT_FAILURE); + } + + sUartLock = open(OPENTHREAD_POSIX_DAEMON_SOCKET_LOCK, O_CREAT | O_RDONLY | O_CLOEXEC, 0600); + + if (sUartLock == -1) + { + DieNowWithMessage("open", OT_EXIT_ERROR_ERRNO); + } + + if (flock(sUartLock, LOCK_EX | LOCK_NB) == -1) + { + DieNowWithMessage("flock", OT_EXIT_ERROR_ERRNO); + } + + memset(&sockname, 0, sizeof(struct sockaddr_un)); + + (void)unlink(OPENTHREAD_POSIX_DAEMON_SOCKET_NAME); + + sockname.sun_family = AF_UNIX; + strncpy(sockname.sun_path, OPENTHREAD_POSIX_DAEMON_SOCKET_NAME, sizeof(sockname.sun_path) - 1); + + ret = bind(sListenSocket, (const struct sockaddr *)&sockname, sizeof(struct sockaddr_un)); + + if (ret == -1) + { + DieNowWithMessage("bind", OT_EXIT_ERROR_ERRNO); + } + + // + // only accept 1 connection. + // + ret = listen(sListenSocket, 1); + if (ret == -1) + { + DieNowWithMessage("listen", OT_EXIT_ERROR_ERRNO); + } + + otCliInit(aInstance, OutputFormatV, aInstance); + +exit: + return; +} + +void platformDaemonDisable(void) +{ + if (sSessionSocket != -1) + { + close(sSessionSocket); + sSessionSocket = -1; + } + + if (sListenSocket != -1) + { + close(sListenSocket); + sListenSocket = -1; + } + + if (gPlatResetReason != OT_PLAT_RESET_REASON_SOFTWARE) + { + otLogCritPlat("Removing daemon socket: %s", OPENTHREAD_POSIX_DAEMON_SOCKET_NAME); + (void)unlink(OPENTHREAD_POSIX_DAEMON_SOCKET_NAME); + } + + if (sUartLock != -1) + { + (void)flock(sUartLock, LOCK_UN); + close(sUartLock); + sUartLock = -1; + } +} + +void platformDaemonUpdate(otSysMainloopContext *aContext) +{ + if (sListenSocket != -1) + { + FD_SET(sListenSocket, &aContext->mReadFdSet); + FD_SET(sListenSocket, &aContext->mErrorFdSet); + + if (aContext->mMaxFd < sListenSocket) + { + aContext->mMaxFd = sListenSocket; + } + } + + if (sSessionSocket != -1) + { + FD_SET(sSessionSocket, &aContext->mReadFdSet); + FD_SET(sSessionSocket, &aContext->mErrorFdSet); + + if (aContext->mMaxFd < sSessionSocket) + { + aContext->mMaxFd = sSessionSocket; + } + } + + return; +} + +void platformDaemonProcess(const otSysMainloopContext *aContext) +{ + ssize_t rval; + + VerifyOrExit(sListenSocket != -1); + + if (FD_ISSET(sListenSocket, &aContext->mErrorFdSet)) + { + DieNowWithMessage("daemon socket error", OT_EXIT_FAILURE); + } + else if (FD_ISSET(sListenSocket, &aContext->mReadFdSet)) + { + InitializeSessionSocket(); + } + + VerifyOrExit(sSessionSocket != -1); + + if (FD_ISSET(sSessionSocket, &aContext->mErrorFdSet)) + { + close(sSessionSocket); + sSessionSocket = -1; + } + else if (FD_ISSET(sSessionSocket, &aContext->mReadFdSet)) + { + uint8_t buffer[OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH]; + + rval = read(sSessionSocket, buffer, sizeof(buffer)); + + if (rval > 0) + { + buffer[rval] = '\0'; + otCliInputLine(reinterpret_cast(buffer)); + otCliOutputFormat("> "); + } + else + { + if (rval < 0) + { + otLogWarnPlat("Daemon read: %s", strerror(errno)); + } + close(sSessionSocket); + sSessionSocket = -1; + } + } + +exit: + return; +} + +#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE diff --git a/src/posix/platform/openthread-core-posix-config.h b/src/posix/platform/openthread-core-posix-config.h index 590522708..1a46017e0 100644 --- a/src/posix/platform/openthread-core-posix-config.h +++ b/src/posix/platform/openthread-core-posix-config.h @@ -97,12 +97,12 @@ #endif /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 /** * @def OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h index 5ad29a420..835bd0ca0 100644 --- a/src/posix/platform/platform-posix.h +++ b/src/posix/platform/platform-posix.h @@ -551,6 +551,36 @@ void platformInfraIfUpdateFdSet(fd_set &aReadFdSet, int &aMaxFd); */ void platformInfraIfProcess(otInstance *aInstance, const fd_set &aReadFdSet); +/** + * This function enables daemon. + * + * @param[in] aInstance The OpenThread instance structure. + * + */ +void platformDaemonEnable(otInstance *aInstance); + +/** + * This function disables daemon. + * + */ +void platformDaemonDisable(void); + +/** + * This function updates the file descriptor sets with file descriptors used by daemon. + * + * @param[inout] aMainloop A pointer to the mainloop context. + * + */ +void platformDaemonUpdate(otSysMainloopContext *aContext); + +/** + * This function performs daemon processing. + * + * @param[in] aMainloop A pointer to the mainloop context. + * + */ +void platformDaemonProcess(const otSysMainloopContext *aContext); + #ifdef __cplusplus } #endif diff --git a/src/posix/platform/system.cpp b/src/posix/platform/system.cpp index 74e3ea1da..3bb55f99a 100644 --- a/src/posix/platform/system.cpp +++ b/src/posix/platform/system.cpp @@ -45,7 +45,6 @@ #include #include #include -#include #include "common/code_utils.hpp" @@ -128,11 +127,17 @@ otInstance *otSysInit(otPlatformConfig *aPlatformConfig) SuccessOrDie(otSetStateChangedCallback(instance, processStateChange, instance)); #endif +#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + platformDaemonEnable(instance); +#endif return instance; } void otSysDeinit(void) { +#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + platformDaemonDisable(); +#endif #if OPENTHREAD_POSIX_VIRTUAL_TIME virtualTimeDeinit(); #endif @@ -143,7 +148,6 @@ void otSysDeinit(void) #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE platformTrelDeinit(); #endif - IgnoreError(otPlatUartDisable()); #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE platformInfraIfDeinit(); @@ -186,8 +190,6 @@ static int trySelect(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSe void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop) { platformAlarmUpdateTimeout(&aMainloop->mTimeout); - platformUartUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, - &aMainloop->mMaxFd); #if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE platformUdpUpdateFdSet(aInstance, &aMainloop->mReadFdSet, &aMainloop->mMaxFd); #endif @@ -211,6 +213,10 @@ void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop) platformTrelUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mMaxFd, &aMainloop->mTimeout); #endif +#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + platformDaemonUpdate(aMainloop); +#endif + if (otTaskletsArePending(aInstance)) { aMainloop->mTimeout.tv_sec = 0; @@ -271,7 +277,6 @@ void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMa #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE platformTrelProcess(aInstance, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet); #endif - platformUartProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet); platformAlarmProcess(aInstance); #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE platformNetifProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet); @@ -285,6 +290,9 @@ void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMa #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE platformInfraIfProcess(aInstance, aMainloop->mReadFdSet); #endif +#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + platformDaemonProcess(aMainloop); +#endif } #if OPENTHREAD_CONFIG_OTNS_ENABLE diff --git a/src/posix/platform/uart.cpp b/src/posix/platform/uart.cpp deleted file mode 100644 index d2b47fa6d..000000000 --- a/src/posix/platform/uart.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ - -#include "openthread-posix-config.h" -#include "platform-posix.h" - -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE -#include -#include -#include -#include -#include -#include -#endif - -#include -#include -#include -#include - -#include -#include - -#include "common/code_utils.hpp" - -#define OPENTHREAD_POSIX_DAEMON_SOCKET_LOCK OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME ".lock" - -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE -static int sUartSocket = -1; -static int sUartLock = -1; -static int sSessionSocket = -1; -#endif - -static bool sEnabled = false; -static const uint8_t *sWriteBuffer = nullptr; -static uint16_t sWriteLength = 0; - -otError otPlatUartEnable(void) -{ - otError error = OT_ERROR_NONE; -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - struct sockaddr_un sockname; - int ret; - - // This allows implementing pseudo reset. - VerifyOrExit(sUartSocket == -1); - - sUartSocket = SocketWithCloseExec(AF_UNIX, SOCK_STREAM, 0, kSocketNonBlock); - - if (sUartSocket == -1) - { - DieNow(OT_EXIT_FAILURE); - } - - sUartLock = open(OPENTHREAD_POSIX_DAEMON_SOCKET_LOCK, O_CREAT | O_RDONLY | O_CLOEXEC, 0600); - - if (sUartLock == -1) - { - DieNowWithMessage("open", OT_EXIT_ERROR_ERRNO); - } - - if (flock(sUartLock, LOCK_EX | LOCK_NB) == -1) - { - DieNowWithMessage("flock", OT_EXIT_ERROR_ERRNO); - } - - memset(&sockname, 0, sizeof(struct sockaddr_un)); - - (void)unlink(OPENTHREAD_POSIX_DAEMON_SOCKET_NAME); - - sockname.sun_family = AF_UNIX; - assert(sizeof(OPENTHREAD_POSIX_DAEMON_SOCKET_NAME) < sizeof(sockname.sun_path)); - strncpy(sockname.sun_path, OPENTHREAD_POSIX_DAEMON_SOCKET_NAME, sizeof(sockname.sun_path) - 1); - - ret = bind(sUartSocket, (const struct sockaddr *)&sockname, sizeof(struct sockaddr_un)); - - if (ret == -1) - { - DieNowWithMessage("bind", OT_EXIT_ERROR_ERRNO); - } - - // - // only accept 1 connection. - // - ret = listen(sUartSocket, 1); - if (ret == -1) - { - DieNowWithMessage("listen", OT_EXIT_ERROR_ERRNO); - } - -exit: -#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - - sEnabled = true; - return error; -} - -otError otPlatUartDisable(void) -{ - otError error = OT_ERROR_NONE; - sEnabled = false; - -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - if (sSessionSocket != -1) - { - close(sSessionSocket); - sSessionSocket = -1; - } - - if (sUartSocket != -1) - { - close(sUartSocket); - sUartSocket = -1; - } - - if (gPlatResetReason != OT_PLAT_RESET_REASON_SOFTWARE) - { - otLogCritPlat("Removing daemon socket: %s", OPENTHREAD_POSIX_DAEMON_SOCKET_NAME); - (void)unlink(OPENTHREAD_POSIX_DAEMON_SOCKET_NAME); - } - - if (sUartLock != -1) - { - (void)flock(sUartLock, LOCK_UN); - close(sUartLock); - sUartLock = -1; - } -#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - - return error; -} - -otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength) -{ - otError error = OT_ERROR_NONE; - - assert(sEnabled); - VerifyOrExit(sWriteLength == 0, error = OT_ERROR_BUSY); - - sWriteBuffer = aBuf; - sWriteLength = aBufLength; - -exit: - return error; -} - -void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd) -{ - VerifyOrExit(sEnabled); - - if (aReadFdSet != nullptr) - { -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - int fd = (sSessionSocket == -1 ? sUartSocket : sSessionSocket); -#else - int fd = STDIN_FILENO; -#endif - - FD_SET(fd, aReadFdSet); - - if (aErrorFdSet != nullptr) - { - FD_SET(fd, aErrorFdSet); - } - - if (aMaxFd != nullptr && *aMaxFd < fd) - { - *aMaxFd = fd; - } - } - if ((aWriteFdSet != nullptr) && (sWriteLength > 0)) - { -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - int fd = (sSessionSocket == -1 ? sUartSocket : sSessionSocket); -#else - int fd = STDOUT_FILENO; -#endif - - FD_SET(fd, aWriteFdSet); - - if (aErrorFdSet != nullptr) - { - FD_SET(fd, aErrorFdSet); - } - - if (aMaxFd != nullptr && *aMaxFd < fd) - { - *aMaxFd = fd; - } - } - -exit: - return; -} - -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE -static void InitializeSessionSocket(void) -{ - int newSessionSocket; - int rval; - - VerifyOrExit((newSessionSocket = accept(sUartSocket, nullptr, nullptr)) != -1, rval = -1); - - VerifyOrExit((rval = fcntl(newSessionSocket, F_GETFD, 0)) != -1); - - rval |= FD_CLOEXEC; - - VerifyOrExit((rval = fcntl(newSessionSocket, F_SETFD, rval)) != -1); - -#ifndef __linux__ - // some platforms (macOS, Solaris) don't have MSG_NOSIGNAL - // SOME of those (macOS, but NOT Solaris) support SO_NOSIGPIPE - // if we have SO_NOSIGPIPE, then set it. Otherwise, we're going - // to simply ignore it. -#if defined(SO_NOSIGPIPE) - rval = setsockopt(newSessionSocket, SOL_SOCKET, SO_NOSIGPIPE, &rval, sizeof(rval)); - VerifyOrExit(rval != -1); -#else -#warning "no support for MSG_NOSIGNAL or SO_NOSIGPIPE" -#endif -#endif // __linux__ - - if (sSessionSocket != -1) - { - close(sSessionSocket); - } - sSessionSocket = newSessionSocket; - -exit: - if (rval == -1) - { - otLogWarnPlat("Failed to initialize session socket: %s", strerror(errno)); - if (newSessionSocket != -1) - { - close(newSessionSocket); - } - } - else - { - otLogInfoPlat("Session socket is ready", strerror(errno)); - } -} -#endif - -static otError UartWrite(int aFd) -{ - otError error = OT_ERROR_NONE; - ssize_t rval; - - VerifyOrExit(sWriteLength > 0, error = OT_ERROR_INVALID_STATE); - -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE && defined(__linux__) - if (aFd == sSessionSocket) - { - // Don't die on SIGPIPE - rval = send(aFd, sWriteBuffer, sWriteLength, MSG_NOSIGNAL); - } - else -#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE && defined(__linux__) - { - rval = write(aFd, sWriteBuffer, sWriteLength); - } - - if (rval < 0) - { -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - otLogWarnPlat("UART write: %s", strerror(errno)); - if (aFd == sSessionSocket) - { - close(sSessionSocket); - sSessionSocket = -1; - } - ExitNow(); -#else - DieNow(OT_EXIT_ERROR_ERRNO); -#endif - } - - sWriteBuffer += rval; - sWriteLength -= static_cast(rval); - -exit: - return error; -} - -void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet) -{ - ssize_t rval; - int fd; - - VerifyOrExit(sEnabled); -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - if (FD_ISSET(sUartSocket, aErrorFdSet)) - { - DieNowWithMessage("socket", OT_EXIT_FAILURE); - } - else if (FD_ISSET(sUartSocket, aReadFdSet)) - { - InitializeSessionSocket(); - } - - if (sSessionSocket == -1 && sWriteBuffer != nullptr) - { - IgnoreReturnValue(write(STDERR_FILENO, sWriteBuffer, sWriteLength)); - sWriteBuffer = nullptr; - sWriteLength = 0; - otPlatUartSendDone(); - } - - VerifyOrExit(sSessionSocket != -1); - - if (FD_ISSET(sSessionSocket, aErrorFdSet)) - { - close(sSessionSocket); - sSessionSocket = -1; - } - - VerifyOrExit(sSessionSocket != -1); - - fd = sSessionSocket; -#else // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - if (FD_ISSET(STDIN_FILENO, aErrorFdSet)) - { - DieNowWithMessage("stdin", OT_EXIT_FAILURE); - } - - if (FD_ISSET(STDOUT_FILENO, aErrorFdSet)) - { - DieNowWithMessage("stdout", OT_EXIT_FAILURE); - } - - fd = STDIN_FILENO; -#endif // OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - - if (FD_ISSET(fd, aReadFdSet)) - { - uint8_t buffer[256]; - - rval = read(fd, buffer, sizeof(buffer)); - - if (rval > 0) - { - otPlatUartReceived(buffer, (uint16_t)rval); - } - else if (rval <= 0) - { -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - if (rval < 0) - { - perror("UART read"); - } - close(sSessionSocket); - sSessionSocket = -1; - ExitNow(); -#else - DieNowWithMessage("UART read", (rval < 0) ? OT_EXIT_ERROR_ERRNO : OT_EXIT_FAILURE); -#endif - } - } - -#if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - fd = STDOUT_FILENO; -#endif - - if ((FD_ISSET(fd, aWriteFdSet))) - { - otError error = UartWrite(fd); - - VerifyOrExit(error == OT_ERROR_NONE, otLogWarnPlat("UART write: %s", otThreadErrorToString(error))); - - if (sWriteLength == 0) - { - otPlatUartSendDone(); - } - } - -exit: - return; -} - -otError otPlatUartFlush(void) -{ - otError error = OT_ERROR_NONE; - - while (sWriteLength > 0) - { - int fd = -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - sSessionSocket != -1 ? sSessionSocket : -#endif - STDOUT_FILENO; - int rval; - - fd_set writeFdSet; - FD_ZERO(&writeFdSet); - FD_SET(fd, &writeFdSet); - - rval = select(fd + 1, nullptr, &writeFdSet, nullptr, nullptr); - - assert(rval != 0); - - if (rval > 0) - { - assert(FD_ISSET(fd, &writeFdSet)); - SuccessOrExit(error = UartWrite(fd)); - } - else if (errno != EINTR) - { -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - if (sSessionSocket == fd) - { - close(sSessionSocket); - sSessionSocket = -1; - } - else -#endif - { - DieNow(OT_EXIT_ERROR_ERRNO); - } - } - } - -exit: - return error; -} diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt index 07eff02ae..08b73757d 100644 --- a/tests/fuzz/CMakeLists.txt +++ b/tests/fuzz/CMakeLists.txt @@ -47,22 +47,22 @@ set(COMMON_LIBS ot-config ) -add_executable(cli-uart-received-fuzzer - cli_uart_received.cpp +add_executable(cli-received-fuzzer + cli_received.cpp ${COMMON_SOURCES} ) -target_compile_options(cli-uart-received-fuzzer +target_compile_options(cli-received-fuzzer PRIVATE ${COMMON_COMPILE_OPTIONS} ) -target_include_directories(cli-uart-received-fuzzer +target_include_directories(cli-received-fuzzer PRIVATE ${COMMON_INCLUDES} ) -target_link_libraries(cli-uart-received-fuzzer +target_link_libraries(cli-received-fuzzer PRIVATE openthread-cli-ftd ${COMMON_LIBS} @@ -108,22 +108,22 @@ target_link_libraries(radio-receive-done-fuzzer ${COMMON_LIBS} ) -add_executable(ncp-uart-received-fuzzer - ncp_uart_received.cpp +add_executable(ncp-hdlc-received-fuzzer + ncp_hdlc_received.cpp ${COMMON_SOURCES} ) -target_compile_options(ncp-uart-received-fuzzer +target_compile_options(ncp-hdlc-received-fuzzer PRIVATE ${COMMON_COMPILE_OPTIONS} ) -target_include_directories(ncp-uart-received-fuzzer +target_include_directories(ncp-hdlc-received-fuzzer PRIVATE ${COMMON_INCLUDES} ) -target_link_libraries(ncp-uart-received-fuzzer +target_link_libraries(ncp-hdlc-received-fuzzer PRIVATE openthread-ncp-ftd ${COMMON_LIBS} diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am index bce0e31a3..0b2f1f4f8 100644 --- a/tests/fuzz/Makefile.am +++ b/tests/fuzz/Makefile.am @@ -29,10 +29,10 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am bin_PROGRAMS = \ - cli-uart-received-fuzzer \ + cli-received-fuzzer \ ip6-send-fuzzer \ radio-receive-done-fuzzer \ - ncp-uart-received-fuzzer \ + ncp-hdlc-received-fuzzer \ $(NULL) AM_CPPFLAGS = \ @@ -51,14 +51,14 @@ COMMON_SOURCES = \ fuzzer_platform.h \ $(NULL) -cli_uart_received_fuzzer_LDADD = \ +cli_received_fuzzer_LDADD = \ $(top_builddir)/src/cli/libopenthread-cli-ftd.a \ $(COMMON_LDADD) \ $(NULL) -cli_uart_received_fuzzer_SOURCES = \ +cli_received_fuzzer_SOURCES = \ $(COMMON_SOURCES) \ - cli_uart_received.cpp \ + cli_received.cpp \ $(NULL) ip6_send_fuzzer_LDADD = \ @@ -79,14 +79,14 @@ radio_receive_done_fuzzer_SOURCES = \ radio_receive_done.cpp \ $(NULL) -ncp_uart_received_fuzzer_LDADD = \ +ncp_hdlc_received_fuzzer_LDADD = \ $(top_builddir)/src/ncp/libopenthread-ncp-ftd.a \ $(COMMON_LDADD) \ $(NULL) -ncp_uart_received_fuzzer_SOURCES = \ +ncp_hdlc_received_fuzzer_SOURCES = \ $(COMMON_SOURCES) \ - ncp_uart_received.cpp \ + ncp_hdlc_received.cpp \ $(NULL) include $(abs_top_nlbuild_autotools_dir)/automake/post.am diff --git a/tests/fuzz/cli_uart_received.cpp b/tests/fuzz/cli_received.cpp similarity index 86% rename from tests/fuzz/cli_uart_received.cpp rename to tests/fuzz/cli_received.cpp index 83f77fe6b..2dcbbd8ee 100644 --- a/tests/fuzz/cli_uart_received.cpp +++ b/tests/fuzz/cli_received.cpp @@ -28,6 +28,8 @@ #define MAX_ITERATIONS 100 +#include +#include #include #include @@ -38,11 +40,19 @@ #include #include #include -#include #include "fuzzer_platform.h" #include "common/code_utils.hpp" +static int CliOutput(void *aContext, const char *aFormat, va_list aArguments) +{ + OT_UNUSED_VARIABLE(aContext); + OT_UNUSED_VARIABLE(aFormat); + OT_UNUSED_VARIABLE(aArguments); + + return vsnprintf(nullptr, 0, aFormat, aArguments); +} + extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { const otPanId panId = 0xdead; @@ -55,17 +65,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) FuzzerPlatformInit(); instance = otInstanceInitSingle(); - otCliUartInit(instance); + otCliInit(instance, CliOutput, nullptr); IgnoreError(otLinkSetPanId(instance, panId)); IgnoreError(otIp6SetEnabled(instance, true)); IgnoreError(otThreadSetEnabled(instance, true)); IgnoreError(otThreadBecomeLeader(instance)); - buf = static_cast(malloc(size)); + buf = static_cast(malloc(size + 1)); memcpy(buf, data, size); + buf[size] = '\0'; - otPlatUartReceived(buf, (uint16_t)size); + otCliInputLine(reinterpret_cast(buf)); VerifyOrExit(!FuzzerPlatformResetWasRequested()); diff --git a/tests/fuzz/fuzzer_platform.cpp b/tests/fuzz/fuzzer_platform.cpp index 463a6d4de..a8ae28b01 100644 --- a/tests/fuzz/fuzzer_platform.cpp +++ b/tests/fuzz/fuzzer_platform.cpp @@ -40,7 +40,6 @@ #include #include #include -#include #include "mac/mac_frame.hpp" @@ -493,28 +492,6 @@ void otPlatSettingsWipe(otInstance *aInstance) OT_UNUSED_VARIABLE(aInstance); } -otError otPlatUartEnable(void) -{ - return OT_ERROR_NONE; -} - -otError otPlatUartDisable(void) -{ - return OT_ERROR_NONE; -} - -otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength) -{ - OT_UNUSED_VARIABLE(aBuf); - OT_UNUSED_VARIABLE(aBufLength); - return OT_ERROR_NONE; -} - -otError otPlatUartFlush(void) -{ - return OT_ERROR_NOT_IMPLEMENTED; -} - otError otPlatDiagProcess(otInstance *aInstance, uint8_t aArgsLength, char * aArgs[], diff --git a/tests/fuzz/ncp_uart_received.cpp b/tests/fuzz/ncp_hdlc_received.cpp similarity index 92% rename from tests/fuzz/ncp_uart_received.cpp rename to tests/fuzz/ncp_hdlc_received.cpp index 9f20aba5b..a61b0faa0 100644 --- a/tests/fuzz/ncp_uart_received.cpp +++ b/tests/fuzz/ncp_hdlc_received.cpp @@ -38,11 +38,18 @@ #include #include #include -#include #include "fuzzer_platform.h" #include "common/code_utils.hpp" +static int HdlcSend(const uint8_t *aBuf, uint16_t aBufLength) +{ + OT_UNUSED_VARIABLE(aBuf); + OT_UNUSED_VARIABLE(aBufLength); + + return aBufLength; +} + extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { const otPanId panId = 0xdead; @@ -55,7 +62,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) FuzzerPlatformInit(); instance = otInstanceInitSingle(); - otNcpInit(instance); + otNcpHdlcInit(instance, HdlcSend); IgnoreError(otLinkSetPanId(instance, panId)); IgnoreError(otIp6SetEnabled(instance, true)); IgnoreError(otThreadSetEnabled(instance, true)); @@ -65,7 +72,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) memcpy(buf, data, size); - otPlatUartReceived(buf, (uint16_t)size); + otNcpHdlcReceive(buf, static_cast(size)); VerifyOrExit(!FuzzerPlatformResetWasRequested()); diff --git a/tests/toranj/openthread-core-toranj-config.h b/tests/toranj/openthread-core-toranj-config.h index 6e4c0d1c5..2dc25c90d 100644 --- a/tests/toranj/openthread-core-toranj-config.h +++ b/tests/toranj/openthread-core-toranj-config.h @@ -313,12 +313,12 @@ #define OPENTHREAD_CONFIG_LOG_PLATFORM 1 /** - * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE * - * Define to 1 to enable NCP UART support. + * Define to 1 to enable NCP HDLC support. * */ -#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 /** * @def OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE diff --git a/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp index 0c47ca4a6..1378e61ee 100755 --- a/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp +++ b/third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp @@ -34,6 +34,8 @@ #include "ncp_base.hpp" +#include "utils/uart.h" + #include "../../third_party/nxp/JN5189DK6/middleware/wireless/openthread/examples/posix_ota_server/app_ota.h" namespace ot { namespace Ncp { @@ -158,20 +160,26 @@ otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey) //------------------------------------------------------------------------------------------------------------------- // When OPENTHREAD_ENABLE_NCP_VENDOR_HOOK is enabled, vendor code is -// expected to provide the `otNcpInit()` function. The reason behind +// expected to provide the `otAppNcpInit()` function. The reason behind // this is to enable vendor code to define its own sub-class of -// `NcpBase` or `NcpUart`/`NcpSpi`. +// `NcpBase` or `NcpHdlc`/`NcpSpi`. // -// Example below show how to add a vendor sub-class over `NcpUart`. +// Example below show how to add a vendor sub-class over `NcpHdlc`. -#include "ncp_uart.hpp" +#include "ncp_hdlc.hpp" #include "common/new.hpp" -class NcpVendorUart : public ot::Ncp::NcpUart +class NcpVendorUart : public ot::Ncp::NcpHdlc { + static int NcpSend(const uint8_t *aBuf, uint16_t aBufLength) + { + IgnoreError(otPlatUartSend(aBuf, aBufLength)); + return aBufLength; + } + public: NcpVendorUart(ot::Instance *aInstance) - : ot::Ncp::NcpUart(aInstance) + : ot::Ncp::NcpHdlc(aInstance, &NcpVendorUart::NcpSend) {} // Add public/private methods or member variables @@ -179,7 +187,7 @@ public: static otDEFINE_ALIGNED_VAR(sNcpVendorRaw, sizeof(NcpVendorUart), uint64_t); -extern "C" void otNcpInit(otInstance *aInstance) +extern "C" void otAppNcpInit(otInstance *aInstance) { NcpVendorUart *ncpVendor = NULL; ot::Instance * instance = static_cast(aInstance); diff --git a/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp index 4d62cd0b9..37547d1fd 100755 --- a/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp +++ b/third_party/nxp/K32W061DK6/middleware/wireless/openthread/examples/posix_ota_server/example_vendor_hook.cpp @@ -160,18 +160,25 @@ otError NcpBase::VendorSetPropertyHandler(spinel_prop_key_t aPropKey) // When OPENTHREAD_ENABLE_NCP_VENDOR_HOOK is enabled, vendor code is // expected to provide the `otNcpInit()` function. The reason behind // this is to enable vendor code to define its own sub-class of -// `NcpBase` or `NcpUart`/`NcpSpi`. +// `NcpBase` or `NcpHdlc`/`NcpSpi`. // -// Example below show how to add a vendor sub-class over `NcpUart`. +// Example below show how to add a vendor sub-class over `NcpHdlc`. -#include "ncp_uart.hpp" +#include "ncp_hdlc.hpp" #include "common/new.hpp" +#include "utils/uart.h" -class NcpVendorUart : public ot::Ncp::NcpUart +class NcpVendorUart : public ot::Ncp::NcpHdlc { + static int NcpSend(const uint8_t *aBuf, uint16_t aBufLength) + { + IgnoreError(otPlatUartSend(aBuf, aBufLength)); + return aBufLength; + } + public: NcpVendorUart(ot::Instance *aInstance) - : ot::Ncp::NcpUart(aInstance) + : ot::Ncp::NcpHdlc(aInstance) {} // Add public/private methods or member variables @@ -179,7 +186,7 @@ public: static otDEFINE_ALIGNED_VAR(sNcpVendorRaw, sizeof(NcpVendorUart), uint64_t); -extern "C" void otNcpInit(otInstance *aInstance) +extern "C" void otAppNcpInit(otInstance *aInstance) { NcpVendorUart *ncpVendor = NULL; ot::Instance * instance = static_cast(aInstance);