From cced005256e070a62c7713713c5d21c1823104c4 Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Tue, 12 Feb 2019 02:58:18 +0800 Subject: [PATCH] [posix-app] fix write in daemon mode (#3576) In daemon mode, UART write should be processed even when no client is connected. This commit writes UART to STDERR in such situation. * add test for daemon mode * remove useless code for UART restore * fix a typo of assert * set FD_CLOEXEC flag to better support reset. --- .travis.yml | 3 +++ .travis/check-posix-app-pty | 17 +++++++++++++---- .travis/script.sh | 1 + src/posix/platform/misc.c | 1 - src/posix/platform/platform-posix.h | 6 ------ src/posix/platform/uart.c | 24 ++++++++++++++++++++++-- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 288459c64..798d97a5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,6 +57,9 @@ matrix: - env: BUILD_TARGET="posix-app-pty" VERBOSE=1 os: linux compiler: gcc + - env: BUILD_TARGET="posix-app-pty" VERBOSE=1 DAEMON=1 + os: linux + compiler: gcc - env: BUILD_TARGET="android-build" VERBOSE=1 os: linux python: "2.7" diff --git a/.travis/check-posix-app-pty b/.travis/check-posix-app-pty index 2a2caea6c..88c9a9bb0 100755 --- a/.travis/check-posix-app-pty +++ b/.travis/check-posix-app-pty @@ -39,13 +39,14 @@ at_exit() { EXIT_CODE=$? sudo killall expect || true + killall ot-ctl || true + killall ot-daemon || true killall socat || true exit $EXIT_CODE } build() { - ./bootstrap COVERAGE=1 make -f examples/Makefile-posix COVERAGE=1 make -f src/posix/Makefile-posix PLATFORM_NETIF=1 PLATFORM_UDP=1 } @@ -70,9 +71,17 @@ check() { RADIO_NCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-ncp-radio)" $RADIO_NCP_PATH 1 > $RADIO_PTY < $RADIO_PTY & - OT_CLI_PATH="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)" - sudo expect < $OT_OUTPUT & -spawn $OT_CLI_PATH ${OT_NCP_PATH} ${CORE_PTY} + + if [[ "${DAEMON}" = 1 ]]; then + sudo "$(pwd)/$(ls output/posix/*linux*/bin/ot-daemon)" ${OT_NCP_PATH} ${CORE_PTY} & + sleep 1 + OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-ctl)" + else + OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) ${OT_NCP_PATH} ${CORE_PTY}" + fi + + sudo expect < "${OT_OUTPUT}" & +spawn ${OT_CLI_CMD} send "panid 0xface\r\n" expect "Done" send "ifconfig up\r\n" diff --git a/.travis/script.sh b/.travis/script.sh index d0ddc7b03..44aed376a 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -433,6 +433,7 @@ build_samr21() { } [ $BUILD_TARGET != posix-app-pty ] || { + ./bootstrap .travis/check-posix-app-pty || die } diff --git a/src/posix/platform/misc.c b/src/posix/platform/misc.c index c7f825727..35fb026a0 100644 --- a/src/posix/platform/misc.c +++ b/src/posix/platform/misc.c @@ -48,7 +48,6 @@ void otPlatReset(otInstance *aInstance) OT_UNUSED_VARIABLE(aInstance); otSysDeinit(); - platformUartRestore(); longjmp(gResetJump, 1); assert(false); diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h index e321bd243..24d280e78 100644 --- a/src/posix/platform/platform-posix.h +++ b/src/posix/platform/platform-posix.h @@ -263,12 +263,6 @@ void platformNetifUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *a */ void platformNetifProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet); -/** - * This function restores the Uart. - * - */ -void platformUartRestore(void); - /** * This function initialize simulation. * diff --git a/src/posix/platform/uart.c b/src/posix/platform/uart.c index 994a6e364..966f95595 100644 --- a/src/posix/platform/uart.c +++ b/src/posix/platform/uart.c @@ -46,6 +46,7 @@ #include #include "code_utils.h" +#include "common/code_utils.hpp" #define OPENTHREAD_POSIX_APP_SOCKET_LOCK OPENTHREAD_POSIX_APP_SOCKET_BASENAME ".lock" @@ -58,9 +59,16 @@ static int sSessionSocket = -1; static const uint8_t *sWriteBuffer = NULL; static uint16_t sWriteLength = 0; -void platformUartRestore(void) +#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON +static void set_flag_cloexec(int a_fd) { + int ret = fcntl(a_fd, F_GETFD, 0); + VerifyOrDie(ret != -1, OT_EXIT_FAILURE); + ret |= FD_CLOEXEC; + ret = fcntl(a_fd, F_SETFD, ret); + VerifyOrDie(ret != -1, OT_EXIT_FAILURE); } +#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON otError otPlatUartEnable(void) { @@ -70,12 +78,15 @@ otError otPlatUartEnable(void) int ret; sUartSocket = socket(AF_UNIX, SOCK_STREAM, 0); + if (sUartSocket == -1) { perror("socket"); exit(OT_EXIT_FAILURE); } + set_flag_cloexec(sUartSocket); + sUartLock = open(OPENTHREAD_POSIX_APP_SOCKET_LOCK, O_CREAT | O_RDONLY, 0600); if (sUartLock == -1) @@ -84,6 +95,8 @@ otError otPlatUartEnable(void) exit(OT_EXIT_FAILURE); } + set_flag_cloexec(sUartLock); + if (flock(sUartLock, LOCK_EX | LOCK_NB) == -1) { perror("flock"); @@ -95,7 +108,7 @@ otError otPlatUartEnable(void) (void)unlink(OPENTHREAD_POSIX_APP_SOCKET_NAME); sockname.sun_family = AF_UNIX; - assert(sizeof(OPENTHREAD_POSIX_APP_SOCKET_NAME) < sizeof(sockname.sun_path), "socket name too long"); + assert(sizeof(OPENTHREAD_POSIX_APP_SOCKET_NAME) < sizeof(sockname.sun_path)); strncpy(sockname.sun_path, OPENTHREAD_POSIX_APP_SOCKET_NAME, sizeof(sockname.sun_path) - 1); ret = bind(sUartSocket, (const struct sockaddr *)&sockname, sizeof(struct sockaddr_un)); @@ -219,6 +232,13 @@ void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, co sSessionSocket = accept(sUartSocket, NULL, NULL); } + if (sSessionSocket == -1 && sWriteBuffer != NULL) + { + IgnoreReturnValue(write(STDERR_FILENO, sWriteBuffer, sWriteLength)); + sWriteBuffer = NULL; + sWriteLength = 0; + } + otEXPECT(sSessionSocket != -1); if (FD_ISSET(sSessionSocket, aErrorFdSet))