[posix] add argument to set max power table (#4878)

This commit adds a max power table for POSIX platform, which can
customize the max allowed transmit power of each channel with the
command line argument --max-power-table.
This commit is contained in:
Yakun Xu
2020-05-01 05:23:16 +08:00
committed by GitHub
parent c4b098f0d3
commit 7b0cb98445
16 changed files with 273 additions and 10 deletions
+1
View File
@@ -150,6 +150,7 @@ jobs:
run: |
sudo apt --no-install-recommends install -y expect ninja-build
./script/test build expect
VIRTUAL_TIME=0 NODE_MODE=rcp ./script/test clean build expect
- name: Codecov
uses: codecov/codecov-action@v1
+7 -3
View File
@@ -48,7 +48,7 @@ at_exit() {
build() {
make -f examples/Makefile-simulation
make -f src/posix/Makefile-posix PLATFORM_NETIF=1 PLATFORM_UDP=1 UDP_FORWARD=0
make -f src/posix/Makefile-posix PLATFORM_NETIF=1 PLATFORM_UDP=1 UDP_FORWARD=0 MAX_POWER_TABLE=1
}
check() {
@@ -75,12 +75,16 @@ check() {
# Cover setting a valid network interface name.
readonly VALID_NETIF_NAME="wan$(date +%H%M%S)"
local options=(
'--max-power-table=11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26'
)
if [[ "${DAEMON}" = 1 ]]; then
sudo "$(pwd)/$(ls output/posix/*linux*/bin/ot-daemon)" -I "${VALID_NETIF_NAME}" ${CORE_PTY} &
sudo "$(pwd)/$(ls output/posix/*linux*/bin/ot-daemon)" "${options[@]}" -I "${VALID_NETIF_NAME}" ${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) ${CORE_PTY}"
OT_CLI_CMD="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli) "${options[@]}" ${CORE_PTY}"
fi
sudo ${OT_CLI_CMD} -I "${VALID_NETIF_NAME}" -n
+9 -3
View File
@@ -122,6 +122,7 @@ build_posix()
options+=(
"-DOT_PLATFORM=posix"
"-DOT_POSIX_MAX_POWER_TABLE=ON"
"-DOT_READLINE=readline"
"-DOT_THREAD_VERSION=${version}"
)
@@ -250,16 +251,21 @@ do_cert_suite() {
do_expect()
{
local ot_command
local rcp_command=
local test_pattern
if [[ "${NODE_MODE}" == rcp ]]; then
ot_command="${OT_CLI_PATH} ${RADIO_DEVICE}"
ot_command="${OT_CLI_PATH}"
rcp_command="${RADIO_DEVICE}"
test_pattern='posix-*.exp'
else
ot_command="${OT_BUILDDIR}/cmake/openthread-simulation-${THREAD_VERSION}/examples/apps/cli/ot-cli-ftd"
test_pattern='cli-*.exp'
fi
while read -r script; do
rm -rf tmp
OT_COMMAND="${ot_command}" "${script}" || {
OT_COMMAND="${ot_command}" RCP_COMMAND="${rcp_command}" "${script}" || {
local exit_code=$?
echo -e "${COLOR_FAIL}FAIL${COLOR_NONE} ${script}"
exit "${exit_code}"
@@ -269,7 +275,7 @@ do_expect()
if [[ $# != 0 ]]; then
for script in "$@"; do echo ${script}; done
else
find tests/scripts/expect -type f -executable
find tests/scripts/expect -type f -executable -name "${test_pattern}"
fi
)
+8
View File
@@ -286,6 +286,14 @@ public:
*/
otRadioState GetState(void) const;
/**
* This method gets the current receiving channel.
*
* @returns Current receiving channel.
*
*/
uint8_t GetChannel(void) const { return mChannel; }
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
/**
* Enable the radio coex.
+5
View File
@@ -58,6 +58,7 @@ LEGACY ?= 1
LINK_RAW ?= 0
LOG_OUTPUT ?= PLATFORM_DEFINED
MAC_FILTER ?= 1
MAX_POWER_TABLE ?= 1
MTD_NETDIAG ?= 1
READLINE ?= readline
REFERENCE_DEVICE ?= 1
@@ -95,6 +96,10 @@ ifneq ($(HOST),)
configure_OPTIONS += --host=$(HOST)
endif
ifeq ($(MAX_POWER_TABLE),1)
COMMONCFLAGS += -DOPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE=1
endif
ifeq ($(PLATFORM_NETIF),1)
COMMONCFLAGS += -DOPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1
endif
+2
View File
@@ -41,6 +41,7 @@ target_include_directories(ot-daemon PRIVATE ${COMMON_INCLUDES})
target_compile_definitions(ot-daemon PRIVATE
OPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_CLI
${OT_PLATFORM_DEFINES}
)
target_compile_options(ot-daemon PRIVATE
@@ -69,6 +70,7 @@ set_target_properties(
target_compile_definitions(ot-ctl PRIVATE
$<$<BOOL:${READLINE}>:HAVE_LIB$<UPPER_CASE:${OT_READLINE}>=1>
${OT_PLATFORM_DEFINES}
)
target_compile_options(ot-ctl PRIVATE
+17
View File
@@ -113,6 +113,8 @@ enum
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'},
@@ -124,6 +126,9 @@ static const struct option kOptions[] = {{"debug-level", required_argument, NULL
{"ncp-dataset", no_argument, NULL, ARG_RESTORE_NCP_DATASET},
{"time-speed", required_argument, NULL, 's'},
{"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},
@@ -177,6 +182,13 @@ static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
" 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
fprintf(aStream,
" --max-power-table Max power for channels in ascending order separated by commas,\n"
" If the number of values is less than that of supported channels,\n"
" the last value will be applied to all remaining channels.\n"
" Special value 0x7f disables a channel.\n");
#endif
exit(aExitCode);
}
@@ -276,6 +288,11 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
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 '?':
PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
break;
+6 -1
View File
@@ -35,7 +35,12 @@ endif()
option(OT_POSIX_VIRTUAL_TIME "enable virtual time" OFF)
if(OT_POSIX_VIRTUAL_TIME)
list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_POSIX_VIRTUAL_TIME=1")
list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_POSIX_VIRTUAL_TIME=1")
endif()
option(OT_POSIX_MAX_POWER_TABLE "enable max power table" OFF)
if(OT_POSIX_MAX_POWER_TABLE)
list(APPEND OT_PLATFORM_DEFINES "OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE=1")
endif()
set(OT_POSIX_CONFIG_RCP_BUS "" CACHE STRING "RCP bus type")
@@ -74,6 +74,7 @@ typedef struct otPlatformConfig
const char *mInterfaceName; ///< Thread network interface name.
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.
+93
View File
@@ -0,0 +1,93 @@
/*
* 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 OT_POSIX_PLATFORM_MAX_POWER_TABLE_HPP_
#define OT_POSIX_PLATFORM_MAX_POWER_TABLE_HPP_
#include "core/radio/radio.hpp"
namespace ot {
namespace Posix {
class MaxPowerTable
{
public:
static const int8_t kPowerDefault = 30; ///< Default power 1 watt (30 dBm).
MaxPowerTable(void) { memset(mPowerTable, kPowerForbidden, sizeof(mPowerTable)); }
/**
* This method gets the max allowed transmit power of channel @p aChannel.
*
* @params[in] aChannel The radio channel number.
*
* @returns The max allowed transmit power in dBm.
*
*/
int8_t GetTransmitPower(uint8_t aChannel) const { return mPowerTable[aChannel - Radio::kChannelMin]; }
/**
* This method sets the max allowed transmit power of channel @p aChannel.
*
* @params[in] aChannel The radio channel number.
* @params[in] aPower The max allowed transmit power in dBm.
*
*/
void SetTransmitPower(uint8_t aChannel, int8_t aPower) { mPowerTable[aChannel - Radio::kChannelMin] = aPower; }
/**
* This method gets the allowed channel masks.
*
* All channels of max power value of 0x7f is considered forbidden.
*
*/
uint32_t GetAllowedChannelMask(void) const
{
uint32_t channelMask = 0;
for (uint8_t i = Radio::kChannelMin; i <= Radio::kChannelMax; ++i)
{
if (mPowerTable[i - Radio::kChannelMin] != kPowerForbidden)
{
channelMask |= (1 << i);
}
}
return channelMask;
}
private:
static const int8_t kPowerForbidden = 0x7f;
int8_t mPowerTable[Radio::kChannelMax - Radio::kChannelMin + 1];
};
} // namespace Posix
} // namespace ot
#endif // OT_POSIX_PLATFORM_MAX_POWER_TABLE_HPP_
@@ -91,4 +91,14 @@
#define OPENTHREAD_POSIX_CONFIG_RCP_BUS OT_POSIX_RCP_BUS_UART
#endif
/**
* @def OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
*
* Define as 1 to enable max power table support.
*
*/
#ifndef OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
#define OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE 0
#endif
#endif // OPENTHREAD_PLATFORM_CONFIG_H_
+56 -3
View File
@@ -32,6 +32,7 @@
*/
#include "platform-posix.h"
#include "lib/spinel/radio_spinel.hpp"
#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART
@@ -50,6 +51,12 @@ static ot::Spinel::RadioSpinel<ot::Posix::SpiInterface, RadioProcessContext> sRa
#error "OPENTHREAD_POSIX_CONFIG_RCP_BUS only allows OT_POSIX_RCP_BUS_UART and OT_POSIX_RCP_BUS_SPI!"
#endif
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
#include "posix/platform/max_power_table.hpp"
static ot::Posix::MaxPowerTable sMaxPowerTable;
#endif
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
OT_UNUSED_VARIABLE(aInstance);
@@ -89,6 +96,32 @@ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
void platformRadioInit(const otPlatformConfig *aPlatformConfig)
{
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
uint8_t channel = ot::Radio::kChannelMin;
int8_t power = ot::Posix::MaxPowerTable::kPowerDefault;
if (aPlatformConfig->mMaxPowerTable != NULL)
{
const char *str = NULL;
for (str = strtok(const_cast<char *>(aPlatformConfig->mMaxPowerTable), ",");
str != NULL && channel <= ot::Radio::kChannelMax; str = strtok(NULL, ","))
{
power = static_cast<int8_t>(strtol(str, NULL, 0));
sMaxPowerTable.SetTransmitPower(channel++, power);
}
VerifyOrDie(str == NULL, OT_EXIT_INVALID_ARGUMENTS);
}
// Use the last power if omitted.
while (channel <= ot::Radio::kChannelMax)
{
sMaxPowerTable.SetTransmitPower(channel, power);
++channel;
}
#endif
SuccessOrDie(sRadioSpinel.GetSpinelInterface().Init(*aPlatformConfig));
sRadioSpinel.Init(aPlatformConfig->mResetRadio, aPlatformConfig->mRestoreDatasetFromNcp);
}
@@ -124,7 +157,19 @@ otError otPlatRadioSleep(otInstance *aInstance)
otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
OT_UNUSED_VARIABLE(aInstance);
return sRadioSpinel.Receive(aChannel);
otError error;
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
if (sRadioSpinel.GetChannel() != aChannel)
{
SuccessOrExit(error = otPlatRadioSetTransmitPower(aInstance, sMaxPowerTable.GetTransmitPower(aChannel)));
}
#endif
SuccessOrExit(error = sRadioSpinel.Receive(aChannel));
exit:
return error;
}
otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
@@ -403,13 +448,21 @@ void otPlatDiagAlarmCallback(otInstance *aInstance)
uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return sRadioSpinel.GetRadioChannelMask(false);
return
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
sMaxPowerTable.GetAllowedChannelMask() &
#endif
sRadioSpinel.GetRadioChannelMask(false);
}
uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return sRadioSpinel.GetRadioChannelMask(true);
return
#if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
sMaxPowerTable.GetAllowedChannelMask() &
#endif
sRadioSpinel.GetRadioChannelMask(true);
}
otRadioState otPlatRadioGetState(otInstance *aInstance)
+2
View File
@@ -43,6 +43,7 @@ target_include_directories(ot-cli PRIVATE ${COMMON_INCLUDES})
target_compile_definitions(ot-cli PRIVATE
$<$<BOOL:${READLINE}>:HAVE_LIB$<UPPER_CASE:${OT_READLINE}>=1>
OPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_CLI
${OT_PLATFORM_DEFINES}
)
target_compile_options(ot-cli PRIVATE
@@ -74,6 +75,7 @@ target_include_directories(ot-ncp PRIVATE ${COMMON_INCLUDES})
target_compile_definitions(ot-ncp PRIVATE
OPENTHREAD_POSIX_APP_TYPE=OT_POSIX_APP_TYPE_NCP
${OT_PLATFORM_DEFINES}
)
target_compile_options(ot-ncp PRIVATE
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/expect -f
#
# 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.
#
# 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
set timeout 1
expect_after {
timeout { exit 1 }
}
send "channel supported\n"
expect "0x3fff800"
expect "Done"
send "channel preferred\n"
expect "0x3fff800"
expect "Done"
send "\x04"
expect eof
# allows all channels by default
spawn $env(OT_COMMAND) $env(RCP_COMMAND) 1
set timeout 1
expect_after {
timeout { exit 1 }
}
send "channel supported\n"
expect "0x7fff800"
expect "Done"
send "channel preferred\n"
expect "0x7fff800"
expect "Done"
send_user "\r\n"