mirror of
https://github.com/espressif/openthread.git
synced 2026-08-02 00:57:47 +00:00
[dua] handle coap error code for DUA.rsp (#5523)
- Configure next response to 5.00 for Reference Device - Handle 5.00 (and other COAP error codes) in DUA.rsp (required by 1.2 Test Spec) - Update DUA test to handle COAP code 5.00
This commit is contained in:
+5
-2
@@ -123,9 +123,9 @@ BBR Primary: None
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr mgmt dua \<status\> [meshLocalIid]
|
||||
### bbr mgmt dua \<status\|coap-code\> [meshLocalIid]
|
||||
|
||||
Configure the response status for DUA.req with meshLocalIid in payload. Without meshLocalIid, simply respond any coming DUA.req next with the specified status.
|
||||
Configure the response status for DUA.req with meshLocalIid in payload. Without meshLocalIid, simply respond any coming DUA.req next with the specified status or COAP code.
|
||||
|
||||
Only for testing/reference device.
|
||||
|
||||
@@ -138,10 +138,13 @@ known status value:
|
||||
- 4: ST_DUA_NO_RESOURCES
|
||||
- 5: ST_DUA_BBR_NOT_PRIMARY
|
||||
- 6: ST_DUA_GENERAL_FAILURE
|
||||
- 160: COAP code 5.00
|
||||
|
||||
```bash
|
||||
> bbr mgmt dua 1 2f7c235e5025a2fd
|
||||
Done
|
||||
> bbr mgmt dua 160
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr mgmt mlr listener
|
||||
|
||||
@@ -296,6 +296,9 @@ void Manager::HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::Me
|
||||
bool hasLastTransactionTime;
|
||||
Ip6::Address target;
|
||||
Ip6::InterfaceIdentifier meshLocalIid;
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
Coap::Code duaRespCoapCode = Coap::kCodeEmpty;
|
||||
#endif
|
||||
|
||||
VerifyOrExit(aMessageInfo.GetPeerAddr().GetIid().IsRoutingLocator(), error = OT_ERROR_DROP);
|
||||
VerifyOrExit(aMessage.IsConfirmablePostRequest(), error = OT_ERROR_PARSE);
|
||||
@@ -307,7 +310,15 @@ void Manager::HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::Me
|
||||
if (mDuaResponseIsSpecified && (mDuaResponseTargetMlIid.IsUnspecified() || mDuaResponseTargetMlIid == meshLocalIid))
|
||||
{
|
||||
mDuaResponseIsSpecified = false;
|
||||
ExitNow(status = mDuaResponseStatus);
|
||||
if (mDuaResponseStatus >= Coap::kCodeResponseMin)
|
||||
{
|
||||
duaRespCoapCode = static_cast<Coap::Code>(mDuaResponseStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = static_cast<ThreadStatusTlv::DuaStatus>(mDuaResponseStatus);
|
||||
}
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -343,7 +354,16 @@ exit:
|
||||
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
SendDuaRegistrationResponse(aMessage, aMessageInfo, target, status);
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
if (duaRespCoapCode != Coap::kCodeEmpty)
|
||||
{
|
||||
IgnoreError(Get<Tmf::TmfAgent>().SendEmptyAck(aMessage, aMessageInfo, duaRespCoapCode));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
SendDuaRegistrationResponse(aMessage, aMessageInfo, target, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +405,7 @@ void Manager::ConfigNextDuaRegistrationResponse(const Ip6::InterfaceIdentifier *
|
||||
mDuaResponseTargetMlIid.Clear();
|
||||
}
|
||||
|
||||
mDuaResponseStatus = static_cast<ThreadStatusTlv::DuaStatus>(aStatus);
|
||||
mDuaResponseStatus = aStatus;
|
||||
}
|
||||
|
||||
void Manager::ConfigNextMulticastListenerRegistrationResponse(ThreadStatusTlv::MlrStatus aStatus)
|
||||
|
||||
@@ -179,7 +179,7 @@ private:
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
Ip6::InterfaceIdentifier mDuaResponseTargetMlIid;
|
||||
ThreadStatusTlv::DuaStatus mDuaResponseStatus;
|
||||
uint8_t mDuaResponseStatus;
|
||||
ThreadStatusTlv::MlrStatus mMlrResponseStatus;
|
||||
bool mDuaResponseIsSpecified : 1;
|
||||
bool mMlrResponseIsSpecified : 1;
|
||||
|
||||
@@ -252,10 +252,9 @@ otError CoapBase::SendAck(const Message &aRequest, const Ip6::MessageInfo &aMess
|
||||
return SendEmptyMessage(kTypeAck, aRequest, aMessageInfo);
|
||||
}
|
||||
|
||||
otError CoapBase::SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
|
||||
otError CoapBase::SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo, Code aCode)
|
||||
{
|
||||
return (aRequest.IsConfirmable() ? SendHeaderResponse(kCodeChanged, aRequest, aMessageInfo)
|
||||
: OT_ERROR_INVALID_ARGS);
|
||||
return (aRequest.IsConfirmable() ? SendHeaderResponse(aCode, aRequest, aMessageInfo) : OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
|
||||
otError CoapBase::SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
|
||||
|
||||
@@ -437,13 +437,14 @@ public:
|
||||
*
|
||||
* @param[in] aRequest A reference to the CoAP Message that was used in CoAP request.
|
||||
* @param[in] aMessageInfo The message info corresponding to the CoAP request.
|
||||
* @param[in] aCode The CoAP code of the dummy CoAP response.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully enqueued the CoAP response message.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffers available to send the CoAP response.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aRequest header is not of confirmable type.
|
||||
*
|
||||
*/
|
||||
otError SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);
|
||||
otError SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo, Code aCode = kCodeChanged);
|
||||
|
||||
/**
|
||||
* This method sends a header-only CoAP message to indicate no resource matched for the request.
|
||||
|
||||
@@ -96,12 +96,13 @@ enum Code : uint8_t
|
||||
|
||||
// Response Codes:
|
||||
|
||||
kCodeCreated = OT_COAP_CODE_CREATED, ///< Created
|
||||
kCodeDeleted = OT_COAP_CODE_DELETED, ///< Deleted
|
||||
kCodeValid = OT_COAP_CODE_VALID, ///< Valid
|
||||
kCodeChanged = OT_COAP_CODE_CHANGED, ///< Changed
|
||||
kCodeContent = OT_COAP_CODE_CONTENT, ///< Content
|
||||
kCodeContinue = OT_COAP_CODE_CONTINUE, ///< RFC7959 Continue
|
||||
kCodeResponseMin = OT_COAP_CODE_RESPONSE_MIN, ///< 2.00
|
||||
kCodeCreated = OT_COAP_CODE_CREATED, ///< Created
|
||||
kCodeDeleted = OT_COAP_CODE_DELETED, ///< Deleted
|
||||
kCodeValid = OT_COAP_CODE_VALID, ///< Valid
|
||||
kCodeChanged = OT_COAP_CODE_CHANGED, ///< Changed
|
||||
kCodeContent = OT_COAP_CODE_CONTENT, ///< Content
|
||||
kCodeContinue = OT_COAP_CODE_CONTINUE, ///< RFC7959 Continue
|
||||
|
||||
// Client Error Codes:
|
||||
|
||||
|
||||
@@ -504,7 +504,8 @@ void DuaManager::PerformNextRegistration(void)
|
||||
SuccessOrExit(error =
|
||||
Get<Tmf::TmfAgent>().SendMessage(*message, messageInfo, &DuaManager::HandleDuaResponse, this));
|
||||
|
||||
mIsDuaPending = true;
|
||||
mIsDuaPending = true;
|
||||
mRegisteringDua = dua;
|
||||
|
||||
// TODO: (DUA) need update when CSL is enabled.
|
||||
if (!Get<Mle::Mle>().IsRxOnWhenIdle())
|
||||
@@ -535,7 +536,9 @@ void DuaManager::HandleDuaResponse(Coap::Message &aMessage, const Ip6::MessageIn
|
||||
ExitNow(error = aResult);
|
||||
}
|
||||
|
||||
VerifyOrExit(aResult == OT_ERROR_NONE && aMessage.GetCode() == Coap::kCodeChanged, error = OT_ERROR_PARSE);
|
||||
VerifyOrExit(aResult == OT_ERROR_NONE, error = OT_ERROR_PARSE);
|
||||
VerifyOrExit(aMessage.GetCode() == Coap::kCodeChanged || aMessage.GetCode() >= Coap::kCodeBadRequest,
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
error = ProcessDuaResponse(aMessage);
|
||||
|
||||
@@ -574,8 +577,16 @@ otError DuaManager::ProcessDuaResponse(Coap::Message &aMessage)
|
||||
Ip6::Address target;
|
||||
uint8_t status;
|
||||
|
||||
SuccessOrExit(error = Tlv::FindUint8Tlv(aMessage, ThreadTlv::kStatus, status));
|
||||
SuccessOrExit(error = Tlv::FindTlv(aMessage, ThreadTlv::kTarget, &target, sizeof(target)));
|
||||
if (aMessage.GetCode() >= Coap::kCodeBadRequest)
|
||||
{
|
||||
status = ThreadStatusTlv::kDuaGeneralFailure;
|
||||
target = mRegisteringDua;
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = Tlv::FindUint8Tlv(aMessage, ThreadTlv::kStatus, status));
|
||||
SuccessOrExit(error = Tlv::FindTlv(aMessage, ThreadTlv::kTarget, &target, sizeof(target)));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_DUA_ENABLE
|
||||
if (Get<ThreadNetif>().HasUnicastAddress(target))
|
||||
|
||||
@@ -218,8 +218,8 @@ private:
|
||||
|
||||
Tasklet mRegistrationTask;
|
||||
Coap::Resource mDuaNotification;
|
||||
|
||||
bool mIsDuaPending : 1;
|
||||
Ip6::Address mRegisteringDua;
|
||||
bool mIsDuaPending : 1;
|
||||
|
||||
#if OPENTHREAD_CONFIG_DUA_ENABLE
|
||||
enum DuaState
|
||||
|
||||
@@ -723,7 +723,13 @@ class NodeImpl:
|
||||
self.remove_prefix(prefix)
|
||||
self.register_netdata()
|
||||
|
||||
def set_next_dua_response(self, status, iid=None):
|
||||
def set_next_dua_response(self, status: Union[str, int], iid=None):
|
||||
# Convert 5.00 to COAP CODE 160
|
||||
if isinstance(status, str):
|
||||
assert '.' in status
|
||||
status = status.split('.')
|
||||
status = (int(status[0]) << 5) + int(status[1])
|
||||
|
||||
cmd = 'bbr mgmt dua {}'.format(status)
|
||||
if iid is not None:
|
||||
cmd += ' ' + str(iid)
|
||||
|
||||
@@ -281,8 +281,8 @@ class TestDomainUnicastAddressRegistration(thread_cert.TestCase):
|
||||
# - increase BBR seqno to trigger reregistration
|
||||
# - ROUTER_1_2 should re-register within BBR_REREGISTRATION_DELAY. For the not fatal errors, ROUTER_1_2
|
||||
# should re-register within another BBR_REREGISTRATION_DELAY (with least delay if ST_DUA_REREGISTER)
|
||||
for status in [ST_DUA_REREGISTER, ST_DUA_NO_RESOURCES, ST_DUA_BBR_NOT_PRIMARY, ST_DUA_GENERAL_FAILURE]:
|
||||
print('Testing Status %d...'.format(status))
|
||||
for status in ['5.00', ST_DUA_REREGISTER, ST_DUA_NO_RESOURCES, ST_DUA_BBR_NOT_PRIMARY, ST_DUA_GENERAL_FAILURE]:
|
||||
print(f'Testing Status {status}...')
|
||||
# Flush relative message queues.
|
||||
self.flush_nodes([ROUTER_1_2])
|
||||
seq_num = seq_num + 1
|
||||
|
||||
Reference in New Issue
Block a user