mirror of
https://github.com/espressif/openthread.git
synced 2026-08-05 10:27:49 +00:00
[mlr] configure MLR.req response status (#5350)
This commit is contained in:
@@ -193,6 +193,18 @@ void otBackboneRouterConfigNextDuaRegistrationResponse(otInstance *
|
||||
const otIp6InterfaceIdentifier *aMlIid,
|
||||
uint8_t aStatus);
|
||||
|
||||
/**
|
||||
* This method configures response status for next Multicast Listener Registration.
|
||||
*
|
||||
* Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
|
||||
* Only used for test and certification.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aStatus The status to respond.
|
||||
*
|
||||
*/
|
||||
void otBackboneRouterConfigNextMulticastListenerRegistrationResponse(otInstance *aInstance, uint8_t aStatus);
|
||||
|
||||
/**
|
||||
* Represents the Multicast Listener events.
|
||||
*
|
||||
|
||||
@@ -185,6 +185,26 @@ Done
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr mgmt mlr response \<status\>
|
||||
|
||||
Configure the response status for the next MLR.req.
|
||||
|
||||
Only for testing/reference device.
|
||||
|
||||
Known status values:
|
||||
|
||||
- 0: ST_MLR_SUCCESS
|
||||
- 2: ST_MLR_INVALID
|
||||
- 3: ST_MLR_NO_PERSISTENT
|
||||
- 4: ST_MLR_NO_RESOURCES
|
||||
- 5: ST_MLR_BBR_NOT_PRIMARY
|
||||
- 6: ST_MLR_GENERAL_FAILURE
|
||||
|
||||
```bash
|
||||
> bbr mgmt mlr response 2
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr state
|
||||
|
||||
Show local Backbone state ([`Disabled`,`Primary`, `Secondary`]) for Thread 1.2 FTD.
|
||||
|
||||
@@ -605,6 +605,19 @@ otError Interpreter::ProcessBackboneRouterMgmtMlr(uint8_t aArgsLength, char **aA
|
||||
error = otBackboneRouterMulticastListenerAdd(mInstance, &address, timeout);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(aArgs[0], "response"))
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = ParseUnsignedLong(aArgs[1], value));
|
||||
|
||||
otBackboneRouterConfigNextMulticastListenerRegistrationResponse(mInstance, static_cast<uint8_t>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -131,6 +131,16 @@ void otBackboneRouterConfigNextDuaRegistrationResponse(otInstance *
|
||||
static_cast<const Ip6::InterfaceIdentifier *>(aMlIid), aStatus);
|
||||
}
|
||||
|
||||
void otBackboneRouterConfigNextMulticastListenerRegistrationResponse(otInstance *aInstance, uint8_t aStatus)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
OT_ASSERT(aStatus <= ThreadStatusTlv::kMlrStatusMax);
|
||||
|
||||
instance.Get<BackboneRouter::Manager>().ConfigNextMulticastListenerRegistrationResponse(
|
||||
static_cast<ThreadStatusTlv::MlrStatus>(aStatus));
|
||||
}
|
||||
|
||||
void otBackboneRouterMulticastListenerClear(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
@@ -57,7 +57,9 @@ Manager::Manager(Instance &aInstance)
|
||||
, mTimer(aInstance, Manager::HandleTimer, this)
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
, mDuaResponseStatus(ThreadStatusTlv::kDuaSuccess)
|
||||
, mMlrResponseStatus(ThreadStatusTlv::kMlrSuccess)
|
||||
, mDuaResponseIsSpecified(false)
|
||||
, mMlrResponseIsSpecified(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
@@ -106,9 +108,17 @@ void Manager::HandleMulticastListenerRegistration(const Coap::Message &aMessage,
|
||||
|
||||
VerifyOrExit(aMessage.IsConfirmable() && aMessage.GetCode() == OT_COAP_CODE_POST, error = OT_ERROR_PARSE);
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
// Required by Test Specification 5.10.22 DUA-TC-26, only for certification purpose
|
||||
if (mMlrResponseIsSpecified)
|
||||
{
|
||||
mMlrResponseIsSpecified = false;
|
||||
ExitNow(status = mMlrResponseStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
VerifyOrExit(isPrimary, status = ThreadStatusTlv::kMlrBbrNotPrimary);
|
||||
|
||||
// TODO: (MLR) send configured MLR response for Reference Device
|
||||
// TODO: (MLR) handle Commissioner Session TLV
|
||||
// TODO: (MLR) handle Timeout TLV
|
||||
|
||||
@@ -292,6 +302,12 @@ void Manager::ConfigNextDuaRegistrationResponse(const Ip6::InterfaceIdentifier *
|
||||
|
||||
mDuaResponseStatus = static_cast<ThreadStatusTlv::DuaStatus>(aStatus);
|
||||
}
|
||||
|
||||
void Manager::ConfigNextMulticastListenerRegistrationResponse(ThreadStatusTlv::MlrStatus aStatus)
|
||||
{
|
||||
mMlrResponseIsSpecified = true;
|
||||
mMlrResponseStatus = aStatus;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
@@ -80,6 +80,18 @@ public:
|
||||
*
|
||||
*/
|
||||
void ConfigNextDuaRegistrationResponse(const Ip6::InterfaceIdentifier *aMlIid, uint8_t aStatus);
|
||||
|
||||
/**
|
||||
* This method configures response status for next Multicast Listener Registration.
|
||||
*
|
||||
* Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
|
||||
* Only used for test and certification.
|
||||
*
|
||||
* @param[in] aStatus The status to respond.
|
||||
*
|
||||
*/
|
||||
void ConfigNextMulticastListenerRegistrationResponse(ThreadStatusTlv::MlrStatus aStatus);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -135,7 +147,9 @@ private:
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
Ip6::InterfaceIdentifier mDuaResponseTargetMlIid;
|
||||
ThreadStatusTlv::DuaStatus mDuaResponseStatus;
|
||||
ThreadStatusTlv::MlrStatus mMlrResponseStatus;
|
||||
bool mDuaResponseIsSpecified : 1;
|
||||
bool mMlrResponseIsSpecified : 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ public:
|
||||
kMlrNoResources = 4, ///< BBR resource shortage.
|
||||
kMlrBbrNotPrimary = 5, ///< BBR is not Primary at this moment.
|
||||
kMlrGeneralFailure = 6, ///< Reason(s) for failure are not further specified.
|
||||
kMlrStatusMax = 6, ///< Max MLR status.
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,7 @@ import time
|
||||
import unittest
|
||||
import binascii
|
||||
|
||||
from typing import Union
|
||||
from typing import Union, Dict
|
||||
|
||||
|
||||
class Node:
|
||||
@@ -530,7 +530,7 @@ class Node:
|
||||
self.send_command(cmd)
|
||||
self._expect('Done')
|
||||
|
||||
def multicast_listener_list(self):
|
||||
def multicast_listener_list(self) -> Dict[ipaddress.IPv6Address, int]:
|
||||
cmd = 'bbr mgmt mlr listener'
|
||||
self.send_command(cmd)
|
||||
|
||||
@@ -559,6 +559,11 @@ class Node:
|
||||
self.send_command(cmd)
|
||||
self._expect(r"(Done|Error .*)")
|
||||
|
||||
def set_next_mlr_response(self, status: int):
|
||||
cmd = 'bbr mgmt mlr response {}'.format(status)
|
||||
self.send_command(cmd)
|
||||
self._expect('Done')
|
||||
|
||||
def set_link_quality(self, addr, lqi):
|
||||
cmd = 'macfilter rss add-lqi %s %s' % (addr, lqi)
|
||||
self.send_command(cmd)
|
||||
|
||||
@@ -285,6 +285,60 @@ class TestMulticastListenerRegistration(thread_cert.TestCase):
|
||||
self._bootstrap()
|
||||
self.__test_multicast_listeners_table_api()
|
||||
|
||||
def testMlrConfigResponse(self):
|
||||
self._bootstrap()
|
||||
self.__test_mlr_config_response()
|
||||
|
||||
def __test_mlr_config_response(self):
|
||||
bbr = self.nodes[BBR_1]
|
||||
router = self.nodes[ROUTER_1_2]
|
||||
|
||||
self.flush_all()
|
||||
|
||||
# Configure next response to 0
|
||||
bbr.set_next_mlr_response(0)
|
||||
router.add_ipmaddr("ff04::1")
|
||||
self.simulator.go(WAIT_REDUNDANCE)
|
||||
self.__check_send_mlr_req(ROUTER_1_2, ["ff04::1"],
|
||||
should_send=True,
|
||||
expect_mlr_rsp=True,
|
||||
expect_mlr_rsp_status=0)
|
||||
self.assertNotIn(ipaddress.IPv6Address("ff04::1"), bbr.multicast_listener_list())
|
||||
|
||||
router.del_ipmaddr("ff04::1")
|
||||
self.simulator.go(WAIT_REDUNDANCE)
|
||||
self.flush_all()
|
||||
|
||||
# Configure next response to 2
|
||||
bbr.set_next_mlr_response(2)
|
||||
router.add_ipmaddr("ff04::2")
|
||||
self.simulator.go(WAIT_REDUNDANCE)
|
||||
self.__check_send_mlr_req(ROUTER_1_2, ["ff04::2"],
|
||||
should_send=True,
|
||||
expect_mlr_rsp=True,
|
||||
expect_mlr_rsp_status=2)
|
||||
|
||||
router.del_ipmaddr("ff04::2")
|
||||
self.simulator.go(WAIT_REDUNDANCE)
|
||||
self.flush_all()
|
||||
|
||||
# Configure next response to 4
|
||||
bbr.set_next_mlr_response(4)
|
||||
router.add_ipmaddr("ff04::4")
|
||||
self.simulator.go(WAIT_REDUNDANCE)
|
||||
self.__check_send_mlr_req(ROUTER_1_2, ["ff04::4"],
|
||||
should_send=True,
|
||||
expect_mlr_rsp=True,
|
||||
expect_mlr_rsp_status=4)
|
||||
|
||||
# The MA should be eventually registered after reregistration
|
||||
self.simulator.go(REREG_DELAY + WAIT_REDUNDANCE)
|
||||
self.assertIn(ipaddress.IPv6Address("ff04::4"), bbr.multicast_listener_list())
|
||||
|
||||
router.del_ipmaddr("ff04::4")
|
||||
self.simulator.go(WAIT_REDUNDANCE)
|
||||
self.flush_all()
|
||||
|
||||
def __test_multicast_listeners_table_api(self):
|
||||
self.assertTrue(self.nodes[BBR_1].multicast_listener_list() == {})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user