[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:
Simon Lin
2020-09-27 22:30:15 -07:00
committed by GitHub
parent 6c6d5f6179
commit 81996b0f3b
10 changed files with 66 additions and 25 deletions
+5 -2
View File
@@ -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
+23 -3
View File
@@ -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)
+1 -1
View File
@@ -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;
+2 -3
View File
@@ -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)
+2 -1
View File
@@ -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.
+7 -6
View File
@@ -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:
+15 -4
View File
@@ -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))
+2 -2
View File
@@ -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
+7 -1
View File
@@ -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