mirror of
https://github.com/espressif/openthread.git
synced 2026-08-05 02:17:47 +00:00
[radio] use stack reset in RCP (#6645)
This commit makes RCP use a stack reset instead of doing a hard reset when a reset command is received.
This commit is contained in:
@@ -240,6 +240,30 @@ jobs:
|
||||
run: |
|
||||
script/check-posix-pty check
|
||||
|
||||
rcp-stack-reset:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Bootstrap
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
run: |
|
||||
sudo apt-get --no-install-recommends install -y expect ninja-build lcov socat
|
||||
sudo python3 -m pip install git+https://github.com/openthread/pyspinel
|
||||
- name: Build
|
||||
run: |
|
||||
script/cmake-build simulation -DOT_CSL_RECEIVER=ON -DOT_FULL_LOGS=ON -DOT_LOG_OUTPUT=PLATFORM_DEFINED
|
||||
- name: Run
|
||||
run: |
|
||||
python3 tests/scripts/misc/test_rcp_reset.py build/simulation/examples/apps/ncp/ot-rcp
|
||||
- name: Generate Coverage
|
||||
run: |
|
||||
./script/test generate_coverage gcc
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cov-rcp-stack-reset
|
||||
path: tmp/coverage.info
|
||||
|
||||
upload-coverage:
|
||||
needs:
|
||||
- expects-linux
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (166)
|
||||
#define OPENTHREAD_API_VERSION (167)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
@@ -244,17 +244,31 @@ void otRemoveStateChangeCallback(otInstance *aInstance, otStateChangedCallback a
|
||||
* The reset process ensures that all the OpenThread state/info (stored in volatile memory) is erased. Note that the
|
||||
* `otPlatformReset` does not erase any persistent state/info saved in non-volatile memory.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
*/
|
||||
void otInstanceReset(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method deletes all the settings stored on non-volatile memory, and then triggers platform reset.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
*/
|
||||
void otInstanceFactoryReset(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method resets the internal states of the OpenThread radio stack.
|
||||
*
|
||||
* Callbacks and configurations are preserved.
|
||||
*
|
||||
* This API is only available under radio builds (`OPENTHREAD_RADIO = 1`).
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
*/
|
||||
void otInstanceResetRadioStack(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function erases all the OpenThread persistent info (network settings) stored on non-volatile memory.
|
||||
* Erase is successful only if the device is in `disabled` state/role.
|
||||
|
||||
@@ -129,6 +129,15 @@ otError otInstanceErasePersistentInfo(otInstance *aInstance)
|
||||
}
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
void otInstanceResetRadioStack(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.ResetRadioStack();
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *otGetVersionString(void)
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -173,6 +173,14 @@ void Instance::Reset(void)
|
||||
otPlatReset(this);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
void Instance::ResetRadioStack(void)
|
||||
{
|
||||
mRadio.Init();
|
||||
mLinkRaw.Init();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Instance::AfterInit(void)
|
||||
{
|
||||
mIsInitialized = true;
|
||||
|
||||
@@ -194,6 +194,14 @@ public:
|
||||
*/
|
||||
void Reset(void);
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
/**
|
||||
* This method resets the internal states of the radio.
|
||||
*
|
||||
*/
|
||||
void ResetRadioStack(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method returns the active log level.
|
||||
*
|
||||
|
||||
@@ -51,17 +51,27 @@ namespace Mac {
|
||||
|
||||
LinkRaw::LinkRaw(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mReceiveChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
|
||||
, mPanId(kPanIdBroadcast)
|
||||
, mReceiveDoneCallback(nullptr)
|
||||
, mTransmitDoneCallback(nullptr)
|
||||
, mEnergyScanDoneCallback(nullptr)
|
||||
#if OPENTHREAD_RADIO
|
||||
, mSubMac(aInstance)
|
||||
#elif OPENTHREAD_CONFIG_LINK_RAW_ENABLE
|
||||
, mSubMac(aInstance.Get<SubMac>())
|
||||
#endif
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void LinkRaw::Init(void)
|
||||
{
|
||||
mEnergyScanDoneCallback = nullptr;
|
||||
mTransmitDoneCallback = nullptr;
|
||||
mReceiveDoneCallback = nullptr;
|
||||
|
||||
mReceiveChannel = OPENTHREAD_CONFIG_DEFAULT_CHANNEL;
|
||||
mPanId = kPanIdBroadcast;
|
||||
mReceiveDoneCallback = nullptr;
|
||||
#if OPENTHREAD_RADIO
|
||||
mSubMac.Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
Error LinkRaw::SetReceiveDone(otLinkRawReceiveDone aCallback)
|
||||
|
||||
@@ -65,6 +65,12 @@ public:
|
||||
*/
|
||||
explicit LinkRaw(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method initializes the states of the raw link-layer.
|
||||
*
|
||||
*/
|
||||
void Init(void);
|
||||
|
||||
/**
|
||||
* This method returns true if the raw link-layer is enabled.
|
||||
*
|
||||
|
||||
+30
-14
@@ -52,32 +52,48 @@ namespace Mac {
|
||||
SubMac::SubMac(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mRadioCaps(Get<Radio>().GetCaps())
|
||||
, mState(kStateDisabled)
|
||||
, mCsmaBackoffs(0)
|
||||
, mTransmitRetries(0)
|
||||
, mShortAddress(kShortAddrInvalid)
|
||||
, mRxOnWhenBackoff(true)
|
||||
, mEnergyScanMaxRssi(kInvalidRssiValue)
|
||||
, mEnergyScanEndTime(0)
|
||||
, mTransmitFrame(Get<Radio>().GetTransmitBuffer())
|
||||
, mCallbacks(aInstance)
|
||||
, mPcapCallback(nullptr)
|
||||
, mPcapCallbackContext(nullptr)
|
||||
, mFrameCounter(0)
|
||||
, mKeyId(0)
|
||||
, mTimer(aInstance, SubMac::HandleTimer)
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
, mCslPeriod(0)
|
||||
, mCslChannel(0)
|
||||
, mIsCslChannelSpecified(false)
|
||||
, mCslLastSync(0)
|
||||
, mCslParentAccuracy(kCslWorstCrystalPpm)
|
||||
, mCslParentUncert(kCslWorstUncertainty)
|
||||
, mCslState(kCslIdle)
|
||||
, mCslTimer(aInstance, SubMac::HandleCslTimer)
|
||||
#endif
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void SubMac::Init(void)
|
||||
{
|
||||
mState = kStateDisabled;
|
||||
mCsmaBackoffs = 0;
|
||||
mTransmitRetries = 0;
|
||||
mShortAddress = kShortAddrInvalid;
|
||||
mExtAddress.Clear();
|
||||
mRxOnWhenBackoff = true;
|
||||
mEnergyScanMaxRssi = kInvalidRssiValue;
|
||||
mEnergyScanEndTime = Time{0};
|
||||
|
||||
mPrevKey.Clear();
|
||||
mCurrKey.Clear();
|
||||
mNextKey.Clear();
|
||||
|
||||
mFrameCounter = 0;
|
||||
mKeyId = 0;
|
||||
mTimer.Stop();
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
mCslPeriod = 0;
|
||||
mCslChannel = 0;
|
||||
mIsCslChannelSpecified = false;
|
||||
mCslSampleTime = TimeMicro{0};
|
||||
mCslLastSync = TimeMicro{0};
|
||||
mCslState = kCslIdle;
|
||||
mCslTimer.Stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
otRadioCaps SubMac::GetCaps(void) const
|
||||
|
||||
@@ -81,6 +81,10 @@ namespace Mac {
|
||||
#error "OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE is required for OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE."
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
|
||||
class LinkRaw;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class implements the IEEE 802.15.4 MAC (sub-MAC).
|
||||
*
|
||||
@@ -101,6 +105,7 @@ namespace Mac {
|
||||
class SubMac : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
friend class Radio::Callbacks;
|
||||
friend class LinkRaw;
|
||||
|
||||
public:
|
||||
static constexpr int8_t kInvalidRssiValue = 127; ///< Invalid Received Signal Strength Indicator (RSSI) value.
|
||||
@@ -591,6 +596,12 @@ private:
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method initializes the states of the sub-MAC layer.
|
||||
*
|
||||
*/
|
||||
void Init(void);
|
||||
|
||||
bool RadioSupportsCsmaBackoff(void) const
|
||||
{
|
||||
return ((mRadioCaps & (OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES)) != 0);
|
||||
|
||||
@@ -33,6 +33,43 @@
|
||||
|
||||
namespace ot {
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
void Radio::Init(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
Error error = OT_ERROR_NONE;
|
||||
|
||||
OT_UNUSED_VARIABLE(error);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
error = EnableCsl(0, Mac::kShortAddrInvalid, nullptr);
|
||||
OT_ASSERT(error == OT_ERROR_NONE);
|
||||
#endif
|
||||
|
||||
EnableSrcMatch(false);
|
||||
ClearSrcMatchShortEntries();
|
||||
ClearSrcMatchExtEntries();
|
||||
|
||||
if (IsEnabled())
|
||||
{
|
||||
error = Sleep();
|
||||
OT_ASSERT(error == OT_ERROR_NONE);
|
||||
|
||||
error = Disable();
|
||||
OT_ASSERT(error == OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
SetPanId(Mac::kPanIdBroadcast);
|
||||
SetExtendedAddress(Mac::ExtAddress{});
|
||||
SetShortAddress(Mac::kShortAddrInvalid);
|
||||
SetMacKey(0, 0, Mac::KeyMaterial{}, Mac::KeyMaterial{}, Mac::KeyMaterial{});
|
||||
SetMacFrameCounter(0);
|
||||
|
||||
SetPromiscuous(false);
|
||||
#endif // OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
}
|
||||
#endif // OPENTHREAD_RADIO
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
|
||||
void Radio::SetExtendedAddress(const Mac::ExtAddress &aExtAddress)
|
||||
|
||||
@@ -244,6 +244,14 @@ public:
|
||||
*/
|
||||
int8_t GetReceiveSensitivity(void);
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
/**
|
||||
* This method initializes the states of the Thread radio.
|
||||
*
|
||||
*/
|
||||
void Init(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method sets the PAN ID for address filtering.
|
||||
*
|
||||
|
||||
+10
-2
@@ -851,6 +851,12 @@ enum
|
||||
SPINEL_MD_FLAG_RESERVED = 0xFFC2, //!< Flags reserved for future use.
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SPINEL_RESET_PLATFORM = 1,
|
||||
SPINEL_RESET_STACK = 2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/**
|
||||
@@ -870,14 +876,16 @@ enum
|
||||
/**
|
||||
* Reset NCP command (Host -> NCP)
|
||||
*
|
||||
* Encoding: Empty
|
||||
* Encoding: Empty or `C`
|
||||
*
|
||||
* Causes the NCP to perform a software reset. Due to the nature of
|
||||
* this command, the TID is ignored. The host should instead wait
|
||||
* for a `CMD_PROP_VALUE_IS` command from the NCP indicating
|
||||
* `PROP_LAST_STATUS` has been set to `STATUS_RESET_SOFTWARE`.
|
||||
*
|
||||
* The command payload for this command SHOULD be empty.
|
||||
* The optional command payload specifies the reset type, can be
|
||||
* `SPINEL_RESET_PLATFORM` or `SPINEL_RESET_STACK`. Defaults to stack
|
||||
* reset if unspecified.
|
||||
*
|
||||
* If an error occurs, the value of `PROP_LAST_STATUS` will be emitted
|
||||
* instead with the value set to the generated status code for the error.
|
||||
|
||||
+36
-11
@@ -1214,22 +1214,47 @@ otError NcpBase::CommandHandler_RESET(uint8_t aHeader)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aHeader);
|
||||
|
||||
otError error = OT_ERROR_NONE;
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t reset_type = SPINEL_RESET_STACK;
|
||||
|
||||
// Signal a platform reset. If implemented, this function
|
||||
// shouldn't return.
|
||||
otInstanceReset(mInstance);
|
||||
if (mDecoder.GetRemainingLengthInStruct() > 0)
|
||||
{
|
||||
error = mDecoder.ReadUint8(reset_type);
|
||||
OT_ASSERT(error == OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
if (reset_type == SPINEL_RESET_STACK)
|
||||
{
|
||||
otInstanceResetRadioStack(mInstance);
|
||||
|
||||
mIsRawStreamEnabled = false;
|
||||
mCurTransmitTID = 0;
|
||||
mCurScanChannel = kInvalidScanChannel;
|
||||
mSrcMatchEnabled = false;
|
||||
|
||||
ResetCounters();
|
||||
|
||||
error = WriteLastStatusFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_STATUS_RESET_POWER_ON);
|
||||
OT_ASSERT(error == OT_ERROR_NONE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Signal a platform reset. If implemented, this function
|
||||
// shouldn't return.
|
||||
otInstanceReset(mInstance);
|
||||
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
// We only get to this point if the
|
||||
// platform doesn't support resetting.
|
||||
// In such a case we fake it.
|
||||
|
||||
IgnoreError(otThreadSetEnabled(mInstance, false));
|
||||
IgnoreError(otIp6SetEnabled(mInstance, false));
|
||||
// We only get to this point if the
|
||||
// platform doesn't support resetting.
|
||||
// In such a case we fake it.
|
||||
IgnoreError(otThreadSetEnabled(mInstance, false));
|
||||
IgnoreError(otIp6SetEnabled(mInstance, false));
|
||||
#endif
|
||||
|
||||
sNcpInstance = nullptr;
|
||||
sNcpInstance = nullptr;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/expect -f
|
||||
#
|
||||
# Copyright (c) 2021, 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.
|
||||
#
|
||||
|
||||
source "tests/scripts/expect/_common.exp"
|
||||
source "tests/scripts/expect/_multinode.exp"
|
||||
|
||||
|
||||
# The expect on macOS doesn't support `try` or `file tempfile`.
|
||||
skip_on_macos
|
||||
|
||||
file tempfile socat_out
|
||||
set socat_pid [exec socat -d -d pty,raw,echo=0 pty,raw,echo=0 >/dev/null 2>$socat_out &]
|
||||
while {true} {
|
||||
if {[exec head -n2 $socat_out | wc -l] == 2} {
|
||||
set radio_pty [exec head -n1 $socat_out | grep -o {/dev/.\+}]
|
||||
set host_pty [exec head -n2 $socat_out | tail -n1 | grep -o {/dev/.\+}]
|
||||
break
|
||||
}
|
||||
sleep 1
|
||||
}
|
||||
|
||||
puts "Radio PTY: $radio_pty"
|
||||
puts "Host PTY: $host_pty"
|
||||
|
||||
set rcp_pid [exec $::env(OT_SIMULATION_APPS)/ncp/ot-rcp 1 < $radio_pty > $radio_pty &]
|
||||
puts "RCP PID: $rcp_pid"
|
||||
|
||||
try {
|
||||
spawn_node 1 "rcp" "spinel+hdlc_uart://$host_pty"
|
||||
spawn_node 2
|
||||
|
||||
setup_two_nodes "rn" false
|
||||
|
||||
switch_node 2
|
||||
set addr [get_ipaddr mleid]
|
||||
|
||||
switch_node 1
|
||||
send "ping $addr\n"
|
||||
expect "16 bytes from $addr: icmp_seq=1"
|
||||
expect_line "Done"
|
||||
send "reset\n"
|
||||
wait_for "state" "disabled"
|
||||
expect_line "Done"
|
||||
send "ifconfig up\n"
|
||||
expect_line "Done"
|
||||
send "thread start\n"
|
||||
expect_line "Done"
|
||||
wait_for "state" "leader"
|
||||
wait_for "ping $addr" "16 bytes from $addr: icmp_seq=\\d+"
|
||||
expect_line "Done"
|
||||
} finally {
|
||||
exec kill $rcp_pid
|
||||
exec kill $socat_pid
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/expect -f
|
||||
#
|
||||
# Copyright (c) 2021, 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.
|
||||
#
|
||||
|
||||
source "tests/scripts/expect/posix-rcp-stack-reset.exp"
|
||||
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2021, 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.
|
||||
#
|
||||
|
||||
import argparse
|
||||
|
||||
from spinel.const import SPINEL
|
||||
from spinel.codec import WpanApi
|
||||
from spinel.stream import StreamOpen
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('rcp', type=str, help='path to rcp executable')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
stream = StreamOpen('p', f'{args.rcp} 1', False, 115200, False)
|
||||
wpan_api = WpanApi(stream, 1)
|
||||
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_PHY_ENABLED, 1) == 1
|
||||
|
||||
ext_addr = b'\x00\x11\x22\x33\x44\x55\x66\x77'
|
||||
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_PHY_CHAN, 17) == 17
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_MAC_15_4_SADDR, 0x1234, 'H') == 0x1234
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_MAC_15_4_LADDR, ext_addr, '8s') == ext_addr
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_MAC_SRC_MATCH_ENABLED, 1) == 1
|
||||
|
||||
while wpan_api.prop_insert_value(SPINEL.PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, ext_addr, '8s') == ext_addr:
|
||||
ext_addr = (int.from_bytes(ext_addr, 'little') + 1).to_bytes(8, 'little')
|
||||
|
||||
short_addr = 0x2345
|
||||
while wpan_api.prop_insert_value(SPINEL.PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, short_addr, 'H') == short_addr:
|
||||
short_addr += 1
|
||||
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_MAC_FILTER_MODE, SPINEL.MAC_FILTER_MODE_PROMISCUOUS) in {
|
||||
SPINEL.MAC_FILTER_MODE_PROMISCUOUS,
|
||||
SPINEL.MAC_FILTER_MODE_MONITOR,
|
||||
}
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_MAC_RAW_STREAM_ENABLED, 1) == 1
|
||||
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_MAC_SCAN_MASK, 11) == [11]
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_MAC_SCAN_STATE, SPINEL.SCAN_STATE_ENERGY) == SPINEL.SCAN_STATE_ENERGY
|
||||
|
||||
wpan_api.cmd_send(SPINEL.CMD_RESET)
|
||||
|
||||
assert wpan_api.prop_get_value(SPINEL.PROP_PHY_ENABLED) == 0
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_PHY_ENABLED, 1) == 1
|
||||
|
||||
assert wpan_api.prop_get_value(SPINEL.PROP_PHY_CHAN) == 11
|
||||
assert wpan_api.prop_get_value(SPINEL.PROP_MAC_15_4_SADDR) == 0xfffe
|
||||
assert wpan_api.prop_get_value(SPINEL.PROP_MAC_15_4_LADDR) == b'\x00' * 8
|
||||
|
||||
assert wpan_api.prop_get_value(SPINEL.PROP_MAC_SRC_MATCH_ENABLED) == 0
|
||||
assert wpan_api.prop_set_value(SPINEL.PROP_MAC_SRC_MATCH_ENABLED, 1) == 1
|
||||
assert wpan_api.prop_insert_value(SPINEL.PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, ext_addr, '8s') == ext_addr
|
||||
assert wpan_api.prop_insert_value(SPINEL.PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, short_addr, 'H') == short_addr
|
||||
|
||||
assert wpan_api.prop_get_value(SPINEL.PROP_MAC_FILTER_MODE) == SPINEL.MAC_FILTER_MDOE_NORMAL
|
||||
assert wpan_api.prop_get_value(SPINEL.PROP_MAC_RAW_STREAM_ENABLED) == 0
|
||||
assert wpan_api.prop_get_value(SPINEL.PROP_MAC_SCAN_STATE) == SPINEL.SCAN_STATE_IDLE
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -550,4 +550,11 @@ bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aThreshold);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user