knx
ETS configurable knx-stack
transport_layer.cpp
Go to the documentation of this file.
1 #include "transport_layer.h"
2 #include "apdu.h"
3 #include "cemi_frame.h"
4 #include "network_layer.h"
5 #include "application_layer.h"
6 #include "platform.h"
7 #include "bits.h"
8 #include <stdio.h>
9 
11  _savedFrameConnecting(0), _applicationLayer(layer)
12 {
13  _currentState = Closed;
14 }
15 
17 {
18  _networkLayer = &layer;
19 }
20 
22 {
23  _groupAddressTable = &addrTable;
24 }
25 
26 void TransportLayer::dataIndividualIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu)
27 {
28  //if (tpdu.apdu().length() > 0)
29  //{
30  // print.print("<- TL ");
31  // tpdu.printPDU();
32  // print.print("<- TL ");
33  // tpdu.apdu().printPDU();
34  //}
35 
36  uint8_t sequenceNo = tpdu.sequenceNumber();
37 
38  switch (tpdu.type())
39  {
40  case DataInduvidual:
41  _applicationLayer.dataIndividualIndication(hopType, priority, source, tpdu.apdu());
42  return;
43 
44  case DataConnected:
45  if (source == _connectionAddress)
46  {
47  if (sequenceNo == _seqNoRecv)
48  {
49  //E4
50  switch (_currentState)
51  {
52  case Closed:
53  //A0 nothing
54  break;
55 
56  case OpenIdle:
57  case OpenWait:
58  A2(source, priority, tpdu.apdu());
59  break;
60 
61  case Connecting:
62  _currentState = Closed;
63  A6(destination);
64  break;
65  }
66  }
67  else if (sequenceNo == ((_seqNoRecv - 1) & 0xF))
68  {
69  //E5
70  switch (_currentState)
71  {
72  case Closed:
73  //A0
74  break;
75 
76  case OpenIdle:
77  case OpenWait:
78  case Connecting:
79  A3(source, priority, tpdu);
80  break;
81  }
82  }
83  else
84  {
85  //E6
86  switch (_currentState)
87  {
88  case Closed:
89  //A0
90  break;
91 
92  case OpenIdle:
93  case OpenWait:
94  A4(source, priority, tpdu);
95  break;
96 
97  case Connecting:
98  A6(destination);
99  break;
100  }
101  }
102  }
103  else
104  {
105  //E7
106  switch (_currentState)
107  {
108  case Closed:
109  case OpenIdle:
110  case OpenWait:
111  //A0
112  break;
113 
114  case Connecting:
115  A10(source);
116  break;
117  }
118  }
119 
120  break;
121 
122  case Connect:
123  if (source == _connectionAddress)
124  {
125  //E0
126  switch (_currentState)
127  {
128  case Closed:
129  _currentState = OpenIdle;
130  A1(source);
131  break;
132 
133  case OpenWait:
134  case OpenIdle:
135  case Connecting:
136  //A0: do nothing
137  break;
138  }
139  }
140  else
141  {
142  //E1
143  switch (_currentState)
144  {
145  case Closed:
146  _currentState = OpenIdle;
147  A1(source);
148  break;
149 
150  case OpenIdle:
151  case OpenWait:
152  case Connecting:
153  A10(source);
154  break;
155  }
156  }
157 
158  break;
159 
160  case Disconnect:
161  if (source == _connectionAddress)
162  {
163  //E2
164  switch (_currentState)
165  {
166  case Closed:
167  //A0 do nothing
168  break;
169 
170  case OpenIdle:
171  case OpenWait:
172  case Connecting:
173  _currentState = Closed;
174  A5(source);
175  break;
176 
177  default:
178  break;
179  }
180  }
181  else
182  {
183  //E3
184  //A0: do nothing
185  }
186 
187  break;
188 
189  case Ack:
190  if (source == _connectionAddress)
191  {
192  if (sequenceNo == _seqNoSend)
193  {
194  //E8
195  switch (_currentState)
196  {
197  case Closed:
198  case OpenIdle:
199  //A0
200  break;
201 
202  case OpenWait:
203  _currentState = OpenIdle;
204  A8();
205  break;
206 
207  case Connecting:
208  _currentState = Closed;
209  A6(source);
210  break;
211  }
212  }
213  else
214  {
215  //E9
216  switch (_currentState)
217  {
218  case Closed:
219  case OpenIdle:
220  //A0
221  break;
222 
223  case OpenWait:
224  case Connecting:
225  _currentState = Closed;
226  A6(source);
227  break;
228  }
229  }
230  }
231  else
232  {
233  //E10
234  switch (_currentState)
235  {
236  case Connecting:
237  A10(source);
238  break;
239 
240  default: /* do nothing */
241  break;
242  }
243  }
244 
245  break;
246 
247  case Nack:
248  if (source == _connectionAddress)
249  {
250  if (sequenceNo != _seqNoSend)
251  {
252  //E11
253  switch (_currentState)
254  {
255  case Closed:
256  case OpenIdle:
257  case OpenWait:
258  //A0
259  break;
260 
261  case Connecting:
262  _currentState = Closed;
263  A6(source);
264  break;
265  }
266  }
267  else
268  {
269  if (_repCount < _maxRepCount)
270  {
271  //E12
272  switch (_currentState)
273  {
274  case Closed:
275  //A0
276  break;
277 
278  case Connecting:
279  case OpenIdle:
280  _currentState = Closed;
281  A6(source);
282  break;
283 
284  case OpenWait:
285  A9();
286  break;
287  }
288  }
289  else
290  {
291  //E13
292  switch (_currentState)
293  {
294  case Closed:
295  //A0
296  break;
297 
298  case OpenIdle:
299  case OpenWait:
300  case Connecting:
301  _currentState = Closed;
302  A6(source);
303  break;
304  }
305  }
306  }
307  }
308  else
309  {
310  //E14
311  switch (_currentState)
312  {
313  case Closed:
314  case OpenIdle:
315  case OpenWait:
316  //A0
317  break;
318 
319  case Connecting:
320  A10(source);
321  break;
322 
323  default:
324  break;
325  }
326  }
327 
328  break;
329 
330  default:
331  break;
332  }
333 }
334 
335 void TransportLayer::dataIndividualConfirm(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu, bool status)
336 {
337  TpduType type = tpdu.type();
338 
339  switch (type)
340  {
341  case DataInduvidual:
342  _applicationLayer.dataIndividualConfirm(ack, hopType, priority, destination, tpdu.apdu(), status);
343  break;
344 
345  case DataConnected:
346  //E22
347  //A0: do nothing
348  break;
349 
350  case Connect:
351  if (status)
352  {
353  //E19
354  switch (_currentState)
355  {
356  case Closed:
357  case OpenIdle:
358  case OpenWait:
359  //A0: do nothing
360  break;
361 
362  case Connecting:
363  _currentState = OpenIdle;
364  A13(destination);
365  break;
366  }
367  }
368  else
369  {
370  //E20
371  switch (_currentState)
372  {
373  case Closed:
374  case OpenIdle:
375  case OpenWait:
376  //A0: do nothing
377  break;
378 
379  case Connecting:
380  A5(destination);
381  break;
382  }
383  }
384 
385  break;
386 
387  case Disconnect:
388  //E21
389  //A0: do nothing
390  break;
391 
392  case Ack:
393  //E23
394  //A0: do nothing
395  break;
396 
397  case Nack:
398  //E24
399  //A0: do nothing
400  break;
401 
402  default:
403  break;
404  /* DataGroup and DataBroadcast should not appear here. If they do ignore them. */
405  }
406 }
407 
408 void TransportLayer::dataGroupIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu)
409 {
410  if (_groupAddressTable == nullptr)
411  return;
412 
413  uint16_t tsap = _groupAddressTable->getTsap(destination);
414 
415  if (tsap == 0)
416  return;
417 
418  _applicationLayer.dataGroupIndication(hopType, priority, tsap, tpdu.apdu());
419 }
420 
421 void TransportLayer::dataGroupConfirm(AckType ack, uint16_t source, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu, bool status)
422 {
423  _applicationLayer.dataGroupConfirm(ack, hopType, priority, destination, tpdu.apdu(), status);
424 }
425 
426 void TransportLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu)
427 {
428  _applicationLayer.dataBroadcastIndication(hopType, priority, source, tpdu.apdu());
429 }
430 
431 void TransportLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu, bool status)
432 {
433  _applicationLayer.dataBroadcastConfirm(ack, hopType, priority, tpdu.apdu(), status);
434 }
435 
436 void TransportLayer::dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu)
437 {
438  _applicationLayer.dataSystemBroadcastIndication(hopType, priority, source, tpdu.apdu());
439 }
440 
441 void TransportLayer::dataSystemBroadcastConfirm(AckType ack, HopCountType hopType, TPDU& tpdu, Priority priority, bool status)
442 {
443  _applicationLayer.dataSystemBroadcastConfirm(hopType, priority, tpdu.apdu(), status);
444 }
445 
446 void TransportLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu)
447 {
448  if (_groupAddressTable == nullptr)
449  return;
450 
451  uint16_t groupAdress = _groupAddressTable->getGroupAddress(tsap);
452  TPDU& tpdu = apdu.frame().tpdu();
453  _networkLayer->dataGroupRequest(ack, groupAdress, hopType, priority, tpdu);
454 }
455 
457 {
458  TPDU& tpdu = apdu.frame().tpdu();
459  _networkLayer->dataBroadcastRequest(ack, hopType, priority, tpdu);
460 }
461 
463 {
464  TPDU& tpdu = apdu.frame().tpdu();
465  return _networkLayer->dataSystemBroadcastRequest(ack, hopType, priority, tpdu);
466 }
467 
468 void TransportLayer::dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu)
469 {
470  //print.print("-> TL ");
471  //apdu.printPDU();
472  TPDU& tpdu = apdu.frame().tpdu();
473  _networkLayer->dataIndividualRequest(ack, destination, hopType, priority, tpdu);
474 }
475 
476 void TransportLayer::connectRequest(uint16_t destination, Priority priority)
477 {
478  //E25
479  switch (_currentState)
480  {
481  case Closed:
482  _currentState = Connecting;
483  A12(destination, priority);
484  break;
485 
486  case OpenIdle:
487  case OpenWait:
488  case Connecting:
489  _currentState = Closed;
490  A6(destination);
491  break;
492  }
493 }
494 
495 void TransportLayer::disconnectRequest(uint16_t tsap, Priority priority)
496 {
497  //E26
498  switch (_currentState)
499  {
500  case Closed:
501  A15(priority, tsap);
502  break;
503 
504  case OpenIdle:
505  case OpenWait:
506  case Connecting:
507  _currentState = Closed;
508  A14(tsap, priority);
509  break;
510  }
511 }
512 
513 void TransportLayer::dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu)
514 {
515  //print.print("-> TL ");
516  //apdu.printPDU();
517  //E15
518  switch (_currentState)
519  {
520  case Closed:
521  //A0
522  break;
523 
524  case OpenIdle:
525  _currentState = OpenWait;
526  A7(priority, apdu);
527  break;
528 
529  case OpenWait:
530  case Connecting:
531  A11(tsap, priority, apdu);
532  break;
533 
534  default:
535  break;
536  }
537 }
538 
540 {
541  //E16
542  switch (_currentState)
543  {
544  case Closed:
545  //A0: do nothing
546  break;
547 
548  case OpenIdle:
549  case OpenWait:
550  case Connecting:
551  _currentState = Closed;
552  A6(_connectionAddress);
553  break;
554  }
555 }
556 
558 {
559  if (_repCount < _maxRepCount)
560  {
561  //E17
562  switch (_currentState)
563  {
564  case Closed:
565  case OpenIdle:
566  case Connecting:
567  //A0: do nothing
568  break;
569 
570  case OpenWait:
571  A9();
572  break;
573  }
574  }
575  else
576  {
577  //E18
578  switch (_currentState)
579  {
580  case Closed:
581  case OpenIdle:
582  case Connecting:
583  //A0: do nothing
584  break;
585 
586  case OpenWait:
587  _currentState = Closed;
588  A6(_connectionAddress);
589  break;
590  }
591  }
592 }
593 
594 // Note: we should probably also add the TSAP as argument if would support multiple concurrent connections
596 {
597  // Return seqNum that would be used for sending next frame
598  // together with the TPDU type.
599  return ((_seqNoSend & 0xF) << 2);
600 }
601 
602 // Note: we should probably also add the TSAP as argument if would support multiple concurrent connections
604 {
605  return _connectionAddress;
606 }
607 
609 {
610  uint32_t milliseconds = millis();
611 
612  if (_connectionTimeoutEnabled
613  && (milliseconds - _connectionTimeoutStartMillis) > _connectionTimeoutMillis)
615 
616  if (_ackTimeoutEnabled
617  && (milliseconds - _ackTimeoutStartMillis) > _ackTimeoutMillis)
619 
620  if (_savedConnectingValid)
621  {
622  //retry saved event
623  _savedConnectingValid = false;
624  dataConnectedRequest(_savedTsapConnecting, _savedPriorityConnecting, _savedFrameConnecting.apdu());
625  }
626 }
627 
628 void TransportLayer::sendControlTelegram(TpduType pduType, uint8_t seqNo)
629 {
630  CemiFrame frame(0);
631  TPDU& tpdu = frame.tpdu();
632  tpdu.type(pduType);
633  tpdu.sequenceNumber(seqNo);
634  _networkLayer->dataIndividualRequest(AckRequested, _connectionAddress, NetworkLayerParameter,
635  SystemPriority, tpdu);
636 }
637 
638 void TransportLayer::A0()
639 {
640  /* do nothing */
641 }
642 
643 void TransportLayer::A1(uint16_t source)
644 {
645  _connectionAddress = source;
646  _applicationLayer.connectIndication(source);
647  _seqNoSend = 0;
648  _seqNoRecv = 0;
649  enableConnectionTimeout();
650 }
651 
652 void incSeqNr(uint8_t& seqNr)
653 {
654  seqNr += 1;
655 
656  if (seqNr > 0xf)
657  seqNr = 0;
658 }
659 
660 void TransportLayer::A2(uint16_t source, Priority priority, APDU& apdu)
661 {
662  sendControlTelegram(Ack, _seqNoRecv);
663  incSeqNr(_seqNoRecv);
664  _applicationLayer.dataConnectedIndication(priority, source, apdu);
665  enableConnectionTimeout();
666 }
667 
668 void TransportLayer::A3(uint16_t source, Priority priority, TPDU& recTpdu)
669 {
670  sendControlTelegram(Ack, recTpdu.sequenceNumber());
671  enableConnectionTimeout();
672 }
673 
674 void TransportLayer::A4(uint16_t source, Priority priority, TPDU& recTpdu)
675 {
676  sendControlTelegram(Nack, recTpdu.sequenceNumber());
677  enableConnectionTimeout();
678 }
679 
680 void TransportLayer::A5(uint16_t tsap)
681 {
682  _applicationLayer.disconnectIndication(tsap);
683  disableConnectionTimeout();
684  disableAckTimeout();
685 }
686 
687 void TransportLayer::A6(uint16_t tsap)
688 {
689  sendControlTelegram(Disconnect, 0);
690  _applicationLayer.disconnectIndication(tsap);
691  disableConnectionTimeout();
692  disableAckTimeout();
693 }
694 
695 void TransportLayer::A7(Priority priority, APDU& apdu)
696 {
697  _savedPriority = priority;
698  TPDU& tpdu = apdu.frame().tpdu();
699  tpdu.type(DataConnected);
700  tpdu.sequenceNumber(_seqNoSend);
701  _savedFrame = apdu.frame();
702  _networkLayer->dataIndividualRequest(AckRequested, _connectionAddress, NetworkLayerParameter, priority, tpdu);
703  _repCount = 0;
704  enableAckTimeout();
705  enableConnectionTimeout();
706 }
707 
708 void TransportLayer::A8()
709 {
710  disableAckTimeout();
711  incSeqNr(_seqNoSend);
712  _applicationLayer.dataConnectedConfirm(0);
713  enableConnectionTimeout();
714 }
715 
716 void TransportLayer::A9()
717 {
718  TPDU& tpdu = _savedFrame.tpdu();
719  // tpdu is still initialized from last send
720  _networkLayer->dataIndividualRequest(AckRequested, _connectionAddress, NetworkLayerParameter, _savedPriority, tpdu);
721  _repCount += 1;
722  enableAckTimeout();
723  enableConnectionTimeout();
724 }
725 
726 void TransportLayer::A10(uint16_t source)
727 {
728  CemiFrame frame(0);
729  TPDU& tpdu = frame.tpdu();
730  tpdu.type(Disconnect);
731  tpdu.sequenceNumber(0);
733 }
734 
735 void TransportLayer::A11(uint16_t tsap, Priority priority, APDU& apdu)
736 {
737  _savedTsapConnecting = tsap;
738  _savedPriorityConnecting = priority;
739  _savedFrameConnecting = apdu.frame();
740  _savedConnectingValid = true;
741 }
742 
743 void TransportLayer::A12(uint16_t destination, Priority priority)
744 {
745  _connectionAddress = destination;
746  CemiFrame frame(0);
747  TPDU& tpdu = frame.tpdu();
748  tpdu.type(Connect);
749  _networkLayer->dataIndividualRequest(AckRequested, destination, NetworkLayerParameter, priority, tpdu);
750  _seqNoRecv = 0;
751  _seqNoSend = 0;
752  enableConnectionTimeout();
753 }
754 
755 void TransportLayer::A13(uint16_t destination)
756 {
757  _applicationLayer.connectConfirm(destination, 0, true);
758 }
759 
760 void TransportLayer::A14(uint16_t tsap, Priority priority)
761 {
762  CemiFrame frame(0);
763  TPDU& tpdu = frame.tpdu();
764  tpdu.type(Disconnect);
765  tpdu.sequenceNumber(0);
766  _networkLayer->dataIndividualRequest(AckRequested, _connectionAddress, NetworkLayerParameter, SystemPriority, tpdu);
767  _applicationLayer.disconnectConfirm(priority, tsap, true);
768  disableConnectionTimeout();
769  disableAckTimeout();
770 }
771 
772 void TransportLayer::A15(Priority priority, uint16_t tsap)
773 {
774  _applicationLayer.disconnectConfirm(priority, tsap, true);
775  disableConnectionTimeout();
776  disableAckTimeout();
777 }
778 
779 void TransportLayer::enableConnectionTimeout()
780 {
781  _connectionTimeoutStartMillis = millis();
782  _connectionTimeoutEnabled = true;
783 }
784 
785 void TransportLayer::disableConnectionTimeout()
786 {
787  _connectionTimeoutEnabled = false;
788 }
789 
790 void TransportLayer::enableAckTimeout()
791 {
792  _ackTimeoutStartMillis = millis();
793  _ackTimeoutEnabled = true;
794 }
795 
796 void TransportLayer::disableAckTimeout()
797 {
798  _ackTimeoutEnabled = false;
799 }
uint32_t millis()
This class represents an Application Protocol Data Unit.
Definition: apdu.h:12
CemiFrame & frame()
Get the CemiFrame this APDU is part of.
Definition: apdu.cpp:33
This class represents the group address table.
uint16_t getGroupAddress(uint16_t tsap)
Get the group address mapped to a TSAP.
uint16_t getTsap(uint16_t groupAddress)
Get the TSAP mapped to a group address.
This is an implementation of the application layer as specified in .
void disconnectConfirm(Priority priority, uint16_t tsap, bool status)
virtual void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU &apdu)
virtual void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU &apdu)
void disconnectIndication(uint16_t tsap)
void connectConfirm(uint16_t destination, uint16_t tsap, bool status)
void connectIndication(uint16_t tsap)
virtual void dataConnectedIndication(Priority priority, uint16_t tsap, APDU &apdu)
virtual void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU &apdu, bool status)
Report the status of an APDU that we sent via multicast communication back to us.
virtual void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU &apdu, bool status)
virtual void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU &apdu, bool status)
virtual void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU &apdu, bool status)
virtual void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU &apdu)
Somebody send us an APDU via multicast communication.
virtual void dataConnectedConfirm(uint16_t tsap)
virtual void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU &apdu)
TPDU & tpdu()
Definition: cemi_frame.cpp:362
APDU & apdu()
Definition: cemi_frame.cpp:367
virtual void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU &tpdu)=0
virtual void dataGroupRequest(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU &tpdu)=0
virtual void dataIndividualRequest(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU &tpdu)=0
virtual void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU &tpdu)=0
Definition: tpdu.h:9
TpduType type() const
Definition: tpdu.cpp:8
uint8_t sequenceNumber() const
Definition: tpdu.cpp:100
APDU & apdu()
Definition: tpdu.cpp:111
void connectRequest(uint16_t destination, Priority priority)
void dataGroupIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU &tpdu)
void dataSystemBroadcastConfirm(AckType ack, HopCountType hopType, TPDU &tpdu, Priority priority, bool status)
void dataIndividualIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU &tpdu)
void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU &apdu)
void dataIndividualConfirm(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU &tpdu, bool status)
void dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU &apdu)
Request to send an APDU that via multicast.
void dataConnectedRequest(uint16_t tsap, Priority priority, APDU &apdu)
void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU &apdu)
void networkLayer(NetworkLayer &layer)
void dataGroupConfirm(AckType ack, uint16_t source, uint16_t destination, HopCountType hopType, Priority priority, TPDU &tpdu, bool status)
void disconnectRequest(uint16_t tsap, Priority priority)
void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU &tpdu)
void dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU &apdu)
void connectionTimeoutIndication()
void groupAddressTable(AddressTableObject &addrTable)
void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, TPDU &tpdu, bool status)
uint16_t getConnectionAddress()
void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU &tpdu)
uint8_t getTpciSeqNum()
TransportLayer(ApplicationLayer &layer)
HopCountType
Definition: knx_types.h:124
@ NetworkLayerParameter
use NetworkLayer::hopCount as NPDU::hopCount
Definition: knx_types.h:126
Priority
Definition: knx_types.h:10
@ SystemPriority
Mainly used by ETS for device programming.
Definition: knx_types.h:14
TpduType
Definition: knx_types.h:130
@ DataConnected
Definition: knx_types.h:134
@ Ack
Definition: knx_types.h:137
@ DataInduvidual
Definition: knx_types.h:133
@ Nack
Definition: knx_types.h:138
@ Disconnect
Definition: knx_types.h:136
@ Connect
Definition: knx_types.h:135
AckType
Definition: knx_types.h:18
@ AckRequested
We want a DataLinkLayer acknowledgement.
Definition: knx_types.h:20
void incSeqNr(uint8_t &seqNr)
@ OpenIdle
@ Closed
@ OpenWait
@ Connecting