mirror of
https://github.com/espressif/openthread.git
synced 2026-10-04 06:47:36 +00:00
[posix] add radio url (#4935)
Radio url provides a unified interface for users to specify the radio peripheral device and arguments to the OpenThread core stack.
This commit is contained in:
@@ -281,6 +281,7 @@ LOCAL_SRC_FILES := \
|
|||||||
src/posix/platform/misc.cpp \
|
src/posix/platform/misc.cpp \
|
||||||
src/posix/platform/netif.cpp \
|
src/posix/platform/netif.cpp \
|
||||||
src/posix/platform/radio.cpp \
|
src/posix/platform/radio.cpp \
|
||||||
|
src/posix/platform/radio_url.cpp \
|
||||||
src/posix/platform/settings.cpp \
|
src/posix/platform/settings.cpp \
|
||||||
src/posix/platform/spi_interface.cpp \
|
src/posix/platform/spi_interface.cpp \
|
||||||
src/posix/platform/system.cpp \
|
src/posix/platform/system.cpp \
|
||||||
|
|||||||
@@ -93,12 +93,12 @@ EOF
|
|||||||
|
|
||||||
echo "Step 2. Start retrieving dataset from Radio..."
|
echo "Step 2. Start retrieving dataset from Radio..."
|
||||||
RADIO_NCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-ncp-ftd)"
|
RADIO_NCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-ncp-ftd)"
|
||||||
"$(pwd)/$(ls output/posix/*linux*/bin/ot-ncp)" -n --radio-version --ncp-dataset -- "${RADIO_NCP_PATH}" 1
|
"$(pwd)/$(ls output/posix/*linux*/bin/ot-ncp)" -n --radio-version "spinel+hdlc+forkpty://${RADIO_NCP_PATH}?arg=1&ncp-dataset=1"
|
||||||
|
|
||||||
echo "Step 3. Start posix app and check whether PAN dataset is the same..."
|
echo "Step 3. Start posix app and check whether PAN dataset is the same..."
|
||||||
RADIO_RCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-rcp)"
|
RADIO_RCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-rcp)"
|
||||||
|
|
||||||
OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) ${RADIO_RCP_PATH} 1"
|
OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) spinel+hdlc+forkpty://${RADIO_RCP_PATH}?arg=1"
|
||||||
|
|
||||||
expect <<EOF
|
expect <<EOF
|
||||||
spawn ${OT_CLI_CMD}
|
spawn ${OT_CLI_CMD}
|
||||||
@@ -126,8 +126,9 @@ expect eof
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "Step 4. Start posix app and check whether it can get radio firmware version..."
|
echo "Step 4. Start posix app and check whether it can get radio firmware version..."
|
||||||
RADIO_VERSION="$("$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)" -n --radio-version --ncp-dataset -- "${RADIO_RCP_PATH}" 1)" || true
|
RADIO_VERSION="$("$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)" -n --radio-version "spinel+hdlc+forkpty://${RADIO_RCP_PATH}?arg=1&ncp-dataset=1")" || true
|
||||||
test -n "${RADIO_VERSION}"
|
echo "${RADIO_VERSION}"
|
||||||
|
test -n "{RADIO_VERSION}"
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -81,12 +81,10 @@ check()
|
|||||||
# Cover setting a valid network interface name.
|
# Cover setting a valid network interface name.
|
||||||
readonly VALID_NETIF_NAME="wan$(date +%H%M%S)"
|
readonly VALID_NETIF_NAME="wan$(date +%H%M%S)"
|
||||||
|
|
||||||
local options=(
|
RADIO_URL="spinel+hdlc+uart://${CORE_PTY}?max-power-table=11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26"
|
||||||
'--max-power-table=11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26'
|
|
||||||
)
|
|
||||||
|
|
||||||
if [[ ${DAEMON} == 1 ]]; then
|
if [[ ${DAEMON} == 1 ]]; then
|
||||||
sudo "$(pwd)/$(ls output/posix/*linux*/bin/ot-daemon)" "${options[@]}" -I "${VALID_NETIF_NAME}" "${CORE_PTY}" &
|
sudo "$(pwd)/$(ls output/posix/*linux*/bin/ot-daemon)" -I "${VALID_NETIF_NAME}" "${RADIO_URL}" &
|
||||||
sleep 1
|
sleep 1
|
||||||
OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-ctl)"
|
OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-ctl)"
|
||||||
sudo "${OT_CLI_CMD}" panid 0xface | grep 'Done' || die 'failed to set panid with ot-ctl'
|
sudo "${OT_CLI_CMD}" panid 0xface | grep 'Done' || die 'failed to set panid with ot-ctl'
|
||||||
@@ -96,14 +94,14 @@ check()
|
|||||||
sudo "${OT_CLI_CMD}" factoryreset
|
sudo "${OT_CLI_CMD}" factoryreset
|
||||||
else
|
else
|
||||||
OT_CLI="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)"
|
OT_CLI="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)"
|
||||||
sudo "${OT_CLI}" -I "${VALID_NETIF_NAME}" -n "${CORE_PTY}"
|
sudo "${OT_CLI}" -I "${VALID_NETIF_NAME}" -n "${RADIO_URL}"
|
||||||
|
|
||||||
# Cover setting a too long(max is 15 characters) network interface name.
|
# Cover setting a too long(max is 15 characters) network interface name.
|
||||||
# Expect exit code to be 2(OT_EXIT_INVALID_ARGUMENTS).
|
# Expect exit code to be 2(OT_EXIT_INVALID_ARGUMENTS).
|
||||||
readonly INVALID_NETIF_NAME="wan0123456789123"
|
readonly INVALID_NETIF_NAME="wan0123456789123"
|
||||||
sudo "${OT_CLI}" -I "${INVALID_NETIF_NAME}" -n "${CORE_PTY}" || test $? = 2
|
sudo "${OT_CLI}" -I "${INVALID_NETIF_NAME}" -n "${RADIO_URL}" || test $? = 2
|
||||||
|
|
||||||
OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) ${CORE_PTY}"
|
OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) ${RADIO_URL}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sudo expect <<EOF | tee "${OT_OUTPUT}" &
|
sudo expect <<EOF | tee "${OT_OUTPUT}" &
|
||||||
|
|||||||
+6
-115
@@ -75,6 +75,7 @@
|
|||||||
#error "Unknown posix app type!"
|
#error "Unknown posix app type!"
|
||||||
#endif
|
#endif
|
||||||
#include <common/code_utils.hpp>
|
#include <common/code_utils.hpp>
|
||||||
|
#include <common/logging.hpp>
|
||||||
#include <lib/platform/exit_code.h>
|
#include <lib/platform/exit_code.h>
|
||||||
#include <openthread/openthread-system.h>
|
#include <openthread/openthread-system.h>
|
||||||
|
|
||||||
@@ -102,88 +103,31 @@ void __gcov_flush();
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ARG_PRINT_RADIO_VERSION = 1001,
|
ARG_PRINT_RADIO_VERSION = 1001,
|
||||||
ARG_NO_RADIO_RESET = 1002,
|
|
||||||
ARG_RESTORE_NCP_DATASET = 1003,
|
|
||||||
ARG_SPI_GPIO_INT_DEV = 1011,
|
|
||||||
ARG_SPI_GPIO_INT_LINE = 1012,
|
|
||||||
ARG_SPI_GPIO_RESET_DEV = 1013,
|
|
||||||
ARG_SPI_GPIO_RESET_LINE = 1014,
|
|
||||||
ARG_SPI_MODE = 1015,
|
|
||||||
ARG_SPI_SPEED = 1016,
|
|
||||||
ARG_SPI_CS_DELAY = 1017,
|
|
||||||
ARG_SPI_RESET_DELAY = 1018,
|
|
||||||
ARG_SPI_ALIGN_ALLOWANCE = 1019,
|
|
||||||
ARG_SPI_SMALL_PACKET = 1020,
|
|
||||||
ARG_MAX_POWER_TABLE = 1021,
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option kOptions[] = {{"debug-level", required_argument, NULL, 'd'},
|
static const struct option kOptions[] = {{"debug-level", required_argument, NULL, 'd'},
|
||||||
{"dry-run", no_argument, NULL, 'n'},
|
{"dry-run", no_argument, NULL, 'n'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"interface-name", required_argument, NULL, 'I'},
|
{"interface-name", required_argument, NULL, 'I'},
|
||||||
{"no-reset", no_argument, NULL, ARG_NO_RADIO_RESET},
|
|
||||||
{"radio-version", no_argument, NULL, ARG_PRINT_RADIO_VERSION},
|
{"radio-version", no_argument, NULL, ARG_PRINT_RADIO_VERSION},
|
||||||
{"ncp-dataset", no_argument, NULL, ARG_RESTORE_NCP_DATASET},
|
|
||||||
{"time-speed", required_argument, NULL, 's'},
|
{"time-speed", required_argument, NULL, 's'},
|
||||||
{"verbose", no_argument, NULL, 'v'},
|
{"verbose", no_argument, NULL, 'v'},
|
||||||
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
|
|
||||||
{"max-power-table", required_argument, NULL, ARG_MAX_POWER_TABLE},
|
|
||||||
#endif
|
|
||||||
#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
|
|
||||||
{"gpio-int-dev", required_argument, NULL, ARG_SPI_GPIO_INT_DEV},
|
|
||||||
{"gpio-int-line", required_argument, NULL, ARG_SPI_GPIO_INT_LINE},
|
|
||||||
{"gpio-reset-dev", required_argument, NULL, ARG_SPI_GPIO_RESET_DEV},
|
|
||||||
{"gpio-reset-line", required_argument, NULL, ARG_SPI_GPIO_RESET_LINE},
|
|
||||||
{"spi-mode", required_argument, NULL, ARG_SPI_MODE},
|
|
||||||
{"spi-speed", required_argument, NULL, ARG_SPI_SPEED},
|
|
||||||
{"spi-cs-delay", required_argument, NULL, ARG_SPI_CS_DELAY},
|
|
||||||
{"spi-reset-delay", required_argument, NULL, ARG_SPI_RESET_DELAY},
|
|
||||||
{"spi-align-allowance", required_argument, NULL, ARG_SPI_ALIGN_ALLOWANCE},
|
|
||||||
{"spi-small-packet", required_argument, NULL, ARG_SPI_SMALL_PACKET},
|
|
||||||
#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
|
|
||||||
{0, 0, 0, 0}};
|
{0, 0, 0, 0}};
|
||||||
|
|
||||||
static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
|
static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
|
||||||
{
|
{
|
||||||
fprintf(aStream,
|
fprintf(aStream,
|
||||||
"Syntax:\n"
|
"Syntax:\n"
|
||||||
" %s [Options] NodeId|Device|Command [DeviceConfig|CommandArgs]\n"
|
" %s [Options] RadioURL\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -d --debug-level Debug level of logging.\n"
|
" -d --debug-level Debug level of logging.\n"
|
||||||
" -h --help Display this usage information.\n"
|
" -h --help Display this usage information.\n"
|
||||||
" -I --interface-name name Thread network interface name.\n"
|
" -I --interface-name name Thread network interface name.\n"
|
||||||
" -n --dry-run Just verify if arguments is valid and radio spinel is compatible.\n"
|
" -n --dry-run Just verify if arguments is valid and radio spinel is compatible.\n"
|
||||||
" --no-reset Do not send Spinel reset command to RCP on initialization.\n"
|
|
||||||
" --radio-version Print radio firmware version.\n"
|
" --radio-version Print radio firmware version.\n"
|
||||||
" --ncp-dataset Retrieve and save NCP dataset to file.\n"
|
|
||||||
" -s --time-speed factor Time speed up factor.\n"
|
" -s --time-speed factor Time speed up factor.\n"
|
||||||
" -v --verbose Also log to stderr.\n",
|
" -v --verbose Also log to stderr.\n",
|
||||||
aProgramName);
|
aProgramName);
|
||||||
#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
|
|
||||||
fprintf(aStream,
|
|
||||||
" --gpio-int-dev[=gpio-device-path]\n"
|
|
||||||
" Specify a path to the Linux sysfs-exported GPIO device for the\n"
|
|
||||||
" `I̅N̅T̅` pin. If not specified, `SPI` interface will fall back to\n"
|
|
||||||
" polling, which is inefficient.\n"
|
|
||||||
" --gpio-int-line[=line-offset]\n"
|
|
||||||
" The offset index of `I̅N̅T̅` pin for the associated GPIO device.\n"
|
|
||||||
" If not specified, `SPI` interface will fall back to polling,\n"
|
|
||||||
" which is inefficient.\n"
|
|
||||||
" --gpio-reset-dev[=gpio-device-path]\n"
|
|
||||||
" Specify a path to the Linux sysfs-exported GPIO device for the\n"
|
|
||||||
" `R̅E̅S̅` pin.\n"
|
|
||||||
" --gpio-reset-line[=line-offset]"
|
|
||||||
" The offset index of `R̅E̅S̅` pin for the associated GPIO device.\n"
|
|
||||||
" --spi-mode[=mode] Specify the SPI mode to use (0-3).\n"
|
|
||||||
" --spi-speed[=hertz] Specify the SPI speed in hertz.\n"
|
|
||||||
" --spi-cs-delay[=usec] Specify the delay after C̅S̅ assertion, in µsec.\n"
|
|
||||||
" --spi-reset-delay[=ms] Specify the delay after R̅E̅S̅E̅T̅ assertion, in milliseconds.\n"
|
|
||||||
" --spi-align-allowance[=n] Specify the maximum number of 0xFF bytes to clip from start of\n"
|
|
||||||
" MISO frame. Max value is 16.\n"
|
|
||||||
" --spi-small-packet=[n] Specify the smallest packet we can receive in a single transaction.\n"
|
|
||||||
" (larger packets will require two transactions). Default value is 32.\n");
|
|
||||||
#endif
|
|
||||||
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
|
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
|
||||||
fprintf(aStream,
|
fprintf(aStream,
|
||||||
" --max-power-table Max power for channels in ascending order separated by commas,\n"
|
" --max-power-table Max power for channels in ascending order separated by commas,\n"
|
||||||
@@ -191,6 +135,7 @@ static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
|
|||||||
" the last value will be applied to all remaining channels.\n"
|
" the last value will be applied to all remaining channels.\n"
|
||||||
" Special value 0x7f disables a channel.\n");
|
" Special value 0x7f disables a channel.\n");
|
||||||
#endif
|
#endif
|
||||||
|
fprintf(aStream, "%s", otSysGetRadioUrlHelpString());
|
||||||
exit(aExitCode);
|
exit(aExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,15 +143,8 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
|
|||||||
{
|
{
|
||||||
memset(aConfig, 0, sizeof(*aConfig));
|
memset(aConfig, 0, sizeof(*aConfig));
|
||||||
|
|
||||||
aConfig->mPlatformConfig.mSpeedUpFactor = 1;
|
aConfig->mPlatformConfig.mSpeedUpFactor = 1;
|
||||||
aConfig->mPlatformConfig.mResetRadio = true;
|
aConfig->mLogLevel = OT_LOG_LEVEL_CRIT;
|
||||||
aConfig->mPlatformConfig.mSpiSpeed = OT_PLATFORM_CONFIG_SPI_DEFAULT_SPEED_HZ;
|
|
||||||
aConfig->mPlatformConfig.mSpiCsDelay = OT_PLATFORM_CONFIG_SPI_DEFAULT_CS_DELAY_US;
|
|
||||||
aConfig->mPlatformConfig.mSpiResetDelay = OT_PLATFORM_CONFIG_SPI_DEFAULT_RESET_DELAY_MS;
|
|
||||||
aConfig->mPlatformConfig.mSpiAlignAllowance = OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE;
|
|
||||||
aConfig->mPlatformConfig.mSpiSmallPacketSize = OT_PLATFORM_CONFIG_SPI_DEFAULT_SMALL_PACKET_SIZE;
|
|
||||||
aConfig->mPlatformConfig.mSpiMode = OT_PLATFORM_CONFIG_SPI_DEFAULT_MODE;
|
|
||||||
aConfig->mLogLevel = OT_LOG_LEVEL_CRIT;
|
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
|
|
||||||
@@ -253,47 +191,6 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
|
|||||||
case ARG_PRINT_RADIO_VERSION:
|
case ARG_PRINT_RADIO_VERSION:
|
||||||
aConfig->mPrintRadioVersion = true;
|
aConfig->mPrintRadioVersion = true;
|
||||||
break;
|
break;
|
||||||
case ARG_NO_RADIO_RESET:
|
|
||||||
aConfig->mPlatformConfig.mResetRadio = false;
|
|
||||||
break;
|
|
||||||
case ARG_RESTORE_NCP_DATASET:
|
|
||||||
aConfig->mPlatformConfig.mRestoreDatasetFromNcp = true;
|
|
||||||
break;
|
|
||||||
case ARG_SPI_GPIO_INT_DEV:
|
|
||||||
aConfig->mPlatformConfig.mSpiGpioIntDevice = optarg;
|
|
||||||
break;
|
|
||||||
case ARG_SPI_GPIO_INT_LINE:
|
|
||||||
aConfig->mPlatformConfig.mSpiGpioIntLine = (uint8_t)atoi(optarg);
|
|
||||||
break;
|
|
||||||
case ARG_SPI_GPIO_RESET_DEV:
|
|
||||||
aConfig->mPlatformConfig.mSpiGpioResetDevice = optarg;
|
|
||||||
break;
|
|
||||||
case ARG_SPI_GPIO_RESET_LINE:
|
|
||||||
aConfig->mPlatformConfig.mSpiGpioResetLine = (uint8_t)atoi(optarg);
|
|
||||||
break;
|
|
||||||
case ARG_SPI_MODE:
|
|
||||||
aConfig->mPlatformConfig.mSpiMode = (uint8_t)atoi(optarg);
|
|
||||||
break;
|
|
||||||
case ARG_SPI_SPEED:
|
|
||||||
aConfig->mPlatformConfig.mSpiSpeed = (uint32_t)atoi(optarg);
|
|
||||||
break;
|
|
||||||
case ARG_SPI_CS_DELAY:
|
|
||||||
aConfig->mPlatformConfig.mSpiCsDelay = (uint16_t)atoi(optarg);
|
|
||||||
break;
|
|
||||||
case ARG_SPI_RESET_DELAY:
|
|
||||||
aConfig->mPlatformConfig.mSpiResetDelay = (uint32_t)atoi(optarg);
|
|
||||||
break;
|
|
||||||
case ARG_SPI_ALIGN_ALLOWANCE:
|
|
||||||
aConfig->mPlatformConfig.mSpiAlignAllowance = (uint8_t)atoi(optarg);
|
|
||||||
break;
|
|
||||||
case ARG_SPI_SMALL_PACKET:
|
|
||||||
aConfig->mPlatformConfig.mSpiSmallPacketSize = (uint8_t)atoi(optarg);
|
|
||||||
break;
|
|
||||||
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
|
|
||||||
case ARG_MAX_POWER_TABLE:
|
|
||||||
aConfig->mPlatformConfig.mMaxPowerTable = optarg;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case '?':
|
case '?':
|
||||||
PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
|
PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
|
||||||
break;
|
break;
|
||||||
@@ -307,13 +204,7 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
|
|||||||
{
|
{
|
||||||
PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
|
PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
|
||||||
}
|
}
|
||||||
|
aConfig->mPlatformConfig.mRadioUrl = aArgVector[optind];
|
||||||
aConfig->mPlatformConfig.mRadioFile = aArgVector[optind];
|
|
||||||
|
|
||||||
if (optind + 1 < aArgCount)
|
|
||||||
{
|
|
||||||
aConfig->mPlatformConfig.mRadioConfig = aArgVector[optind + 1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static otInstance *InitInstance(int aArgCount, char *aArgVector[])
|
static otInstance *InitInstance(int aArgCount, char *aArgVector[])
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ add_library(openthread-posix
|
|||||||
misc.cpp
|
misc.cpp
|
||||||
netif.cpp
|
netif.cpp
|
||||||
radio.cpp
|
radio.cpp
|
||||||
|
radio_url.cpp
|
||||||
settings.cpp
|
settings.cpp
|
||||||
spi_interface.cpp
|
spi_interface.cpp
|
||||||
system.cpp
|
system.cpp
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ libopenthread_posix_a_SOURCES = \
|
|||||||
misc.cpp \
|
misc.cpp \
|
||||||
netif.cpp \
|
netif.cpp \
|
||||||
radio.cpp \
|
radio.cpp \
|
||||||
|
radio_url.cpp \
|
||||||
settings.cpp \
|
settings.cpp \
|
||||||
spi_interface.cpp \
|
spi_interface.cpp \
|
||||||
system.cpp \
|
system.cpp \
|
||||||
@@ -62,6 +63,7 @@ noinst_HEADERS = \
|
|||||||
hdlc_interface.hpp \
|
hdlc_interface.hpp \
|
||||||
openthread-posix-config.h \
|
openthread-posix-config.h \
|
||||||
platform-posix.h \
|
platform-posix.h \
|
||||||
|
radio_url.hpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
openthread_HEADERS = \
|
openthread_HEADERS = \
|
||||||
@@ -75,7 +77,7 @@ if OPENTHREAD_BUILD_COVERAGE
|
|||||||
CLEANFILES = $(wildcard *.gcda *.gcno)
|
CLEANFILES = $(wildcard *.gcda *.gcno)
|
||||||
endif # OPENTHREAD_BUILD_COVERAGE
|
endif # OPENTHREAD_BUILD_COVERAGE
|
||||||
|
|
||||||
check_PROGRAMS = test-settings
|
check_PROGRAMS = test-settings test-radio-url
|
||||||
|
|
||||||
test_settings_CPPFLAGS = \
|
test_settings_CPPFLAGS = \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
@@ -90,8 +92,22 @@ test_settings_SOURCES = \
|
|||||||
settings.cpp \
|
settings.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
test_radio_url_CPPFLAGS = \
|
||||||
|
-I$(top_srcdir)/include \
|
||||||
|
-I$(top_srcdir)/src \
|
||||||
|
-I$(top_srcdir)/src/core \
|
||||||
|
-I$(top_srcdir)/src/posix/platform/include \
|
||||||
|
-DOPENTHREAD_CONFIG_LOG_PLATFORM=0 \
|
||||||
|
-DSELF_TEST \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
test_radio_url_SOURCES = \
|
||||||
|
radio_url.cpp \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
TESTS = \
|
TESTS = \
|
||||||
test-settings \
|
test-settings \
|
||||||
|
test-radio-url \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
|
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
|
||||||
|
|||||||
@@ -138,30 +138,30 @@ HdlcInterface::HdlcInterface(SpinelInterface::ReceiveFrameCallback aCallback,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
otError HdlcInterface::Init(const otPlatformConfig &aPlatformConfig)
|
otError HdlcInterface::Init(Arguments &aArguments)
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY);
|
VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY);
|
||||||
|
|
||||||
VerifyOrDie(stat(aPlatformConfig.mRadioFile, &st) == 0, OT_EXIT_INVALID_ARGUMENTS);
|
VerifyOrDie(stat(aArguments.GetPath(), &st) == 0, OT_EXIT_INVALID_ARGUMENTS);
|
||||||
|
|
||||||
if (S_ISCHR(st.st_mode))
|
if (S_ISCHR(st.st_mode))
|
||||||
{
|
{
|
||||||
mSockFd = OpenFile(aPlatformConfig.mRadioFile, aPlatformConfig.mRadioConfig);
|
mSockFd = OpenFile(aArguments.GetPath(), aArguments);
|
||||||
VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS);
|
VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS);
|
||||||
}
|
}
|
||||||
#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
|
#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
|
||||||
else if (S_ISREG(st.st_mode))
|
else if (S_ISREG(st.st_mode))
|
||||||
{
|
{
|
||||||
mSockFd = ForkPty(aPlatformConfig.mRadioFile, aPlatformConfig.mRadioConfig);
|
mSockFd = ForkPty(aArguments.GetPath(), aArguments.GetValue("arg"));
|
||||||
VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS);
|
VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS);
|
||||||
}
|
}
|
||||||
#endif // OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
|
#endif // OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
otLogCritPlat("Radio file '%s' not supported", aPlatformConfig.mRadioFile);
|
otLogCritPlat("Radio file '%s' not supported", aArguments.GetPath());
|
||||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,10 +407,12 @@ exit:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HdlcInterface::OpenFile(const char *aFile, const char *aConfig)
|
int HdlcInterface::OpenFile(const char *aFile, Arguments &aArguments)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
const char *parity = aArguments.GetValue("uart-parity");
|
||||||
|
uint32_t baudrate = 115200;
|
||||||
|
|
||||||
fd = open(aFile, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC);
|
fd = open(aFile, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
@@ -423,10 +425,8 @@ int HdlcInterface::OpenFile(const char *aFile, const char *aConfig)
|
|||||||
{
|
{
|
||||||
struct termios tios;
|
struct termios tios;
|
||||||
|
|
||||||
unsigned int speed = 115200;
|
unsigned int speed = 115200;
|
||||||
int cstopb = 1;
|
int stopBit = 1;
|
||||||
char parity = 'N';
|
|
||||||
char flow = 'N';
|
|
||||||
|
|
||||||
VerifyOrExit((rval = tcgetattr(fd, &tios)) == 0, OT_NOOP);
|
VerifyOrExit((rval = tcgetattr(fd, &tios)) == 0, OT_NOOP);
|
||||||
|
|
||||||
@@ -434,29 +434,29 @@ int HdlcInterface::OpenFile(const char *aFile, const char *aConfig)
|
|||||||
|
|
||||||
tios.c_cflag = CS8 | HUPCL | CREAD | CLOCAL;
|
tios.c_cflag = CS8 | HUPCL | CREAD | CLOCAL;
|
||||||
|
|
||||||
// example: 115200N1H
|
if (parity)
|
||||||
if (aConfig != NULL)
|
|
||||||
{
|
{
|
||||||
sscanf(aConfig, "%u%c%d%c", &speed, &parity, &cstopb, &flow);
|
if (strncmp(parity, "odd", 3) == 0)
|
||||||
|
{
|
||||||
|
tios.c_cflag |= PARENB;
|
||||||
|
tios.c_cflag |= PARODD;
|
||||||
|
}
|
||||||
|
else if (strncmp(parity, "even", 4) == 0)
|
||||||
|
{
|
||||||
|
tios.c_cflag |= PARENB;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (parity)
|
if (aArguments.GetValue("uart-stop"))
|
||||||
{
|
{
|
||||||
case 'N':
|
stopBit = atoi(aArguments.GetValue("uart-stop"));
|
||||||
break;
|
|
||||||
case 'E':
|
|
||||||
tios.c_cflag |= PARENB;
|
|
||||||
break;
|
|
||||||
case 'O':
|
|
||||||
tios.c_cflag |= (PARENB | PARODD);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// not supported
|
|
||||||
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cstopb)
|
switch (stopBit)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
tios.c_cflag &= static_cast<unsigned long>(~CSTOPB);
|
tios.c_cflag &= static_cast<unsigned long>(~CSTOPB);
|
||||||
@@ -469,7 +469,11 @@ int HdlcInterface::OpenFile(const char *aFile, const char *aConfig)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (speed)
|
if (aArguments.GetValue("baudrate"))
|
||||||
|
{
|
||||||
|
baudrate = static_cast<uint32_t>(atoi(aArguments.GetValue("baudrate")));
|
||||||
|
}
|
||||||
|
switch (baudrate)
|
||||||
{
|
{
|
||||||
case 9600:
|
case 9600:
|
||||||
speed = B9600;
|
speed = B9600;
|
||||||
@@ -556,17 +560,9 @@ int HdlcInterface::OpenFile(const char *aFile, const char *aConfig)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (flow)
|
if (aArguments.GetValue("uart-flow-control") != NULL)
|
||||||
{
|
{
|
||||||
case 'N':
|
|
||||||
break;
|
|
||||||
case 'H':
|
|
||||||
tios.c_cflag |= CRTSCTS;
|
tios.c_cflag |= CRTSCTS;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// not supported
|
|
||||||
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VerifyOrExit((rval = cfsetspeed(&tios, static_cast<speed_t>(speed))) == 0, perror("cfsetspeed"));
|
VerifyOrExit((rval = cfsetspeed(&tios, static_cast<speed_t>(speed))) == 0, perror("cfsetspeed"));
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ public:
|
|||||||
*
|
*
|
||||||
* @note This method should be called before reading and sending spinel frames to the interface.
|
* @note This method should be called before reading and sending spinel frames to the interface.
|
||||||
*
|
*
|
||||||
* @param[in] aPlatformConfig Platform configuration structure.
|
* @param[in] aArguments Arguments parsed from radio url.
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE The interface is initialized successfully
|
* @retval OT_ERROR_NONE The interface is initialized successfully
|
||||||
* @retval OT_ERROR_ALREADY The interface is already initialized.
|
* @retval OT_ERROR_ALREADY The interface is already initialized.
|
||||||
* @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run.
|
* @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
otError Init(const otPlatformConfig &aPlatformConfig);
|
otError Init(Arguments &aArguments);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method deinitializes the interface to the RCP.
|
* This method deinitializes the interface to the RCP.
|
||||||
@@ -198,7 +198,7 @@ private:
|
|||||||
static void HandleHdlcFrame(void *aContext, otError aError);
|
static void HandleHdlcFrame(void *aContext, otError aError);
|
||||||
void HandleHdlcFrame(otError aError);
|
void HandleHdlcFrame(otError aError);
|
||||||
|
|
||||||
static int OpenFile(const char *aFile, const char *aConfig);
|
static int OpenFile(const char *aFile, Arguments &aArguments);
|
||||||
#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
|
#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
|
||||||
static int ForkPty(const char *aCommand, const char *aArguments);
|
static int ForkPty(const char *aCommand, const char *aArguments);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
#include <openthread/error.h>
|
#include <openthread/error.h>
|
||||||
@@ -69,25 +70,9 @@ enum
|
|||||||
*/
|
*/
|
||||||
typedef struct otPlatformConfig
|
typedef struct otPlatformConfig
|
||||||
{
|
{
|
||||||
uint64_t mNodeId; ///< Unique node ID.
|
uint32_t mSpeedUpFactor; ///< Speed up factor.
|
||||||
uint32_t mSpeedUpFactor; ///< Speed up factor.
|
const char *mInterfaceName; ///< Thread network interface name.
|
||||||
const char *mInterfaceName; ///< Thread network interface name.
|
const char *mRadioUrl; ///< Radio url.
|
||||||
const char *mRadioFile; ///< Radio file path.
|
|
||||||
const char *mRadioConfig; ///< Radio configurations.
|
|
||||||
const char *mMaxPowerTable; ///< Radio max transmit power table.
|
|
||||||
bool mResetRadio; ///< Whether to reset RCP when initializing.
|
|
||||||
bool mRestoreDatasetFromNcp; ///< Whether to retrieve dataset from NCP and save to file.
|
|
||||||
|
|
||||||
char * mSpiGpioIntDevice; ///< Path to the Linux GPIO character device for the `I̅N̅T̅` pin.
|
|
||||||
char * mSpiGpioResetDevice; ///< Path to the Linux GPIO character device for the `R̅E̅S̅E̅T̅` pin.
|
|
||||||
uint8_t mSpiGpioIntLine; ///< Line index of the `I̅N̅T̅` pin for the associated GPIO character device.
|
|
||||||
uint8_t mSpiGpioResetLine; ///< Line index of the `R̅E̅S̅E̅T̅` pin for the associated GPIO character device.
|
|
||||||
uint8_t mSpiMode; ///< SPI mode to use (0-3).
|
|
||||||
uint32_t mSpiSpeed; ///< SPI speed in hertz.
|
|
||||||
uint32_t mSpiResetDelay; ///< The delay after R̅E̅S̅E̅T̅ assertion, in miliseconds.
|
|
||||||
uint16_t mSpiCsDelay; ///< The delay after SPI C̅S̅ assertion, in µsec.
|
|
||||||
uint8_t mSpiAlignAllowance; ///< Maximum number of 0xFF bytes to clip from start of MISO frame.
|
|
||||||
uint8_t mSpiSmallPacketSize; ///< Smallest SPI packet size we can receive in a single transaction.
|
|
||||||
} otPlatformConfig;
|
} otPlatformConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,6 +141,14 @@ int otSysMainloopPoll(otSysMainloopContext *aMainloop);
|
|||||||
*/
|
*/
|
||||||
void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop);
|
void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the radio url help string.
|
||||||
|
*
|
||||||
|
* @returns the radio url help string.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const char *otSysGetRadioUrlHelpString(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // end of extern "C"
|
} // end of extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
|
|
||||||
#include "common/logging.hpp"
|
#include "common/logging.hpp"
|
||||||
|
|
||||||
|
#include "radio_url.hpp"
|
||||||
#include "lib/platform/exit_code.h"
|
#include "lib/platform/exit_code.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,7 +163,7 @@ void platformAlarmAdvanceNow(uint64_t aDelta);
|
|||||||
* @param[in] aPlatformConfig Platform configuration structure.
|
* @param[in] aPlatformConfig Platform configuration structure.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void platformRadioInit(const otPlatformConfig *aPlatformConfig);
|
void platformRadioInit(otPosixRadioArguments *aArguments);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function shuts down the radio service used by OpenThread.
|
* This function shuts down the radio service used by OpenThread.
|
||||||
|
|||||||
@@ -94,18 +94,22 @@ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
|
|||||||
SuccessOrDie(sRadioSpinel.SetPromiscuous(aEnable));
|
SuccessOrDie(sRadioSpinel.SetPromiscuous(aEnable));
|
||||||
}
|
}
|
||||||
|
|
||||||
void platformRadioInit(const otPlatformConfig *aPlatformConfig)
|
void platformRadioInit(otPosixRadioArguments *aArguments)
|
||||||
{
|
{
|
||||||
|
ot::Posix::Arguments *args = reinterpret_cast<ot::Posix::Arguments *>(aArguments);
|
||||||
|
bool resetRadio = (args->GetValue("no-reset") == NULL);
|
||||||
|
bool restoreDataset = (args->GetValue("ncp-dataset") != NULL);
|
||||||
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
|
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
|
||||||
uint8_t channel = ot::Radio::kChannelMin;
|
uint8_t channel = ot::Radio::kChannelMin;
|
||||||
int8_t power = ot::Posix::MaxPowerTable::kPowerDefault;
|
int8_t power = ot::Posix::MaxPowerTable::kPowerDefault;
|
||||||
|
const char *maxPowerTable = args->GetValue("max-power-table");
|
||||||
|
|
||||||
if (aPlatformConfig->mMaxPowerTable != NULL)
|
if (maxPowerTable != NULL)
|
||||||
{
|
{
|
||||||
const char *str = NULL;
|
const char *str = NULL;
|
||||||
|
|
||||||
for (str = strtok(const_cast<char *>(aPlatformConfig->mMaxPowerTable), ",");
|
for (str = strtok(const_cast<char *>(maxPowerTable), ","); str != NULL && channel <= ot::Radio::kChannelMax;
|
||||||
str != NULL && channel <= ot::Radio::kChannelMax; str = strtok(NULL, ","))
|
str = strtok(NULL, ","))
|
||||||
{
|
{
|
||||||
power = static_cast<int8_t>(strtol(str, NULL, 0));
|
power = static_cast<int8_t>(strtol(str, NULL, 0));
|
||||||
sMaxPowerTable.SetTransmitPower(channel++, power);
|
sMaxPowerTable.SetTransmitPower(channel++, power);
|
||||||
@@ -122,8 +126,8 @@ void platformRadioInit(const otPlatformConfig *aPlatformConfig)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SuccessOrDie(sRadioSpinel.GetSpinelInterface().Init(*aPlatformConfig));
|
SuccessOrDie(sRadioSpinel.GetSpinelInterface().Init(*args));
|
||||||
sRadioSpinel.Init(aPlatformConfig->mResetRadio, aPlatformConfig->mRestoreDatasetFromNcp);
|
sRadioSpinel.Init(resetRadio, restoreDataset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void platformRadioDeinit(void)
|
void platformRadioDeinit(void)
|
||||||
|
|||||||
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 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 "posix/platform/radio_url.hpp"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <openthread/openthread-system.h>
|
||||||
|
|
||||||
|
#include "core/common/code_utils.hpp"
|
||||||
|
#include "posix/platform/platform-posix.h"
|
||||||
|
|
||||||
|
const char *otSysGetRadioUrlHelpString(void)
|
||||||
|
{
|
||||||
|
#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI
|
||||||
|
#define RADIO_URL_HELP_BUS \
|
||||||
|
"Radio URL:\n" \
|
||||||
|
"spinel+spi://${PATH_TO_SPI_DEVICE}?${arguments}\n" \
|
||||||
|
"arguments:\n" \
|
||||||
|
" gpio-int-device[=gpio-device-path]\n" \
|
||||||
|
" Specify a path to the Linux sysfs-exported GPIO device for the\n" \
|
||||||
|
" `I̅N̅T̅` pin. If not specified, `SPI` interface will fall back to\n" \
|
||||||
|
" polling, which is inefficient.\n" \
|
||||||
|
" gpio-int-line[=line-offset]\n" \
|
||||||
|
" The offset index of `I̅N̅T̅` pin for the associated GPIO device.\n" \
|
||||||
|
" If not specified, `SPI` interface will fall back to polling,\n" \
|
||||||
|
" which is inefficient.\n" \
|
||||||
|
" gpio-reset-dev[=gpio-device-path]\n" \
|
||||||
|
" Specify a path to the Linux sysfs-exported GPIO device for the\n" \
|
||||||
|
" `R̅E̅S̅` pin.\n" \
|
||||||
|
" gpio-reset-line[=line-offset]" \
|
||||||
|
" The offset index of `R̅E̅S̅` pin for the associated GPIO device.\n" \
|
||||||
|
" spi-mode[=mode] Specify the SPI mode to use (0-3).\n" \
|
||||||
|
" spi-speed[=hertz] Specify the SPI speed in hertz.\n" \
|
||||||
|
" spi-cs-delay[=usec] Specify the delay after C̅S̅ assertion, in µsec.\n" \
|
||||||
|
" spi-reset-delay[=ms] Specify the delay after R̅E̅S̅E̅T̅ assertion, in milliseconds.\n" \
|
||||||
|
" spi-align-allowance[=n] Specify the maximum number of 0xFF bytes to clip from start of\n" \
|
||||||
|
" MISO frame. Max value is 16.\n" \
|
||||||
|
" spi-small-packet=[n] Specify the smallest packet we can receive in a single transaction.\n" \
|
||||||
|
" (larger packets will require two transactions). Default value is 32.\n"
|
||||||
|
#else
|
||||||
|
#define RADIO_URL_HELP_BUS \
|
||||||
|
"Radio URL:\n" \
|
||||||
|
"spinel+hdlc+uart://${PATH_TO_UART_DEVICE}?${arguments} for real uart device\n" \
|
||||||
|
"spinel+hdlc+fortpty://${PATH_TO_UART_DEVICE}?${arguments} for forking a pty subprocess.\n" \
|
||||||
|
"arguments:\n" \
|
||||||
|
" uart-parity[=even|odd] Uart parity config, optional.\n" \
|
||||||
|
" uart-stop[=number-of-bits] Uart stop bit, default is 1.\n" \
|
||||||
|
" baudrate[=baudrate] Uart baud rate, default is 115200.\n" \
|
||||||
|
" arg[=argument string] Command line arguments for subprocess, can be repeated.\n"
|
||||||
|
#endif
|
||||||
|
return RADIO_URL_HELP_BUS " no-reset Skip resetting the radio device.\n"
|
||||||
|
" ncp-dataset Retrieve dataset from ncp.\n"
|
||||||
|
" max-power-table Max power table for each channel, splitted by comma.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ot {
|
||||||
|
namespace Posix {
|
||||||
|
|
||||||
|
Arguments::Arguments(const char *aUrl)
|
||||||
|
{
|
||||||
|
char *url = &mUrl[0];
|
||||||
|
|
||||||
|
mPath = NULL;
|
||||||
|
mStart = NULL;
|
||||||
|
mEnd = NULL;
|
||||||
|
|
||||||
|
VerifyOrExit(aUrl != NULL, OT_NOOP);
|
||||||
|
VerifyOrExit(strnlen(aUrl, sizeof(mUrl)) < sizeof(mUrl), OT_NOOP);
|
||||||
|
strncpy(mUrl, aUrl, sizeof(mUrl) - 1);
|
||||||
|
url = strstr(url, "://");
|
||||||
|
VerifyOrExit(url != NULL, OT_NOOP);
|
||||||
|
url += sizeof("://") - 1;
|
||||||
|
mPath = url;
|
||||||
|
|
||||||
|
mStart = strstr(url, "?");
|
||||||
|
|
||||||
|
if (mStart != NULL)
|
||||||
|
{
|
||||||
|
mStart[0] = '\0';
|
||||||
|
mStart++;
|
||||||
|
|
||||||
|
mEnd = mStart + strlen(mStart);
|
||||||
|
|
||||||
|
for (char *cur = strtok(mStart, "&"); cur != NULL; cur = strtok(NULL, "&"))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mEnd = url + strlen(url);
|
||||||
|
mStart = mEnd;
|
||||||
|
}
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Arguments::GetValue(const char *aName, const char *aLastValue)
|
||||||
|
{
|
||||||
|
const char * rval = NULL;
|
||||||
|
const size_t len = strlen(aName);
|
||||||
|
char * start = (aLastValue == NULL ? mStart : (const_cast<char *>(aLastValue) + strlen(aLastValue) + 1));
|
||||||
|
|
||||||
|
while (start < mEnd)
|
||||||
|
{
|
||||||
|
char *last = NULL;
|
||||||
|
|
||||||
|
if (!strncmp(aName, start, len))
|
||||||
|
{
|
||||||
|
if (start[len] == '=')
|
||||||
|
{
|
||||||
|
ExitNow(rval = &start[len + 1]);
|
||||||
|
}
|
||||||
|
else if (start[len] == '&' || start[len] == '\0')
|
||||||
|
{
|
||||||
|
ExitNow(rval = "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last = start;
|
||||||
|
start = last + strlen(last) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Posix
|
||||||
|
} // namespace ot
|
||||||
|
|
||||||
|
#ifndef SELF_TEST
|
||||||
|
#define SELF_TEST 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SELF_TEST
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
void TestSimple()
|
||||||
|
{
|
||||||
|
char url[] = "spinel:///dev/ttyUSB0?baudrate=115200";
|
||||||
|
ot::Posix::Arguments args(url);
|
||||||
|
|
||||||
|
assert(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
|
||||||
|
assert(!strcmp(args.GetValue("baudrate"), "115200"));
|
||||||
|
|
||||||
|
printf("PASS %s\r\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSimpleNoArguments()
|
||||||
|
{
|
||||||
|
char url[] = "spinel:///dev/ttyUSB0";
|
||||||
|
ot::Posix::Arguments args(url);
|
||||||
|
|
||||||
|
assert(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
|
||||||
|
|
||||||
|
printf("PASS %s\r\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestMultipleProtocols()
|
||||||
|
{
|
||||||
|
char url[] = "spinel+spi:///dev/ttyUSB0?baudrate=115200";
|
||||||
|
ot::Posix::Arguments args(url);
|
||||||
|
|
||||||
|
assert(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
|
||||||
|
assert(!strcmp(args.GetValue("baudrate"), "115200"));
|
||||||
|
|
||||||
|
printf("PASS %s\r\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestMultipleProtocolsAndDuplicateParameters()
|
||||||
|
{
|
||||||
|
char url[] = "spinel+exec:///path/to/ot-rcp?arg=1&arg=arg2&arg=3";
|
||||||
|
ot::Posix::Arguments args(url);
|
||||||
|
const char * arg = NULL;
|
||||||
|
|
||||||
|
assert(!strcmp(args.GetPath(), "/path/to/ot-rcp"));
|
||||||
|
|
||||||
|
arg = args.GetValue("arg");
|
||||||
|
assert(!strcmp(arg, "1"));
|
||||||
|
|
||||||
|
arg = args.GetValue("arg", arg);
|
||||||
|
assert(!strcmp(arg, "arg2"));
|
||||||
|
|
||||||
|
arg = args.GetValue("arg", arg);
|
||||||
|
assert(!strcmp(arg, "3"));
|
||||||
|
|
||||||
|
printf("PASS %s\r\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
TestSimple();
|
||||||
|
TestSimpleNoArguments();
|
||||||
|
TestMultipleProtocols();
|
||||||
|
TestMultipleProtocolsAndDuplicateParameters();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SELF_TEST
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef POSIX_PLATFORM_RADIO_URL_HPP_
|
||||||
|
#define POSIX_PLATFORM_RADIO_URL_HPP_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <openthread/openthread-system.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
typedef struct otPosixRadioArguments
|
||||||
|
{
|
||||||
|
const char *mPath; ///< The path to the executable or device
|
||||||
|
} otPosixRadioArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ot {
|
||||||
|
namespace Posix {
|
||||||
|
|
||||||
|
class Arguments : public otPosixRadioArguments
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Arguments(const char *aUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the path in url
|
||||||
|
*
|
||||||
|
* @returns The path in url.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const char *GetPath(void) const { return mPath; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the url agument value.
|
||||||
|
*
|
||||||
|
* @param[in] aName Argument name.
|
||||||
|
* @param[in] aLastValue The last iterated argument value, NULL for first value.
|
||||||
|
*
|
||||||
|
* @returns The argument value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const char *GetValue(const char *aName, const char *aLastValue = NULL);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kRadioUrlMaxSize = 512,
|
||||||
|
};
|
||||||
|
char mUrl[kRadioUrlMaxSize];
|
||||||
|
|
||||||
|
char *mStart;
|
||||||
|
char *mEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Posix
|
||||||
|
} // namespace ot
|
||||||
|
|
||||||
|
#endif // POSIX_PLATFORM_RADIO_URL_HPP_
|
||||||
@@ -91,32 +91,91 @@ SpiInterface::SpiInterface(SpinelInterface::ReceiveFrameCallback aCallback,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
otError SpiInterface::Init(const otPlatformConfig &aPlatformConfig)
|
otError SpiInterface::Init(Arguments &aArguments)
|
||||||
{
|
{
|
||||||
VerifyOrDie(aPlatformConfig.mSpiAlignAllowance <= kSpiAlignAllowanceMax, OT_EXIT_FAILURE);
|
const char *spiGpioIntDevice;
|
||||||
|
const char *spiGpioResetDevice;
|
||||||
|
uint8_t spiGpioIntLine = 0;
|
||||||
|
uint8_t spiGpioResetLine = 0;
|
||||||
|
uint8_t spiMode = OT_PLATFORM_CONFIG_SPI_DEFAULT_MODE;
|
||||||
|
uint32_t spiSpeed = SPI_IOC_WR_MAX_SPEED_HZ;
|
||||||
|
uint32_t spiResetDelay = OT_PLATFORM_CONFIG_SPI_DEFAULT_RESET_DELAY_MS;
|
||||||
|
uint16_t spiCsDelay = OT_PLATFORM_CONFIG_SPI_DEFAULT_CS_DELAY_US;
|
||||||
|
uint8_t spiAlignAllowance = OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE;
|
||||||
|
uint8_t spiSmallPacketSize = OT_PLATFORM_CONFIG_SPI_DEFAULT_SMALL_PACKET_SIZE;
|
||||||
|
|
||||||
mSpiCsDelayUs = aPlatformConfig.mSpiCsDelay;
|
spiGpioIntDevice = aArguments.GetValue("gpio-int-device");
|
||||||
mSpiSmallPacketSize = aPlatformConfig.mSpiSmallPacketSize;
|
spiGpioResetDevice = aArguments.GetValue("gpio-reset-device");
|
||||||
mSpiAlignAllowance = aPlatformConfig.mSpiAlignAllowance;
|
if (!spiGpioIntDevice || !spiGpioResetDevice)
|
||||||
|
{
|
||||||
|
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
||||||
|
}
|
||||||
|
|
||||||
if (aPlatformConfig.mSpiGpioIntDevice != NULL)
|
if (aArguments.GetValue("gpio-int-line"))
|
||||||
|
{
|
||||||
|
spiGpioIntLine = static_cast<uint8_t>(atoi(aArguments.GetValue("gpio-int-line")));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
||||||
|
}
|
||||||
|
if (aArguments.GetValue("gpio-reset-line"))
|
||||||
|
{
|
||||||
|
spiGpioResetLine = static_cast<uint8_t>(atoi(aArguments.GetValue("gpio-reset-line")));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DieNow(OT_EXIT_INVALID_ARGUMENTS);
|
||||||
|
}
|
||||||
|
if (aArguments.GetValue("spi-mode"))
|
||||||
|
{
|
||||||
|
spiMode = static_cast<uint8_t>(atoi(aArguments.GetValue("spi-mode")));
|
||||||
|
}
|
||||||
|
if (aArguments.GetValue("spi-speed"))
|
||||||
|
{
|
||||||
|
spiSpeed = static_cast<uint32_t>(atoi(aArguments.GetValue("spi-speed")));
|
||||||
|
}
|
||||||
|
if (aArguments.GetValue("spi-reset-delay"))
|
||||||
|
{
|
||||||
|
spiResetDelay = static_cast<uint32_t>(atoi(aArguments.GetValue("spi-reset-delay")));
|
||||||
|
}
|
||||||
|
if (aArguments.GetValue("spi-cs-delay"))
|
||||||
|
{
|
||||||
|
spiCsDelay = static_cast<uint16_t>(atoi(aArguments.GetValue("spi-cs-delay")));
|
||||||
|
}
|
||||||
|
if (aArguments.GetValue("spi-align-allowance"))
|
||||||
|
{
|
||||||
|
spiAlignAllowance = static_cast<uint8_t>(atoi(aArguments.GetValue("spi-align-allowance")));
|
||||||
|
}
|
||||||
|
if (aArguments.GetValue("spi-small-packet"))
|
||||||
|
{
|
||||||
|
spiSmallPacketSize = static_cast<uint8_t>(atoi(aArguments.GetValue("spi-small-packet")));
|
||||||
|
}
|
||||||
|
|
||||||
|
VerifyOrDie(spiAlignAllowance <= kSpiAlignAllowanceMax, OT_EXIT_FAILURE);
|
||||||
|
|
||||||
|
mSpiCsDelayUs = spiCsDelay;
|
||||||
|
mSpiSmallPacketSize = spiSmallPacketSize;
|
||||||
|
mSpiAlignAllowance = spiAlignAllowance;
|
||||||
|
|
||||||
|
if (spiGpioIntDevice != NULL)
|
||||||
{
|
{
|
||||||
// If the interrupt pin is not set, SPI interface will use polling mode.
|
// If the interrupt pin is not set, SPI interface will use polling mode.
|
||||||
InitIntPin(aPlatformConfig.mSpiGpioIntDevice, aPlatformConfig.mSpiGpioIntLine);
|
InitIntPin(spiGpioIntDevice, spiGpioIntLine);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
otLogNotePlat("SPI interface enters polling mode.");
|
otLogNotePlat("SPI interface enters polling mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
InitResetPin(aPlatformConfig.mSpiGpioResetDevice, aPlatformConfig.mSpiGpioResetLine);
|
InitResetPin(spiGpioResetDevice, spiGpioResetLine);
|
||||||
InitSpiDev(aPlatformConfig.mRadioFile, aPlatformConfig.mSpiMode, aPlatformConfig.mSpiSpeed);
|
InitSpiDev(aArguments.GetPath(), spiMode, spiSpeed);
|
||||||
|
|
||||||
// Reset RCP chip.
|
// Reset RCP chip.
|
||||||
TrigerReset();
|
TrigerReset();
|
||||||
|
|
||||||
// Waiting for the RCP chip starts up.
|
// Waiting for the RCP chip starts up.
|
||||||
usleep(static_cast<useconds_t>(aPlatformConfig.mSpiResetDelay) * kUsecPerMsec);
|
usleep(static_cast<useconds_t>(spiResetDelay) * kUsecPerMsec);
|
||||||
|
|
||||||
return OT_ERROR_NONE;
|
return OT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,14 +79,14 @@ public:
|
|||||||
*
|
*
|
||||||
* @note This method should be called before reading and sending spinel frames to the interface.
|
* @note This method should be called before reading and sending spinel frames to the interface.
|
||||||
*
|
*
|
||||||
* @param[in] aPlatformConfig Platform configuration structure.
|
* @param[in] aArguments Arguments parsed from radio url.
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE The interface is initialized successfully.
|
* @retval OT_ERROR_NONE The interface is initialized successfully.
|
||||||
* @retval OT_ERROR_ALREADY The interface is already initialized.
|
* @retval OT_ERROR_ALREADY The interface is already initialized.
|
||||||
* @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run.
|
* @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
otError Init(const otPlatformConfig &aPlatformConfig);
|
otError Init(Arguments &aArguments);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method deinitializes the interface to the RCP.
|
* This method deinitializes the interface to the RCP.
|
||||||
|
|||||||
@@ -49,13 +49,16 @@ uint64_t gNodeId = 0;
|
|||||||
|
|
||||||
otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
|
otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
|
||||||
{
|
{
|
||||||
otInstance *instance = NULL;
|
otInstance * instance = NULL;
|
||||||
|
ot::Posix::Arguments args(aPlatformConfig->mRadioUrl);
|
||||||
|
|
||||||
#if OPENTHREAD_POSIX_VIRTUAL_TIME
|
#if OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||||
virtualTimeInit(static_cast<uint16_t>(atoi(aPlatformConfig->mRadioConfig)));
|
virtualTimeInit(static_cast<uint16_t>(atoi(args.GetValue("arg"))));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
VerifyOrDie(args.GetPath() != NULL, OT_EXIT_INVALID_ARGUMENTS);
|
||||||
platformAlarmInit(aPlatformConfig->mSpeedUpFactor);
|
platformAlarmInit(aPlatformConfig->mSpeedUpFactor);
|
||||||
platformRadioInit(aPlatformConfig);
|
platformRadioInit(&args);
|
||||||
platformRandomInit();
|
platformRandomInit();
|
||||||
|
|
||||||
instance = otInstanceInitSingle();
|
instance = otInstanceInitSingle();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
|
|
||||||
spawn $env(OT_COMMAND) $env(RCP_COMMAND) 1
|
spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?arg=1"
|
||||||
set timeout 1
|
set timeout 1
|
||||||
expect_after {
|
expect_after {
|
||||||
timeout { exit 1 }
|
timeout { exit 1 }
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# allows 11-25 and forbidden 26
|
# allows 11-25 and forbidden 26
|
||||||
spawn $env(OT_COMMAND) --max-power-table 11,12,13,14,15,16,17,18,19,20,21,22,23,24,-1,0x7f $env(RCP_COMMAND) 1
|
spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?max-power-table=11,12,13,14,15,16,17,18,19,20,21,22,23,24,-1,0x7f&arg=1"
|
||||||
set timeout 1
|
set timeout 1
|
||||||
expect_after {
|
expect_after {
|
||||||
timeout { exit 1 }
|
timeout { exit 1 }
|
||||||
@@ -42,7 +42,7 @@ expect "Done"
|
|||||||
send "\x04"
|
send "\x04"
|
||||||
expect eof
|
expect eof
|
||||||
# allows all channels by default
|
# allows all channels by default
|
||||||
spawn $env(OT_COMMAND) $env(RCP_COMMAND) 1
|
spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?arg=1"
|
||||||
set timeout 1
|
set timeout 1
|
||||||
expect_after {
|
expect_after {
|
||||||
timeout { exit 1 }
|
timeout { exit 1 }
|
||||||
|
|||||||
@@ -108,7 +108,8 @@ class Node:
|
|||||||
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
|
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
|
||||||
|
|
||||||
if 'RADIO_DEVICE' in os.environ:
|
if 'RADIO_DEVICE' in os.environ:
|
||||||
cmd += ' -v %s' % os.environ['RADIO_DEVICE']
|
cmd += ' -v spinel+hdlc+uart://%s?arg=%d' % (
|
||||||
|
os.environ['RADIO_DEVICE'], nodeid)
|
||||||
|
|
||||||
# Load Thread 1.1 node when testing Thread 1.2 scenarios for interoperability
|
# Load Thread 1.1 node when testing Thread 1.2 scenarios for interoperability
|
||||||
elif self.version == '1.1':
|
elif self.version == '1.1':
|
||||||
@@ -120,7 +121,8 @@ class Node:
|
|||||||
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
|
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
|
||||||
|
|
||||||
if 'RADIO_DEVICE_1_1' in os.environ:
|
if 'RADIO_DEVICE_1_1' in os.environ:
|
||||||
cmd += ' -v %s' % os.environ['RADIO_DEVICE_1_1']
|
cmd += ' -v spinel+hdlc+uart://%s?arg=%d' % (
|
||||||
|
os.environ['RADIO_DEVICE_1_1'], nodeid)
|
||||||
|
|
||||||
cmd += ' %d' % nodeid
|
cmd += ' %d' % nodeid
|
||||||
print("%s" % cmd)
|
print("%s" % cmd)
|
||||||
@@ -146,7 +148,8 @@ class Node:
|
|||||||
# If Thread version of node matches the testing environment version.
|
# If Thread version of node matches the testing environment version.
|
||||||
if self.version == self.env_version:
|
if self.version == self.env_version:
|
||||||
if 'RADIO_DEVICE' in os.environ:
|
if 'RADIO_DEVICE' in os.environ:
|
||||||
args = ' %s' % os.environ['RADIO_DEVICE']
|
args = ' spinel+hdlc+uart://%s?arg=%d' % (
|
||||||
|
os.environ['RADIO_DEVICE'], nodeid)
|
||||||
else:
|
else:
|
||||||
args = ''
|
args = ''
|
||||||
|
|
||||||
@@ -184,7 +187,8 @@ class Node:
|
|||||||
# Load Thread 1.1 node when testing Thread 1.2 scenarios for interoperability.
|
# Load Thread 1.1 node when testing Thread 1.2 scenarios for interoperability.
|
||||||
elif self.version == '1.1':
|
elif self.version == '1.1':
|
||||||
if 'RADIO_DEVICE_1_1' in os.environ:
|
if 'RADIO_DEVICE_1_1' in os.environ:
|
||||||
args = ' %s' % os.environ['RADIO_DEVICE_1_1']
|
args = ' spinel+hdlc+uart://%s?arg=%d' % (
|
||||||
|
os.environ['RADIO_DEVICE_1_1'], nodeid)
|
||||||
else:
|
else:
|
||||||
args = ''
|
args = ''
|
||||||
|
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ class Node(object):
|
|||||||
self._use_posix_with_rcp = False
|
self._use_posix_with_rcp = False
|
||||||
|
|
||||||
if self._use_posix_with_rcp:
|
if self._use_posix_with_rcp:
|
||||||
ncp_socket_path = 'system:{} -s {} {} {}'.format(
|
ncp_socket_path = 'system:{} -s {} spinel+hdlc+uart://{}?arg={}'.format(
|
||||||
self._OT_NCP_FTD_POSIX, self._SPEED_UP_FACTOR, self._OT_RCP,
|
self._OT_NCP_FTD_POSIX, self._SPEED_UP_FACTOR, self._OT_RCP,
|
||||||
index)
|
index)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user