mirror of
https://github.com/espressif/openthread.git
synced 2026-08-18 00:19:52 +00:00
[posix-app] add daemon mode (#3463)
This commit adds the daemon mode for POSIX CLI app. The daemon simply receive UART input from a unix socket connection.
This commit is contained in:
@@ -470,6 +470,38 @@ AC_SUBST(OPENTHREAD_ENABLE_POSIX_APP)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_POSIX_APP], [test "${enable_posix_app}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_POSIX_APP], [${OPENTHREAD_ENABLE_POSIX_APP}], [Define to 1 to build posix application.])
|
||||
|
||||
#
|
||||
# POSIX Daemon
|
||||
#
|
||||
|
||||
AC_MSG_CHECKING([whether to build POSIX applicaton in daemon mode])
|
||||
AC_ARG_ENABLE(posix-app-daemon,
|
||||
[AS_HELP_STRING([--enable-posix-app-daemon], [Build POSIX application in daemon mode@<:@default=no@:>@.])],
|
||||
[
|
||||
case "${enableval}" in
|
||||
|
||||
no|yes)
|
||||
enable_posix_app_daemon=${enableval}
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid value ${enable_posix_app} for --enable-posix-app-daemon])
|
||||
;;
|
||||
esac
|
||||
],
|
||||
[enable_posix_app_daemon=no])
|
||||
|
||||
if test "$enable_posix_app_daemon" = "yes"; then
|
||||
OPENTHREAD_ENABLE_POSIX_APP_DAEMON=1
|
||||
else
|
||||
OPENTHREAD_ENABLE_POSIX_APP_DAEMON=0
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(${enable_posix_app_daemon})
|
||||
AC_SUBST(OPENTHREAD_ENABLE_POSIX_APP_DAEMON)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_POSIX_APP_DAEMON], [test "${enable_posix_app_daemon}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_POSIX_APP_DAEMON], [${OPENTHREAD_ENABLE_POSIX_APP_DAEMON}], [Define to 1 to build posix application in daemon mode.])
|
||||
|
||||
#
|
||||
# FTD Library
|
||||
#
|
||||
|
||||
@@ -44,6 +44,7 @@ COMMISSIONER ?= 1
|
||||
CHANNEL_MANAGER ?= 1
|
||||
CHANNEL_MONITOR ?= 1
|
||||
CHILD_SUPERVISION ?= 1
|
||||
DAEMON ?= 0
|
||||
DHCP6_CLIENT ?= 1
|
||||
DHCP6_SERVER ?= 1
|
||||
DIAGNOSTIC ?= 1
|
||||
@@ -76,6 +77,10 @@ configure_OPTIONS = \
|
||||
|
||||
# Platform specific switches
|
||||
|
||||
ifeq (${DAEMON},1)
|
||||
configure_OPTIONS += --enable-posix-app-daemon
|
||||
endif
|
||||
|
||||
ifneq ($(DEBUG),1)
|
||||
COMMONCFLAGS += \
|
||||
-O2 \
|
||||
|
||||
+45
-6
@@ -77,12 +77,6 @@ bin_PROGRAMS = \
|
||||
$(NULL)
|
||||
|
||||
if OPENTHREAD_ENABLE_EXECUTABLE
|
||||
if OPENTHREAD_ENABLE_NCP
|
||||
bin_PROGRAMS += \
|
||||
ot-ncp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ot_ncp_CPPFLAGS = \
|
||||
$(CPPFLAGS_COMMON) \
|
||||
-DOPENTHREAD_POSIX_APP=1 \
|
||||
@@ -108,11 +102,56 @@ ot_ncp_LIBTOOLFLAGS = \
|
||||
$(LIBTOOLFLAGS_COMMON) \
|
||||
$(NULL)
|
||||
|
||||
if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
bin_PROGRAMS += \
|
||||
ot-ctl \
|
||||
ot-daemon \
|
||||
$(NULL)
|
||||
else # OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
if OPENTHREAD_ENABLE_CLI
|
||||
bin_PROGRAMS += \
|
||||
ot-cli \
|
||||
$(NULL)
|
||||
endif
|
||||
if OPENTHREAD_ENABLE_NCP
|
||||
bin_PROGRAMS += \
|
||||
ot-ncp \
|
||||
$(NULL)
|
||||
endif
|
||||
endif # OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
|
||||
ot_ctl_SOURCES = \
|
||||
client.c \
|
||||
$(NULL)
|
||||
|
||||
ot_ctl_CPPFLAGS = \
|
||||
$(CPPFLAGS_COMMON) \
|
||||
$(NULL)
|
||||
|
||||
ot_daemon_CPPFLAGS = \
|
||||
$(CPPFLAGS_COMMON) \
|
||||
-DOPENTHREAD_POSIX_APP=2 \
|
||||
$(NULL)
|
||||
|
||||
ot_daemon_SOURCES = \
|
||||
main.c \
|
||||
$(NULL)
|
||||
|
||||
ot_daemon_LDADD = \
|
||||
$(top_builddir)/src/cli/libopenthread-cli-ftd.a \
|
||||
$(top_builddir)/src/core/libopenthread-ftd.a \
|
||||
$(LDADD_COMMON) \
|
||||
$(top_builddir)/src/core/libopenthread-ftd.a \
|
||||
$(LDADD_COMMON) \
|
||||
$(NULL)
|
||||
|
||||
ot_daemon_LDFLAGS = \
|
||||
$(LDFLAGS_COMMON) \
|
||||
$(NULL)
|
||||
|
||||
ot_daemon_LIBTOOLFLAGS = \
|
||||
$(LIBTOOLFLAGS_COMMON) \
|
||||
$(NULL)
|
||||
|
||||
ot_cli_CPPFLAGS = \
|
||||
$(CPPFLAGS_COMMON) \
|
||||
|
||||
@@ -105,3 +105,20 @@ sudo wpantund -s 'system:./output/posix/x86_64-unknown-linux-gnu/bin/ot-ncp /dev
|
||||
# CC2538
|
||||
sudo wpantund -s 'system:./output/posix/x86_64-unknown-linux-gnu/bin/ot-ncp /dev/ttyUSB0 115200'
|
||||
```
|
||||
|
||||
Daemon Mode Support
|
||||
-------------------
|
||||
|
||||
OpenThread Posix Daemon mode uses a unix socket as input and output, so that OpenThread core can run as a service. And a client
|
||||
can communicate with it by connecting to the socket. The protocol is OpenThread CLI.
|
||||
|
||||
```
|
||||
# build daemon mode core stack for POSIX
|
||||
make -f src/posix/Makefile-posix DAEMON=1
|
||||
# Daemon with simulation
|
||||
./output/posix/x86_64-unknown-linux-gnu/bin/ot-daemon ./output/x86_64-unknown-linux-gnu/bin/ot-ncp-radio 1
|
||||
# Daemon with real device
|
||||
./output/posix/x86_64-unknown-linux-gnu/bin/ot-daemon /dev/ttyACM0 115200
|
||||
# Built-in controller
|
||||
./output/posix/x86_64-unknown-linux-gnu/bin/ot-ctl
|
||||
```
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2019, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/platform/toolchain.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "code_utils.h"
|
||||
#include "platform-posix.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(argc);
|
||||
OT_UNUSED_VARIABLE(argv);
|
||||
|
||||
int ret;
|
||||
int session = -1;
|
||||
|
||||
session = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
otEXPECT_ACTION(session != -1, perror("socket"); ret = OT_EXIT_FAILURE);
|
||||
|
||||
{
|
||||
struct sockaddr_un sockname;
|
||||
|
||||
memset(&sockname, 0, sizeof(struct sockaddr_un));
|
||||
sockname.sun_family = AF_UNIX;
|
||||
strncpy(sockname.sun_path, OPENTHREAD_POSIX_APP_SOCKET_NAME, sizeof(sockname.sun_path) - 1);
|
||||
|
||||
ret = connect(session, (const struct sockaddr *)&sockname, sizeof(struct sockaddr_un));
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, "OpenThread daemon is not running.\n");
|
||||
otEXIT_NOW(ret = OT_EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
char buffer[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE];
|
||||
fd_set readFdSet;
|
||||
int maxFd = STDIN_FILENO;
|
||||
|
||||
FD_ZERO(&readFdSet);
|
||||
|
||||
FD_SET(STDIN_FILENO, &readFdSet);
|
||||
FD_SET(session, &readFdSet);
|
||||
|
||||
maxFd = session > maxFd ? session : maxFd;
|
||||
|
||||
ret = select(maxFd + 1, &readFdSet, NULL, NULL, NULL);
|
||||
|
||||
otEXPECT_ACTION(ret != -1, perror("select"); ret = OT_EXIT_FAILURE);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
otEXIT_NOW(ret = OT_EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (FD_ISSET(STDIN_FILENO, &readFdSet))
|
||||
{
|
||||
otEXPECT_ACTION(fgets(buffer, sizeof(buffer), stdin) != NULL, ret = OT_EXIT_FAILURE);
|
||||
|
||||
ret = (int)write(session, buffer, strlen(buffer));
|
||||
otEXPECT_ACTION(ret != -1, perror("write"); ret = OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (FD_ISSET(session, &readFdSet))
|
||||
{
|
||||
ret = (int)read(session, buffer, sizeof(buffer));
|
||||
otEXPECT_ACTION(ret != -1, perror("read"); ret = OT_EXIT_FAILURE);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
// daemon closed session
|
||||
otEXIT_NOW(ret = OT_EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[ret] = 0;
|
||||
printf("%s", buffer);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
if (session != -1)
|
||||
{
|
||||
close(session);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -34,7 +34,7 @@
|
||||
#ifndef POSIX_APP_HDLC_INTERFACE_HPP_
|
||||
#define POSIX_APP_HDLC_INTERFACE_HPP_
|
||||
|
||||
#include "platform-posix.h"
|
||||
#include "platform-config.h"
|
||||
|
||||
#include "hdlc.hpp"
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2019, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file includes the POSIX platform-specific configurations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
|
||||
*
|
||||
* Define as 1 to enable PTY device support in POSIX app.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
|
||||
#define OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_POSIX_APP_SOCKET_BASENAME
|
||||
*
|
||||
* Define socket basename used by POSIX app daemon.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_POSIX_APP_SOCKET_BASENAME
|
||||
#define OPENTHREAD_POSIX_APP_SOCKET_BASENAME "/tmp/openthread"
|
||||
#endif
|
||||
@@ -40,15 +40,13 @@
|
||||
|
||||
#include <openthread/instance.h>
|
||||
|
||||
#include "platform-config.h"
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
|
||||
*
|
||||
* Define as 1 to enable PTY device support in POSIX app.
|
||||
* This is the socket name used by daemon mode.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
|
||||
#define OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE 1
|
||||
#endif
|
||||
#define OPENTHREAD_POSIX_APP_SOCKET_NAME OPENTHREAD_POSIX_APP_SOCKET_BASENAME ".sock"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
+174
-27
@@ -29,6 +29,16 @@
|
||||
#include "openthread-core-config.h"
|
||||
#include "platform-posix.h"
|
||||
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -37,9 +47,16 @@
|
||||
|
||||
#include "code_utils.h"
|
||||
|
||||
static uint8_t sReceiveBuffer[128];
|
||||
static const uint8_t *sWriteBuffer;
|
||||
static uint16_t sWriteLength;
|
||||
#define OPENTHREAD_POSIX_APP_SOCKET_LOCK OPENTHREAD_POSIX_APP_SOCKET_BASENAME ".lock"
|
||||
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
static int sUartSocket = -1;
|
||||
static int sUartLock = -1;
|
||||
static int sSessionSocket = -1;
|
||||
#endif
|
||||
|
||||
static const uint8_t *sWriteBuffer = NULL;
|
||||
static uint16_t sWriteLength = 0;
|
||||
|
||||
void platformUartRestore(void)
|
||||
{
|
||||
@@ -47,12 +64,86 @@ void platformUartRestore(void)
|
||||
|
||||
otError otPlatUartEnable(void)
|
||||
{
|
||||
return OT_ERROR_NONE;
|
||||
otError error = OT_ERROR_NONE;
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
struct sockaddr_un sockname;
|
||||
int ret;
|
||||
|
||||
sUartSocket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sUartSocket == -1)
|
||||
{
|
||||
perror("socket");
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sUartLock = open(OPENTHREAD_POSIX_APP_SOCKET_LOCK, O_CREAT | O_RDONLY, 0600);
|
||||
|
||||
if (sUartLock == -1)
|
||||
{
|
||||
perror("open");
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (flock(sUartLock, LOCK_EX | LOCK_NB) == -1)
|
||||
{
|
||||
perror("flock");
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset(&sockname, 0, sizeof(struct sockaddr_un));
|
||||
|
||||
(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");
|
||||
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));
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("bind");
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//
|
||||
// only accept 1 connection.
|
||||
//
|
||||
ret = listen(sUartSocket, 1);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("listen");
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatUartDisable(void)
|
||||
{
|
||||
return OT_ERROR_NONE;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
if (sSessionSocket != -1)
|
||||
{
|
||||
close(sSessionSocket);
|
||||
sSessionSocket = -1;
|
||||
}
|
||||
|
||||
if (sUartSocket != -1)
|
||||
{
|
||||
close(sUartSocket);
|
||||
sUartSocket = -1;
|
||||
}
|
||||
|
||||
if (sUartLock != -1)
|
||||
{
|
||||
close(sUartLock);
|
||||
sUartLock = -1;
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
@@ -72,31 +163,42 @@ void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aE
|
||||
{
|
||||
if (aReadFdSet != NULL)
|
||||
{
|
||||
FD_SET(STDIN_FILENO, aReadFdSet);
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
int fd = (sSessionSocket == -1 ? sUartSocket : sSessionSocket);
|
||||
#else
|
||||
int fd = STDIN_FILENO;
|
||||
#endif
|
||||
|
||||
FD_SET(fd, aReadFdSet);
|
||||
|
||||
if (aErrorFdSet != NULL)
|
||||
{
|
||||
FD_SET(STDIN_FILENO, aErrorFdSet);
|
||||
FD_SET(fd, aErrorFdSet);
|
||||
}
|
||||
|
||||
if (aMaxFd != NULL && *aMaxFd < STDIN_FILENO)
|
||||
if (aMaxFd != NULL && *aMaxFd < fd)
|
||||
{
|
||||
*aMaxFd = STDIN_FILENO;
|
||||
*aMaxFd = fd;
|
||||
}
|
||||
}
|
||||
|
||||
if ((aWriteFdSet != NULL) && (sWriteLength > 0))
|
||||
{
|
||||
FD_SET(STDOUT_FILENO, aWriteFdSet);
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
int fd = (sSessionSocket == -1 ? sUartSocket : sSessionSocket);
|
||||
#else
|
||||
int fd = STDOUT_FILENO;
|
||||
#endif
|
||||
|
||||
FD_SET(fd, aWriteFdSet);
|
||||
|
||||
if (aErrorFdSet != NULL)
|
||||
{
|
||||
FD_SET(STDOUT_FILENO, aErrorFdSet);
|
||||
FD_SET(fd, aErrorFdSet);
|
||||
}
|
||||
|
||||
if (aMaxFd != NULL && *aMaxFd < STDOUT_FILENO)
|
||||
if (aMaxFd != NULL && *aMaxFd < fd)
|
||||
{
|
||||
*aMaxFd = STDOUT_FILENO;
|
||||
*aMaxFd = fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +206,31 @@ void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aE
|
||||
void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet)
|
||||
{
|
||||
ssize_t rval;
|
||||
int fd;
|
||||
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
if (FD_ISSET(sUartSocket, aErrorFdSet))
|
||||
{
|
||||
perror("socket error");
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
else if (FD_ISSET(sUartSocket, aReadFdSet))
|
||||
{
|
||||
sSessionSocket = accept(sUartSocket, NULL, NULL);
|
||||
}
|
||||
|
||||
otEXPECT(sSessionSocket != -1);
|
||||
|
||||
if (FD_ISSET(sSessionSocket, aErrorFdSet))
|
||||
{
|
||||
close(sSessionSocket);
|
||||
sSessionSocket = -1;
|
||||
}
|
||||
|
||||
otEXPECT(sSessionSocket != -1);
|
||||
|
||||
fd = sSessionSocket;
|
||||
#else // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
if (FD_ISSET(STDIN_FILENO, aErrorFdSet))
|
||||
{
|
||||
perror("stdin");
|
||||
@@ -117,36 +243,54 @@ void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, co
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (FD_ISSET(STDIN_FILENO, aReadFdSet))
|
||||
fd = STDIN_FILENO;
|
||||
#endif // OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
|
||||
if (FD_ISSET(fd, aReadFdSet))
|
||||
{
|
||||
rval = read(STDIN_FILENO, sReceiveBuffer, sizeof(sReceiveBuffer));
|
||||
uint8_t buffer[256];
|
||||
|
||||
rval = read(fd, buffer, sizeof(buffer));
|
||||
|
||||
if (rval > 0)
|
||||
{
|
||||
otPlatUartReceived(sReceiveBuffer, (uint16_t)rval);
|
||||
otPlatUartReceived(buffer, (uint16_t)rval);
|
||||
}
|
||||
else if (rval < 0)
|
||||
else if (rval <= 0)
|
||||
{
|
||||
perror("UART read");
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
close(sSessionSocket);
|
||||
sSessionSocket = -1;
|
||||
otEXIT_NOW();
|
||||
#else
|
||||
exit(OT_EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "UART ended\r\n");
|
||||
exit(OT_EXIT_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ((sWriteLength > 0) && (FD_ISSET(STDOUT_FILENO, aWriteFdSet)))
|
||||
{
|
||||
rval = write(STDOUT_FILENO, sWriteBuffer, sWriteLength);
|
||||
#if !OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
fd = STDOUT_FILENO;
|
||||
#endif
|
||||
|
||||
if (rval <= 0)
|
||||
if ((sWriteLength > 0) && (FD_ISSET(fd, aWriteFdSet)))
|
||||
{
|
||||
rval = write(fd, sWriteBuffer, sWriteLength);
|
||||
|
||||
if (rval < 0)
|
||||
{
|
||||
perror("UART write");
|
||||
#if OPENTHREAD_ENABLE_POSIX_APP_DAEMON
|
||||
close(sSessionSocket);
|
||||
sSessionSocket = -1;
|
||||
otEXIT_NOW();
|
||||
#else
|
||||
exit(OT_EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
otEXPECT(rval > 0);
|
||||
|
||||
sWriteBuffer += (uint16_t)rval;
|
||||
sWriteLength -= (uint16_t)rval;
|
||||
|
||||
@@ -155,4 +299,7 @@ void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, co
|
||||
otPlatUartSendDone();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user