diff --git a/src/ncp/ncp_host.cpp b/src/ncp/ncp_host.cpp index ddefe8581bb..4a37a2740e5 100644 --- a/src/ncp/ncp_host.cpp +++ b/src/ncp/ncp_host.cpp @@ -182,6 +182,15 @@ void NcpHost::GetChannelMasks(const ChannelMasksReceiver &aReceiver, const Async mTaskRunner.Post([aErrReceiver](void) { aErrReceiver(OT_ERROR_NOT_IMPLEMENTED, "Not implemented!"); }); } +void NcpHost::SetChannelMaxPowers(const std::vector &aChannelMaxPowers, + const AsyncResultReceiver &aReceiver) +{ + OT_UNUSED_VARIABLE(aChannelMaxPowers); + + // TODO: Implement SetChannelMaxPowers under NCP mode. + mTaskRunner.Post([aReceiver](void) { aReceiver(OT_ERROR_NOT_IMPLEMENTED, "Not implemented!"); }); +} + void NcpHost::Process(const MainloopContext &aMainloop) { mSpinelDriver.Process(&aMainloop); diff --git a/src/ncp/ncp_host.hpp b/src/ncp/ncp_host.hpp index 16f21669276..d5482a42dee 100644 --- a/src/ncp/ncp_host.hpp +++ b/src/ncp/ncp_host.hpp @@ -93,6 +93,8 @@ class NcpHost : public MainloopProcessor, public ThreadHost, public NcpNetworkPr void SetThreadEnabled(bool aEnabled, const AsyncResultReceiver aReceiver) override; void SetCountryCode(const std::string &aCountryCode, const AsyncResultReceiver &aReceiver) override; void GetChannelMasks(const ChannelMasksReceiver &aReceiver, const AsyncResultReceiver &aErrReceiver) override; + void SetChannelMaxPowers(const std::vector &aChannelMaxPowers, + const AsyncResultReceiver &aReceiver) override; CoprocessorType GetCoprocessorType(void) override { return OT_COPROCESSOR_NCP; } const char *GetCoprocessorVersion(void) override; const char *GetInterfaceName(void) const override { return mConfig.mInterfaceName; } diff --git a/src/ncp/rcp_host.cpp b/src/ncp/rcp_host.cpp index 0ff0cf94e04..4b3e5951ecf 100644 --- a/src/ncp/rcp_host.cpp +++ b/src/ncp/rcp_host.cpp @@ -31,6 +31,7 @@ #include "ncp/rcp_host.hpp" #include +#include #include #include @@ -487,6 +488,34 @@ void RcpHost::GetChannelMasks(const ChannelMasksReceiver &aReceiver, const Async } } +void RcpHost::SetChannelMaxPowers(const std::vector &aChannelMaxPowers, + const AsyncResultReceiver &aReceiver) +{ + otError error = OT_ERROR_NONE; + std::string errorMsg; + + VerifyOrExit(mInstance != nullptr, error = OT_ERROR_INVALID_STATE, errorMsg = "OT is not initialized"); + + for (ChannelMaxPower channelMaxPower : aChannelMaxPowers) + { + VerifyOrExit((channelMaxPower.mChannel >= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN) && + (channelMaxPower.mChannel <= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX), + error = OT_ERROR_INVALID_ARGS, errorMsg = "The channel is invalid"); + } + + for (ChannelMaxPower channelMaxPower : aChannelMaxPowers) + { + otbrLogInfo("Set channel max power: channel=%u, maxPower=%u", static_cast(channelMaxPower.mChannel), + static_cast(channelMaxPower.mMaxPower)); + SuccessOrExit(error = otPlatRadioSetChannelTargetPower( + mInstance, static_cast(channelMaxPower.mChannel), channelMaxPower.mMaxPower), + errorMsg = "Failed to set channel max power"); + } + +exit: + mTaskRunner.Post([aReceiver, error, errorMsg](void) { aReceiver(error, errorMsg); }); +} + void RcpHost::DisableThreadAfterDetach(void *aContext) { static_cast(aContext)->DisableThreadAfterDetach(); diff --git a/src/ncp/rcp_host.hpp b/src/ncp/rcp_host.hpp index 6de94667384..6f216310602 100644 --- a/src/ncp/rcp_host.hpp +++ b/src/ncp/rcp_host.hpp @@ -211,6 +211,8 @@ class RcpHost : public MainloopProcessor, public ThreadHost, public OtNetworkPro void SetThreadEnabled(bool aEnabled, const AsyncResultReceiver aReceiver) override; void SetCountryCode(const std::string &aCountryCode, const AsyncResultReceiver &aReceiver) override; void GetChannelMasks(const ChannelMasksReceiver &aReceiver, const AsyncResultReceiver &aErrReceiver) override; + void SetChannelMaxPowers(const std::vector &aChannelMaxPowers, + const AsyncResultReceiver &aReceiver) override; CoprocessorType GetCoprocessorType(void) override { diff --git a/src/ncp/thread_host.hpp b/src/ncp/thread_host.hpp index dbc2018a2e3..c4f3f55d913 100644 --- a/src/ncp/thread_host.hpp +++ b/src/ncp/thread_host.hpp @@ -90,6 +90,12 @@ class ThreadHost : virtual public NetworkProperties std::function; using DeviceRoleHandler = std::function; + struct ChannelMaxPower + { + uint16_t mChannel; + int16_t mMaxPower; // INT16_MAX indicates that the corresponding channel is disabled. + }; + /** * Create a Thread Controller Instance. * @@ -182,6 +188,19 @@ class ThreadHost : virtual public NetworkProperties */ virtual void GetChannelMasks(const ChannelMasksReceiver &aReceiver, const AsyncResultReceiver &aErrReceiver) = 0; + /** + * Sets the max power of each channel. + * + * 1. If the host hasn't been initialized, @p aReceiver will be invoked with error OT_ERROR_INVALID_STATE. + * 2. If any value in @p aChannelMaxPowers is invalid, @p aReceiver will be invoked with error + * OT_ERROR_INVALID_ARGS. + * + * @param[in] aChannelMaxPowers A vector of ChannelMaxPower. + * @param[in] aReceiver A receiver to get the async result of this operation. + */ + virtual void SetChannelMaxPowers(const std::vector &aChannelMaxPowers, + const AsyncResultReceiver &aReceiver) = 0; + /** * Returns the co-processor type. */