node-red-contrib-knx-ultimate 1.3.13 → 1.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@
4
4
 
5
5
  <br/>
6
6
  <p>
7
+ <b>Version 1.3.14</b> - 26 December 2021<br/>
8
+ - KNXEngine: ACK management: the not acknowledged message will be re-transmitted once, then the connection will be dropped, as per KNX specs.<br/>
9
+ - KNXEngine: ACK management: the telegram's queue to be sent to the KNX BUS will be paused during the ACK waiting.<br/>
10
+ - KNXEngine: Routing: now the routing_busy and routing_lost_messages telegrams sent by the KNX/IP Router are handled.<br/>
11
+ </p>
12
+ <p>
7
13
  <b>Version 1.3.13</b> - 25 December 2021<br/>
8
14
  - KNXEngine: when in tunneling and suppress ACK request is disabled, the error is raised only after 3° failed ACK reception instead of 1°.<br/>
9
15
  - KNXEngine: at disconnection, delete all pending ACK requests timer.<br/>
@@ -86,7 +86,7 @@ class KNXClient extends EventEmitter {
86
86
  }
87
87
 
88
88
  super();
89
- this._clientTunnelSeqNumber = 0;
89
+ this._clientTunnelSeqNumber = -1;
90
90
  this._options = options;//Object.assign(optionsDefaults, options);
91
91
  this._options.connectionKeepAliveTimeout = KNXConstants.KNX_CONSTANTS.CONNECTION_ALIVE_TIME,
92
92
  this._localPort = null;
@@ -169,10 +169,10 @@ class KNXClient extends EventEmitter {
169
169
  });
170
170
  }
171
171
 
172
- this._clientTunnelSeqNumber = 0;
172
+ this._clientTunnelSeqNumber = -1;
173
173
  this._channelID = null;
174
174
  this._connectionState = STATE.DISCONNECTED;
175
- this._tunnelReqTimer = new Map();
175
+ this._tunnelReqTimer = null;
176
176
  this._numFailedTelegramACK = 0; // 25/12/2021 Keep count of the failed tunnelig ACK telegrams
177
177
 
178
178
  }
@@ -240,6 +240,7 @@ class KNXClient extends EventEmitter {
240
240
  });
241
241
  }
242
242
  send(knxPacket) {
243
+
243
244
  // Logging
244
245
  if (this.sysLogger !== undefined && this.sysLogger !== null) {
245
246
  try {
@@ -342,9 +343,11 @@ class KNXClient extends EventEmitter {
342
343
  cEMIMessage.control.priority = 3;
343
344
  cEMIMessage.control.addressType = 1;
344
345
  cEMIMessage.control.hopCount = 6;
346
+ this._incSeqNumber(); // 26/12/2021
345
347
  const seqNum = this._getSeqNumber();
346
348
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
347
- if (!this._options.suppress_ack_ldatareq) this._setTimerAndCallback(knxPacketRequest);
349
+ if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
350
+ //if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error("this._tunnelReqTimer "+ this._tunnelReqTimer.size);
348
351
  this.send(knxPacketRequest);
349
352
  // 06/12/2021 Echo the sent telegram. Last parameter is the echo true/false
350
353
  try {
@@ -386,9 +389,10 @@ class KNXClient extends EventEmitter {
386
389
  cEMIMessage.control.priority = 3;
387
390
  cEMIMessage.control.addressType = 1;
388
391
  cEMIMessage.control.hopCount = 6;
392
+ this._incSeqNumber(); // 26/12/2021
389
393
  const seqNum = this._getSeqNumber();
390
394
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
391
- if (!this._options.suppress_ack_ldatareq) this._setTimerAndCallback(knxPacketRequest);
395
+ if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
392
396
  this.send(knxPacketRequest);
393
397
  // 06/12/2021 Echo the sent telegram. Last parameter is the echo true/false
394
398
  try {
@@ -427,9 +431,10 @@ class KNXClient extends EventEmitter {
427
431
  cEMIMessage.control.priority = 3;
428
432
  cEMIMessage.control.addressType = 1;
429
433
  cEMIMessage.control.hopCount = 6;
434
+ this._incSeqNumber(); // 26/12/2021
430
435
  const seqNum = this._getSeqNumber();
431
436
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
432
- if (!this._options.suppress_ack_ldatareq) this._setTimerAndCallback(knxPacketRequest);
437
+ if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
433
438
  this.send(knxPacketRequest);
434
439
  // 06/12/2021 Echo the sent telegram. Last parameter is the echo true/false
435
440
  try {
@@ -475,9 +480,10 @@ class KNXClient extends EventEmitter {
475
480
  cEMIMessage.control.priority = 3;
476
481
  cEMIMessage.control.addressType = 1;
477
482
  cEMIMessage.control.hopCount = 6;
483
+ this._incSeqNumber(); // 26/12/2021
478
484
  const seqNum = this._getSeqNumber();
479
485
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
480
- if (!this._options.suppress_ack_ldatareq) this._setTimerAndCallback(knxPacketRequest);
486
+ if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
481
487
  this.send(knxPacketRequest);
482
488
  // 06/12/2021 Echo the sent telegram. Last parameter is the echo true/false
483
489
  try {
@@ -546,6 +552,7 @@ class KNXClient extends EventEmitter {
546
552
 
547
553
  this._connectionState = STATE.CONNECTING;
548
554
  this._numFailedTelegramACK = 0; // 25/12/2021 Reset the failed ACK counter
555
+ this._clearToSend = true; // 26/12/2021 allow to send
549
556
 
550
557
  if (this._timer !== null) clearTimeout(this._timer);
551
558
 
@@ -566,7 +573,7 @@ class KNXClient extends EventEmitter {
566
573
 
567
574
  }, 1000 * KNXConstants.KNX_CONSTANTS.CONNECT_REQUEST_TIMEOUT);
568
575
  this._awaitingResponseType = KNXConstants.KNX_CONSTANTS.CONNECT_RESPONSE;
569
- this._clientTunnelSeqNumber = 0;
576
+ this._clientTunnelSeqNumber = -1;
570
577
  this._sendConnectRequestMessage(new TunnelCRI.TunnelCRI(knxLayer));
571
578
 
572
579
  } else if (this._options.hostProtocol === "TunnelTCP") {
@@ -584,12 +591,11 @@ class KNXClient extends EventEmitter {
584
591
  if (conn._options.isSecureKNXEnabled) conn._sendSecureSessionRequestMessage(new TunnelCRI.TunnelCRI(knxLayer));
585
592
  });
586
593
 
587
-
588
594
  } else {
589
595
 
590
596
  // Multicast
591
597
  this._connectionState = STATE.CONNECTED;
592
- this._clientTunnelSeqNumber = 0;
598
+ this._clientTunnelSeqNumber = -1;
593
599
  try {
594
600
  this.emit(KNXClientEvents.connected, this._options);
595
601
  } catch (error) {
@@ -647,6 +653,7 @@ class KNXClient extends EventEmitter {
647
653
  if (this._timerTimeoutSendDisconnectRequestMessagetimer !== null) clearTimeout(this._timerTimeoutSendDisconnectRequestMessagetimer);
648
654
  this._timerTimeoutSendDisconnectRequestMessage = null;
649
655
  if (this._timer !== null) clearTimeout(this._timer);
656
+ if (this._tunnelReqTimer !== null) clearTimeout(this._tunnelReqTimer);
650
657
  this.stopHeartBeat();
651
658
  this._connectionState = STATE.DISCONNECTED;
652
659
  try {
@@ -654,16 +661,9 @@ class KNXClient extends EventEmitter {
654
661
  } catch (error) {
655
662
  }
656
663
 
657
- // 25/12/2021 Stops all awaiting ACK timers
658
- for (const [key, oTimer] of this._tunnelReqTimer.entries()) {
659
- try {
660
- clearTimeout(oTimer);
661
- } catch (error) { }
662
- }
663
- this._tunnelReqTimer.clear();
664
- this._clientTunnelSeqNumber = 0;
664
+ this._clientTunnelSeqNumber = -1;
665
+ this._clearToSend = true; // 26/12/2021 allow to send
665
666
  this._channelID = null;
666
- this._tunnelReqTimer = new Map();
667
667
 
668
668
  // 08/12/2021
669
669
  try {
@@ -682,50 +682,77 @@ class KNXClient extends EventEmitter {
682
682
  _getSeqNumber() {
683
683
  return this._clientTunnelSeqNumber;
684
684
  }
685
+ // 26/12/2021 Handle the busy state, for example while waiting for ACK
686
+ _getClearToSend() {
687
+ return (this._clearToSend !== undefined ? this._clearToSend : true);
688
+ }
689
+
685
690
  _incSeqNumber(seq) {
686
- this._clientTunnelSeqNumber = seq ? seq + 1 : this._clientTunnelSeqNumber + 1;
691
+ this._clientTunnelSeqNumber++;
687
692
  if (this._clientTunnelSeqNumber > 255) {
688
693
  this._clientTunnelSeqNumber = 0;
689
694
  }
690
695
  return this._clientTunnelSeqNumber;
691
696
  }
692
-
693
697
  _keyFromCEMIMessage(cEMIMessage) {
694
698
  return cEMIMessage.dstAddress.toString();
695
699
  }
696
- _setTimerAndCallback(knxTunnelingRequest) {
700
+ _setTimerWaitingForACK(knxTunnelingRequest) {
697
701
  const timeoutErr = new errors.RequestTimeoutError(`RequestTimeoutError seqCounter:${knxTunnelingRequest.seqCounter}, DestAddr:${knxTunnelingRequest.cEMIMessage.dstAddress.toString() || "Non definito"}, AckRequested:${knxTunnelingRequest.cEMIMessage.control.ack}, timed out waiting telegram acknowledge by ${this._options.ipAddr || "No Peer host detected"}`);
698
- this._tunnelReqTimer.set(knxTunnelingRequest.seqCounter, setTimeout(() => {
699
- this._tunnelReqTimer.delete(knxTunnelingRequest.seqCounter);
702
+ if (this._tunnelReqTimer !== null) clearTimeout(this._tunnelReqTimer);
703
+ this._clearToSend = false; // 26/12/2021 stop sending until ACK received
704
+ this._tunnelReqTimer = setTimeout(() => {
700
705
  try {
701
706
  this._numFailedTelegramACK += 1;
702
- if (this._numFailedTelegramACK > 3) {
707
+ if (this._numFailedTelegramACK > 2) {
703
708
  this._numFailedTelegramACK = 0;
709
+ this._clearToSend = true;
704
710
  this.emit(KNXClientEvents.error, timeoutErr);
705
711
  } else {
706
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error("KNXClient: _setTimerAndCallback: " + (timeoutErr.message || "Undef error") + " " + this._numFailedTelegramACK + " of 3 times before emitting error.");
712
+ // 26/12/2021 // If no ACK received, resend the datagram once with the same sequence number
713
+ this._setTimerWaitingForACK(knxTunnelingRequest);
714
+ this.send(knxTunnelingRequest);
715
+ if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error("KNXClient: _setTimerWaitingForACK: " + (timeoutErr.message || "Undef error") + " no ACK received. Retransmit datagram with seqNumber " + this._getSeqNumber());
707
716
  }
708
- } catch (error) {
709
- }
710
- }, KNXConstants.KNX_CONSTANTS.TUNNELING_REQUEST_TIMEOUT * 1000));
717
+ } catch (error) { }
718
+ }, KNXConstants.KNX_CONSTANTS.TUNNELING_REQUEST_TIMEOUT * 1000);
719
+
711
720
  }
712
721
  _processInboundMessage(msg, rinfo) {
713
722
 
714
723
  try {
715
724
 
716
725
  // Composing debug string
717
- var sProcessInboundLog = "???";
718
- try {
719
- sProcessInboundLog = "Data received: " + msg.toString("hex");
720
- sProcessInboundLog += " srcAddress: " + JSON.stringify(rinfo);
721
- } catch (error) { }
722
726
  try {
723
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.trace("Received KNX packet: _processInboundMessage, " + sProcessInboundLog + " ChannelID:" + this._channelID || "??" + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
727
+ if (this.sysLogger !== undefined && this.sysLogger !== null) {
728
+ var sProcessInboundLog = "???";
729
+ try {
730
+ sProcessInboundLog = "Data received: " + msg.toString("hex");
731
+ sProcessInboundLog += " srcAddress: " + JSON.stringify(rinfo);
732
+ } catch (error) { }
733
+ this.sysLogger.trace("Received KNX packet: _processInboundMessage, " + sProcessInboundLog + " ChannelID:" + this._channelID || "??" + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
734
+ }
724
735
  } catch (error) { }
725
736
 
726
737
  const { knxHeader, knxMessage } = KNXProtocol.KNXProtocol.parseMessage(msg);
727
738
 
739
+ // 26/12/2021 ROUTING LOST MESSAGE OR BUSY
740
+ if (knxHeader.service_type === KNXConstants.KNX_CONSTANTS.ROUTING_LOST_MESSAGE) {
741
+ try {
742
+ this.emit(KNXClientEvents.error, new Error('ROUTING_LOST_MESSAGE'));
743
+ this._setDisconnected();
744
+ return;
745
+ } catch (error) { }
746
+ } else if (knxHeader.service_type === KNXConstants.KNX_CONSTANTS.ROUTING_BUSY) {
747
+ try {
748
+ this.emit(KNXClientEvents.error, new Error('ROUTING_BUSY'));
749
+ this._setDisconnected();
750
+ return;
751
+ } catch (error) { }
752
+ }
753
+
728
754
  if (knxHeader.service_type === KNXConstants.KNX_CONSTANTS.SEARCH_RESPONSE) {
755
+
729
756
  if (this._discovery_timer == null) {
730
757
  return;
731
758
  }
@@ -743,8 +770,7 @@ class KNXClient extends EventEmitter {
743
770
  if (knxConnectResponse.status !== KNXConstants.ConnectionStatus.E_NO_ERROR) {
744
771
  try {
745
772
  this.emit(KNXClientEvents.error, KNXConnectResponse.KNXConnectResponse.statusToString(knxConnectResponse.status));
746
- } catch (error) {
747
- }
773
+ } catch (error) { }
748
774
  this._setDisconnected();
749
775
  return;
750
776
  }
@@ -799,34 +825,38 @@ class KNXClient extends EventEmitter {
799
825
  if (knxTunnelingRequest.cEMIMessage.msgCode === CEMIConstants.CEMIConstants.L_DATA_IND) {
800
826
 
801
827
  // Composing debug string
802
- let sDebugString = "???";
803
- try {
804
- sDebugString = "Data: " + JSON.stringify(knxTunnelingRequest.cEMIMessage.npdu);
805
- sDebugString += " srcAddress: " + knxTunnelingRequest.cEMIMessage.srcAddress.toString();
806
- sDebugString += " dstAddress: " + knxTunnelingRequest.cEMIMessage.dstAddress.toString();
807
- } catch (error) { }
808
-
809
828
  try {
810
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug("Received KNX packet: TUNNELING: L_DATA_IND, " + sDebugString + " ChannelID:" + this._channelID + " seqCounter:" + knxTunnelingRequest.seqCounter + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
829
+ if (this.sysLogger !== undefined && this.sysLogger !== null) {
830
+ let sDebugString = "???";
831
+ try {
832
+ sDebugString = "Data: " + JSON.stringify(knxTunnelingRequest.cEMIMessage.npdu);
833
+ sDebugString += " srcAddress: " + knxTunnelingRequest.cEMIMessage.srcAddress.toString();
834
+ sDebugString += " dstAddress: " + knxTunnelingRequest.cEMIMessage.dstAddress.toString();
835
+ } catch (error) { }
836
+ this.sysLogger.debug("Received KNX packet: TUNNELING: L_DATA_IND, " + sDebugString + " ChannelID:" + this._channelID + " seqCounter:" + knxTunnelingRequest.seqCounter + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
837
+ }
811
838
  } catch (error) { }
812
839
 
813
840
  try {
814
841
  this.emit(KNXClientEvents.indication, knxTunnelingRequest, false, msg.toString("hex"));
815
- } catch (error) {
816
- }
842
+ } catch (error) { }
817
843
 
818
- }
819
- else if (knxTunnelingRequest.cEMIMessage.msgCode === CEMIConstants.CEMIConstants.L_DATA_CON) {
844
+ } else if (knxTunnelingRequest.cEMIMessage.msgCode === CEMIConstants.CEMIConstants.L_DATA_CON) {
820
845
 
821
846
  try {
822
847
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug("Received KNX packet: TUNNELING: L_DATA_CON, ChannelID:" + this._channelID + " seqCounter:" + knxTunnelingRequest.seqCounter + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
823
848
  } catch (error) { }
824
849
 
825
850
  }
851
+
852
+ // 26/12/2021 send the ACK if the server requestet that
853
+ // Then REMOVED, because some interfaces sets the "ack request" always to 0 even if it needs ack.
854
+ //if (knxMessage.cEMIMessage.control.ack){
826
855
  const knxTunnelAck = KNXProtocol.KNXProtocol.newKNXTunnelingACK(knxTunnelingRequest.channelID, knxTunnelingRequest.seqCounter, KNXConstants.KNX_CONSTANTS.E_NO_ERROR);
827
856
  this.send(knxTunnelAck);
828
- }
829
- else if (knxHeader.service_type === KNXConstants.KNX_CONSTANTS.TUNNELING_ACK) {
857
+ //}
858
+
859
+ } else if (knxHeader.service_type === KNXConstants.KNX_CONSTANTS.TUNNELING_ACK) {
830
860
  //const knxTunnelingAck = lodash.cloneDeep(knxMessage);
831
861
  const knxTunnelingAck = knxMessage;
832
862
  if (knxTunnelingAck.channelID !== this._channelID) {
@@ -837,22 +867,17 @@ class KNXClient extends EventEmitter {
837
867
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug("Received KNX packet: TUNNELING: TUNNELING_ACK, ChannelID:" + this._channelID + " seqCounter:" + knxTunnelingAck.seqCounter + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
838
868
  } catch (error) { }
839
869
 
840
- this._incSeqNumber(knxTunnelingAck.seqCounter);
841
-
842
- if (this._tunnelReqTimer.has(knxTunnelingAck.seqCounter)) {
843
- if (this._tunnelReqTimer.get(knxTunnelingAck.seqCounter) !== null) {
844
- clearTimeout(this._tunnelReqTimer.get(knxTunnelingAck.seqCounter));
845
- this._tunnelReqTimer.delete(knxTunnelingAck.seqCounter);
846
- }
847
- this._numFailedTelegramACK = 0; // 25/12/2021 clear the current ACK failed telegram number
848
- try {
849
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug("Received KNX packet: TUNNELING: DELETED_TUNNELING_ACK FROM PENDING ACK's, ChannelID:" + this._channelID + " seqCounter:" + knxTunnelingAck.seqCounter + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
850
- } catch (error) { }
851
- }
852
- else {
853
-
854
- // Avoid warning if the KNXEngine is set to ignore ACK's telegrams
855
- if (!this._options.suppress_ack_ldatareq) {
870
+ // Check the received ACK sequence number
871
+ if (!this._options.suppress_ack_ldatareq) {
872
+ if (knxTunnelingAck.seqCounter === this._getSeqNumber()) {
873
+ if (this._tunnelReqTimer !== null) clearTimeout(this._tunnelReqTimer);
874
+ this._numFailedTelegramACK = 0; // 25/12/2021 clear the current ACK failed telegram number
875
+ this._clearToSend = true; // I'm ready to send a new datagram now
876
+ try {
877
+ if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug("Received KNX packet: TUNNELING: DELETED_TUNNELING_ACK FROM PENDING ACK's, ChannelID:" + this._channelID + " seqCounter:" + knxTunnelingAck.seqCounter + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
878
+ } catch (error) { }
879
+ } else {
880
+ // Inform that i received an ACK with an unexpected sequence number
856
881
  try {
857
882
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error("Received KNX packet: TUNNELING: Unexpected Tunnel Ack with seqCounter = " + knxTunnelingAck.seqCounter);
858
883
  } catch (error) { }
@@ -867,15 +892,16 @@ class KNXClient extends EventEmitter {
867
892
  if (knxRoutingInd.cEMIMessage.msgCode === CEMIConstants.CEMIConstants.L_DATA_IND) {
868
893
 
869
894
  // Composing debug string
870
- let sDebugString = "???";
871
- try {
872
- sDebugString = "Data: " + JSON.stringify(knxRoutingInd.cEMIMessage.npdu);
873
- sDebugString += " srcAddress: " + knxRoutingInd.cEMIMessage.srcAddress.toString();
874
- sDebugString += " dstAddress: " + knxRoutingInd.cEMIMessage.dstAddress.toString();
875
- } catch (error) { }
876
-
877
895
  try {
878
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug("Received KNX packet: ROUTING: L_DATA_IND, " + sDebugString + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
896
+ if (this.sysLogger !== undefined && this.sysLogger !== null) {
897
+ let sDebugString = "???";
898
+ try {
899
+ sDebugString = "Data: " + JSON.stringify(knxRoutingInd.cEMIMessage.npdu);
900
+ sDebugString += " srcAddress: " + knxRoutingInd.cEMIMessage.srcAddress.toString();
901
+ sDebugString += " dstAddress: " + knxRoutingInd.cEMIMessage.dstAddress.toString();
902
+ } catch (error) { }
903
+ this.sysLogger.debug("Received KNX packet: ROUTING: L_DATA_IND, " + sDebugString + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
904
+ }
879
905
  } catch (error) { }
880
906
 
881
907
  try {
@@ -932,6 +958,7 @@ class KNXClient extends EventEmitter {
932
958
  } catch (error) { }
933
959
  try {
934
960
  this.emit(KNXClientEvents.error, e);
961
+ this._setDisconnected();
935
962
  } catch (error) { }
936
963
 
937
964
  }
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.KNXConnectResponse = void 0;
4
- const KNXConstants_1 = require("./KNXConstants");
5
- const KNXPacket_1 = require("./KNXPacket");
6
- const HPAI_1 = require("./HPAI");
7
- const CRD_1 = require("./CRD");
8
- class KNXConnectResponse extends KNXPacket_1.KNXPacket {
4
+ const KNXConstants = require("./KNXConstants");
5
+ const KNXPacket = require("./KNXPacket");
6
+ const HPAI = require("./HPAI");
7
+ const CRD = require("./CRD");
8
+ class KNXConnectResponse extends KNXPacket.KNXPacket {
9
9
  constructor(channelID, status, hpai, crd) {
10
- super(KNXConstants_1.KNX_CONSTANTS.CONNECT_RESPONSE, hpai == null ? 2 : 2 + hpai.length + crd.length);
10
+ super(KNXConstants.KNX_CONSTANTS.CONNECT_RESPONSE, hpai == null ? 2 : 2 + hpai.length + crd.length);
11
11
  this.channelID = channelID;
12
12
  this.status = status;
13
13
  this.hpai = hpai;
@@ -21,27 +21,27 @@ class KNXConnectResponse extends KNXPacket_1.KNXPacket {
21
21
  const status = buffer.readUInt8(offset++);
22
22
  let hpai, crd;
23
23
  if (offset < buffer.length) {
24
- hpai = HPAI_1.HPAI.createFromBuffer(buffer, offset);
24
+ hpai = HPAI.HPAI.createFromBuffer(buffer, offset);
25
25
  offset += hpai.length;
26
- crd = CRD_1.CRD.createFromBuffer(buffer, offset);
26
+ crd = CRD.CRD.createFromBuffer(buffer, offset);
27
27
  }
28
28
  return new KNXConnectResponse(channelID, status, hpai, crd);
29
29
  }
30
30
  static statusToString(status) {
31
31
  switch (status) {
32
- case KNXConstants_1.KNX_CONSTANTS.E_SEQUENCE_NUMBER:
32
+ case KNXConstants.KNX_CONSTANTS.E_SEQUENCE_NUMBER:
33
33
  return 'Invalid Sequence Number';
34
- case KNXConstants_1.KNX_CONSTANTS.E_CONNECTION_TYPE:
34
+ case KNXConstants.KNX_CONSTANTS.E_CONNECTION_TYPE:
35
35
  return 'Invalid Connection Type';
36
- case KNXConstants_1.KNX_CONSTANTS.E_CONNECTION_OPTION:
36
+ case KNXConstants.KNX_CONSTANTS.E_CONNECTION_OPTION:
37
37
  return 'Invalid Connection Option';
38
- case KNXConstants_1.KNX_CONSTANTS.E_NO_MORE_CONNECTIONS:
38
+ case KNXConstants.KNX_CONSTANTS.E_NO_MORE_CONNECTIONS:
39
39
  return 'No More Connections';
40
- case KNXConstants_1.KNX_CONSTANTS.E_DATA_CONNECTION:
40
+ case KNXConstants.KNX_CONSTANTS.E_DATA_CONNECTION:
41
41
  return 'Invalid Data Connection';
42
- case KNXConstants_1.KNX_CONSTANTS.E_KNX_CONNECTION:
42
+ case KNXConstants.KNX_CONSTANTS.E_KNX_CONNECTION:
43
43
  return 'Invalid KNX Connection';
44
- case KNXConstants_1.KNX_CONSTANTS.E_TUNNELING_LAYER:
44
+ case KNXConstants.KNX_CONSTANTS.E_TUNNELING_LAYER:
45
45
  return 'Invalid Tunneling Layer';
46
46
  default:
47
47
  return `Unknown error ${status}`;
@@ -18,6 +18,7 @@ exports.KNX_CONSTANTS = {
18
18
  DEVICE_CONFIGURATION_ACK: 0x0311,
19
19
  TUNNELING_REQUEST: 0x0420,
20
20
  TUNNELING_ACK: 0x0421,
21
+ ROUTING_BUSY: 0x0532,
21
22
  ROUTING_INDICATION: 0x0530,
22
23
  ROUTING_LOST_MESSAGE: 0x0531,
23
24
  DEVICE_MGMT_CONNECTION: 0x03,
@@ -61,15 +62,15 @@ exports.KNX_CONSTANTS = {
61
62
  KNX_IP: '224.0.23.12',
62
63
  IPV4_ADDRESS_LENGTH: 4,
63
64
  // Search for KNX IP Secure Unicasts Setups
64
- SECURE_SEARCH_REQUEST : 0x20b,
65
- SECURE_SEARCH_RESPONSE : 0x20c,
65
+ SECURE_SEARCH_REQUEST: 0x20b,
66
+ SECURE_SEARCH_RESPONSE: 0x20c,
66
67
  // KNX IP Secure
67
- SECURE_WRAPPER : 0x0950,
68
- SECURE_SESSION_REQUEST : 0x0951,
69
- SECURE_SESSION_RESPONSE : 0x0952,
70
- SECURE_SESSION_AUTH : 0x0953,
71
- SECURE_SESSION_STATUS : 0x0954,
72
- SECURE_GROUP_SYNC : 0x0955
68
+ SECURE_WRAPPER: 0x0950,
69
+ SECURE_SESSION_REQUEST: 0x0951,
70
+ SECURE_SESSION_RESPONSE: 0x0952,
71
+ SECURE_SESSION_AUTH: 0x0953,
72
+ SECURE_SESSION_STATUS: 0x0954,
73
+ SECURE_GROUP_SYNC: 0x0955
73
74
  };
74
75
 
75
76
  var ConnectionStatus;
@@ -82,7 +82,7 @@ class ControlField {
82
82
  }
83
83
  this.control2 = (this.control2 & 0xF0) | Number(format);
84
84
  }
85
- get framrFormat() {
85
+ get frameFormat() {
86
86
  return this.control2 & 0xF;
87
87
  }
88
88
  static get DEFAULT_CONTROL1() {
@@ -801,7 +801,7 @@ return msg;`, "helplink": "https://github.com/Supergiovane/node-red-contrib-knx-
801
801
  //function handleBusEvents(_evt, _src, _dest, _rawValue, _datagram, _isRepeated) {
802
802
  function handleBusEvents(_datagram, _echoed, _CEMI) {
803
803
 
804
-
804
+
805
805
  // _rawValue
806
806
  try {
807
807
  _rawValue = _datagram.cEMIMessage.npdu.dataValue;
@@ -835,7 +835,7 @@ return msg;`, "helplink": "https://github.com/Supergiovane/node-red-contrib-knx-
835
835
  // I'm receiving a telegram from the BUS
836
836
  try {
837
837
  var iStart = _datagram._header._headerLength; //+ 4;
838
- _cemiETS = _CEMI.substring(iStart*2 );
838
+ _cemiETS = _CEMI.substring(iStart * 2);
839
839
  //_cemiETS = datagram.cEMIMessage.srcAddress.toBuffer().toString("hex") + _datagram.cEMIMessage.dstAddress.toBuffer().toString("hex") + "01" + _datagram.cEMIMessage.npdu._tpci.toString(16)
840
840
  } catch (error) { }
841
841
 
@@ -1087,7 +1087,6 @@ return msg;`, "helplink": "https://github.com/Supergiovane/node-red-contrib-knx-
1087
1087
 
1088
1088
  function handleTelegramQueue() {
1089
1089
  if (node.knxConnection !== null || node.host.toUpperCase() === "EMULATE") {
1090
- //console.log("BANANA handleTelegramQueueSONO BLOCCATO ? ",node.lockHandleTelegramQueue, "CONNECTED ? ", node.linkStatus )
1091
1090
  if (node.lockHandleTelegramQueue === true) return; // Exits if the funtion is busy
1092
1091
  node.lockHandleTelegramQueue = true; // Lock the function. It cannot be called again until finished.
1093
1092
 
@@ -1098,6 +1097,15 @@ return msg;`, "helplink": "https://github.com/Supergiovane/node-red-contrib-knx-
1098
1097
  return;
1099
1098
  }
1100
1099
 
1100
+ // 26/12/2021 If the KNXEngine is busy waiting for telegram's ACK, exit
1101
+ if (!node.knxConnection._getClearToSend()) {
1102
+ node.lockHandleTelegramQueue = false; // Unlock the function
1103
+ if (node.telegramsQueue.length > 0) {
1104
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.warn("knxUltimate-config: handleTelegramQueue: the KNXEngine is busy or is waiting for a telegram ACK with seqNumner " + node.knxConnection._getSeqNumber() + ". Delay handling queue.");
1105
+ }
1106
+ return;
1107
+ }
1108
+
1101
1109
  // Retrieving oKNXMessage { grpaddr, payload,dpt,outputtype (write or response),nodecallerid (node caller)}. 06/03/2020 "Read" request does have the lower priority in the queue, so firstly, i search for "read" telegrams and i move it on the top of the queue pile.
1102
1110
  var aTelegramsFiltered = [];
1103
1111
  aTelegramsFiltered = node.telegramsQueue.filter(a => a.outputtype !== "read");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-knx-ultimate",
3
- "version": "1.3.13",
3
+ "version": "1.3.14",
4
4
  "description": "Control your KNX intallation via Node-Red! Single Node KNX IN/OUT with optional ETS group address importer. Easy to use and highly configurable.",
5
5
  "dependencies": {
6
6
  "fs": "0.0.1-security",