@@ -17,7 +17,7 @@ import {
1717 type ReceivedDataResponse ,
1818 type Request ,
1919} from "./constants" ;
20- import { apsBusyQueue , busyQueue } from "./driver" ;
20+ import { apsBusyQueue , apsQueue , busyQueue } from "./driver" ;
2121
2222const NS = "zh:deconz:frameparser" ;
2323
@@ -193,25 +193,38 @@ function parseApsConfirmResponse(view: DataView): DataStateResponse | null {
193193 const i = apsBusyQueue . findIndex ( ( r : ApsRequest ) => r . request && r . request . requestId === requestId ) ;
194194
195195 if ( i < 0 ) {
196+ logger . debug ( `Response APS-DATA.confirm seq: ${ seqNr } but no matching request` , NS ) ;
196197 return null ;
197198 }
198199
199200 const req : ApsRequest = apsBusyQueue [ i ] ;
201+ //remove from busyqueue
202+ apsBusyQueue . splice ( i , 1 ) ;
200203
201204 let strstatus = "unknown" ;
202205 const hexstatus = `0x${ confirmStatus . toString ( 16 ) . padStart ( 2 , "0" ) } ` ;
203206 if ( confirmStatus in ApsStatusCode ) {
204207 strstatus = ApsStatusCode [ confirmStatus ] ;
205208 }
206209
210+ // TODO(mpi): This function should not change the queue and resolve/reject the request promise.
211+ // It should only do what the name says and remaining parts handled in upper callframe.
212+
207213 if ( confirmStatus === ApsStatusCode . Success ) {
208214 req . resolve ( confirmStatus ) ;
209215 } else {
210- req . reject ( new Error ( `Failed APS-DATA. request with confirm status: ${ strstatus } ( ${ hexstatus } )` ) ) ;
211- }
216+ // if the request failed check if we can resend with APS ACK enabled
217+ const hasTimeLeft = Date . now ( ) - req . ts < req . request . timeout ;
212218
213- //remove from busyqueue
214- apsBusyQueue . splice ( i , 1 ) ;
219+ if ( req . request . txOptions === 0 && hasTimeLeft && req . request . destAddrMode === ApsAddressMode . Nwk ) {
220+ req . request . txOptions = 0x04 ;
221+
222+ logger . debug ( `Resend request with APS ACK enabled seq: ${ seqNr } ` , NS ) ;
223+ apsQueue . push ( req ) ;
224+ } else {
225+ req . reject ( new Error ( `Failed APS-DATA.request with confirm status: ${ strstatus } (${ hexstatus } )` ) ) ;
226+ }
227+ }
215228
216229 logger . debug ( `APS-DATA.confirm destAddr: 0x${ destAddr } APS request id: ${ requestId } confirm status: ${ strstatus } ${ hexstatus } ` , NS ) ;
217230 frameParserEvents . emit ( "deviceStateUpdated" , deviceState ) ;
0 commit comments