From 5a7d0a7e32823ef74d49c818e666062ed84f7513 Mon Sep 17 00:00:00 2001 From: Mathew Date: Tue, 30 Jan 2024 14:12:34 +1100 Subject: [PATCH] continue to use srcRtg if the failure is only an indirect timeout --- lib/Af.js | 10 ++++------ lib/AfController.js | 28 ++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lib/Af.js b/lib/Af.js index 21ae812..7699686 100644 --- a/lib/Af.js +++ b/lib/Af.js @@ -314,10 +314,9 @@ class Af extends EventEmitter { } } - let isResend = false - const afSend = async () => { + const afSend = async (canSrcRtg) => { let rsp - if (!isBroadcast && dstEp.getSrcRtg && !isResend) { + if (!isBroadcast && dstEp.getSrcRtg && canSrcRtg) { const srcRtg = dstEp.getSrcRtg() if (srcRtg) { let options = afParams.options | 0 @@ -383,12 +382,11 @@ class Af extends EventEmitter { } while(true) // ZApsTableFull } - isResend = true } - const indirectSendFn = async (attempt) => { + const indirectSendFn = async (attempt, canSrcRtg) => { try { - await afSend() + await afSend(canSrcRtg) return await startAreq(attempt) } catch (ex) { areqCancelable.cancel() diff --git a/lib/AfController.js b/lib/AfController.js index 27c42a5..816f912 100644 --- a/lib/AfController.js +++ b/lib/AfController.js @@ -2,6 +2,13 @@ const EventEmitter = require('eventemitter2') const Q = require('@halleyassist/q-lite') const debug = require('debug')("zstack-af:controller") +/** +"INDIRECT_TRANS_EXPIRY": 6, +"VALIDATE_ROUTE": 10, +"SOURCE_ROUTE_FAILURE": 11, + */ +const DefaultCodesOfInterest = [6, 0x10, 0x11, 0xb2] + class AfController extends EventEmitter { constructor(){ super() @@ -31,7 +38,7 @@ class AfController extends EventEmitter { } /* eslint-enable no-unused-vars */ - registerResend(dstAddr, interestedCodes = [6, 0x10, 0x11, 0xb2]){ + registerResend(dstAddr, interestedCodes = DefaultCodesOfInterest){ const afResendEvt = 'ZDO:networkStatus:' + dstAddr.toString(16) let sendTime = Date.now() const deferred = Q.defer() @@ -40,13 +47,13 @@ class AfController extends EventEmitter { const handleResend = data=>{ if(done) return if(interestedCodes.includes(data.code) && (Date.now() - sendTime) > 6500){ - debug(`possible indirect expiration, resending (status: 0x${data.code.toString(16)})`) + debug(`possible indirect expiration for 0x${dstAddr.toString(16)}, resending (status: 0x${data.code.toString(16)})`) done = true deferred.resolve(data.code) + } else { + this.removeListener(...eventArgs) + this.once(...eventArgs) } - - this.removeListener(...eventArgs) - this.once(...eventArgs) } const eventArgs = [afResendEvt, handleResend] // declaration gets hoisted, handleResend can reference it @@ -67,7 +74,7 @@ class AfController extends EventEmitter { retries = 1; } - let workPromise + let workPromise, canSrcRtg = true // Loop retries times for(let i = 1; i<=retries; i++){ @@ -81,7 +88,7 @@ class AfController extends EventEmitter { debug(`Doing indirect send attempt ${i}/${retries}`) } - workPromise = sendFn(i) + workPromise = sendFn(i, canSrcRtg) // It's a race for who can return first const promises = [Q.delay(cfg.indirectTimeout), workPromise] @@ -98,17 +105,22 @@ class AfController extends EventEmitter { if(result === 'resend'){ // signalTimeout and signalResend can do these await Q.cancelledRace([Q.delay(5000), workPromise]) // Wait at-least 5 seconds after a module error + canSrcRtg = false } else if(typeof result === 'number') { // network status code if(result != 6 && i != retries) { const waitTime = 3500 - (Date.now() - attemptStart) - if(waitTime > 0) await await Q.cancelledRace([Q.delay(waitTime), workPromise]) + if(waitTime > 0) await Q.cancelledRace([Q.delay(waitTime), workPromise]) + canSrcRtg = false } + // if is 6 (INDIRECT_TRANS_EXPIRY) we continue } else if(result !== undefined) { // should be the same as result return await workPromise + } else { + canSrcRtg = false } } finally { if(resend) resend.cleanup()