2 * Routines for BACnet (APDU) dissection
3 * Copyright 2001, Hartmut Mueller <hartmut[AT]abmlinux.org>, FH Dortmund
4 * Enhanced by Steve Karg, 2005, <skarg[AT]users.sourceforge.net>, Atlanta
5 * Enhanced by Herbert Lischka, 2005, <lischka[AT]kieback-peter.de>, Berlin
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald[AT]wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * Copied from README.developer,v 1.23
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
39 #include <epan/packet.h>
40 #include <epan/reassemble.h>
41 #include <epan/expert.h>
43 /* formerly bacapp.h contains definitions and forward declarations */
46 #define FAULT proto_tree_add_text(subtree, tvb, offset, tvb_length(tvb) - offset, "something is going wrong here !!"); \
47 offset = tvb_length(tvb);
50 /* BACnet PDU Types */
51 #define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0
52 #define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1
53 #define BACAPP_TYPE_SIMPLE_ACK 2
54 #define BACAPP_TYPE_COMPLEX_ACK 3
55 #define BACAPP_TYPE_SEGMENT_ACK 4
56 #define BACAPP_TYPE_ERROR 5
57 #define BACAPP_TYPE_REJECT 6
58 #define BACAPP_TYPE_ABORT 7
59 #define MAX_BACAPP_TYPE 8
61 #define BACAPP_SEGMENTED_REQUEST 0x08
62 #define BACAPP_MORE_SEGMENTS 0x04
63 #define BACAPP_SEGMENTED_RESPONSE 0x02
64 #define BACAPP_SEGMENT_NAK 0x02
65 #define BACAPP_SENT_BY 0x01
69 * dissect_bacapp ::= CHOICE {
70 * confirmed-request-PDU [0] BACnet-Confirmed-Request-PDU,
71 * unconfirmed-request-PDU [1] BACnet-Unconfirmed-Request-PDU,
72 * simpleACK-PDU [2] BACnet-SimpleACK-PDU,
73 * complexACK-PDU [3] BACnet-ComplexACK-PDU,
74 * segmentACK-PDU [4] BACnet-SegmentACK-PDU,
75 * error-PDU [5] BACnet-Error-PDU,
76 * reject-PDU [6] BACnet-Reject-PDU,
77 * abort-PDU [7] BACnet-Abort-PDU
84 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
87 * ConfirmedRequest-PDU ::= SEQUENCE {
88 * pdu-type [0] Unsigned (0..15), -- 0 for this PDU Type
89 * segmentedMessage [1] BOOLEAN,
90 * moreFollows [2] BOOLEAN,
91 * segmented-response-accepted [3] BOOLEAN,
92 * reserved [4] Unsigned (0..3), -- must be set zero
93 * max-segments-accepted [5] Unsigned (0..7), -- as per 20.1.2.4
94 * max-APDU-length-accepted [5] Unsigned (0..15), -- as per 20.1.2.5
95 * invokeID [6] Unsigned (0..255),
96 * sequence-number [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
97 * proposed-window-size [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
98 * service-choice [9] BACnetConfirmedServiceChoice,
99 * service-request [10] BACnet-Confirmed-Service-Request OPTIONAL
105 * @return modified offset
108 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
115 * @param ack - indocates whether working on request or ack
116 * @param svc - output variable to return service choice
117 * @param tt - output varable to return service choice item
118 * @return modified offset
121 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 ack,
122 gint *svc, proto_item **tt);
125 * Unconfirmed-Request-PDU ::= SEQUENCE {
126 * pdu-type [0] Unsigned (0..15), -- 1 for this PDU type
127 * reserved [1] Unsigned (0..15), -- must be set zero
128 * service-choice [2] BACnetUnconfirmedServiceChoice,
129 * service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
135 * @return modified offset
138 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
141 * SimpleACK-PDU ::= SEQUENCE {
142 * pdu-type [0] Unsigned (0..15), -- 2 for this PDU type
143 * reserved [1] Unsigned (0..15), -- must be set zero
144 * invokeID [2] Unsigned (0..255),
145 * service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
151 * @return modified offset
154 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
157 * ComplexACK-PDU ::= SEQUENCE {
158 * pdu-type [0] Unsigned (0..15), -- 3 for this PDU Type
159 * segmentedMessage [1] BOOLEAN,
160 * moreFollows [2] BOOLEAN,
161 * reserved [3] Unsigned (0..3), -- must be set zero
162 * invokeID [4] Unsigned (0..255),
163 * sequence-number [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
164 * proposed-window-size [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
165 * service-ACK-choice [7] BACnetConfirmedServiceChoice,
166 * service-ACK [8] BACnet-Confirmed-Service-Request -- Context-specific tags 0..8 are NOT used in header encoding
172 * @return modified offset
175 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
178 * SegmentACK-PDU ::= SEQUENCE {
179 * pdu-type [0] Unsigned (0..15), -- 4 for this PDU Type
180 * reserved [1] Unsigned (0..3), -- must be set zero
181 * negative-ACK [2] BOOLEAN,
182 * server [3] BOOLEAN,
183 * original-invokeID [4] Unsigned (0..255),
184 * sequence-number [5] Unsigned (0..255),
185 * actual-window-size [6] Unsigned (0..127)
191 * @return modified offset
194 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
197 * Error-PDU ::= SEQUENCE {
198 * pdu-type [0] Unsigned (0..15), -- 5 for this PDU Type
199 * reserved [1] Unsigned (0..3), -- must be set zero
200 * original-invokeID [2] Unsigned (0..255),
201 * error-choice [3] BACnetConfirmedServiceChoice,
202 * error [4] BACnet-Error
208 * @return modified offset
211 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
214 * Reject-PDU ::= SEQUENCE {
215 * pdu-type [0] Unsigned (0..15), -- 6 for this PDU Type
216 * reserved [1] Unsigned (0..3), -- must be set zero
217 * original-invokeID [2] Unsigned (0..255),
218 * reject-reason [3] BACnetRejectReason
224 * @return modified offset
227 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
230 * Abort-PDU ::= SEQUENCE {
231 * pdu-type [0] Unsigned (0..15), -- 7 for this PDU Type
232 * reserved [1] Unsigned (0..3), -- must be set zero
233 * server [2] BOOLEAN,
234 * original-invokeID [3] Unsigned (0..255),
235 * abort-reason [4] BACnetAbortReason
241 * @return modified offset
244 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
247 * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree
252 * @return modified offset
255 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
258 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
263 * @return modified offset
266 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
269 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
274 * @param lvt length of String
275 * @return modified offset
278 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
281 * 20.2.12, adds the label with Date Value to tree
286 * @return modified offset
289 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
292 * 20.2.13, adds the label with Time Value to tree
297 * @return modified offset
300 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
303 * 20.2.14, adds Object Identifier to tree
304 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
309 * @return modified offset
312 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
315 * BACnet-Confirmed-Service-Request ::= CHOICE {
321 * @param service_choice
325 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
328 * BACnet-Confirmed-Service-ACK ::= CHOICE {
334 * @param service_choice
338 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
341 * AcknowledgeAlarm-Request ::= SEQUENCE {
342 * acknowledgingProcessIdentifier [0] Unsigned32,
343 * eventObjectIdentifier [1] BACnetObjectIdentifer,
344 * eventStateAcknowledge [2] BACnetEventState,
345 * timeStamp [3] BACnetTimeStamp,
346 * acknowledgementSource [4] Character String,
347 * timeOfAcknowledgement [5] BACnetTimeStamp
353 * @return modified offset
356 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
359 * ConfirmedCOVNotification-Request ::= SEQUENCE {
360 * subscriberProcessIdentifier [0] Unsigned32,
361 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
362 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
363 * timeRemaining [3] unsigned,
364 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
370 * @return modified offset
373 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
376 * ConfirmedEventNotification-Request ::= SEQUENCE {
377 * ProcessIdentifier [0] Unsigned32,
378 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
379 * eventObjectIdentifier [2] BACnetObjectIdentifer,
380 * timeStamp [3] BACnetTimeStamp,
381 * notificationClass [4] unsigned,
382 * priority [5] unsigned8,
383 * eventType [6] BACnetEventType,
384 * messageText [7] CharacterString OPTIONAL,
385 * notifyType [8] BACnetNotifyType,
386 * ackRequired [9] BOOLEAN OPTIONAL,
387 * fromState [10] BACnetEventState OPTIONAL,
388 * toState [11] BACnetEventState,
389 * eventValues [12] BACnetNotificationParameters OPTIONAL
395 * @return modified offset
398 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
401 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
402 * objectIdentifier BACnetObjectIdentifer,
403 * alarmState BACnetEventState,
404 * acknowledgedTransitions BACnetEventTransitionBits
410 * @return modified offset
413 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
416 * GetEnrollmentSummary-Request ::= SEQUENCE {
417 * acknowledgmentFilter [0] ENUMERATED {
422 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
423 * eventStateFilter [2] ENUMERATED {
430 * eventTypeFilter [3] BACnetEventType OPTIONAL,
431 * priorityFilter [4] SEQUENCE {
432 * minPriority [0] Unsigned8,
433 * maxPriority [1] Unsigned8
435 * notificationClassFilter [5] Unsigned OPTIONAL
441 * @return modified offset
444 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
447 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
448 * objectIdentifier BACnetObjectIdentifer,
449 * eventType BACnetEventType,
450 * eventState BACnetEventState,
451 * priority Unsigned8,
452 * notificationClass Unsigned OPTIONAL
458 * @return modified offset
461 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
464 * GetEventInformation-Request ::= SEQUENCE {
465 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
471 * @return modified offset
474 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
477 * GetEventInformation-ACK ::= SEQUENCE {
478 * listOfEventSummaries [0] listOfEventSummaries,
479 * moreEvents [1] BOOLEAN
485 * @return modified offset
488 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
491 * LifeSafetyOperation-Request ::= SEQUENCE {
492 * requestingProcessIdentifier [0] Unsigned32
493 * requestingSource [1] CharacterString
494 * request [2] BACnetLifeSafetyOperation
495 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
501 * @return modified offset
504 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
507 * SubscribeCOV-Request ::= SEQUENCE {
508 * subscriberProcessIdentifier [0] Unsigned32
509 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
510 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
511 * lifetime [3] Unsigned OPTIONAL
519 * @return modified offset
522 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
525 * SubscribeCOVProperty-Request ::= SEQUENCE {
526 * subscriberProcessIdentifier [0] Unsigned32
527 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
528 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
529 * lifetime [3] Unsigned OPTIONAL
530 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
531 * covIncrement [5] Unsigned OPTIONAL
537 * @return modified offset
540 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
543 * AtomicReadFile-Request ::= SEQUENCE {
544 * fileIdentifier BACnetObjectIdentifier,
545 * accessMethod CHOICE {
546 * streamAccess [0] SEQUENCE {
547 * fileStartPosition INTEGER,
548 * requestedOctetCount Unsigned
550 * recordAccess [1] SEQUENCE {
551 * fileStartRecord INTEGER,
552 * requestedRecordCount Unsigned
560 * @return modified offset
563 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
566 * AtomicWriteFile-ACK ::= SEQUENCE {
568 * accessMethod CHOICE {
569 * streamAccess [0] SEQUENCE {
570 * fileStartPosition INTEGER,
571 * fileData OCTET STRING
573 * recordAccess [1] SEQUENCE {
574 * fileStartRecord INTEGER,
575 * returnedRecordCount Unsigned,
576 * fileRecordData SEQUENCE OF OCTET STRING
584 * @return modified offset
587 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
590 * AtomicWriteFile-Request ::= SEQUENCE {
591 * fileIdentifier BACnetObjectIdentifier,
592 * accessMethod CHOICE {
593 * streamAccess [0] SEQUENCE {
594 * fileStartPosition INTEGER,
595 * fileData OCTET STRING
597 * recordAccess [1] SEQUENCE {
598 * fileStartRecord INTEGER,
599 * recordCount Unsigned,
600 * fileRecordData SEQUENCE OF OCTET STRING
608 * @return modified offset
611 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
614 * AtomicWriteFile-ACK ::= SEQUENCE {
615 * fileStartPosition [0] INTEGER,
616 * fileStartRecord [1] INTEGER,
621 * @return modified offset
624 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
627 * AddListElement-Request ::= SEQUENCE {
628 * objectIdentifier [0] BACnetObjectIdentifier,
629 * propertyIdentifier [1] BACnetPropertyIdentifier,
630 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
631 * listOfElements [3] ABSTRACT-SYNTAX.&Type
637 * @return modified offset
640 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
643 * CreateObject-Request ::= SEQUENCE {
644 * objectSpecifier [0] ObjectSpecifier,
645 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
651 * @return modified offset
654 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
657 * CreateObject-Request ::= BACnetObjectIdentifier
662 * @return modified offset
665 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
668 * DeleteObject-Request ::= SEQUENCE {
669 * ObjectIdentifier BACnetObjectIdentifer
675 * @return modified offset
678 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
681 * ReadProperty-Request ::= SEQUENCE {
682 * objectIdentifier [0] BACnetObjectIdentifier,
683 * propertyIdentifier [1] BACnetPropertyIdentifier,
684 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
690 * @return modified offset
693 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
696 * ReadProperty-ACK ::= SEQUENCE {
697 * objectIdentifier [0] BACnetObjectIdentifier,
698 * propertyIdentifier [1] BACnetPropertyIdentifier,
699 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
700 * propertyValue [3] ABSTRACT-SYNTAX.&Type
706 * @return modified offset
709 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
712 * ReadPropertyConditional-Request ::= SEQUENCE {
713 * objectSelectionCriteria [0] objectSelectionCriteria,
714 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
720 * @return modified offset
723 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
726 * ReadPropertyConditional-ACK ::= SEQUENCE {
727 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
733 * @return modified offset
736 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
739 * ReadPropertyMultiple-Request ::= SEQUENCE {
740 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
746 * @return offset modified
749 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
752 * ReadPropertyMultiple-Ack ::= SEQUENCE {
753 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
759 * @return offset modified
762 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
765 * ReadRange-Request ::= SEQUENCE {
766 * objectIdentifier [0] BACnetObjectIdentifier,
767 * propertyIdentifier [1] BACnetPropertyIdentifier,
768 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
770 * byPosition [3] SEQUENCE {
771 * referencedIndex Unsigned,
774 * byTime [4] SEQUENCE {
775 * referenceTime BACnetDateTime,
778 * timeRange [5] SEQUENCE {
779 * beginningTime BACnetDateTime,
780 * endingTime BACnetDateTime
788 * @return modified offset
791 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
794 * ReadRange-ACK ::= SEQUENCE {
795 * objectIdentifier [0] BACnetObjectIdentifier,
796 * propertyIdentifier [1] BACnetPropertyIdentifier,
797 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
798 * resultFlags [3] BACnetResultFlags,
799 * itemCount [4] Unsigned,
800 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
806 * @return modified offset
809 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
812 * RemoveListElement-Request ::= SEQUENCE {
813 * objectIdentifier [0] BACnetObjectIdentifier,
814 * propertyIdentifier [1] BACnetPropertyIdentifier,
815 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
816 * listOfElements [3] ABSTRACT-SYNTAX.&Type
822 * @return modified offset
825 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
828 * WriteProperty-Request ::= SEQUENCE {
829 * objectIdentifier [0] BACnetObjectIdentifier,
830 * propertyIdentifier [1] BACnetPropertyIdentifier,
831 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
832 * propertyValue [3] ABSTRACT-SYNTAX.&Type
833 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
839 * @return modified offset
842 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
845 * WritePropertyMultiple-Request ::= SEQUENCE {
846 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
852 * @return modified offset
855 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
858 * DeviceCommunicationControl-Request ::= SEQUENCE {
859 * timeDuration [0] Unsigned16 OPTIONAL,
860 * enable-disable [1] ENUMERATED {
864 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
869 * @return modified offset
872 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
875 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
876 * vendorID [0] Unsigned,
877 * serviceNumber [1] Unsigned,
878 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
884 * @return modified offset
887 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
890 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
891 * vendorID [0] Unsigned,
892 * serviceNumber [1] Unsigned,
893 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
899 * @return modified offset
902 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
905 * ConfirmedTextMessage-Request ::= SEQUENCE {
906 * textMessageSourceDevice [0] BACnetObjectIdentifier,
907 * messageClass [1] CHOICE {
908 * numeric [0] Unsigned,
909 * character [1] CharacterString
911 * messagePriority [2] ENUMERATED {
915 * message [3] CharacterString
921 * @return modified offset
924 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
927 * ReinitializeDevice-Request ::= SEQUENCE {
928 * reinitializedStateOfDevice [0] ENUMERATED {
937 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
942 * @return modified offset
945 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
948 * VTOpen-Request ::= SEQUENCE {
949 * vtClass BACnetVTClass,
950 * localVTSessionIdentifier Unsigned8
956 * @return modified offset
959 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
962 * VTOpen-ACK ::= SEQUENCE {
963 * remoteVTSessionIdentifier Unsigned8
969 * @return modified offset
972 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
975 * VTClose-Request ::= SEQUENCE {
976 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
982 * @return modified offset
985 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
988 * VTData-Request ::= SEQUENCE {
989 * vtSessionIdentifier Unsigned8,
990 * vtNewData OCTET STRING,
991 * vtDataFlag Unsigned (0..1)
997 * @return modified offset
1000 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1003 * VTData-ACK ::= SEQUENCE {
1004 * allNewDataAccepted [0] BOOLEAN,
1005 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1010 * @return modified offset
1013 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
1016 * Authenticate-Request ::= SEQUENCE {
1017 * pseudoRandomNumber [0] Unsigned32,
1018 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1019 * operatorName [2] CharacterString OPTIONAL,
1020 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1021 * startEncypheredSession [4] BOOLEAN OPTIONAL
1026 * @return modified offset
1029 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1032 * Authenticate-ACK ::= SEQUENCE {
1033 * modifiedRandomNumber Unsigned32,
1039 * @return modified offset
1042 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1045 * RequestKey-Request ::= SEQUENCE {
1046 * requestingDeviceIdentifier BACnetObjectIdentifier,
1047 * requestingDeviceAddress BACnetAddress,
1048 * remoteDeviceIdentifier BACnetObjectIdentifier,
1049 * remoteDeviceAddress BACnetAddress
1055 * @return modified offset
1058 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1061 * Unconfirmed-Service-Request ::= CHOICE {
1067 * @param service_choice
1068 * @return modified offset
1071 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1074 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1075 * subscriberProcessIdentifier [0] Unsigned32,
1076 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1077 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1078 * timeRemaining [3] unsigned,
1079 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1085 * @return modified offset
1088 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1091 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1092 * ProcessIdentifier [0] Unsigned32,
1093 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1094 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1095 * timeStamp [3] BACnetTimeStamp,
1096 * notificationClass [4] unsigned,
1097 * priority [5] unsigned8,
1098 * eventType [6] BACnetEventType,
1099 * messageText [7] CharacterString OPTIONAL,
1100 * notifyType [8] BACnetNotifyType,
1101 * ackRequired [9] BOOLEAN OPTIONAL,
1102 * fromState [10] BACnetEventState OPTIONAL,
1103 * toState [11] BACnetEventState,
1104 * eventValues [12] BACnetNotificationParameters OPTIONAL
1110 * @return modified offset
1113 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1116 * I-Am-Request ::= SEQUENCE {
1117 * aAmDeviceIdentifier BACnetObjectIdentifier,
1118 * maxAPDULengthAccepted Unsigned,
1119 * segmentationSupported BACnetSegmentation,
1126 * @return modified offset
1129 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1133 * I-Have-Request ::= SEQUENCE {
1134 * deviceIdentifier BACnetObjectIdentifier,
1135 * objectIdentifier BACnetObjectIdentifier,
1136 * objectName CharacterString
1142 * @return modified offset
1145 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1148 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1149 * vendorID [0] Unsigned,
1150 * serviceNumber [1] Unsigned,
1151 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1157 * @return modified offset
1160 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1163 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1164 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1165 * messageClass [1] CHOICE {
1166 * numeric [0] Unsigned,
1167 * character [1] CharacterString
1169 * messagePriority [2] ENUMERATED {
1173 * message [3] CharacterString
1179 * @return modified offset
1182 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1185 * TimeSynchronization-Request ::= SEQUENCE {
1191 * @return modified offset
1194 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1197 * UTCTimeSynchronization-Request ::= SEQUENCE {
1203 * @return modified offset
1206 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1209 * Who-Has-Request ::= SEQUENCE {
1211 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1212 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1215 * objectIdentifier [2] BACnetObjectIdentifier,
1216 * objectName [3] CharacterString
1223 * @return modified offset
1226 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1229 * Who-Is-Request ::= SEQUENCE {
1230 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1231 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1236 * @return modified offset
1239 fWhoIsRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1242 * BACnet-Error ::= CHOICE {
1243 * addListElement [8] ChangeList-Error,
1244 * removeListElement [9] ChangeList-Error,
1245 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1246 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1247 * vtClose [22] VTClose-Error,
1248 * readRange [26] ObjectAccessService-Error
1256 * @return modified offset
1259 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1262 * Dissect a BACnetError in a context tag
1268 * @return modified offset
1270 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1273 * ChangeList-Error ::= SEQUENCE {
1274 * errorType [0] Error,
1275 * firstFailedElementNumber [1] Unsigned
1282 * @return modified offset
1285 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1288 * CreateObject-Error ::= SEQUENCE {
1289 * errorType [0] Error,
1290 * firstFailedElementNumber [1] Unsigned
1297 * @return modified offset
1300 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1303 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1304 * errorType [0] Error,
1305 * vendorID [1] Unsigned,
1306 * serviceNumber [2] Unsigned,
1307 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1314 * @return modified offset
1317 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1320 * WritePropertyMultiple-Error ::= SEQUENCE {
1321 * errorType [0] Error,
1322 * firstFailedWriteAttempt [1] Unsigned
1329 * @return modified offset
1332 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1335 * VTClose-Error ::= SEQUENCE {
1336 * errorType [0] Error,
1337 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1344 * @return modified offset
1347 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1350 * BACnet Application Types chapter 20.2.1
1356 * @return modified offset
1359 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1362 * BACnetActionCommand ::= SEQUENCE {
1363 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1364 * objectIdentifier [1] BACnetObjectIdentifier,
1365 * propertyIdentifier [2] BACnetPropertyIdentifier,
1366 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1367 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1368 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1369 * postDelay [6] Unsigned OPTIONAL,
1370 * quitOnFailure [7] BOOLEAN,
1371 * writeSuccessful [8] BOOLEAN
1377 * @param matching tag number
1378 * @return modified offset
1381 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1384 * BACnetActionList ::= SEQUENCE {
1385 * action [0] SEQUENCE of BACnetActionCommand
1391 * @return modified offset
1394 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1396 /** BACnetAddress ::= SEQUENCE {
1397 * network-number Unsigned16, -- A value 0 indicates the local network
1398 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1403 * @return modified offset
1406 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset);
1409 * BACnetAddressBinding ::= SEQUENCE {
1410 * deviceObjectID BACnetObjectIdentifier
1411 * deviceAddress BacnetAddress
1417 * @return modified offset
1420 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1423 * BACnetCalendaryEntry ::= CHOICE {
1425 * dateRange [1] BACnetDateRange,
1426 * weekNDay [2] BacnetWeekNday
1431 * @return modified offset
1434 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset);
1437 * BACnetClientCOV ::= CHOICE {
1438 * real-increment REAL,
1439 * default-increment NULL
1444 * @return modified offset
1447 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1451 * BACnetDailySchedule ::= SEQUENCE {
1452 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1458 * @return modified offset
1461 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1464 * BACnetWeeklySchedule ::= SEQUENCE {
1465 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1471 * @return modified offset
1474 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1477 * BACnetDateRange ::= SEQUENCE {
1484 * @return modified offset
1487 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset);
1490 * BACnetDateTime ::= SEQUENCE {
1498 * @return modified offset
1501 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1504 * BACnetDestination ::= SEQUENCE {
1505 * validDays BACnetDaysOfWeek,
1508 * recipient BACnetRecipient,
1509 * processIdentifier Unsigned32,
1510 * issueConfirmedNotifications BOOLEAN,
1511 * transitions BACnetEventTransitionBits
1517 * @return modified offset
1520 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1523 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1524 * objectIdentifier [0] BACnetObjectIdentifier,
1525 * propertyIdentifier [1] BACnetPropertyIdentifier,
1526 * propertyArrayIndex [2] Unsigend OPTIONAL,
1527 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1533 * @return modified offset
1536 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1539 * BACnetDeviceObjectReference ::= SEQUENCE {
1540 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1541 * objectIdentifier [1] BACnetObjectIdentifier
1547 * @return modified offset
1550 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1554 * BACnetEventParameter ::= CHOICE {
1555 * change-of-bitstring [0] SEQUENCE {
1556 * time-delay [0] Unsigned,
1557 * bitmask [1] BIT STRING,
1558 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1560 * change-of-state [1] SEQUENCE {
1561 * time-delay [0] Unsigned,
1562 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1564 * change-of-value [2] SEQUENCE {
1565 * time-delay [0] Unsigned,
1566 * cov-criteria [1] CHOICE {
1567 * bitmask [0] BIT STRING,
1568 * referenced-property-increment [1] REAL
1571 * command-failure [3] SEQUENCE {
1572 * time-delay [0] Unsigned,
1573 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1575 * floating-limit [4] SEQUENCE {
1576 * time-delay [0] Unsigned,
1577 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1578 * low-diff-limit [2] REAL,
1579 * high-diff-limit [3] REAL,
1582 * out-of-range [5] SEQUENCE {
1583 * time-delay [0] Unsigned,
1584 * low-limit [1] REAL,
1585 * high-limit [2] REAL,
1588 * buffer-ready [7] SEQUENCE {
1589 * notification-threshold [0] Unsigned,
1590 * previous-notification-count [1] Unsigned32
1592 * change-of-life-safety [8] SEQUENCE {
1593 * time-delay [0] Unsigned,
1594 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1595 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1596 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1602 * @return modified offset
1605 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset);
1611 * BACnetLogRecord ::= SEQUENCE {
1612 * timestamp [0] BACnetDateTime,
1613 * logDatum [1] CHOICE {
1614 * log-status [0] BACnetLogStatus,
1615 * boolean-value [1] BOOLEAN,
1616 * real-value [2] REAL,
1617 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1618 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1619 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1620 * bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
1621 * null-value [7] NULL,
1622 * failure [8] Error,
1623 * time-change [9] REAL,
1624 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1626 * statusFlags [2] BACnetStatusFlags OPTIONAL
1632 * @return modified offset
1635 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1639 * BACnetNotificationParameters ::= CHOICE {
1640 * change-of-bitstring [0] SEQUENCE {
1641 * referenced-bitstring [0] BIT STRING,
1642 * status-flags [1] BACnetStatusFlags
1644 * change-of-state [1] SEQUENCE {
1645 * new-state [0] BACnetPropertyStatus,
1646 * status-flags [1] BACnetStatusFlags
1648 * change-of-value [2] SEQUENCE {
1649 * new-value [0] CHOICE {
1650 * changed-bits [0] BIT STRING,
1651 * changed-value [1] REAL
1653 * status-flags [1] BACnetStatusFlags
1655 * command-failure [3] SEQUENCE {
1656 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1657 * status-flags [1] BACnetStatusFlags
1658 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1660 * floating-limit [4] SEQUENCE {
1661 * reference-value [0] REAL,
1662 * status-flags [1] BACnetStatusFlags
1663 * setpoint-value [2] REAL,
1664 * error-limit [3] REAL
1666 * out-of-range [5] SEQUENCE {
1667 * exceeding-value [0] REAL,
1668 * status-flags [1] BACnetStatusFlags
1669 * deadband [2] REAL,
1670 * exceeded-limit [0] REAL
1672 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1673 * buffer-ready [7] SEQUENCE {
1674 * buffer-device [0] BACnetObjectIdentifier,
1675 * buffer-object [1] BACnetObjectIdentifier
1676 * previous-notification [2] BACnetDateTime,
1677 * current-notification [3] BACnetDateTime
1679 * change-of-life-safety [8] SEQUENCE {
1680 * new-state [0] BACnetLifeSafetyState,
1681 * new-mode [1] BACnetLifeSafetyState
1682 * status-flags [2] BACnetStatusFlags,
1683 * operation-expected [3] BACnetLifeSafetyOperation
1690 * @return modified offset
1693 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1696 * BACnetObjectPropertyReference ::= SEQUENCE {
1697 * objectIdentifier [0] BACnetObjectIdentifier,
1698 * propertyIdentifier [1] BACnetPropertyIdentifier,
1699 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1705 * @return modified offset
1708 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1712 * BACnetObjectPropertyValue ::= SEQUENCE {
1713 * objectIdentifier [0] BACnetObjectIdentifier,
1714 * propertyIdentifier [1] BACnetPropertyIdentifier,
1715 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1716 * -- if omitted with an array the entire array is referenced
1717 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1718 * priority [4] Unsigned (1..16) OPTIONAL
1723 * @return modified offset
1726 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
1730 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1735 * @return modified offset
1738 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1741 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1744 * BACnetPropertyReference ::= SEQUENCE {
1745 * propertyIdentifier [0] BACnetPropertyIdentifier,
1746 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1752 * @return modified offset
1755 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1758 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1761 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1764 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1767 * BACnetPropertyValue ::= SEQUENCE {
1768 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1769 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1770 * -- if omitted with an array the entire array is referenced
1771 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1772 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1778 * @return modified offset
1781 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1784 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1787 * BACnet Application PDUs chapter 21
1788 * BACnetRecipient::= CHOICE {
1789 * device [0] BACnetObjectIdentifier
1790 * address [1] BACnetAddress
1796 * @return modified offset
1799 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1802 * BACnet Application PDUs chapter 21
1803 * BACnetRecipientProcess::= SEQUENCE {
1804 * recipient [0] BACnetRecipient
1805 * processID [1] Unsigned32
1811 * @return modified offset
1814 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1817 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1821 * BACnetSessionKey ::= SEQUENCE {
1822 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1823 * peerAddress BACnetAddress
1828 * @return modified offset
1829 * @todo check if checksum is displayed correctly
1832 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1836 * BACnetSpecialEvent ::= SEQUENCE {
1838 * calendarEntry [0] BACnetCalendarEntry,
1839 * calendarRefernce [1] BACnetObjectIdentifier
1841 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1842 * eventPriority [3] Unsigned (1..16)
1848 * @return modified offset
1851 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1854 * BACnetTimeStamp ::= CHOICE {
1856 * sequenceNumber [1] Unsigned (0..65535),
1857 * dateTime [2] BACnetDateTime
1863 * @return modified offset
1866 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1869 * BACnetTimeValue ::= SEQUENCE {
1871 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1877 * @return modified offset
1880 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1884 * BACnetVTSession ::= SEQUENCE {
1885 * local-vtSessionID Unsigned8,
1886 * remote-vtSessionID Unsigned8,
1887 * remote-vtAddress BACnetAddress
1892 * @return modified offset
1895 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1899 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1900 * -- first octet month (1..12) January = 1, X'FF' = any month
1901 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1902 * -- 2 = days numbered 8-14
1903 * -- 3 = days numbered 15-21
1904 * -- 4 = days numbered 22-28
1905 * -- 5 = days numbered 29-31
1906 * -- 6 = last 7 days of this month
1907 * -- X'FF' = any week of this month
1908 * -- third octet dayOfWeek (1..7) where 1 = Monday
1910 * -- X'FF' = any day of week
1914 * @return modified offset
1917 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
1920 * ReadAccessResult ::= SEQUENCE {
1921 * objectIdentifier [0] BACnetObjectIdentifier,
1922 * listOfResults [1] SEQUENCE OF SEQUENCE {
1923 * propertyIdentifier [2] BACnetPropertyIdentifier,
1924 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1925 * readResult CHOICE {
1926 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1927 * propertyAccessError [5] Error
1935 * @return modified offset
1938 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1941 * ReadAccessSpecification ::= SEQUENCE {
1942 * objectIdentifier [0] BACnetObjectIdentifier,
1943 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
1949 * @return modified offset
1952 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1955 * WriteAccessSpecification ::= SEQUENCE {
1956 * objectIdentifier [0] BACnetObjectIdentifier,
1957 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
1963 * @return modified offset
1966 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1969 /********************************************************* Helper functions *******************************************/
1972 * extracts the tag number from the tag header.
1973 * @param tvb "TestyVirtualBuffer"
1974 * @param offset in actual tvb
1975 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
1978 fTagNo (tvbuff_t *tvb, guint offset);
1981 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
1982 * @param tvb = "TestyVirtualBuffer"
1983 * @param offset = offset in actual tvb
1984 * @return tag_no BACnet 20.2.1.2 Tag Number
1985 * @return class_tag BACnet 20.2.1.1 Class
1986 * @return lvt BACnet 20.2.1.3 Length/Value/Type
1987 * @return offs = length of this header
1991 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
1995 * adds processID with max 32Bit unsigned Integer Value to tree
1999 * @return modified offset
2002 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
2005 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2009 * @return modified offset
2012 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2015 * BACnet Application PDUs chapter 21
2016 * BACnetPropertyIdentifier::= ENUMERATED {
2017 * @see bacapp_property_identifier
2023 * @param tt returnvalue of this item
2024 * @return modified offset
2027 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2030 * BACnet Application PDUs chapter 21
2031 * BACnetPropertyArrayIndex::= ENUMERATED {
2032 * @see bacapp_property_array_index
2037 * @param tt returnvalue of this item
2038 * @return modified offset
2041 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
2044 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2045 * objectIdentifier [0] BACnetObjectIdentifier,
2046 * eventState [1] BACnetEventState,
2047 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2048 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2049 * notifyType [4] BACnetNotifyType,
2050 * eventEnable [5] BACnetEventTransitionBits,
2051 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2057 * @return modified offset
2060 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2063 * SelectionCriteria ::= SEQUENCE {
2064 * propertyIdentifier [0] BACnetPropertyIdentifier,
2065 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2066 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2067 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2073 * @return modified offset
2076 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2079 * objectSelectionCriteria ::= SEQUENCE {
2080 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2081 * listOfSelectionCriteria [1] SelectionCriteria
2087 * @return modified offset
2090 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2093 * BACnet-Error ::= SEQUENCE {
2094 * error-class ENUMERATED {},
2095 * error-code ENUMERATED {}
2102 * @return modified offset
2105 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2108 * Generic handler for context tagged values. Mostly for handling
2109 * vendor-defined properties and services.
2113 * @return modified offset
2114 * @todo beautify this ugly construct
2117 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2120 * realizes some ABSTRACT-SYNTAX.&Type
2125 * @return modified offset
2126 * @todo beautify this ugly construct
2129 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2133 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2134 const value_string *src);
2140 proto_register_bacapp(void);
2143 * proto_reg_handoff_bacapp
2146 proto_reg_handoff_bacapp(void);
2149 * converts XXX coded strings to UTF-8
2150 * else 'in' is copied to 'out'
2151 * @param in -- pointer to string
2152 * @param inbytesleft
2153 * @param out -- pointer to string
2154 * @param outbytesleft
2156 * @return count of modified characters of returned string, -1 for errors
2159 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2162 uni_to_string(char * data, gsize str_length, char *dest_buf);
2164 /* <<<< formerly bacapp.h */
2166 /* some hashes for segmented messages */
2167 static GHashTable *msg_fragment_table = NULL;
2168 static GHashTable *msg_reassembled_table = NULL;
2170 /* some necessary forward function prototypes */
2172 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2173 const gchar *label, const value_string *vs);
2175 static const char *bacapp_unknown_service_str = "unknown service";
2176 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2177 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2179 static const value_string
2180 BACnetTypeName[] = {
2181 {0, "Confirmed-REQ"},
2182 {1, "Unconfirmed-REQ"},
2192 static const true_false_string segments_follow = {
2193 "Segmented Request",
2194 "Unsegmented Request"
2197 static const true_false_string more_follow = {
2198 "More Segments Follow",
2199 "No More Segments Follow"
2202 static const true_false_string segmented_accept = {
2203 "Segmented Response accepted",
2204 "Segmented Response not accepted"
2207 static const true_false_string
2209 "Context Specific Tag",
2213 static const value_string
2214 BACnetMaxSegmentsAccepted [] = {
2222 {7,"Greater than 64 segments"},
2226 static const value_string
2227 BACnetMaxAPDULengthAccepted [] = {
2228 {0,"Up to MinimumMessageSize (50 octets)"},
2229 {1,"Up to 128 octets"},
2230 {2,"Up to 206 octets (fits in a LonTalk frame)"},
2231 {3,"Up to 480 octets (fits in an ARCNET frame)"},
2232 {4,"Up to 1024 octets"},
2233 {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2234 {6,"reserved by ASHRAE"},
2235 {7,"reserved by ASHRAE"},
2236 {8,"reserved by ASHRAE"},
2237 {9,"reserved by ASHRAE"},
2238 {10,"reserved by ASHRAE"},
2239 {11,"reserved by ASHRAE"},
2240 {12,"reserved by ASHRAE"},
2241 {13,"reserved by ASHRAE"},
2242 {14,"reserved by ASHRAE"},
2243 {15,"reserved by ASHRAE"},
2247 static const value_string
2248 BACnetRejectReason [] = {
2250 {1,"buffer-overflow"},
2251 {2,"inconsistent-parameters"},
2252 {3,"invalid-parameter-data-type"},
2254 {5,"missing-required-parameter"},
2255 {6,"parameter-out-of-range"},
2256 {7,"too-many-arguments"},
2257 {8,"undefined-enumeration"},
2258 {9,"unrecognized-service"},
2262 static const value_string
2263 BACnetRestartReason [] = {
2267 {3,"detected-power-lost"},
2268 {4,"detected-powered-off"},
2269 {5,"hardware-watchdog"},
2270 {6,"software-watchdog"},
2275 static const value_string
2276 BACnetApplicationTagNumber [] = {
2279 {2,"Unsigned Integer"},
2280 {3,"Signed Integer (2's complement notation)"},
2281 {4,"Real (ANSI/IEE-754 floating point)"},
2282 {5,"Double (ANSI/IEE-754 double precision floating point)"},
2284 {7,"Character String"},
2289 {12,"BACnetObjectIdentifier"},
2290 {13,"reserved by ASHRAE"},
2291 {14,"reserved by ASHRAE"},
2292 {15,"reserved by ASHRAE"},
2296 static const value_string
2303 static const value_string
2304 BACnetFileAccessMethod [] = {
2305 {0,"record-access"},
2306 {1,"stream-access"},
2310 /* For some reason, BACnet defines the choice parameter
2311 in the file read and write services backwards from the
2312 BACnetFileAccessMethod enumeration.
2314 static const value_string
2315 BACnetFileAccessOption [] = {
2316 {0,"stream access"},
2317 {1,"record access"},
2321 static const value_string
2322 BACnetFileStartOption [] = {
2323 {0, "File Start Position: "},
2324 {1, "File Start Record: "},
2328 static const value_string
2329 BACnetFileRequestCount [] = {
2330 {0, "Requested Octet Count: "},
2331 {1, "Requested Record Count: "},
2335 static const value_string
2336 BACnetFileWriteInfo [] = {
2338 {1, "Record Count: "},
2342 static const value_string
2343 BACnetAbortReason [] = {
2345 {1,"buffer-overflow"},
2346 {2,"invalid-apdu-in-this-state"},
2347 {3,"preempted-by-higher-priority-task"},
2348 {4,"segmentation-not-supported"},
2352 static const value_string
2353 BACnetLifeSafetyMode [] = {
2364 {10,"disconnected"},
2367 {13,"atomic-release-disabled"},
2370 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2371 Enumerated values 256-65535 may be used by others subject to
2372 procedures and constraints described in Clause 23. */
2375 static const value_string
2376 BACnetLifeSafetyOperation [] = {
2379 {2,"silence-audible"},
2380 {3,"silence-visual"},
2385 {8,"unsilence-audible"},
2386 {9,"unsilence-visual"},
2388 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2389 Enumerated values 64-65535 may be used by others subject to
2390 procedures and constraints described in Clause 23. */
2393 static const value_string
2394 BACnetLimitEnable [] = {
2395 {0,"lowLimitEnable"},
2396 {1,"highLimitEnable"},
2400 static const value_string
2401 BACnetLifeSafetyState [] = {
2406 {4,"fault-pre-alarm"},
2414 {12,"test-fault-alarm"},
2417 {15,"tamper-alarm"},
2419 {17,"emergency-power"},
2423 {21,"general-alarm"},
2425 {23,"test-supervisory"},
2427 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2428 Enumerated values 256-65535 may be used by others subject to
2429 procedures and constraints described in Clause 23. */
2432 static const value_string
2433 BACnetConfirmedServiceChoice [] = {
2434 {0,"acknowledgeAlarm"},
2435 {1,"confirmedCOVNotification"},
2436 {2,"confirmedEventNotification"},
2437 {3,"getAlarmSummary"},
2438 {4,"getEnrollmentSummary"},
2440 {6,"atomicReadFile"},
2441 {7,"atomicWriteFile"},
2442 {8,"addListElement"},
2443 {9,"removeListElement"},
2444 {10,"createObject"},
2445 {11,"deleteObject"},
2446 {12,"readProperty"},
2447 {13,"readPropertyConditional"},
2448 {14,"readPropertyMultiple"},
2449 {15,"writeProperty"},
2450 {16,"writePropertyMultiple"},
2451 {17,"deviceCommunicationControl"},
2452 {18,"confirmedPrivateTransfer"},
2453 {19,"confirmedTextMessage"},
2454 {20,"reinitializeDevice"},
2458 {24,"authenticate"},
2461 {27,"lifeSafetyOperation"},
2462 {28,"subscribeCOVProperty"},
2463 {29,"getEventInformation"},
2464 {30,"reserved by ASHRAE"},
2468 static const value_string
2469 BACnetReliability [] = {
2470 {0,"no-fault-detected"},
2477 {7,"unreliable-other"},
2478 {8,"process-error"},
2479 {9,"multi-state-fault"},
2483 static const value_string
2484 BACnetUnconfirmedServiceChoice [] = {
2487 {2,"unconfirmedCOVNotification"},
2488 {3,"unconfirmedEventNotification"},
2489 {4,"unconfirmedPrivateTransfer"},
2490 {5,"unconfirmedTextMessage"},
2491 {6,"timeSynchronization"},
2494 {9,"utcTimeSynchonization"},
2498 static const value_string
2499 BACnetUnconfirmedServiceRequest [] = {
2501 {1,"i-Have-Request"},
2502 {2,"unconfirmedCOVNotification-Request"},
2503 {3,"unconfirmedEventNotification-Request"},
2504 {4,"unconfirmedPrivateTransfer-Request"},
2505 {5,"unconfirmedTextMessage-Request"},
2506 {6,"timeSynchronization-Request"},
2507 {7,"who-Has-Request"},
2508 {8,"who-Is-Request"},
2509 {9,"utcTimeSynchonization-Request"},
2513 static const value_string
2514 BACnetObjectType [] = {
2516 {1,"analog-output"},
2519 {4,"binary-output"},
2524 {9,"event-enrollment"},
2528 {13,"multi-state-input"},
2529 {14,"multi-state-output"},
2530 {15,"notification-class"},
2534 {19,"multi-state-value"},
2536 {21,"life-safety-point"},
2537 {22,"life-safety-zone"},
2539 {24,"pulse-converter"},
2541 {26,"global-group"},
2542 {27,"trend-log-multiple"},
2543 {28,"load-control"},
2544 {29,"structured-view"},
2545 {30,"access-door"}, /* 30-37 added with addanda 135-2008j */
2546 {32,"access-credential"},
2547 {33,"access-point"},
2548 {34,"access-rights"},
2551 {37,"credential-data-input"},
2552 {39,"bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2553 {40,"characterstring-value"},
2554 {41,"date-pattern-value"},
2556 {43,"datetime-pattern-value"},
2557 {44,"datetime-value"},
2558 {45,"integer-value"},
2559 {46,"large-analog-value"},
2560 {47,"octetstring-value"},
2561 {48,"positive-Integer-value"},
2562 {49,"time-pattern-value"},
2565 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2566 Enumerated values 128-1023 may be used by others subject to
2567 the procedures and constraints described in Clause 23. */
2570 static const value_string
2571 BACnetEngineeringUnits [] = {
2581 {9,"Kilovolt Amperes"},
2582 {10,"Megavolt Amperes"},
2583 {11,"Volt Amperes Reactive"},
2584 {12,"Kilovolt Amperes Reactive"},
2585 {13,"Megavolt Amperes Reactive"},
2586 {14,"Degrees Phase"},
2587 {15,"Power Factor"},
2591 {19,"Kilowatt Hours"},
2595 {23,"Joules Per Kg Dry Air"},
2596 {24,"BTUs Per Pound Dry Air"},
2597 {25,"Cycles Per Hour"},
2598 {26,"Cycles Per Minute"},
2600 {28,"Grams Of Water Per Kilogram Dry Air"},
2601 {29,"Relative Humidity"},
2606 {34,"Watts Per Sq Foot"},
2607 {35,"Watts Per Sq meter"},
2610 {38,"Foot Candles"},
2614 {42,"Kgs per Second"},
2615 {43,"Kgs Per Minute"},
2616 {44,"Kgs Per Hour"},
2617 {45,"Pounds Mass Per Minute"},
2618 {46,"Pounds Mass Per Hour"},
2622 {50,"BTUs Per Hour"},
2624 {52,"Tons Refrigeration"},
2628 {56,"Pounds Force Per Square Inch"},
2629 {57,"Centimeters Of Water"},
2630 {58,"Inches Of Water"},
2631 {59,"Millimeters Of Mercury"},
2632 {60,"Centimeters Of Mercury"},
2633 {61,"Inches Of Mercury"},
2634 {62,"Degrees Celsius"},
2635 {63,"Degrees Kelvin"},
2636 {64,"Degrees Fahrenheit"},
2637 {65,"Degree Days Celsius"},
2638 {66,"Degree Days Fahrenheit"},
2646 {74,"Meters Per Second"},
2647 {75,"Kilometers Per Hour"},
2648 {76,"Feed Per Second"},
2649 {77,"Feet Per Minute"},
2650 {78,"Miles Per Hour"},
2652 {80,"Cubic Meters"},
2653 {81,"Imperial Gallons"},
2656 {84,"Cubic Feet Per Minute"},
2657 {85,"Cubic Meters Per Second"},
2658 {86,"Imperial Gallons Per Minute"},
2659 {87,"Liters Per Second"},
2660 {88,"Liters Per Minute"},
2661 {89,"US Gallons Per Minute"},
2662 {90,"Degrees Angular"},
2663 {91,"Degrees Celsius Per Hour"},
2664 {92,"Degrees Celsius Per Minute"},
2665 {93,"Degrees Fahrenheit Per Hour"},
2666 {94,"Degrees Fahrenheit Per Minute"},
2668 {96,"Parts Per Million"},
2669 {97,"Parts Per Billion"},
2671 {99,"Pecent Per Second"},
2674 {102,"Psi Per Degree Fahrenheit"},
2676 {104,"Revolutions Per Min"},
2688 {116,"Sq Centimeters"},
2689 {117,"BTUs Per Pound"},
2690 {118,"Centimeters"},
2691 {119,"Pounds Mass Per Second"},
2692 {120,"Delta Degrees Fahrenheit"},
2693 {121,"Delta Degrees Kelvin"},
2697 {125,"Kilojoules Per Kg"},
2699 {127,"Joules Per Degree Kelvin"},
2700 {128,"Joules Per Kg Degree Kelvin"},
2705 {133,"Hectopascals"},
2707 {135,"Cubic Meters Per Hour"},
2708 {136,"Liters Per Hour"},
2709 {137,"KWatt Hours Per Square Meter"},
2710 {138,"KWatt Hours Per Square Foot"},
2711 {139,"Megajoules Per Square Meter"},
2712 {140,"Megajoules Per Square Foot"},
2713 {141,"Watts Per Sq Meter Degree Kelvin"},
2714 {142,"Cubic Feet Per Second"},
2715 {143,"Percent Obstruction Per Foot"},
2716 {144,"Percent Obstruction Per Meter"},
2718 {146,"megawatt-hours"},
2721 {149,"kilojoules-per-kilogram-dry-air"},
2722 {150,"megajoules-per-kilogram-dry-air"},
2723 {151,"kilojoules-per-degree-Kelvin"},
2724 {152,"megajoules-per-degree-Kelvin"},
2726 {154,"grams-per-second"},
2727 {155,"grams-per-minute"},
2728 {156,"tons-per-hour"},
2729 {157,"kilo-btus-per-hour"},
2730 {158,"hundredths-seconds"},
2731 {159,"milliseconds"},
2732 {160,"newton-meters"},
2733 {161,"millimeters-per-second"},
2734 {162,"millimeters-per-minute"},
2735 {163,"meters-per-minute"},
2736 {164,"meters-per-hour"},
2737 {165,"cubic-meters-per-minute"},
2738 {166,"meters-per-second-per-second"},
2739 {167,"amperes-per-meter"},
2740 {168,"amperes-per-square-meter"},
2741 {169,"ampere-square-meters"},
2746 {174,"siemens-per-meter"},
2748 {176,"volts-per-degree-Kelvin"},
2749 {177,"volts-per-meter"},
2752 {180,"candelas-per-square-meter"},
2753 {181,"degrees-Kelvin-per-hour"},
2754 {182,"degrees-Kelvin-per-minute"},
2755 {183,"joule-seconds"},
2756 {184,"radians-per-second"},
2757 {185,"square-meters-per-Newton"},
2758 {186,"kilograms-per-cubic-meter"},
2759 {187,"newton-seconds"},
2760 {188,"newtons-per-meter"},
2761 {189,"watts-per-meter-per-degree-Kelvin"},
2763 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2764 Enumerated values 256-65535 may be used by others subject to
2765 the procedures and constraints described in Clause 23. */
2768 static const value_string
2769 BACnetErrorCode [] = {
2771 {1,"authentication-failed"},
2772 {2,"configuration-in-progress"},
2774 {4,"dynamic-creation-not-supported"},
2775 {5,"file-access-denied"},
2776 {6,"incompatible-security-levels"},
2777 {7,"inconsistent-parameters"},
2778 {8,"inconsistent-selection-criterion"},
2779 {9,"invalid-data-type"},
2780 {10,"invalid-file-access-method"},
2781 {11,"invalid-file-start-position"},
2782 {12,"invalid-operator-name"},
2783 {13,"invalid-parameter-data-type"},
2784 {14,"invalid-time-stamp"},
2785 {15,"key-generation-error"},
2786 {16,"missing-required-parameter"},
2787 {17,"no-objects-of-specified-type"},
2788 {18,"no-space-for-object"},
2789 {19,"no-space-to-add-list-element"},
2790 {20,"no-space-to-write-property"},
2791 {21,"no-vt-sessions-available"},
2792 {22,"property-is-not-a-list"},
2793 {23,"object-deletion-not-permitted"},
2794 {24,"object-identifier-already-exists"},
2795 {25,"operational-problem"},
2796 {26,"password-failure"},
2797 {27,"read-access-denied"},
2798 {28,"security-not-supported"},
2799 {29,"service-request-denied"},
2801 {31,"unknown-object"},
2802 {32,"unknown-property"},
2803 {33,"removed enumeration"},
2804 {34,"unknown-vt-class"},
2805 {35,"unknown-vt-session"},
2806 {36,"unsupported-object-type"},
2807 {37,"value-out-of-range"},
2808 {38,"vt-session-already-closed"},
2809 {39,"vt-session-termination-failure"},
2810 {40,"write-access-denied"},
2811 {41,"character-set-not-supported"},
2812 {42,"invalid-array-index"},
2813 {43,"cov-subscription-failed"},
2814 {44,"not-cov-property"},
2815 {45,"optional-functionality-not-supported"},
2816 {46,"invalid-configuration-data"},
2817 {47,"datatype-not-supported"},
2818 {48,"duplicate-name"},
2819 {49,"duplicate-object-id"},
2820 {50,"property-is-not-an-array"},
2821 {73,"invalid-event-state"},
2822 {74,"no-alarm-configured"},
2824 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2825 Enumerated values 256-65535 may be used by others subject to the
2826 procedures and constraints described in Clause 23. */
2829 static const value_string
2830 BACnetPropertyIdentifier [] = {
2831 {0,"acked-transition"},
2836 {5,"active-vt-session"},
2840 {9,"all-write-successful"},
2841 {10,"apdu-segment-timeout"},
2842 {11,"apdu-timeout"},
2843 {12,"application-software-version"},
2846 {15,"change-of-state-count"},
2847 {16,"change-of-state-time"},
2848 {17,"notification-class"},
2849 {18,"the property in this place was deleted"},
2850 {19,"controlled-variable-reference"},
2851 {20,"controlled-variable-units"},
2852 {21,"controlled-variable-value"},
2853 {22,"cov-increment"},
2855 {24,"daylights-savings-status"},
2857 {26,"derivative-constant"},
2858 {27,"derivative-constant-units"},
2860 {29,"description-of-halt"},
2861 {30,"device-address-binding"},
2863 {32,"effective-period"},
2864 {33,"elapsed-active-time"},
2866 {35,"event-enable"},
2869 {38,"exception-schedule"},
2870 {39,"fault-values"},
2871 {40,"feedback-value"},
2872 {41,"file-access-method"},
2875 {44,"firmware-revision"},
2877 {46,"inactive-text"},
2880 {49,"integral-constant"},
2881 {50,"integral-constant-units"},
2882 {51,"issue-confirmed-notifications"},
2883 {52,"limit-enable"},
2884 {53,"list-of-group-members"},
2885 {54,"list-of-object-property-references"},
2886 {55,"list-of-session-keys"},
2891 {60,"manipulated-variable-reference"},
2892 {61,"maximum-output"},
2893 {62,"max-apdu-length-accepted"},
2894 {63,"max-info-frames"},
2896 {65,"max-pres-value"},
2897 {66,"minimum-off-time"},
2898 {67,"minimum-on-time"},
2899 {68,"minimum-output"},
2900 {69,"min-pres-value"},
2902 {71,"modification-date"},
2904 {73,"number-of-APDU-retries"},
2905 {74,"number-of-states"},
2906 {75,"object-identifier"},
2909 {78,"object-property-reference"},
2912 {81,"out-of-service"},
2913 {82,"output-units"},
2914 {83,"event-parameters"},
2916 {85,"present-value"},
2918 {87,"priority-array"},
2919 {88,"priority-for-writing"},
2920 {89,"process-identifier"},
2921 {90,"program-change"},
2922 {91,"program-location"},
2923 {92,"program-state"},
2924 {93,"proportional-constant"},
2925 {94,"proportional-constant-units"},
2926 {95,"protocol-conformance-class"},
2927 {96,"protocol-object-types-supported"},
2928 {97,"protocol-services-supported"},
2929 {98,"protocol-version"},
2931 {100,"reason-for-halt"},
2933 {102,"recipient-list"},
2934 {103,"reliability"},
2935 {104,"relinquish-default"},
2938 {107,"segmentation-supported"},
2940 {109,"setpoint-reference"},
2942 {111,"status-flags"},
2943 {112,"system-status"},
2945 {114,"time-of-active-time-reset"},
2946 {115,"time-of-state-count-reset"},
2947 {116,"time-synchronization-recipients"},
2949 {118,"update-interval"},
2951 {120,"vendor-identifier"},
2952 {121,"vendor-name"},
2953 {122,"vt-class-supported"},
2954 {123,"weekly-schedule"},
2955 {124,"attempted-samples"},
2956 {125,"average-value"},
2957 {126,"buffer-size"},
2958 {127,"client-cov-increment"},
2959 {128,"cov-resubscription-interval"},
2960 {129,"current-notify-time"},
2961 {130,"event-time-stamp"},
2963 {132,"log-device-object-property"},
2964 {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
2965 {134,"log-interval"},
2966 {135,"maximum-value"},
2967 {136,"minimum-value"},
2968 {137,"notification-threshold"},
2969 {138,"previous-notify-time"},
2970 {139,"protocol-revision"},
2971 {140,"records-since-notification"},
2972 {141,"record-count"},
2975 {144,"stop-when-full"},
2976 {145,"total-record-count"},
2977 {146,"valid-samples"},
2978 {147,"window-interval"},
2979 {148,"window-samples"},
2980 {149,"maximum-value-time-stamp"},
2981 {150,"minimum-value-time-stamp"},
2982 {151,"variance-value"},
2983 {152,"active-cov-subscriptions"},
2984 {153,"backup-failure-timeout"},
2985 {154,"configuration-files"},
2986 {155,"database-revision"},
2987 {156,"direct-reading"},
2988 {157,"last-restore-time"},
2989 {158,"maintenance-required"},
2992 {161,"operation-expected"},
2995 {164,"tracking-value"},
2996 {165,"zone-members"},
2997 {166,"life-safety-alarm-values"},
2998 {167,"max-segments-accepted"},
2999 {168,"profile-name"},
3000 {169,"auto-slave-discovery"},
3001 {170,"manual-slave-address-binding"},
3002 {171,"slave-address-binding"},
3003 {172,"slave-proxy-enable"},
3004 {173,"last-notify-record"}, /* bug 4117 */
3005 {174,"schedule-default"},
3006 {175,"accepted-modes"},
3007 {176,"adjust-value"},
3009 {178,"count-before-change"},
3010 {179,"count-change-time"},
3012 {181,"input-reference"},
3013 {182,"limit-monitoring-interval"},
3014 {183,"logging-device"},
3015 {184,"logging-record"},
3019 {188,"scale-factor"},
3020 {189,"update-time"},
3021 {190,"value-before-change"},
3023 {192,"value-change-time"},
3024 {193,"align-intervals"},
3025 {194,"group-member-names"},
3026 {195,"interval-offset"},
3027 {196,"last-restart-reason"},
3028 {197,"logging-type"},
3029 {198,"member-status-flags"},
3030 {199,"notification-period"},
3031 {200,"previous-notify-record"},
3032 {201,"requested-update-interval"},
3033 {202,"restart-notification-recipients"},
3034 {203,"time-of-device-restart"},
3035 {204,"time-synchronization-recipients"},
3037 {206,"UTC-time-synchronization-recipients"},
3038 {207,"node-subtype"},
3040 {209,"structured-object-list"},
3041 {210,"subordinate-annotations"},
3042 {211,"subordinate-list"},
3043 {212,"actual-shed-level"},
3044 {213,"duty-window"},
3045 {214,"expected-shed-level"},
3046 {215,"full-duty-baseline"},
3047 {216,"node-subtype"},
3049 {218,"requested-shed-level"},
3050 {219,"shed-duration"},
3051 {220,"shed-level-descriptions"},
3052 {221,"shed-levels"},
3053 {222,"state-description"},
3054 {226,"door-alarm-state"},
3055 {227,"door-extended-pulse-time"},
3056 {228,"door-members"},
3057 {229,"door-open-too-long-time"},
3058 {230,"door-pulse-time"},
3059 {231,"door-status"},
3060 {232,"door-unlock-delay-time"},
3061 {233,"lock-status"},
3062 {234,"masked-alarm-values"},
3063 {235,"secured-status"},
3064 {244,"absentee-limit"}, /* added with addenda 135-2008j */
3065 {245,"access-alarm-events"},
3066 {246,"access-doors"},
3067 {247,"access-event"},
3068 {248,"access-event-authentication-factor"},
3069 {249,"access-event-credential"},
3070 {250,"access-event-time"},
3071 {251,"access-transaction-events"},
3072 {252,"accompaniment"},
3073 {253,"accompaniment-time"},
3074 {254,"activation-time"},
3075 {255,"active-authentication-policy"},
3076 {256,"assigned-access-rights"},
3077 {257,"authentication-factors"},
3078 {258,"authentication-policy-list"},
3079 {259,"authentication-policy-names"},
3080 {260,"authentication-status"},
3081 {261,"authorization-mode"},
3083 {263,"credential-disable"},
3084 {264,"credential-status"},
3085 {265,"credentials"},
3086 {266,"credentials-in-zone"},
3087 {267,"days-remaining"},
3088 {268,"entry-points"},
3089 {269,"exit-points"},
3090 {270,"expiry-time"},
3091 {271,"extended-time-enable"},
3092 {272,"failed-attempt-events"},
3093 {273,"failed-attempts"},
3094 {274,"failed-attempts-time"},
3095 {275,"last-access-event"},
3096 {276,"last-access-point"},
3097 {277,"last-credential-added"},
3098 {278,"last-credential-added-time"},
3099 {279,"last-credential-removed"},
3100 {280,"last-credential-removed-time"},
3101 {281,"last-use-time"},
3103 {283,"lockout-relinquish-time"},
3104 {284,"master-exemption"},
3105 {285,"max-failed-attempts"},
3107 {287,"muster-point"},
3108 {288,"negative-access-rules"},
3109 {289,"number-of-authentication-policies"},
3110 {290,"occupancy-count"},
3111 {291,"occupancy-count-adjust"},
3112 {292,"occupancy-count-enable"},
3113 {293,"occupancy-exemption"},
3114 {294,"occupancy-lower-limit"},
3115 {295,"occupancy-lower-limit-enforced"},
3116 {296,"occupancy-state"},
3117 {297,"occupancy-upper-limit"},
3118 {298,"occupancy-upper-limit-enforced"},
3119 {299,"passback-exemption"},
3120 {300,"passback-mode"},
3121 {301,"passback-timeout"},
3122 {302,"positive-access-rules"},
3123 {303,"reason-for-disable"},
3124 {304,"supported-formats"},
3125 {305,"supported-format-classes"},
3126 {306,"threat-authority"},
3127 {307,"threat-level"},
3129 {309,"transaction-notification-class"},
3130 {310,"user-external-identifier"},
3131 {311,"user-information-reference"},
3132 /* enumeration values 312-316 reserved for future addenda */
3135 {319,"uses-remaining"},
3138 {322,"access-event-tag"},
3139 {323,"global-identifier"},
3140 /* enumeration values 324-325 reserved for future addenda */
3141 {326,"verification-time"},
3142 {342,"bit-mask"}, /* addenda 135-2008w */
3146 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3147 Enumerated values 512-4194303 may be used by others subject to
3148 the procedures and constraints described in Clause 23. */
3151 static const value_string
3152 BACnetBinaryPV [] = {
3160 #define IBM_MS_DBCS 1
3161 #define JIS_C_6226 2
3162 #define ISO_10646_UCS4 3
3163 #define ISO_10646_UCS2 4
3164 #define ISO_18859_1 5
3165 static const value_string
3166 BACnetCharacterSet [] = {
3167 {ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3168 {IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3169 {JIS_C_6226, "JIS C 6226"},
3170 {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3171 {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3172 {ISO_18859_1, "ISO 18859-1"},
3176 static const value_string
3177 BACnetStatusFlags [] = {
3181 {3,"out-of-service"},
3185 static const value_string
3186 BACnetMessagePriority [] = {
3192 static const value_string
3193 BACnetAcknowledgementFilter [] = {
3200 static const value_string
3201 BACnetResultFlags [] = {
3208 static const value_string
3209 BACnetRelationSpecifier [] = {
3214 {4,"less-than-or-equal"},
3215 {5,"greater-than-or-equal"},
3219 static const value_string
3220 BACnetSelectionLogic [] = {
3227 static const value_string
3228 BACnetEventStateFilter [] = {
3237 static const value_string
3238 BACnetEventTransitionBits [] = {
3245 static const value_string
3246 BACnetSegmentation [] = {
3247 {0,"segmented-both"},
3248 {1,"segmented-transmit"},
3249 {2,"segmented-receive"},
3250 {3,"no-segmentation"},
3254 static const value_string
3255 BACnetSilencedState [] = {
3257 {1,"audible-silenced"},
3258 {2,"visible-silenced"},
3263 static const value_string
3264 BACnetDeviceStatus [] = {
3266 {1,"operational-read-only"},
3267 {2,"download-required"},
3268 {3,"download-in-progress"},
3269 {4,"non-operational"},
3270 {5,"backup-in-progress"},
3274 static const value_string
3275 BACnetEnableDisable [] = {
3278 {2,"disable-initiation"},
3282 static const value_string
3300 static const value_string
3302 {1,"days numbered 1-7" },
3303 {2,"days numbered 8-14" },
3304 {3,"days numbered 15-21" },
3305 {4,"days numbered 22-28" },
3306 {5,"days numbered 29-31" },
3307 {6,"last 7 days of this month" },
3308 {255,"any week of this month" },
3312 /* note: notification class object recipient-list uses
3313 different day-of-week enum */
3314 static const value_string
3323 {255,"any day of week" },
3327 static const value_string
3328 BACnetErrorClass [] = {
3337 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3338 Enumerated values64-65535 may be used by others subject to
3339 the procedures and constraints described in Clause 23. */
3342 static const value_string
3343 BACnetVTClass [] = {
3344 {0,"default-terminal" },
3354 static const value_string
3355 BACnetEventType [] = {
3356 {0,"change-of-bitstring" },
3357 {1,"change-of-state" },
3358 {2,"change-of-value" },
3359 {3,"command-failure" },
3360 {4,"floating-limit" },
3361 {5,"out-of-range" },
3362 {6,"complex-event-type" },
3363 {7,"buffer-ready" },
3364 {8,"change-of-life-safety" },
3366 {10,"buffer-ready" },
3367 {11,"unsigned-range" },
3368 {14,"double-out-of-range"}, /* added with addenda 135-2008w */
3369 {15,"signed-out-of-range"},
3370 {16,"unsigned-out-of-range"},
3371 {17,"change-of-characterstring"},
3373 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3374 Enumerated values 64-65535 may be used by others subject to
3375 the procedures and constraints described in Clause 23.
3376 It is expected that these enumerated values will correspond
3377 to the use of the complex-event-type CHOICE [6] of the
3378 BACnetNotificationParameters production. */
3381 static const value_string
3382 BACnetEventState [] = {
3388 {5,"life-safety-alarm" },
3390 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3391 Enumerated values 64-65535 may be used by others subject to
3392 the procedures and constraints described in Clause 23. */
3395 static const value_string
3396 BACnetLogStatus [] = {
3397 {0,"log-disabled" },
3398 {1,"buffer-purged" },
3402 static const value_string
3403 BACnetMaintenance [] = {
3405 {1,"periodic-test" },
3406 {2,"need-service-operational" },
3407 {3,"need-service-inoperative" },
3411 static const value_string
3412 BACnetNotifyType [] = {
3415 {2,"ack-notification" },
3419 static const value_string
3420 BACnetServicesSupported [] = {
3421 {0,"acknowledgeAlarm"},
3422 {1,"confirmedCOVNotification"},
3423 {2,"confirmedEventNotification"},
3424 {3,"getAlarmSummary"},
3425 {4,"getEnrollmentSummary"},
3427 {6,"atomicReadFile"},
3428 {7,"atomicWriteFile"},
3429 {8,"addListElement"},
3430 {9,"removeListElement"},
3431 {10,"createObject"},
3432 {11,"deleteObject"},
3433 {12,"readProperty"},
3434 {13,"readPropertyConditional"},
3435 {14,"readPropertyMultiple"},
3436 {15,"writeProperty"},
3437 {16,"writePropertyMultiple"},
3438 {17,"deviceCommunicationControl"},
3439 {18,"confirmedPrivateTransfer"},
3440 {19,"confirmedTextMessage"},
3441 {20,"reinitializeDevice"},
3445 {24,"authenticate"},
3449 {28,"unconfirmedCOVNotification"},
3450 {29,"unconfirmedEventNotification"},
3451 {30,"unconfirmedPrivateTransfer"},
3452 {31,"unconfirmedTextMessage"},
3453 {32,"timeSynchronization"},
3457 {36,"utcTimeSynchronization"},
3458 {37,"lifeSafetyOperation"},
3459 {38,"subscribeCOVProperty"},
3460 {39,"getEventInformation"},
3464 static const value_string
3465 BACnetPropertyStates [] = {
3466 {0,"boolean-value"},
3470 {4,"program-change"},
3471 {5,"program-state"},
3472 {6,"reason-for-halt"},
3475 {9,"system-status"},
3477 {11,"unsigned-value"},
3478 {12,"life-safety-mode"},
3479 {13,"life-safety-state"},
3480 {14,"door-alarm-state"},
3482 /* Tag values 0-63 are reserved for definition by ASHRAE.
3483 Tag values of 64-254 may be used by others to accommodate
3484 vendor specific properties that have discrete or enumerated values,
3485 subject to the constraints described in Clause 23. */
3488 static const value_string
3489 BACnetProgramError [] = {
3496 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3497 Enumerated values 64-65535 may be used by others subject to
3498 the procedures and constraints described in Clause 23. */
3501 static const value_string
3502 BACnetProgramRequest [] = {
3512 static const value_string
3513 BACnetProgramState [] = {
3523 static const value_string
3524 BACnetReinitializedStateOfDevice [] = {
3535 static const value_string
3536 BACnetPolarity [] = {
3542 static const value_string
3543 BACnetTagNames[] = {
3544 { 5, "Extended Value" },
3545 { 6, "Opening Tag" },
3546 { 7, "Closing Tag" },
3550 static const value_string
3551 BACnetReadRangeOptions[] = {
3552 { 3, "range byPosition" },
3553 { 4, "range byTime" },
3554 { 5, "range timeRange" },
3555 { 6, "range bySequenceNumber" },
3556 { 7, "range byTime" },
3560 /* Present_Value for Load Control Object */
3561 static const value_string
3562 BACnetShedState[] = {
3563 { 0, "shed-inactive" },
3564 { 1, "shed-request-pending" },
3565 { 2, "shed-compliant" },
3566 { 3, "shed-non-compliant" },
3570 static const value_string
3571 BACnetVendorIdentifiers [] = {
3574 { 2, "The Trane Company" },
3575 { 3, "McQuay International" },
3577 { 5, "Johnson Controls, Inc." },
3578 { 6, "American Auto-Matrix" },
3579 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3580 { 8, "Delta Controls" },
3581 { 9, "Siemens Building Technologies, Inc." },
3582 { 10, "Tour Andover Controls Corporation" },
3584 { 12, "Orion Analysis Corporation" },
3585 { 13, "Teletrol Systems Inc." },
3586 { 14, "Cimetrics Technology" },
3587 { 15, "Cornell University" },
3588 { 16, "United Technologies Carrier" },
3589 { 17, "Honeywell Inc." },
3590 { 18, "Alerton / Honeywell" },
3592 { 20, "Hewlett-Packard Company" },
3593 { 21, "Dorsette's Inc." },
3594 { 22, "Cerberus AG" },
3595 { 23, "York Controls Group" },
3596 { 24, "Automated Logic Corporation" },
3597 { 25, "CSI Control Systems International" },
3598 { 26, "Phoenix Controls Corporation" },
3599 { 27, "Innovex Technologies, Inc." },
3600 { 28, "KMC Controls, Inc." },
3601 { 29, "Xn Technologies, Inc." },
3602 { 30, "Hyundai Information Technology Co., Ltd." },
3603 { 31, "Tokimec Inc." },
3605 { 33, "North Communications Limited" },
3607 { 35, "Reliable Controls Corporation" },
3608 { 36, "Tridium Inc." },
3609 { 37, "Sierra Monitor Corp." },
3610 { 38, "Silicon Energy" },
3611 { 39, "Kieback & Peter GmbH & Co KG" },
3612 { 40, "Anacon Systems, Inc." },
3613 { 41, "Systems Controls & Instruments, LLC" },
3614 { 42, "Lithonia Lighting" },
3615 { 43, "Micropower Manufacturing" },
3616 { 44, "Matrix Controls" },
3617 { 45, "METALAIRE" },
3618 { 46, "ESS Engineering" },
3619 { 47, "Sphere Systems Pty Ltd." },
3620 { 48, "Walker Technologies Corporation" },
3621 { 49, "H I Solutions, Inc." },
3623 { 51, "SAMSON AG" },
3624 { 52, "Badger Meter Inc." },
3625 { 53, "DAIKIN Industries Ltd." },
3626 { 54, "NARA Controls Inc." },
3627 { 55, "Mammoth Inc." },
3628 { 56, "Liebert Corporation" },
3629 { 57, "SEMCO Incorporated" },
3630 { 58, "Air Monitor Corporation" },
3631 { 59, "TRIATEK, Inc." },
3633 { 61, "Multistack" },
3634 { 62, "TSI Incorporated" },
3635 { 63, "Weather-Rite, Inc." },
3636 { 64, "Dunham-Bush" },
3637 { 65, "Reliance Electric" },
3639 { 67, "Regulator Australia PTY Ltd." },
3640 { 68, "Touch-Plate Lighting Controls" },
3641 { 69, "Amann GmbH" },
3642 { 70, "RLE Technologies" },
3643 { 71, "Cardkey Systems" },
3644 { 72, "SECOM Co., Ltd." },
3645 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3646 { 74, "KNX Association cvba" },
3647 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3648 { 76, "Nohmi Bosai, Ltd." },
3649 { 77, "Carel S.p.A." },
3650 { 78, "AirSense Technology, Inc." },
3651 { 79, "Hochiki Corporation" },
3652 { 80, "Fr. Sauter AG" },
3653 { 81, "Matsushita Electric Works, Ltd." },
3654 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3655 { 83, "Mitsubishi Heavy Industries, Ltd." },
3656 { 84, "ITT Bell & Gossett" },
3657 { 85, "Yamatake Building Systems Co., Ltd." },
3658 { 86, "The Watt Stopper, Inc." },
3659 { 87, "Aichi Tokei Denki Co., Ltd." },
3660 { 88, "Activation Technologies, LLC" },
3661 { 89, "Saia-Burgess Controls, Ltd." },
3662 { 90, "Hitachi, Ltd." },
3663 { 91, "Novar Corp./Trend Control Systems Ltd." },
3664 { 92, "Mitsubishi Electric Lighting Corporation" },
3665 { 93, "Argus Control Systems, Ltd." },
3666 { 94, "Kyuki Corporation" },
3667 { 95, "Richards-Zeta Building Intelligence, Inc." },
3668 { 96, "Scientech R&D, Inc." },
3669 { 97, "VCI Controls, Inc." },
3670 { 98, "Toshiba Corporation" },
3671 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3672 { 100, "Custom Mechanical Equipment, LLC" },
3673 { 101, "ClimateMaster" },
3674 { 102, "ICP Panel-Tec, Inc." },
3675 { 103, "D-Tek Controls" },
3676 { 104, "NEC Engineering, Ltd." },
3677 { 105, "PRIVA BV" },
3678 { 106, "Meidensha Corporation" },
3679 { 107, "JCI Systems Integration Services" },
3680 { 108, "Freedom Corporation" },
3681 { 109, "Neuberger Gebaudeautomation GmbH" },
3682 { 110, "Sitronix" },
3683 { 111, "Leviton Manufacturing" },
3684 { 112, "Fujitsu Limited" },
3685 { 113, "Emerson Network Power" },
3686 { 114, "S. A. Armstrong, Ltd." },
3687 { 115, "Visonet AG" },
3688 { 116, "M&M Systems, Inc." },
3689 { 117, "Custom Software Engineering" },
3690 { 118, "Nittan Company, Limited" },
3691 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3692 { 120, "Pacom Systems Pty., Ltd." },
3693 { 121, "Unico, Inc." },
3694 { 122, "Ebtron, Inc." },
3695 { 123, "Scada Engine" },
3696 { 124, "AC Technology Corporation" },
3697 { 125, "Eagle Technology" },
3698 { 126, "Data Aire, Inc." },
3699 { 127, "ABB, Inc." },
3700 { 128, "Transbit Sp. z o. o." },
3701 { 129, "Toshiba Carrier Corporation" },
3702 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
3703 { 131, "Tokai Soft" },
3705 { 133, "Veris Industries" },
3706 { 134, "Centaurus Prime" },
3707 { 135, "Sand Network Systems" },
3708 { 136, "Regulvar, Inc." },
3709 { 137, "Fastek International, Ltd." },
3710 { 138, "PowerCold Comfort Air Solutions, Inc." },
3711 { 139, "I Controls" },
3712 { 140, "Viconics Electronics, Inc." },
3713 { 141, "Yaskawa Electric America, Inc." },
3714 { 142, "Plueth Regelsysteme" },
3715 { 143, "Digitale Mess- und Steuersysteme AG" },
3716 { 144, "Fujitsu General Limited" },
3717 { 145, "Project Engineering S.r.l." },
3718 { 146, "Sanyo Electric Co., Ltd." },
3719 { 147, "Integrated Information Systems, Inc." },
3720 { 148, "Temco Controls, Ltd." },
3721 { 149, "Airtek Technologies, Inc." },
3722 { 150, "Advantech Corporation" },
3723 { 151, "Titan Products, Ltd." },
3724 { 152, "Regel Partners" },
3725 { 153, "National Environmental Product" },
3726 { 154, "Unitec Corporation" },
3727 { 155, "Kanden Engineering Company" },
3728 { 156, "Messner Gebaudetechnik GmbH" },
3729 { 157, "Integrated.CH" },
3730 { 158, "EH Price Limited" },
3731 { 159, "SE-Elektronic GmbH" },
3732 { 160, "Rockwell Automation" },
3733 { 161, "Enflex Corp." },
3734 { 162, "ASI Controls" },
3735 { 163, "SysMik GmbH Dresden" },
3736 { 164, "HSC Regelungstechnik GmbH" },
3737 { 165, "Smart Temp Australia Pty. Ltd." },
3738 { 166, "PCI Lighting Control Systems" },
3739 { 167, "Duksan Mecasys Co., Ltd." },
3740 { 168, "Fuji IT Co., Ltd." },
3741 { 169, "Vacon Plc" },
3742 { 170, "Leader Controls" },
3743 { 171, "Cylon Controls, Ltd." },
3745 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
3746 { 174, "Building Control Integrators" },
3747 { 175, "ITG Worldwide (M) Sdn Bhd" },
3748 { 176, "Lutron Electronics Co., Inc." },
3749 { 177, "Cooper-Atkins Corporation" },
3750 { 178, "LOYTEC Electronics GmbH" },
3752 { 180, "Mega Controls Limited" },
3753 { 181, "Micro Control Systems, Inc." },
3754 { 182, "Kiyon, Inc." },
3755 { 183, "Dust Networks" },
3756 { 184, "Advanced Building Automation Systems" },
3757 { 185, "Hermos AG" },
3760 { 188, "Lynxspring" },
3761 { 189, "Schneider Toshiba Inverter Europe" },
3762 { 190, "Danfoss Drives A/S" },
3763 { 191, "Eaton Corporation" },
3764 { 192, "Matyca S.A." },
3765 { 193, "Botech AB" },
3766 { 194, "Noveo, Inc." },
3768 { 196, "Yokogawa Electric Corporation" },
3769 { 197, "GFR Gesellschaft fur Regelungstechnik" },
3770 { 198, "Exact Logic" },
3771 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
3772 { 200, "Kandenko Co., Ltd." },
3773 { 201, "DTF, Daten-Technik Fries" },
3774 { 202, "Klimasoft, Ltd." },
3775 { 203, "Toshiba Schneider Inverter Corporation" },
3776 { 204, "Control Applications, Ltd." },
3777 { 205, "KDT Systems Co., Ltd." },
3778 { 206, "Onicon Incorporated" },
3779 { 207, "Automation Displays, Inc." },
3780 { 208, "Control Solutions, Inc." },
3781 { 209, "Remsdaq Limited" },
3782 { 210, "NTT Facilities, Inc." },
3783 { 211, "VIPA GmbH" },
3784 { 212, "TSC21 Association of Japan" },
3785 { 213, "BBP Energie Ltee" },
3786 { 214, "HRW Limited" },
3787 { 215, "Lighting Control & Design, Inc." },
3788 { 216, "Mercy Electronic and Electrical Industries" },
3789 { 217, "Samsung SDS Co., Ltd" },
3790 { 218, "Impact Facility Solutions, Inc." },
3791 { 219, "Aircuity" },
3792 { 220, "Control Techniques, Ltd." },
3793 { 221, "Evolve Control Systems, LLC" },
3794 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
3795 { 223, "Cerus Industrial" },
3796 { 224, "Chloride Power Protection Company" },
3797 { 225, "Computrols, Inc." },
3798 { 226, "Phoenix Contact GmbH & Co. KG" },
3799 { 227, "Grundfos Management A/S" },
3800 { 228, "Ridder Drive Systems" },
3801 { 229, "Soft Device SDN BHD" },
3802 { 230, "Integrated Control Technology Limited" },
3803 { 231, "AIRxpert Systems, Inc." },
3804 { 232, "Microtrol Limited" },
3805 { 233, "Red Lion Controls" },
3806 { 234, "Digital Electronics Corporation" },
3807 { 235, "Ennovatis GmbH" },
3808 { 236, "Serotonin Software Technologies, Inc." },
3809 { 237, "LS Industrial Systems Co., Ltd." },
3810 { 238, "Square D Company" },
3811 { 239, "S Squared Innovations, Inc." },
3812 { 240, "Aricent Ltd." },
3813 { 241, "EtherMetrics, LLC" },
3814 { 242, "Industrial Control Communications, Inc." },
3815 { 243, "Paragon Controls, Inc." },
3816 { 244, "A. O. Smith Corporation" },
3817 { 245, "Contemporary Control Systems, Inc." },
3818 { 246, "Intesis Software SL" },
3819 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
3820 { 248, "Heat-Timer Corporation" },
3821 { 249, "Ingrasys Technology, Inc." },
3822 { 250, "Costerm Building Automation" },
3824 { 252, "Embedia Technologies Corp." },
3825 { 253, "Technilog" },
3826 { 254, "HR Controls Ltd. & Co. KG" },
3827 { 255, "Lennox International, Inc." },
3828 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
3829 { 257, "Thermomax, Ltd." },
3830 { 258, "ELCON Electronic Control, Ltd." },
3831 { 259, "Larmia Control AB" },
3832 { 260, "BACnet Stack at SourceForge" },
3833 { 261, "G4S Security Services A/S" },
3834 { 262, "Sitek S.p.A." },
3835 { 263, "Cristal Controles" },
3836 { 264, "Regin AB" },
3837 { 265, "Dimension Software, Inc. " },
3838 { 266, "SynapSense Corporation" },
3839 { 267, "Beijing Nantree Electronic Co., Ltd." },
3840 { 268, "Camus Hydronics Ltd." },
3841 { 269, "Kawasaki Heavy Industries, Ltd. " },
3842 { 270, "Critical Environment Technologies" },
3843 { 271, "ILSHIN IBS Co., Ltd." },
3844 { 272, "ELESTA Energy Control AG" },
3845 { 273, "KROPMAN Installatietechniek" },
3846 { 274, "Baldor Electric Company" },
3847 { 275, "INGA mbH" },
3848 { 276, "GE Consumer & Industrial" },
3849 { 277, "Functional Devices, Inc." },
3851 { 279, "M-System Co., Ltd." },
3852 { 280, "Yokota Co., Ltd." },
3853 { 281, "Hitranse Technology Co., LTD" },
3854 { 282, "Federspiel Controls" },
3855 { 283, "Kele, Inc." },
3856 { 284, "Opera Electronics, Inc." },
3858 { 286, "Embedded Science Labs, LLC" },
3859 { 287, "Parker Hannifin Corporation" },
3860 { 288, "MaCaPS International Limited" },
3861 { 289, "Link4 Corporation" },
3862 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
3863 { 291, "Pribusin, Inc." },
3864 { 292, "Advantage Controls" },
3865 { 293, "Critical Room Control" },
3867 { 295, "Tongdy Control Technology Co., Ltd." },
3868 { 296, "ISSARO Integrierte Systemtechnik" },
3869 { 297, "Pro-Dev Industries" },
3870 { 298, "DRI-STEEM" },
3871 { 299, "Creative Electronic GmbH" },
3872 { 300, "Swegon AB" },
3873 { 301, "Jan Brachacek" },
3874 { 302, "Hitachi Appliances, Inc." },
3875 { 303, "Real Time Automation, Inc." },
3876 { 304, "ITEC Hankyu-Hanshin Co." },
3877 { 305, "Cyrus E&M Engineering Co., Ltd." },
3878 { 306, "Racine Federated, Inc." },
3879 { 307, "Verari Systems, Inc." },
3880 { 308, "Elesta GmbH Building Automation" },
3881 { 309, "Securiton" },
3882 { 310, "OSlsoft, Inc." },
3883 { 311, "Hanazeder Electronic GmbH" },
3884 { 312, "Honeywell Security Deutschland, Novar GmbH" },
3885 { 313, "Siemens Energy & Automation, Inc." },
3886 { 314, "ETM Professional Control GmbH" },
3887 { 315, "Meitav-tec, Ltd." },
3888 { 316, "Janitza Electronics GmbH" },
3889 { 317, "MKS Nordhausen" },
3890 { 318, "De Gier Drive Systems B.V." },
3891 { 319, "Cypress Envirosystems" },
3892 { 320, "SMARTron s.r.o." },
3893 { 321, "Verari Systems, Inc." },
3894 { 322, "K-W Electronic Service, Inc." },
3895 { 323, "ALFA-SMART Energy Management" },
3896 { 324, "Telkonet, Inc." },
3897 { 325, "Securiton GmbH" },
3898 { 326, "Cemtrex, Inc." },
3899 { 327, "Performance Technologies, Inc." },
3900 { 328, "Xtralis (Aust) Pty Ltd" },
3901 { 329, "TROX GmbH" },
3902 { 330, "Beijing Hysine Technology Co., Ltd" },
3903 { 331, "RCK Controls, Inc." },
3905 { 333, "Novar/Honeywell" },
3906 { 334, "The S4 Group, Inc." },
3907 { 335, "Schneider Electric" },
3908 { 336, "LHA Systems" },
3909 { 337, "GHM engineering Group, Inc." },
3910 { 338, "Cllimalux S.A." },
3911 { 339, "VAISALA Oyj" },
3912 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
3913 { 342, "POWERPEG NSI Limited" },
3914 { 343, "BACnet Interoperability Testing Services, Inc." },
3915 { 344, "Teco a.s." },
3919 static int proto_bacapp = -1;
3920 static int hf_bacapp_type = -1;
3921 static int hf_bacapp_pduflags = -1;
3922 static int hf_bacapp_SEG = -1;
3923 static int hf_bacapp_MOR = -1;
3924 static int hf_bacapp_SA = -1;
3925 static int hf_bacapp_response_segments = -1;
3926 static int hf_bacapp_max_adpu_size = -1;
3927 static int hf_bacapp_invoke_id = -1;
3928 static int hf_bacapp_objectType = -1;
3929 static int hf_bacapp_instanceNumber = -1;
3930 static int hf_bacapp_sequence_number = -1;
3931 static int hf_bacapp_window_size = -1;
3932 static int hf_bacapp_service = -1;
3933 static int hf_bacapp_NAK = -1;
3934 static int hf_bacapp_SRV = -1;
3935 static int hf_BACnetRejectReason = -1;
3936 static int hf_BACnetAbortReason = -1;
3937 static int hf_BACnetApplicationTagNumber = -1;
3938 static int hf_BACnetContextTagNumber = -1;
3939 static int hf_BACnetExtendedTagNumber = -1;
3940 static int hf_BACnetNamedTag = -1;
3941 static int hf_BACnetTagClass = -1;
3942 static int hf_BACnetCharacterSet = -1;
3943 static int hf_bacapp_tag = -1;
3944 static int hf_bacapp_tag_lvt = -1;
3945 static int hf_bacapp_tag_value8 = -1;
3946 static int hf_bacapp_tag_value16 = -1;
3947 static int hf_bacapp_tag_value32 = -1;
3948 static int hf_bacapp_tag_ProcessId = -1;
3949 static int hf_bacapp_tag_initiatingObjectType = -1;
3950 static int hf_bacapp_vpart = -1;
3951 static int hf_bacapp_uservice = -1;
3952 static int hf_BACnetPropertyIdentifier = -1;
3953 static int hf_BACnetVendorIdentifier = -1;
3954 static int hf_BACnetRestartReason = -1;
3955 static int hf_bacapp_tag_IPV4 = -1;
3956 static int hf_bacapp_tag_IPV6 = -1;
3957 static int hf_bacapp_tag_PORT = -1;
3958 /* some more variables for segmented messages */
3959 static int hf_msg_fragments = -1;
3960 static int hf_msg_fragment = -1;
3961 static int hf_msg_fragment_overlap = -1;
3962 static int hf_msg_fragment_overlap_conflicts = -1;
3963 static int hf_msg_fragment_multiple_tails = -1;
3964 static int hf_msg_fragment_too_long_fragment = -1;
3965 static int hf_msg_fragment_error = -1;
3966 static int hf_msg_reassembled_in = -1;
3967 static int hf_msg_reassembled_length = -1;
3969 static gint ett_msg_fragment = -1;
3970 static gint ett_msg_fragments = -1;
3972 static gint ett_bacapp = -1;
3973 static gint ett_bacapp_control = -1;
3974 static gint ett_bacapp_tag = -1;
3975 static gint ett_bacapp_list = -1;
3976 static gint ett_bacapp_value = -1;
3978 static dissector_handle_t data_handle;
3979 static gint32 propertyIdentifier = -1;
3980 static gint32 propertyArrayIndex = -1;
3981 static guint32 object_type = 4096;
3983 static guint8 bacapp_flags = 0;
3984 static guint8 bacapp_seq = 0;
3986 /* Defined to allow vendor identifier registration of private transfer dissectors */
3987 static dissector_table_t bacapp_dissector_table;
3989 static const fragment_items msg_frag_items = {
3990 /* Fragment subtrees */
3993 /* Fragment fields */
3996 &hf_msg_fragment_overlap,
3997 &hf_msg_fragment_overlap_conflicts,
3998 &hf_msg_fragment_multiple_tails,
3999 &hf_msg_fragment_too_long_fragment,
4000 &hf_msg_fragment_error,
4001 /* Reassembled in field */
4002 &hf_msg_reassembled_in,
4003 /* Reassembled length field */
4004 &hf_msg_reassembled_length,
4009 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
4010 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
4013 fGetMaxAPDUSize(guint8 idx)
4015 /* only 16 values are defined, so use & 0x0f */
4016 /* check the size of the Array, deliver either the entry
4017 or the first entry if idx is outside of the array (bug 3736 comment#7) */
4018 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
4019 return MaxAPDUSize[0];
4021 return MaxAPDUSize[idx & 0x0f];
4024 /* Used when there are ranges of reserved and proprietary enumerations */
4026 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
4027 const char *fmt, const char *split_fmt)
4029 if (val < split_val)
4030 return val_to_str(val, vs, fmt);
4032 return val_to_str(val, vs, split_fmt);
4035 /* from clause 20.2.1.3.2 Constructed Data */
4036 /* returns true if the extended value is used */
4038 tag_is_extended_value(guint8 tag)
4040 return (tag & 0x07) == 5;
4044 tag_is_opening(guint8 tag)
4046 return (tag & 0x07) == 6;
4050 tag_is_closing(guint8 tag)
4052 return (tag & 0x07) == 7;
4055 /* from clause 20.2.1.1 Class
4056 class bit shall be one for context specific tags */
4057 /* returns true if the tag is context specific */
4059 tag_is_context_specific(guint8 tag)
4061 return (tag & 0x08) != 0;
4065 tag_is_extended_tag_number(guint8 tag)
4067 return ((tag & 0xF0) == 0xF0);
4071 object_id_type(guint32 object_identifier)
4073 return ((object_identifier >> 22) & 0x3FF);
4077 object_id_instance(guint32 object_identifier)
4079 return (object_identifier & 0x3FFFFF);
4083 fTagNo (tvbuff_t *tvb, guint offset)
4085 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
4089 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
4091 gboolean valid = TRUE;
4095 *val = tvb_get_guint8(tvb, offset);
4098 *val = tvb_get_ntohs(tvb, offset);
4101 *val = tvb_get_ntoh24(tvb, offset);
4104 *val = tvb_get_ntohl(tvb, offset);
4115 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4117 gboolean valid = FALSE;
4121 if (lvt && (lvt <= 8)) {
4123 data = tvb_get_guint8(tvb, offset);
4124 for (i = 0; i < lvt; i++) {
4125 data = tvb_get_guint8(tvb, offset+i);
4126 value = (value << 8) + data;
4134 /* BACnet Signed Value uses 2's complement notation, but with a twist:
4135 All signed integers shall be encoded in the smallest number of octets
4136 possible. That is, the first octet of any multi-octet encoded value
4137 shall not be X'00' if the most significant bit (bit 7) of the second
4138 octet is 0, and the first octet shall not be X'FF' if the most
4139 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4141 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4143 gboolean valid = FALSE;
4148 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4149 if (lvt && (lvt <= 7)) {
4151 data = tvb_get_guint8(tvb, offset);
4152 if ((data & 0x80) != 0)
4153 value = (-1 << 8) | data;
4156 for (i = 1; i < lvt; i++) {
4157 data = tvb_get_guint8(tvb, offset+i);
4158 value = (value << 8) + data;
4167 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
4168 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4173 guint lvt_len = 1; /* used for tree display of lvt */
4174 guint lvt_offset; /* used for tree display of lvt */
4176 proto_tree *subtree;
4178 lvt_offset = offset;
4179 tag = tvb_get_guint8(tvb, offset);
4182 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4183 /* can mean open/close tag or length of 6/7 after the length is */
4184 /* computed below - store whole tag info, not just context bit. */
4185 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4187 if (tag_is_extended_tag_number(tag)) {
4188 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4190 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4191 lvt_offset += tag_len;
4192 value = tvb_get_guint8(tvb, lvt_offset);
4194 if (value == 254) { /* length is encoded with 16 Bits */
4195 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4198 } else if (value == 255) { /* length is encoded with 32 Bits */
4199 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4207 if (tag_is_opening(tag))
4208 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4209 else if (tag_is_closing(tag))
4210 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4211 else if (tag_is_context_specific(tag)) {
4212 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4213 "Context Tag: %u, Length/Value/Type: %u",
4216 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4217 "Application Tag: %s, Length/Value/Type: %u",
4219 BACnetApplicationTagNumber,
4220 ASHRAE_Reserved_Fmt),
4223 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4224 /* details if needed */
4225 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, FALSE);
4226 if (tag_is_extended_tag_number(tag)) {
4227 proto_tree_add_uint_format(subtree,
4228 hf_BACnetContextTagNumber,
4229 tvb, offset, 1, tag,
4230 "Extended Tag Number");
4231 proto_tree_add_item(subtree,
4232 hf_BACnetExtendedTagNumber,
4233 tvb, offset + 1, 1, FALSE);
4235 if (tag_is_context_specific(tag))
4236 proto_tree_add_item(subtree,
4237 hf_BACnetContextTagNumber,
4238 tvb, offset, 1, FALSE);
4240 proto_tree_add_item(subtree,
4241 hf_BACnetApplicationTagNumber,
4242 tvb, offset, 1, FALSE);
4244 if (tag_is_closing(tag) || tag_is_opening(tag))
4245 proto_tree_add_item(subtree,
4247 tvb, offset, 1, FALSE);
4248 else if (tag_is_extended_value(tag)) {
4249 proto_tree_add_item(subtree,
4251 tvb, offset, 1, FALSE);
4252 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4253 tvb, lvt_offset, lvt_len, *lvt);
4255 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4256 tvb, lvt_offset, lvt_len, *lvt);
4263 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
4266 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
4270 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4272 guint8 tag_no, tag_info;
4275 proto_tree *subtree;
4277 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4278 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4279 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4285 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4287 guint8 tag_no, tag_info;
4291 proto_tree *subtree;
4294 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4295 if (tag_info && lvt == 1)
4297 lvt = tvb_get_guint8(tvb, offset+1);
4301 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
4302 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
4303 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4304 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4306 return offset + bool_len;
4310 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4313 guint8 tag_no, tag_info;
4317 proto_tree *subtree;
4319 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4320 /* only support up to an 8 byte (64-bit) integer */
4321 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
4322 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4323 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
4325 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4326 "%s - %u octets (Unsigned)", label, lvt);
4327 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4328 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4330 return offset+tag_len+lvt;
4333 /* set split_val to zero when not needed */
4335 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4336 const value_string *vs, guint32 split_val)
4339 guint8 tag_no, tag_info;
4343 proto_tree *subtree;
4345 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4346 /* only support up to a 4 byte (32-bit) enumeration */
4347 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
4349 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4350 "%s %s", label, val_to_split_str(val, split_val, vs,
4351 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
4353 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4354 "%s %u", label, val);
4356 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4357 "%s - %u octets (enumeration)", label, lvt);
4359 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4360 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4362 return offset+tag_len+lvt;
4366 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4367 const value_string *vs)
4369 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
4373 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4376 guint8 tag_no, tag_info;
4380 proto_tree *subtree;
4382 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4383 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
4384 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4385 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
4387 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4388 "%s - %u octets (Signed)", label, lvt);
4389 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4390 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4392 return offset+tag_len+lvt;
4396 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4398 guint8 tag_no, tag_info;
4403 proto_tree *subtree;
4405 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4406 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
4407 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
4408 "%s%f (Real)", label, f_val);
4409 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4410 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4412 return offset+tag_len+4;
4416 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4418 guint8 tag_no, tag_info;
4423 proto_tree *subtree;
4425 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4426 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
4427 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
4428 "%s%f (Double)", label, d_val);
4429 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4430 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4432 return offset+tag_len+8;
4436 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
4438 guint32 val = 0, lvt;
4439 guint8 tag_no, tag_info;
4441 proto_tree *subtree;
4444 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4445 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4446 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
4447 tvb, offset, lvt+tag_len, val);
4449 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4450 "Process Identifier - %u octets (Signed)", lvt);
4451 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4452 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4453 offset += tag_len + lvt;
4459 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4461 guint32 val = 0, lvt;
4462 guint8 tag_no, tag_info;
4464 proto_tree *subtree;
4467 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4468 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4469 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4470 "%s (hh.mm.ss): %d.%02d.%02d%s",
4472 (val / 3600), ((val % 3600) / 60), (val % 60),
4473 val == 0 ? " (indefinite)" : "");
4475 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4476 "%s - %u octets (Signed)", label, lvt);
4477 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4478 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4480 return offset+tag_len+lvt;
4484 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
4486 guint32 month, weekOfMonth, dayOfWeek;
4487 guint8 tag_no, tag_info;
4491 proto_tree *subtree;
4493 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4494 month = tvb_get_guint8(tvb, offset+tag_len);
4495 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
4496 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
4497 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
4498 val_to_str(month, months, "month (%d) not found"),
4499 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
4500 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
4501 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4502 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4504 return offset+tag_len+lvt;
4508 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4510 guint32 year, month, day, weekday;
4511 guint8 tag_no, tag_info;
4515 proto_tree *subtree;
4517 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4518 year = tvb_get_guint8(tvb, offset+tag_len);
4519 month = tvb_get_guint8(tvb, offset+tag_len+1);
4520 day = tvb_get_guint8(tvb, offset+tag_len+2);
4521 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
4522 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255))
4524 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4527 else if (year != 255)
4530 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4531 "%s%s %d, %d, (Day of Week = %s)",
4532 label, val_to_str(month,
4534 "month (%d) not found"),
4535 day, year, val_to_str(weekday,
4541 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4542 "%s%s %d, any year, (Day of Week = %s)",
4543 label, val_to_str(month, months, "month (%d) not found"),
4544 day, val_to_str(weekday, day_of_week, "(%d) not found"));
4546 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4547 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4549 return offset+tag_len+lvt;
4553 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4555 guint32 hour, minute, second, msec, lvt;
4556 guint8 tag_no, tag_info;
4559 proto_tree *subtree;
4561 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4562 hour = tvb_get_guint8(tvb, offset+tag_len);
4563 minute = tvb_get_guint8(tvb, offset+tag_len+1);
4564 second = tvb_get_guint8(tvb, offset+tag_len+2);
4565 msec = tvb_get_guint8(tvb, offset+tag_len+3);
4566 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
4567 ti = proto_tree_add_text(tree, tvb, offset,
4568 lvt+tag_len, "%sany", label);
4570 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4571 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
4573 hour > 12 ? hour - 12 : hour,
4574 minute, second, msec,
4575 hour >= 12 ? "P.M." : "A.M.",
4576 hour, minute, second, msec);
4577 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4578 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4580 return offset+tag_len+lvt;
4584 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4586 proto_tree *subtree = tree;
4589 if (label != NULL) {
4590 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
4591 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4593 offset = fDate (tvb,subtree,offset,"Date: ");
4594 return fTime (tvb,subtree,offset,"Time: ");
4598 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4600 guint lastoffset = 0;
4601 guint8 tag_no, tag_info;
4604 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4605 lastoffset = offset;
4606 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4607 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
4610 offset = fTime (tvb,tree,offset,"Time: ");
4611 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
4613 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
4619 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
4621 guint8 tag_no, tag_info;
4624 switch (fTagNo(tvb, offset)) {
4626 offset = fDate (tvb, tree, offset, "Date: ");
4628 case 1: /* dateRange */
4629 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4630 offset = fDateRange (tvb, tree, offset);
4631 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4633 case 2: /* BACnetWeekNDay */
4634 offset = fWeekNDay (tvb, tree, offset);
4643 static guint fTimeStamp (tvbuff_t *tvb, proto_tree *tree,
4644 guint offset, const gchar *label)
4646 guint8 tag_no = 0, tag_info = 0;
4649 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
4650 switch (fTagNo(tvb, offset)) {
4652 offset = fTime (tvb, tree, offset, label?label:"timestamp: ");
4654 case 1: /* sequenceNumber */
4655 offset = fUnsignedTag (tvb, tree, offset,
4656 label?label:"sequence Number: ");
4658 case 2: /* dateTime */
4659 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4660 offset = fDateTime (tvb, tree, offset, label?label:"timestamp: ");
4661 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4673 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4675 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4676 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
4681 static const value_string
4682 BACnetDaysOfWeek [] = {
4694 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4696 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4697 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
4698 "valid Days: ", BACnetDaysOfWeek);
4699 offset = fTime (tvb,tree,offset,"from time: ");
4700 offset = fTime (tvb,tree,offset,"to time: ");
4701 offset = fRecipient (tvb,pinfo,tree,offset);
4702 offset = fProcessId (tvb,tree,offset);
4703 offset = fApplicationTypes (tvb,pinfo,tree,offset,
4704 "issue confirmed notifications: ");
4705 offset = fBitStringTagVS (tvb,tree,offset,
4706 "transitions: ", BACnetEventTransitionBits);
4713 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4716 guint start = offset;
4717 guint8 tag_no, tag_info;
4718 proto_tree* subtree = tree;
4721 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4725 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4726 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
4731 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4733 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4739 fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4742 guint start = offset;
4743 guint8 tag_no, tag_info;
4744 proto_tree* subtree = tree;
4747 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4749 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
4753 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
4755 guint32 ip = tvb_get_ipv4(tvb, offset);
4756 guint16 port = tvb_get_ntohs(tvb, offset+4);
4758 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
4759 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
4762 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
4763 struct e_in6_addr addr;
4764 guint16 port = tvb_get_ntohs(tvb, offset+16);
4765 tvb_get_ipv6(tvb, offset, &addr);
4767 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
4768 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
4770 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
4771 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4772 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
4779 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4781 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4787 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
4789 guint8 tag_no, tag_info;
4793 offset = fUnsignedTag (tvb, tree, offset, "network-number");
4794 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4796 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
4799 offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
4805 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
4807 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
4808 return fAddress (tvb,tree,offset);
4812 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4814 guint8 tag_no, tag_info;
4818 proto_tree *subtree;
4821 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4822 object_id = tvb_get_ntohl(tvb,offset+tag_length);
4823 object_type = object_id_type(object_id);
4824 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
4825 "ObjectIdentifier: %s, %u",
4826 val_to_split_str(object_type,
4829 ASHRAE_Reserved_Fmt,
4830 Vendor_Proprietary_Fmt),
4831 object_id_instance(object_id));
4832 if (col_get_writable(pinfo->cinfo))
4833 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
4834 val_to_split_str(object_type,
4837 ASHRAE_Reserved_Fmt,
4838 Vendor_Proprietary_Fmt),
4839 object_id_instance(object_id));
4841 /* here are the details of how we arrived at the above text */
4842 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4843 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4844 offset += tag_length;
4845 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, FALSE);
4846 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, FALSE);
4853 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4855 guint8 tag_no, tag_info;
4858 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4860 if (tag_no == 0) { /* device */
4861 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
4863 else { /* address */
4864 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4865 offset = fAddress (tvb, tree, offset);
4866 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4873 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4875 guint lastoffset = 0;
4876 guint8 tag_no, tag_info;
4878 proto_tree* orgtree = tree;
4880 proto_tree* subtree;
4882 /* beginning of new item - indent and label */
4883 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
4884 tree = proto_item_add_subtree(tt, ett_bacapp_value);
4886 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4887 lastoffset = offset;
4889 switch (fTagNo(tvb, offset)) {
4890 case 0: /* recipient */
4891 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
4892 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
4893 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4894 offset = fRecipient (tvb, pinfo, subtree, offset);
4895 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
4897 case 1: /* processId */
4898 offset = fProcessId (tvb, tree, offset);
4899 lastoffset = offset;
4904 if (offset == lastoffset) break; /* nothing happened, exit loop */
4910 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4912 guint lastoffset = 0, len;
4913 guint8 tag_no, tag_info;
4915 proto_tree* subtree;
4917 proto_tree* orgtree = tree;
4920 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4921 lastoffset = offset;
4922 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4923 if (tag_is_closing(tag_info) ) {
4928 case 0: /* recipient */
4929 /* beginning of new item in list */
4930 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
4931 itemno = itemno + 1;
4932 tree = proto_item_add_subtree(tt, ett_bacapp_value);
4934 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
4935 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4936 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
4937 offset = fRecipientProcess (tvb, pinfo, subtree, offset);
4938 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
4939 subtree = tree; /* done with this level - return to previous tree */
4941 case 1: /* MonitoredPropertyReference */
4942 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
4943 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4944 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4945 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
4946 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4949 case 2: /* IssueConfirmedNotifications - boolean */
4950 offset = fBooleanTag (tvb, tree, offset, "Issue Confirmed Notifications: ");
4952 case 3: /* TimeRemaining */
4953 offset = fUnsignedTag (tvb, tree, offset, "Time Remaining: ");
4955 case 4: /* COVIncrement */
4956 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
4961 if (offset == lastoffset) break; /* nothing happened, exit loop */
4967 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4969 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
4970 return fAddress (tvb, tree, offset);
4974 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
4976 guint lastoffset = 0, len;
4977 guint8 tag_no, tag_info;
4979 proto_tree *subtree = tree;
4981 /* set the optional global properties to indicate not-used */
4982 propertyArrayIndex = -1;
4983 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4984 lastoffset = offset;
4985 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4986 if (tag_is_closing(tag_info) ) {
4987 if (tag_no == tag_match) {
4996 case 0: /* deviceIdentifier */
4997 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
4999 case 1: /* objectIdentifier */
5000 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5002 case 2: /* propertyIdentifier */
5003 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
5005 case 3: /* propertyArrayIndex */
5006 offset = fPropertyArrayIndex (tvb, subtree, offset);
5008 case 4: /* propertyValue */
5009 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
5011 case 5: /* priority */
5012 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
5014 case 6: /* postDelay */
5015 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
5017 case 7: /* quitOnFailure */
5018 offset = fBooleanTag(tvb, subtree, offset,
5019 "Quit On Failure: ");
5021 case 8: /* writeSuccessful */
5022 offset = fBooleanTag(tvb, subtree, offset,
5023 "Write Successful: ");
5028 if (offset == lastoffset) break; /* nothing happened, exit loop */
5033 /* BACnetActionList ::= SEQUENCE{
5034 action [0] SEQUENCE OF BACnetActionCommand
5038 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5040 guint lastoffset = 0, len;
5041 guint8 tag_no, tag_info;
5043 proto_tree *subtree = tree;
5046 while (tvb_reported_length_remaining(tvb, offset)) {
5047 lastoffset = offset;
5048 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5049 if (tag_is_closing(tag_info)) {
5054 if (tag_is_opening(tag_info)) {
5055 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
5056 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5057 offset += fTagHeaderTree (tvb, subtree, offset,
5058 &tag_no, &tag_info, &lvt);
5061 case 0: /* BACnetActionCommand */
5062 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
5067 if (offset == lastoffset) break; /* nothing happened, exit loop */
5073 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5075 guint8 tag_no, tag_info;
5079 proto_tree *subtree;
5080 const gchar *label = "Property Identifier";
5082 propertyIdentifier = 0; /* global Variable */
5083 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5084 /* can we decode this value? */
5085 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
5086 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5087 "%s: %s (%u)", label,
5088 val_to_split_str(propertyIdentifier, 512,
5089 BACnetPropertyIdentifier,
5090 ASHRAE_Reserved_Fmt,
5091 Vendor_Proprietary_Fmt), propertyIdentifier);
5092 if (col_get_writable(pinfo->cinfo))
5093 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
5094 val_to_split_str(propertyIdentifier, 512,
5095 BACnetPropertyIdentifier,
5096 ASHRAE_Reserved_Fmt,
5097 Vendor_Proprietary_Fmt));
5099 /* property identifiers cannot be larger than 22-bits */
5102 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5103 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5104 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
5105 offset+tag_len, lvt, FALSE);
5107 return offset+tag_len+lvt;
5111 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
5113 guint8 tag_no, tag_info;
5117 proto_tree *subtree;
5119 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5120 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
5121 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5122 "property Array Index (Unsigned) %u", propertyArrayIndex);
5124 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5125 "property Array Index - %u octets (Unsigned)", lvt);
5126 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5127 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5129 return offset+tag_len+lvt;
5133 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5135 guint8 tag_no, tag_info, character_set;
5137 gsize inbytesleft, outbytesleft = 512;
5138 guint offs, extra = 1;
5141 guint8 bf_arr[512], *out = &bf_arr[0];
5143 proto_tree *subtree;
5144 guint start = offset;
5146 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5148 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5150 character_set = tvb_get_guint8(tvb, offset+offs);
5151 /* Account for code page if DBCS */
5152 if (character_set == 1)
5156 offset += (offs+extra);
5160 inbytesleft = l = MIN(lvt, 255);
5162 * XXX - are we guaranteed that these encoding
5163 * names correspond, on *all* platforms with
5164 * iconv(), to the encodings we want?
5165 * If not (and perhaps even if so), we should
5166 * perhaps have our own iconv() implementation,
5167 * with a different name, so that we control the
5168 * encodings it supports and the names of those
5171 * We should also handle that in the general
5172 * string handling code, rather than making it
5173 * specific to the BACAPP dissector, as many
5174 * other dissectors need to handle various
5175 * character encodings.
5177 str_val = tvb_get_ephemeral_string(tvb, offset, l);
5178 /** this decoding may be not correct for multi-byte characters, Lka */
5179 switch (character_set) {
5181 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ANSI_X3.4");
5182 coding = "ANSI X3.4";
5186 coding = "IBM MS DBCS";
5190 coding = "JIS C 6226";
5192 case ISO_10646_UCS4:
5193 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5194 coding = "ISO 10646 UCS-4";
5196 case ISO_10646_UCS2:
5197 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5198 coding = "ISO 10646 UCS-2";
5201 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5202 coding = "ISO 8859-1";
5209 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s'%s'", label, coding, out);
5214 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5216 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
5217 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, FALSE);
5219 if (character_set == 1)
5221 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5228 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5229 const value_string *src)
5231 guint8 tag_no, tag_info, tmp;
5232 gint j, unused, skip;
5233 guint start = offset;
5235 guint32 lvt, i, numberOfBytes;
5237 proto_tree* subtree = tree;
5240 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5241 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
5243 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
5244 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
5248 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5250 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5251 proto_tree_add_text(subtree, tvb, offset, 1,
5255 for (i = 0; i < numberOfBytes; i++) {
5256 tmp = tvb_get_guint8(tvb, (offset)+i+1);
5257 if (i == numberOfBytes-1) { skip = unused; }
5258 for (j = 0; j < 8-skip; j++) {
5260 if (tmp & (1 << (7 - j)))
5261 proto_tree_add_text(subtree, tvb,
5264 val_to_str((guint) (i*8 +j),
5266 ASHRAE_Reserved_Fmt));
5268 proto_tree_add_text(subtree, tvb,
5271 val_to_str((guint) (i*8 +j),
5273 ASHRAE_Reserved_Fmt));
5275 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
5282 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
5283 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
5292 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5294 return fBitStringTagVS (tvb, tree, offset, label, NULL);
5297 /* handles generic application types, as well as enumerated and enumerations
5298 with reserved and proprietarty ranges (split) */
5300 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5301 const gchar *label, const value_string *src, guint32 split_val)
5303 guint8 tag_no, tag_info;
5307 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5309 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5310 if (!tag_is_context_specific(tag_info))
5313 case 0: /** NULL 20.2.2 */
5314 offset = fNullTag(tvb, tree, offset, label);
5316 case 1: /** BOOLEAN 20.2.3 */
5317 offset = fBooleanTag(tvb, tree, offset, label);
5319 case 2: /** Unsigned Integer 20.2.4 */
5320 offset = fUnsignedTag(tvb, tree, offset, label);
5322 case 3: /** Signed Integer 20.2.5 */
5323 offset = fSignedTag(tvb, tree, offset, label);
5325 case 4: /** Real 20.2.6 */
5326 offset = fRealTag(tvb, tree, offset, label);
5328 case 5: /** Double 20.2.7 */
5329 offset = fDoubleTag(tvb, tree, offset, label);
5331 case 6: /** Octet String 20.2.8 */
5332 offset = fOctetString (tvb, tree, offset, label, lvt);
5334 case 7: /** Character String 20.2.9 */
5335 offset = fCharacterString (tvb,tree,offset,label);
5337 case 8: /** Bit String 20.2.10 */
5338 offset = fBitStringTagVS (tvb, tree, offset, label, src);
5340 case 9: /** Enumerated 20.2.11 */
5341 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
5343 case 10: /** Date 20.2.12 */
5344 offset = fDate (tvb, tree, offset, label);
5346 case 11: /** Time 20.2.13 */
5347 offset = fTime (tvb, tree, offset, label);
5349 case 12: /** BACnetObjectIdentifier 20.2.14 */
5350 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5352 case 13: /* reserved for ASHRAE */
5355 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
5356 offset+=lvt+tag_len;
5368 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
5370 guint lastoffset = 0;
5372 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5373 lastoffset = offset;
5375 switch (fTagNo(tvb,offset)) {
5376 case 0: /* percent */
5377 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
5380 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
5382 case 2: /* amount */
5383 offset = fRealTag(tvb, tree, offset, "shed amount: ");
5388 if (offset == lastoffset) break; /* nothing happened, exit loop */
5394 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5395 const gchar *label, const value_string *vs)
5397 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
5401 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5404 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
5408 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5410 guint8 tag_no, tag_info;
5414 proto_tree *subtree;
5418 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5419 /* cap the the suggested length in case of bad data */
5420 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
5421 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt))
5425 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
5426 "Context Value (as %u DATA octets)", lvt);
5428 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5429 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5431 return offset + tag_len + lvt;
5435 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5437 guint8 tag_no, tag_info;
5439 guint lastoffset = 0, depth = 0;
5442 if (propertyIdentifier >= 0)
5444 g_snprintf (ar, sizeof(ar), "%s: ",
5445 val_to_split_str(propertyIdentifier, 512,
5446 BACnetPropertyIdentifier,
5447 ASHRAE_Reserved_Fmt,
5448 Vendor_Proprietary_Fmt));
5452 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
5454 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5455 lastoffset = offset;
5456 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5457 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
5458 if (depth <= 0) return offset;
5461 /* Application Tags */
5462 switch (propertyIdentifier) {
5463 case 2: /* action */
5464 /* loop object is application tagged,
5465 command object is context tagged */
5466 if (tag_is_context_specific(tag_info)) {
5467 /* BACnetActionList */
5468 offset = fActionList (tvb, pinfo, tree,offset);
5471 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5475 case 30: /* BACnetAddressBinding */
5476 offset = fAddressBinding (tvb,pinfo,tree,offset);
5478 case 54: /* list of object property reference */
5479 offset = fLOPR (tvb, pinfo, tree,offset);
5481 case 55: /* list-of-session-keys */
5482 fSessionKey (tvb, tree, offset);
5484 case 79: /* object-type */
5485 case 96: /* protocol-object-types-supported */
5486 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
5487 BACnetObjectType, 128);
5489 case 97: /* Protocol-Services-Supported */
5490 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5491 BACnetServicesSupported);
5493 case 102: /* recipient-list */
5494 offset = fDestination (tvb, pinfo, tree, offset);
5496 case 107: /* segmentation-supported */
5497 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5498 BACnetSegmentation);
5500 case 111: /* Status-Flags */
5501 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5504 case 112: /* System-Status */
5505 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5506 BACnetDeviceStatus);
5508 case 117: /* units */
5509 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5510 BACnetEngineeringUnits);
5512 case 87: /* priority-array -- accessed as a BACnetARRAY */
5513 if (propertyArrayIndex == 0) {
5514 /* BACnetARRAY index 0 refers to the length
5515 of the array, not the elements of the array */
5516 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5518 offset = fPriorityArray (tvb, pinfo, tree, offset);
5521 case 38: /* exception-schedule */
5522 if (object_type < 128)
5524 if (propertyArrayIndex == 0) {
5525 /* BACnetARRAY index 0 refers to the length
5526 of the array, not the elements of the array */
5527 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5529 offset = fSpecialEvent (tvb,pinfo,tree,offset);
5533 case 19: /* controlled-variable-reference */
5534 case 60: /* manipulated-variable-reference */
5535 case 109: /* Setpoint-Reference */
5536 case 132: /* log-device-object-property */
5537 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
5539 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
5540 if (object_type < 128)
5542 if (propertyArrayIndex == 0) {
5543 /* BACnetARRAY index 0 refers to the length
5544 of the array, not the elements of the array */
5545 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5547 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
5551 case 127: /* client COV increment */
5552 offset = fClientCOV (tvb, pinfo, tree, offset);
5554 case 131: /* log-buffer */
5555 offset = fLogRecord (tvb, pinfo, tree, offset);
5557 case 159: /* member-of */
5558 case 165: /* zone-members */
5559 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
5561 case 196: /* last-restart-reason */
5562 offset = fRestartReason (tvb, pinfo, tree, offset);
5564 case 212: /* actual-shed-level */
5565 case 214: /* expected-shed-level */
5566 case 218: /* requested-shed-level */
5567 offset = fShedLevel (tvb, tree, offset);
5569 case 152: /* active-cov-subscriptions */
5570 offset = fCOVSubscription (tvb, pinfo, tree, offset);
5575 if (tag_is_opening(tag_info))
5578 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5580 else if (tag_is_closing(tag_info))
5583 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5587 offset = fContextTaggedValue(tvb, tree, offset, ar);
5592 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5596 if (offset == lastoffset) break; /* nothing happened, exit loop */
5603 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
5608 if (tag_is_opening(tag_info)) {
5609 offset += fTagHeaderTree(tvb, tree, offset,
5610 &tag_no, &tag_info, &lvt);
5611 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
5612 if (tvb_length_remaining(tvb, offset) > 0) {
5613 offset += fTagHeaderTree(tvb, tree, offset,
5614 &tag_no, &tag_info, &lvt);
5617 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
5618 "expected Opening Tag!"); \
5619 offset = tvb_length(tvb);
5627 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
5629 guint lastoffset = offset;
5630 guint8 tag_no, tag_info;
5633 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
5634 if (offset > lastoffset)
5636 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5637 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
5638 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
5645 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5647 guint lastoffset = 0;
5648 guint8 tag_no, tag_info;
5651 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5652 lastoffset = offset;
5653 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
5654 if (offset > lastoffset)
5656 /* detect optional priority
5657 by looking to see if the next tag is context tag number 3 */
5658 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5659 if (tag_is_context_specific(tag_info) && (tag_no == 3))
5660 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
5662 if (offset == lastoffset) break; /* nothing happened, exit loop */
5668 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5670 guint lastoffset = 0, len;
5671 guint8 tag_no, tag_info;
5673 proto_tree *subtree = tree;
5676 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5677 lastoffset = offset;
5678 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5679 if (tag_is_closing(tag_info)) {
5686 case 0: /* ProcessId */
5687 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
5689 case 1: /* monitored ObjectId */
5690 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5692 case 2: /* issueConfirmedNotifications */
5693 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
5695 case 3: /* life time */
5696 offset = fTimeSpan (tvb,tree,offset,"life time");
5698 case 4: /* monitoredPropertyIdentifier */
5699 if (tag_is_opening(tag_info)) {
5700 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
5702 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5704 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5705 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
5710 case 5: /* covIncrement */
5711 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5716 if (offset == lastoffset) break; /* nothing happened, exit loop */
5722 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5724 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
5728 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5730 guint lastoffset = 0;
5732 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5733 lastoffset = offset;
5735 switch (fTagNo(tvb, offset)) {
5736 case 0: /* deviceInstanceLowLimit */
5737 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
5739 case 1: /* deviceInstanceHighLimit */
5740 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
5742 case 2: /* BACnetObjectId */
5743 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5745 case 3: /* messageText */
5746 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
5751 if (offset == lastoffset) break; /* nothing happened, exit loop */
5758 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
5760 guint lastoffset = 0;
5761 guint8 tag_no, tag_info;
5764 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5765 if (tag_is_opening(tag_info) && tag_no == 0)
5767 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
5768 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5769 lastoffset = offset;
5770 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5771 if (tag_is_closing(tag_info)) {
5772 /* should be closing context tag 0 */
5773 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5777 offset = fTimeValue (tvb, pinfo, subtree, offset);
5778 if (offset == lastoffset) break; /* nothing happened, exit loop */
5781 else if (tag_no == 0 && lvt == 0)
5783 /* not sure null (empty array element) is legal */
5784 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5790 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5792 guint lastoffset = 0;
5793 guint8 tag_no, tag_info;
5795 guint i = 1; /* day of week array index */
5796 proto_tree *subtree = tree;
5799 if (propertyArrayIndex > 0) {
5800 /* BACnetARRAY index 0 refers to the length
5801 of the array, not the elements of the array.
5802 BACnetARRAY index -1 is our internal flag that
5803 the optional index was not used.
5804 BACnetARRAY refers to this as all elements of the array.
5805 If the optional index is specified for a BACnetARRAY,
5806 then that specific array element is referenced. */
5807 i = propertyArrayIndex;
5809 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5810 lastoffset = offset;
5811 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5812 if (tag_is_closing(tag_info)) {
5813 return offset; /* outer encoding will print out closing tag */
5815 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
5816 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5817 offset = fDailySchedule (tvb, pinfo, subtree, offset);
5818 if (offset == lastoffset) break; /* nothing happened, exit loop */
5825 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5827 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5830 return fDateTime (tvb, tree, offset, "UTC-Time: ");
5834 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5836 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5839 return fDateTime (tvb, tree, offset, NULL);
5843 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
5845 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5847 offset = fDate (tvb,tree,offset,"Start Date: ");
5848 return fDate (tvb, tree, offset, "End Date: ");
5852 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5855 guint8 tag_no, tag_info;
5859 proto_tree *subtree;
5860 const gchar *label = "Vendor ID";
5862 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5863 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
5864 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5865 "%s: %s (%u)", label,
5866 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
5868 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5869 "%s - %u octets (Unsigned)", label, lvt);
5870 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5871 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5873 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
5874 proto_item *expert_item;
5875 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
5876 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
5877 PROTO_ITEM_SET_GENERATED(expert_item);
5878 return offset+tag_len+lvt;
5881 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
5882 offset+tag_len, lvt, FALSE);
5884 return offset+tag_len+lvt;
5888 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5891 guint8 tag_no, tag_info;
5895 proto_tree *subtree;
5896 const gchar *label = "Restart Reason";
5898 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5899 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
5900 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5901 "%s: %s (%u)", label,
5902 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
5904 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5905 "%s - %u octets (Unsigned)", label, lvt);
5906 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5907 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5910 proto_item *expert_item;
5911 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
5912 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
5913 PROTO_ITEM_SET_GENERATED(expert_item);
5914 return offset+tag_len+lvt;
5917 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
5918 offset+tag_len, lvt, FALSE);
5920 return offset+tag_len+lvt;
5924 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5926 guint lastoffset = 0;
5928 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5929 lastoffset = offset;
5930 switch (fTagNo(tvb, offset)) {
5932 case 0: /* textMessageSourceDevice */
5933 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5935 case 1: /* messageClass */
5936 switch (fTagNo(tvb, offset)) {
5937 case 0: /* numeric */
5938 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
5940 case 1: /* character */
5941 offset = fCharacterString (tvb, tree, offset, "message Class: ");
5945 case 2: /* messagePriority */
5946 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
5947 BACnetMessagePriority);
5949 case 3: /* message */
5950 offset = fCharacterString (tvb, tree, offset, "message: ");
5955 if (offset == lastoffset) break; /* nothing happened, exit loop */
5961 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5963 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
5967 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5969 guint lastoffset = 0, len;
5970 guint8 tag_no, tag_info;
5972 proto_tree *subtree = tree;
5975 guint vendor_identifier = 0;
5976 guint service_number = 0;
5978 lastoffset = offset;
5979 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5980 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
5981 if (col_get_writable(pinfo->cinfo))
5982 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
5983 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
5985 next_tvb = tvb_new_subset_remaining(tvb,offset);
5986 if (dissector_try_uint(bacapp_dissector_table,
5987 vendor_identifier, next_tvb, pinfo, tree))
5989 /* we parsed it so skip over length and we are done */
5990 offset += tvb_length(next_tvb);
5994 /* Not handled by vendor dissector */
5996 /* exit loop if nothing happens inside */
5997 while (tvb_reported_length_remaining(tvb, offset)) {
5998 lastoffset = offset;
5999 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6000 if (tag_is_closing(tag_info)) {
6001 if (tag_no == 2) /* Make sure it's the expected tag */
6009 break; /* End loop if incorrect closing tag */
6014 /* vendorID is now parsed above */
6015 case 1: /* serviceNumber */
6016 fUnsigned32(tvb, offset+len, lvt, &service_number);
6017 if (col_get_writable(pinfo->cinfo))
6018 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
6019 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
6021 case 2: /*serviceParameters */
6022 if (tag_is_opening(tag_info)) {
6023 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
6024 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6025 propertyIdentifier = -1;
6026 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6034 if (offset == lastoffset) break; /* nothing happened, exit loop */
6041 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6043 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
6047 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6049 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
6053 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6055 guint lastoffset = 0;
6056 guint8 tag_no, tag_info;
6058 proto_tree *subtree = tree;
6061 if (label != NULL) {
6062 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
6063 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6066 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6067 lastoffset = offset;
6068 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6071 case 0: /* subscriberProcessId */
6072 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
6074 case 1: /* requestingSource */
6075 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
6077 case 2: /* request */
6078 offset = fEnumeratedTagSplit (tvb, tree, offset,
6079 "request: ", BACnetLifeSafetyOperation, 64);
6081 case 3: /* objectId */
6082 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6087 if (offset == lastoffset) break; /* nothing happened, exit loop */
6093 fBACnetPropertyStates(tvbuff_t *tvb, proto_tree *tree, guint offset)
6095 switch (fTagNo(tvb, offset))
6098 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6101 offset = fEnumeratedTagSplit (tvb, tree, offset,
6102 "binary-value: ", BACnetBinaryPV, 2);
6105 offset = fEnumeratedTagSplit (tvb, tree, offset,
6106 "event-type: ", BACnetEventType, 12);
6109 offset = fEnumeratedTagSplit (tvb, tree, offset,
6110 "polarity: ", BACnetPolarity, 2);
6113 offset = fEnumeratedTagSplit (tvb, tree, offset,
6114 "program-change: ", BACnetProgramRequest, 5);
6117 offset = fEnumeratedTagSplit (tvb, tree, offset,
6118 "program-state: ", BACnetProgramState, 5);
6121 offset = fEnumeratedTagSplit (tvb, tree, offset,
6122 "reason-for-halt: ", BACnetProgramError, 5);
6125 offset = fEnumeratedTagSplit (tvb, tree, offset,
6126 "reliability: ", BACnetReliability, 10);
6129 offset = fEnumeratedTagSplit (tvb, tree, offset,
6130 "state: ", BACnetEventState, 64);
6133 offset = fEnumeratedTagSplit (tvb, tree, offset,
6134 "system-status: ", BACnetDeviceStatus, 64);
6137 offset = fEnumeratedTagSplit (tvb, tree, offset,
6138 "units: ", BACnetEngineeringUnits, 2);
6141 offset = fUnsignedTag(tvb, tree, offset, "unsigned-value: ");
6144 offset = fEnumeratedTagSplit (tvb, tree, offset,
6145 "life-safety-mode: ", BACnetLifeSafetyMode, 64);
6148 offset = fEnumeratedTagSplit (tvb, tree, offset,
6149 "life-safety-state: ", BACnetLifeSafetyState, 64);
6159 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
6160 deviceIdentifier [0] BACnetObjectIdentifier,
6161 objectIdentifier [1] BACnetObjectIdentifier,
6162 propertyIdentifier [2] BACnetPropertyIdentifier,
6163 arrayIndex [3] Unsigned OPTIONAL,
6164 value [4] ABSTRACT-SYNTAX.&Type
6168 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6170 guint lastoffset = 0;
6171 guint8 tag_no, tag_info;
6174 while (tvb_reported_length_remaining(tvb, offset)) {
6175 lastoffset = offset;
6176 /* check the tag. A closing tag means we are done */
6177 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6178 if (tag_is_closing(tag_info)) {
6182 case 0: /* deviceIdentifier */
6183 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6185 case 1: /* objectIdentifier */
6186 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6188 case 2: /* propertyIdentifier */
6189 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6191 case 3: /* arrayIndex - OPTIONAL */
6192 offset = fUnsignedTag (tvb, tree, offset,
6196 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6197 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6198 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6203 if (offset == lastoffset) break; /* nothing happened, exit loop */
6210 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
6211 objectIdentifier [0] BACnetObjectIdentifier,
6212 propertyIdentifier [1] BACnetPropertyIdentifier,
6213 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
6214 -- if omitted with an array then
6215 -- the entire array is referenced
6216 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
6220 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6222 guint lastoffset = 0;
6223 guint8 tag_no, tag_info;
6226 while (tvb_reported_length_remaining(tvb, offset)) {
6227 lastoffset = offset;
6228 /* check the tag. A closing tag means we are done */
6229 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6230 if (tag_is_closing(tag_info)) {
6234 case 0: /* objectIdentifier */
6235 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6237 case 1: /* propertyIdentifier */
6238 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6240 case 2: /* arrayIndex - OPTIONAL */
6241 offset = fUnsignedTag (tvb, tree, offset,
6244 case 3: /* deviceIdentifier - OPTIONAL */
6245 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6250 if (offset == lastoffset) break; /* nothing happened, exit loop */
6256 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6258 guint lastoffset = offset;
6259 guint8 tag_no, tag_info;
6261 proto_tree *subtree = tree;
6264 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6265 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
6266 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
6267 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6268 /* Opening tag for parameter choice */
6269 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6272 case 0: /* change-of-bitstring */
6273 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6274 lastoffset = offset;
6275 switch (fTagNo(tvb, offset)) {
6277 offset = fBitStringTag (tvb, subtree, offset,
6278 "referenced-bitstring: ");
6281 offset = fBitStringTagVS (tvb, subtree, offset,
6282 "status-flags: ", BACnetStatusFlags);
6283 lastoffset = offset;
6288 if (offset == lastoffset) break; /* nothing happened, exit loop */
6291 case 1: /* change-of-state */
6292 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6293 lastoffset = offset;
6294 switch (fTagNo(tvb, offset)) {
6296 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6297 offset = fBACnetPropertyStates(tvb, subtree, offset);
6298 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6301 offset = fBitStringTagVS (tvb, subtree, offset,
6302 "status-flags: ", BACnetStatusFlags);
6303 lastoffset = offset;
6308 if (offset == lastoffset) break; /* nothing happened, exit loop */
6311 case 2: /* change-of-value */
6312 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6313 lastoffset = offset;
6314 switch (fTagNo(tvb, offset)) {
6316 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6317 switch (fTagNo(tvb, offset)) {
6319 offset = fBitStringTag (tvb, subtree, offset,
6323 offset = fRealTag (tvb, subtree, offset,
6329 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6332 offset = fBitStringTagVS (tvb, subtree, offset,
6333 "status-flags: ", BACnetStatusFlags);
6334 lastoffset = offset;
6339 if (offset == lastoffset) break; /* nothing happened, exit loop */
6342 case 3: /* command-failure */
6343 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6344 lastoffset = offset;
6345 switch (fTagNo(tvb, offset)) {
6346 case 0: /* "command-value: " */
6347 /* from BACnet Table 13-3,
6348 Standard Object Property Values Returned in Notifications */
6349 propertyIdentifier = 85; /* PRESENT_VALUE */
6350 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6351 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6352 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6355 offset = fBitStringTagVS (tvb, subtree, offset,
6356 "status-flags: ", BACnetStatusFlags);
6358 case 2: /* "feedback-value: " */
6359 propertyIdentifier = 40; /* FEEDBACK_VALUE */
6360 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6361 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6362 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6363 lastoffset = offset;
6368 if (offset == lastoffset) break; /* nothing happened, exit loop */
6371 case 4: /* floating-limit */
6372 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6373 lastoffset = offset;
6374 switch (fTagNo(tvb, offset)) {
6376 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
6379 offset = fBitStringTagVS (tvb, subtree, offset,
6380 "status-flags: ", BACnetStatusFlags);
6383 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
6386 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
6387 lastoffset = offset;
6392 if (offset == lastoffset) break; /* nothing happened, exit loop */
6395 case 5: /* out-of-range */
6396 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6397 lastoffset = offset;
6398 switch (fTagNo(tvb, offset)) {
6400 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
6403 offset = fBitStringTagVS (tvb, subtree, offset,
6404 "status-flags: ", BACnetStatusFlags);
6407 offset = fRealTag (tvb, subtree, offset, "deadband: ");
6410 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
6411 lastoffset = offset;
6416 if (offset == lastoffset) break; /* nothing happened, exit loop */
6420 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6421 lastoffset = offset;
6422 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
6423 if (offset == lastoffset) break; /* nothing happened, exit loop */
6426 case 7: /* buffer-ready */
6427 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6428 lastoffset = offset;
6429 switch (fTagNo(tvb, offset)) {
6431 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
6434 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
6437 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6438 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
6439 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6442 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6443 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
6444 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6445 lastoffset = offset;
6450 if (offset == lastoffset) break; /* nothing happened, exit loop */
6453 case 8: /* change-of-life-safety */
6454 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6455 lastoffset = offset;
6456 switch (fTagNo(tvb, offset)) {
6458 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6459 "new-state: ", BACnetLifeSafetyState, 256);
6462 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6463 "new-mode: ", BACnetLifeSafetyMode, 256);
6466 offset = fBitStringTagVS (tvb, subtree, offset,
6467 "status-flags: ", BACnetStatusFlags);
6470 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6471 "operation-expected: ", BACnetLifeSafetyOperation, 64);
6472 lastoffset = offset;
6477 if (offset == lastoffset) break; /* nothing happened, exit loop */
6480 case 9: /* extended */
6481 while (tvb_reported_length_remaining(tvb, offset)) {
6482 lastoffset = offset;
6483 switch (fTagNo(tvb, offset)) {
6485 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6488 offset = fUnsignedTag (tvb, subtree, offset,
6489 "extended-event-type: ");
6491 case 2: /* parameters */
6492 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6493 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
6494 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
6495 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6496 lastoffset = offset;
6501 if (offset == lastoffset) break; /* nothing happened, exit loop */
6504 case 10: /* buffer ready */
6505 while (tvb_reported_length_remaining(tvb, offset)) {
6506 lastoffset = offset;
6507 switch (fTagNo(tvb, offset)) {
6508 case 0: /* buffer-property */
6509 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6510 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
6511 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6514 offset = fUnsignedTag (tvb, subtree, offset,
6515 "previous-notification: ");
6518 offset = fUnsignedTag (tvb, subtree, offset,
6519 "current-notification: ");
6520 lastoffset = offset;
6525 if (offset == lastoffset) break; /* nothing happened, exit loop */
6528 case 11: /* unsigned range */
6529 while (tvb_reported_length_remaining(tvb, offset)) {
6530 lastoffset = offset;
6531 switch (fTagNo(tvb, offset)) {
6533 offset = fUnsignedTag (tvb, subtree, offset,
6534 "exceeding-value: ");
6537 offset = fBitStringTagVS (tvb, subtree, offset,
6538 "status-flags: ", BACnetStatusFlags);
6541 offset = fUnsignedTag (tvb, subtree, offset,
6542 "exceeded-limit: ");
6543 lastoffset = offset;
6548 if (offset == lastoffset) break; /* nothing happened, exit loop */
6555 /* Closing tag for parameter choice */
6556 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6563 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset)
6565 guint lastoffset = 0;
6567 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6568 lastoffset = offset;
6569 switch (fTagNo(tvb, offset)) {
6570 case 0: /* change-of-bitstring */
6571 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6572 lastoffset = offset;
6573 switch (fTagNo(tvb, offset)) {
6575 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6578 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6580 case 2: /* SEQUENCE OF BIT STRING */
6581 offset = fBitStringTagVS (tvb, tree, offset,
6582 "bitstring value: ", BACnetEventTransitionBits);
6589 case 1: /* change-of-state */
6590 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6591 lastoffset = offset;
6592 switch (fTagNo(tvb, offset)) {
6594 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6596 case 1: /* SEQUENCE OF BACnetPropertyStates */
6597 offset = fEnumeratedTagSplit (tvb, tree, offset,
6598 "value: ", BACnetPropertyStates, 64);
6605 case 2: /* change-of-value */
6606 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6607 lastoffset = offset;
6608 switch (fTagNo(tvb, offset)) {
6610 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6612 case 1: /* don't loop it, it's a CHOICE */
6613 switch (fTagNo(tvb, offset)) {
6615 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6618 offset = fRealTag (tvb, tree, offset,
6619 "referenced Property Increment: ");
6629 case 3: /* command-failure */
6630 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6631 lastoffset = offset;
6632 switch (fTagNo(tvb, offset)) {
6634 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6637 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6643 case 4: /* floating-limit */
6644 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6645 lastoffset = offset;
6646 switch (fTagNo(tvb, offset)) {
6648 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6651 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6654 offset = fRealTag (tvb, tree, offset, "low diff limit: ");
6657 offset = fRealTag (tvb, tree, offset, "high diff limit: ");
6660 offset = fRealTag (tvb, tree, offset, "deadband: ");
6667 case 5: /* out-of-range */
6668 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6669 lastoffset = offset;
6670 switch (fTagNo(tvb, offset)) {
6672 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6675 offset = fRealTag (tvb, tree, offset, "low limit: ");
6678 offset = fRealTag (tvb, tree, offset, "high limit: ");
6681 offset = fRealTag (tvb, tree, offset, "deadband: ");
6689 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
6691 case 7: /* buffer-ready */
6692 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6693 lastoffset = offset;
6694 switch (fTagNo(tvb, offset)) {
6696 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
6699 offset = fUnsignedTag (tvb,tree,offset,
6700 "previous notification count: ");
6707 case 8: /* change-of-life-safety */
6708 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6709 lastoffset = offset;
6710 switch (fTagNo(tvb, offset)) {
6712 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6715 offset = fEnumeratedTagSplit (tvb, tree, offset,
6716 "life safety alarm value: ", BACnetLifeSafetyState, 256);
6719 offset = fEnumeratedTagSplit (tvb, tree, offset,
6720 "alarm value: ", BACnetLifeSafetyState, 256);
6723 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6739 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6741 guint lastoffset = 0;
6742 guint8 tag_no, tag_info;
6745 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6746 lastoffset = offset;
6747 switch (fTagNo(tvb, offset)) {
6748 case 0: /* timestamp */
6749 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6750 offset = fDate (tvb,tree,offset,"Date: ");
6751 offset = fTime (tvb,tree,offset,"Time: ");
6752 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6754 case 1: /* logDatum: don't loop, it's a CHOICE */
6755 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6756 switch (fTagNo(tvb, offset)) {
6757 case 0: /* logStatus */
6758 offset = fEnumeratedTag (tvb, tree, offset,
6759 "log status: ", BACnetLogStatus);
6762 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6765 offset = fRealTag (tvb, tree, offset, "real value: ");
6768 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
6771 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
6774 offset = fSignedTag (tvb, tree, offset, "signed value: ");
6777 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
6780 offset = fNullTag(tvb, tree, offset, "null value: ");
6783 offset = fError (tvb, pinfo, tree, offset);
6786 offset = fRealTag (tvb, tree, offset, "time change: ");
6788 case 10: /* any Value */
6789 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6790 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6791 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6796 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6799 offset = fEnumeratedTag (tvb, tree, offset,
6800 "Status Flags: ", BACnetStatusFlags);
6805 if (offset == lastoffset) break; /* nothing happened, exit loop */
6812 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6814 guint lastoffset = 0;
6815 guint8 tag_no, tag_info;
6818 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6819 lastoffset = offset;
6821 switch (fTagNo(tvb,offset)) {
6822 case 0: /* ProcessId */
6823 offset = fProcessId (tvb,tree,offset);
6825 case 1: /* initiating ObjectId */
6826 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6828 case 2: /* event ObjectId */
6829 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6831 case 3: /* time stamp */
6832 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6833 offset = fTimeStamp (tvb, tree, offset, NULL);
6834 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6836 case 4: /* notificationClass */
6837 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
6839 case 5: /* Priority */
6840 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
6842 case 6: /* EventType */
6843 offset = fEnumeratedTagSplit (tvb, tree, offset,
6844 "Event Type: ", BACnetEventType, 64);
6846 case 7: /* messageText */
6847 offset = fCharacterString (tvb, tree, offset, "message Text: ");
6849 case 8: /* NotifyType */
6850 offset = fEnumeratedTag (tvb, tree, offset,
6851 "Notify Type: ", BACnetNotifyType);
6853 case 9: /* ackRequired */
6854 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
6856 case 10: /* fromState */
6857 offset = fEnumeratedTagSplit (tvb, tree, offset,
6858 "from State: ", BACnetEventState, 64);
6860 case 11: /* toState */
6861 offset = fEnumeratedTagSplit (tvb, tree, offset,
6862 "to State: ", BACnetEventState, 64);
6864 case 12: /* NotificationParameters */
6865 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6866 offset = fNotificationParameters (tvb, pinfo, tree, offset);
6867 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6872 if (offset == lastoffset) break; /* nothing happened, exit loop */
6878 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6880 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
6884 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6886 guint lastoffset = 0, len;
6887 guint8 tag_no, tag_info;
6889 proto_tree *subtree = tree;
6892 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6893 lastoffset = offset;
6894 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6895 if (tag_is_closing(tag_info)) {
6902 case 0: /* ProcessId */
6903 offset = fProcessId (tvb,tree,offset);
6905 case 1: /* initiating DeviceId */
6906 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6908 case 2: /* monitored ObjectId */
6909 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6911 case 3: /* time remaining */
6912 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
6914 case 4: /* List of Values */
6915 if (tag_is_opening(tag_info)) {
6916 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
6917 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6918 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6919 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
6927 if (offset == lastoffset) break; /* nothing happened, exit loop */
6933 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6935 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
6939 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6941 guint lastoffset = 0;
6942 guint8 tag_no = 0, tag_info = 0;
6945 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6946 lastoffset = offset;
6947 switch (fTagNo(tvb, offset)) {
6948 case 0: /* acknowledgingProcessId */
6949 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
6951 case 1: /* eventObjectId */
6952 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6954 case 2: /* eventStateAcknowledged */
6955 offset = fEnumeratedTagSplit (tvb, tree, offset,
6956 "event State Acknowledged: ", BACnetEventState, 64);
6958 case 3: /* timeStamp */
6959 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6960 offset = fTimeStamp(tvb, tree, offset, NULL);
6961 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6963 case 4: /* acknowledgementSource */
6964 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
6966 case 5: /* timeOfAcknowledgement */
6967 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6968 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
6969 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6974 if (offset == lastoffset) break; /* nothing happened, exit loop */
6980 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6982 guint lastoffset = 0;
6984 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6985 lastoffset = offset;
6986 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
6987 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
6988 "alarm State: ", BACnetEventState, 64);
6989 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
6990 "acknowledged Transitions: ", BACnetEventTransitionBits);
6991 if (offset == lastoffset) break; /* nothing happened, exit loop */
6997 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6999 guint lastoffset = 0;
7000 guint8 tag_no, tag_info;
7003 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7004 lastoffset = offset;
7005 switch (fTagNo(tvb, offset)) {
7006 case 0: /* acknowledgmentFilter */
7007 offset = fEnumeratedTag (tvb, tree, offset,
7008 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
7010 case 1: /* eventObjectId - OPTIONAL */
7011 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7012 offset = fRecipientProcess (tvb, pinfo, tree, offset);
7013 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7015 case 2: /* eventStateFilter */
7016 offset = fEnumeratedTag (tvb, tree, offset,
7017 "event State Filter: ", BACnetEventStateFilter);
7019 case 3: /* eventTypeFilter - OPTIONAL */
7020 offset = fEnumeratedTag (tvb, tree, offset,
7021 "event Type Filter: ", BACnetEventType);
7023 case 4: /* priorityFilter */
7024 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7025 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
7026 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
7027 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7029 case 5: /* notificationClassFilter - OPTIONAL */
7030 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
7035 if (offset == lastoffset) break; /* nothing happened, exit loop */
7041 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7043 guint lastoffset = 0;
7045 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7046 lastoffset = offset;
7047 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
7048 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
7049 "event Type: ", BACnetEventType, 64);
7050 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7051 "event State: ", BACnetEventState);
7052 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
7053 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
7054 if (offset == lastoffset) break; /* nothing happened, exit loop */
7061 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7063 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7064 if (fTagNo(tvb, offset) == 0) {
7065 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7072 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7074 guint lastoffset = 0;
7075 guint8 tag_no, tag_info;
7077 proto_tree* subtree = tree;
7080 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7081 lastoffset = offset;
7082 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7083 /* we are finished here if we spot a closing tag */
7084 if (tag_is_closing(tag_info)) {
7088 case 0: /* ObjectId */
7089 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7091 case 1: /* eventState */
7092 offset = fEnumeratedTag (tvb, tree, offset,
7093 "event State: ", BACnetEventState);
7095 case 2: /* acknowledgedTransitions */
7096 offset = fBitStringTagVS (tvb, tree, offset,
7097 "acknowledged Transitions: ", BACnetEventTransitionBits);
7099 case 3: /* eventTimeStamps */
7100 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
7102 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7104 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7105 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
7106 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
7107 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
7108 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7110 case 4: /* notifyType */
7111 offset = fEnumeratedTag (tvb, tree, offset,
7112 "Notify Type: ", BACnetNotifyType);
7114 case 5: /* eventEnable */
7115 offset = fBitStringTagVS (tvb, tree, offset,
7116 "event Enable: ", BACnetEventTransitionBits);
7118 case 6: /* eventPriorities */
7119 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
7121 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7123 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7124 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
7125 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
7126 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
7127 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7132 if (offset == lastoffset) break; /* nothing happened, exit loop */
7138 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7140 guint lastoffset = 0;
7141 guint8 tag_no, tag_info;
7144 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7145 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7146 lastoffset = offset;
7147 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7148 /* we are finished here if we spot a closing tag */
7149 if (tag_is_closing(tag_info)) {
7152 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7153 if (offset == lastoffset) break; /* nothing happened, exit loop */
7159 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7161 guint lastoffset = 0;
7162 guint8 tag_no, tag_info;
7165 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7166 lastoffset = offset;
7167 switch (fTagNo(tvb, offset)) {
7168 case 0: /* listOfEventSummaries */
7169 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7170 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
7171 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7173 case 1: /* moreEvents */
7174 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
7179 if (offset == lastoffset) break; /* nothing happened, exit loop */
7185 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7187 guint lastoffset = 0, len;
7188 guint8 tag_no, tag_info;
7190 proto_tree *subtree = tree;
7193 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7195 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7196 lastoffset = offset;
7197 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7198 if (tag_is_closing(tag_info)) {
7205 case 0: /* ObjectId */
7206 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
7208 case 3: /* listOfElements */
7209 if (tag_is_opening(tag_info)) {
7210 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
7211 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7212 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7213 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7221 if (offset == lastoffset) break; /* nothing happened, exit loop */
7227 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7229 return fObjectIdentifier (tvb, pinfo, tree, offset);
7233 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7235 guint lastoffset = 0;
7237 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7238 lastoffset = offset;
7240 switch (fTagNo(tvb, offset)) {
7241 case 0: /* timeDuration */
7242 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
7244 case 1: /* enable-disable */
7245 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
7246 BACnetEnableDisable);
7248 case 2: /* password - OPTIONAL */
7249 offset = fCharacterString (tvb, tree, offset, "Password: ");
7254 if (offset == lastoffset) break; /* nothing happened, exit loop */
7260 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7262 guint lastoffset = 0;
7264 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7265 lastoffset = offset;
7267 switch (fTagNo(tvb, offset)) {
7268 case 0: /* reinitializedStateOfDevice */
7269 offset = fEnumeratedTag (tvb, tree, offset,
7270 "reinitialized State Of Device: ",
7271 BACnetReinitializedStateOfDevice);
7273 case 1: /* password - OPTIONAL */
7274 offset = fCharacterString (tvb, tree, offset, "Password: ");
7279 if (offset == lastoffset) break; /* nothing happened, exit loop */
7285 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7287 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7288 "vtClass: ", BACnetVTClass);
7289 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
7293 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7295 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7299 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7301 guint lastoffset = 0;
7303 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7304 lastoffset = offset;
7305 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7306 if (offset == lastoffset) break; /* nothing happened, exit loop */
7312 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7314 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
7315 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
7316 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
7320 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
7322 guint lastoffset = 0;
7324 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7325 lastoffset = offset;
7327 switch (fTagNo(tvb,offset)) {
7328 case 0: /* BOOLEAN */
7329 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
7331 case 1: /* Unsigned OPTIONAL */
7332 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
7337 if (offset == lastoffset) break; /* nothing happened, exit loop */
7343 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
7345 guint lastoffset = 0;
7347 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7348 lastoffset = offset;
7350 switch (fTagNo(tvb,offset)) {
7351 case 0: /* Unsigned32 */
7352 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
7354 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
7355 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
7357 case 2: /* Chararacter String OPTIONAL */
7358 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
7360 case 3: /* Chararacter String OPTIONAL */
7361 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
7363 case 4: /* Boolean OPTIONAL */
7364 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
7369 if (offset == lastoffset) break; /* nothing happened, exit loop */
7375 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7377 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
7381 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7383 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
7384 offset = fAddress (tvb, tree, offset);
7385 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
7386 return fAddress (tvb, tree, offset);
7390 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7392 /* Same as AddListElement request after service choice */
7393 return fAddListElementRequest(tvb, pinfo, tree, offset);
7397 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7399 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
7403 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7405 guint lastoffset = 0, len;
7406 guint8 tag_no, tag_info;
7408 proto_tree *subtree = tree;
7410 /* set the optional global properties to indicate not-used */
7411 propertyArrayIndex = -1;
7412 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7413 lastoffset = offset;
7414 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7415 if (tag_is_closing(tag_info)) {
7421 case 0: /* objectIdentifier */
7422 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7424 case 1: /* propertyIdentifier */
7425 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7427 case 2: /* propertyArrayIndex */
7428 offset = fPropertyArrayIndex (tvb, subtree, offset);
7430 case 3: /* propertyValue */
7431 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7436 if (offset == lastoffset) break; /* nothing happened, exit loop */
7442 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7444 guint lastoffset = 0;
7445 guint8 tag_no, tag_info;
7447 proto_tree *subtree = tree;
7449 /* set the optional global properties to indicate not-used */
7450 propertyArrayIndex = -1;
7451 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7452 lastoffset = offset;
7453 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7454 /* quit loop if we spot a closing tag */
7455 if (tag_is_closing(tag_info)) {
7461 case 0: /* objectIdentifier */
7462 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7464 case 1: /* propertyIdentifier */
7465 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7467 case 2: /* propertyArrayIndex */
7468 offset = fPropertyArrayIndex (tvb, subtree, offset);
7470 case 3: /* propertyValue */
7471 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7473 case 4: /* Priority (only used for write) */
7474 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7479 if (offset == lastoffset) break; /* nothing happened, exit loop */
7485 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7487 guint lastoffset = 0, len;
7488 guint8 tag_no, tag_info;
7491 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7492 lastoffset = offset;
7493 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7494 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
7495 if (tag_is_closing(tag_info)) {
7501 case 0: /* objectIdentifier */
7502 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7504 case 1: /* listOfPropertyValues */
7505 if (tag_is_opening(tag_info)) {
7506 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7507 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7515 if (offset == lastoffset) break; /* nothing happened, exit loop */
7521 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7523 if (offset >= tvb_reported_length(tvb))
7526 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7527 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
7531 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
7533 guint lastoffset = 0;
7534 guint8 tag_no, tag_info;
7537 /* set the optional global properties to indicate not-used */
7538 propertyArrayIndex = -1;
7539 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7540 lastoffset = offset;
7541 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7542 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
7544 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
7547 switch (tag_no-tagoffset) {
7548 case 0: /* PropertyIdentifier */
7549 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7551 case 1: /* propertyArrayIndex */
7552 offset = fPropertyArrayIndex (tvb, tree, offset);
7553 if (list != 0) break; /* Continue decoding if this may be a list */
7555 lastoffset = offset; /* Set loop end condition */
7558 if (offset == lastoffset) break; /* nothing happened, exit loop */
7564 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
7566 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7567 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
7571 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7573 guint lastoffset = 0;
7575 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7576 lastoffset = offset;
7578 switch (fTagNo(tvb,offset)) {
7579 case 0: /* ObjectIdentifier */
7580 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7582 case 1: /* PropertyIdentifier and propertyArrayIndex */
7583 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
7584 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7586 lastoffset = offset; /* Set loop end condition */
7589 if (offset == lastoffset) break; /* nothing happened, exit loop */
7596 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
7598 guint lastoffset = 0;
7599 guint8 tag_no, tag_info;
7601 proto_tree* subtree = tree;
7604 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7605 lastoffset = offset;
7606 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7607 if (tag_is_closing(tag_info)) {
7608 offset += fTagHeaderTree (tvb, subtree, offset,
7609 &tag_no, &tag_info, &lvt);
7613 case 0: /* ObjectIdentifier */
7614 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7616 case 1: /* PropertyIdentifier */
7617 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7619 case 2: /* propertyArrayIndex */
7620 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
7623 offset = fPropertyValue (tvb, subtree, offset, tag_info);
7625 case 4: /* Priority */
7626 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7637 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7639 char i = 1, ar[256];
7640 guint lastoffset = 0;
7642 if (propertyArrayIndex > 0) {
7643 /* BACnetARRAY index 0 refers to the length
7644 of the array, not the elements of the array.
7645 BACnetARRAY index -1 is our internal flag that
7646 the optional index was not used.
7647 BACnetARRAY refers to this as all elements of the array.
7648 If the optional index is specified for a BACnetARRAY,
7649 then that specific array element is referenced. */
7650 i = propertyArrayIndex;
7652 while (tvb_reported_length_remaining(tvb, offset)) {
7653 /* exit loop if nothing happens inside */
7654 lastoffset = offset;
7655 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
7656 val_to_split_str(87 , 512,
7657 BACnetPropertyIdentifier,
7658 ASHRAE_Reserved_Fmt,
7659 Vendor_Proprietary_Fmt),
7661 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
7662 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
7663 /* there are only 16 priority array elements */
7667 if (offset == lastoffset) break; /* nothing happened, exit loop */
7674 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7676 guint lastoffset = 0;
7678 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7679 lastoffset = offset;
7681 switch (fTagNo(tvb,offset)) {
7682 case 0: /* deviceIdentifier - OPTIONAL */
7683 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7685 case 1: /* ObjectIdentifier */
7686 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7691 if (offset == lastoffset) break; /* nothing happened, exit loop */
7697 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7699 guint8 tag_no, tag_info;
7701 guint lastoffset = 0, len;
7703 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7704 lastoffset = offset;
7705 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7706 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
7707 if (tag_is_closing(tag_info)) {
7713 case 0: /* calendaryEntry */
7714 if (tag_is_opening(tag_info))
7716 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7717 offset = fCalendaryEntry (tvb, subtree, offset);
7718 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7721 case 1: /* calendarReference */
7722 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7724 case 2: /* list of BACnetTimeValue */
7725 if (tag_is_opening(tag_info)) {
7726 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7727 offset = fTimeValue (tvb, pinfo, subtree, offset);
7728 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7733 case 3: /* eventPriority */
7734 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
7739 if (offset == lastoffset) break; /* nothing happened, exit loop */
7745 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7747 guint lastoffset = 0, len;
7748 guint8 tag_no, tag_info;
7751 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7752 lastoffset = offset;
7753 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7754 /* maybe a listOfSelectionCriteria if we spot a closing tag */
7755 if (tag_is_closing(tag_info)) {
7760 switch (fTagNo(tvb,offset)) {
7761 case 0: /* propertyIdentifier */
7762 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7764 case 1: /* propertyArrayIndex */
7765 offset = fPropertyArrayIndex (tvb, tree, offset);
7767 case 2: /* relationSpecifier */
7768 offset = fEnumeratedTag (tvb, tree, offset,
7769 "relation Specifier: ", BACnetRelationSpecifier);
7771 case 3: /* comparisonValue */
7772 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7773 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7774 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7779 if (offset == lastoffset) break; /* nothing happened, exit loop */
7785 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7787 guint lastoffset = 0;
7788 guint8 tag_no, tag_info;
7791 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7792 lastoffset = offset;
7793 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7794 /* quit loop if we spot a closing tag */
7795 if (tag_is_closing(tag_info)) {
7800 case 0: /* selectionLogic */
7801 offset = fEnumeratedTag (tvb, subtree, offset,
7802 "selection Logic: ", BACnetSelectionLogic);
7804 case 1: /* listOfSelectionCriteria */
7805 if (tag_is_opening(tag_info)) {
7806 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7807 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
7808 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7816 if (offset == lastoffset) break; /* nothing happened, exit loop */
7823 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
7825 guint lastoffset = 0;
7826 guint8 tag_no, tag_info;
7829 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7830 lastoffset = offset;
7831 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7833 if (tag_is_opening(tag_info) && tag_no < 2) {
7834 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7836 case 0: /* objectSelectionCriteria */
7837 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
7839 case 1: /* listOfPropertyReferences */
7840 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
7845 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7847 if (offset == lastoffset) break; /* nothing happened, exit loop */
7853 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7855 guint lastoffset = 0;
7856 guint8 tag_no, tag_info;
7859 proto_tree *subtree = tree;
7861 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7862 lastoffset = offset;
7863 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7865 case 0: /* objectIdentifier */
7866 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7868 case 1: /* listOfPropertyReferences */
7869 if (tag_is_opening(tag_info)) {
7870 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
7871 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7872 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7873 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
7874 } else if (tag_is_closing(tag_info)) {
7875 offset += fTagHeaderTree (tvb, subtree, offset,
7876 &tag_no, &tag_info, &lvt);
7879 /* error condition: let caller handle */
7886 if (offset == lastoffset) break; /* nothing happened, exit loop */
7892 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7894 guint lastoffset = 0, len;
7898 proto_tree *subtree = tree;
7901 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7902 lastoffset = offset;
7903 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7904 /* maybe a listOfReadAccessResults if we spot a closing tag here */
7905 if (tag_is_closing(tag_info)) {
7907 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
7912 case 0: /* objectSpecifier */
7913 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7915 case 1: /* list of Results */
7916 if (tag_is_opening(tag_info)) {
7917 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
7918 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7919 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7924 case 2: /* propertyIdentifier */
7925 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
7927 case 5: /* propertyAccessError */
7928 if (tag_is_opening(tag_info)) {
7929 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
7930 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7931 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7932 /* Error Code follows */
7933 offset = fError(tvb, pinfo, subtree, offset);
7941 if (offset == lastoffset) break; /* nothing happened, exit loop */
7948 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7950 /* listOfReadAccessResults */
7951 return fReadAccessResult (tvb, pinfo, tree, offset);
7956 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7958 guint lastoffset = 0;
7959 guint8 tag_no, tag_info;
7962 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7963 lastoffset = offset;
7964 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7968 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7970 case 0: /* objectSpecifier */
7971 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
7972 case 0: /* objectType */
7973 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
7975 case 1: /* objectIdentifier */
7976 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7982 case 1: /* propertyValue */
7983 if (tag_is_opening(tag_info)) {
7984 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7992 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7994 if (offset == lastoffset) break; /* nothing happened, exit loop */
8000 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8002 return fObjectIdentifier (tvb, pinfo, tree, offset);
8006 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8008 guint8 tag_no, tag_info;
8010 proto_tree *subtree = tree;
8013 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
8015 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8016 /* optional range choice */
8017 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8018 if (tag_is_opening(tag_info)) {
8019 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
8020 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8021 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8023 case 3: /* range byPosition */
8024 case 6: /* range bySequenceNumber, 2004 spec */
8025 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
8026 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
8028 case 4: /* range byTime - deprecated in 2004 */
8029 case 7: /* 2004 spec */
8030 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
8031 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
8033 case 5: /* range timeRange - deprecated in 2004 */
8034 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
8035 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
8040 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8047 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8049 guint8 tag_no, tag_info;
8051 proto_tree *subtree = tree;
8054 /* set the optional global properties to indicate not-used */
8055 propertyArrayIndex = -1;
8056 /* objectIdentifier, propertyIdentifier, and
8057 OPTIONAL propertyArrayIndex */
8058 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
8059 /* resultFlags => BACnetResultFlags ::= BIT STRING */
8060 offset = fBitStringTagVS (tvb, tree, offset,
8064 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
8066 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8067 if (tag_is_opening(tag_info)) {
8068 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8069 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
8070 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8071 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8072 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8073 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8075 /* firstSequenceNumber - OPTIONAL */
8076 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8077 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
8084 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8086 guint lastoffset = 0;
8088 guint8 tag_no, tag_info;
8090 proto_tree* subtree = NULL;
8092 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8094 if (tag_is_opening(tag_info))
8096 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
8097 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8098 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8099 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
8100 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
8104 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset))
8105 { /* exit loop if nothing happens inside */
8106 lastoffset = offset;
8107 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
8111 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0)
8113 /* More Flag is not set, so we can look for closing tag in this segment */
8114 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8115 if (tag_is_closing(tag_info)) {
8116 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8124 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8126 guint8 tag_no, tag_info;
8128 proto_tree *subtree = tree;
8131 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8133 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8135 if (tag_is_opening(tag_info))
8137 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
8138 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8139 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8140 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
8141 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
8142 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8148 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8151 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
8152 offset = fAccessMethod(tvb, pinfo, tree, offset);
8158 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
8160 guint tag_no = fTagNo(tvb, offset);
8161 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
8165 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8167 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
8168 offset = fAccessMethod(tvb,pinfo, tree, offset);
8174 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8176 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8177 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
8181 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8183 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8184 return fReadAccessResult (tvb,pinfo,tree,offset);
8188 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8190 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8193 switch (service_choice) {
8194 case 0: /* acknowledgeAlarm */
8195 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
8197 case 1: /* confirmedCOVNotification */
8198 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8200 case 2: /* confirmedEventNotification */
8201 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8203 case 3: /* confirmedGetAlarmSummary conveys no parameters */
8205 case 4: /* getEnrollmentSummaryRequest */
8206 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
8208 case 5: /* subscribeCOVRequest */
8209 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
8211 case 6: /* atomicReadFile-Request */
8212 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
8214 case 7: /* atomicWriteFile-Request */
8215 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
8217 case 8: /* AddListElement-Request */
8218 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
8220 case 9: /* removeListElement-Request */
8221 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
8223 case 10: /* createObjectRequest */
8224 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
8226 case 11: /* deleteObject */
8227 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
8230 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
8233 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
8236 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
8239 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
8242 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
8245 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
8248 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8251 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8254 offset = fReinitializeDeviceRequest(tvb, tree, offset);
8257 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
8260 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8263 offset = fVtDataRequest (tvb, pinfo, tree, offset);
8266 offset = fAuthenticateRequest (tvb, tree, offset);
8269 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
8272 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
8275 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
8278 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
8281 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
8290 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8292 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8295 switch (service_choice) {
8296 case 3: /* confirmedEventNotificationAck */
8297 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
8299 case 4: /* getEnrollmentSummaryAck */
8300 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
8302 case 6: /* atomicReadFile */
8303 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
8305 case 7: /* atomicReadFileAck */
8306 offset = fAtomicWriteFileAck (tvb, tree, offset);
8308 case 10: /* createObject */
8309 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
8312 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
8315 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
8318 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
8321 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
8324 offset = fVtOpenAck (tvb, pinfo, tree, offset);
8327 offset = fVtDataAck (tvb, tree, offset);
8330 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
8333 offset = fReadRangeAck (tvb, pinfo, tree, offset);
8336 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
8345 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8347 /* BACnetObjectIdentifier */
8348 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
8350 /* MaxAPDULengthAccepted */
8351 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
8353 /* segmentationSupported */
8354 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8355 "Segmentation Supported: ", BACnetSegmentation);
8358 return fVendorIdentifier (tvb, pinfo, tree, offset);
8362 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8364 /* BACnetDeviceIdentifier */
8365 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
8367 /* BACnetObjectIdentifier */
8368 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8371 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
8376 fWhoIsRequest (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
8378 guint lastoffset = 0;
8382 guint8 tag_no, tag_info;
8385 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8386 lastoffset = offset;
8388 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8391 case 0: /* DeviceInstanceRangeLowLimit Optional */
8392 fUnsigned32(tvb, offset+tag_len, lvt, &val);
8393 if (col_get_writable(pinfo->cinfo))
8394 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
8396 offset = fUnsignedTag (tvb, tree, offset, "Device Instance Range Low Limit: ");
8398 case 1: /* DeviceInstanceRangeHighLimit Optional but required if DeviceInstanceRangeLowLimit is there */
8399 fUnsigned32(tvb, offset+tag_len, lvt, &val);
8400 if (col_get_writable(pinfo->cinfo))
8401 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
8403 offset = fUnsignedTag (tvb, tree, offset, "Device Instance Range High Limit: ");
8408 if (offset == lastoffset) break; /* nothing happened, exit loop */
8414 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8416 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8419 switch (service_choice) {
8420 case 0: /* I-Am-Request */
8421 offset = fIAmRequest (tvb, pinfo, tree, offset);
8423 case 1: /* i-Have Request */
8424 offset = fIHaveRequest (tvb, pinfo, tree, offset);
8426 case 2: /* unconfirmedCOVNotification */
8427 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8429 case 3: /* unconfirmedEventNotification */
8430 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8432 case 4: /* unconfirmedPrivateTransfer */
8433 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8435 case 5: /* unconfirmedTextMessage */
8436 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8438 case 6: /* timeSynchronization */
8439 offset = fTimeSynchronizationRequest (tvb, tree, offset);
8441 case 7: /* who-Has */
8442 offset = fWhoHas (tvb, pinfo, tree, offset);
8444 case 8: /* who-Is */
8445 offset = fWhoIsRequest (tvb, pinfo, tree, offset);
8447 case 9: /* utcTimeSynchronization */
8448 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
8457 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
8458 gint *svc, proto_item **tt)
8461 proto_tree *bacapp_tree_control;
8462 gint tmp, bacapp_type;
8466 tmp = (gint) tvb_get_guint8(tvb, offset);
8467 bacapp_type = (tmp >> 4) & 0x0f;
8468 bacapp_flags = tmp & 0x0f;
8473 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
8474 if (bacapp_flags & 0x08)
8475 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
8477 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8478 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, TRUE);
8479 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
8481 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, TRUE);
8482 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, TRUE);
8483 if (ack == 0) /* The following are for ConfirmedRequest, not Complex ack */
8485 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, TRUE);
8486 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
8488 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
8492 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
8493 if (bacapp_flags & 0x08) {
8494 bacapp_seq = tvb_get_guint8(tvb, offset);
8495 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
8497 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
8500 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8506 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
8507 { /* BACnet-Confirmed-Request */
8508 /* ASHRAE 135-2001 20.1.2 */
8510 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
8514 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8515 { /* BACnet-Confirmed-Request */
8516 /* ASHRAE 135-2001 20.1.2 */
8520 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
8521 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
8525 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8526 { /* BACnet-Unconfirmed-Request-PDU */
8527 /* ASHRAE 135-2001 20.1.3 */
8531 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8533 tmp = tvb_get_guint8(tvb, offset);
8534 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
8536 /* Service Request follows... Variable Encoding 20.2ff */
8537 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
8541 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8542 { /* BACnet-Simple-Ack-PDU */
8543 /* ASHRAE 135-2001 20.1.4 */
8547 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8549 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8551 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8558 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
8559 { /* BACnet-Complex-Ack-PDU */
8560 /* ASHRAE 135-2001 20.1.5 */
8562 /* Service ACK follows... */
8563 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
8567 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8568 { /* BACnet-Complex-Ack-PDU */
8569 /* ASHRAE 135-2001 20.1.5 */
8573 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
8574 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
8578 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8579 { /* BACnet-SegmentAck-PDU */
8580 /* ASHRAE 135-2001 20.1.6 */
8583 proto_tree *bacapp_tree_control;
8585 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8586 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8588 proto_tree_add_item(bacapp_tree, hf_bacapp_NAK, tvb, offset, 1, TRUE);
8589 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8590 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8592 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
8594 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
8600 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8602 guint8 tag_info = 0;
8603 guint8 parsed_tag = 0;
8605 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8606 offset = fError(tvb, pinfo, tree, offset);
8607 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8611 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8613 guint lastoffset = 0;
8614 guint8 tag_no = 0, tag_info = 0;
8616 proto_tree *subtree = tree;
8619 guint vendor_identifier = 0;
8620 guint service_number = 0;
8623 while (tvb_reported_length_remaining(tvb, offset)) {
8624 /* exit loop if nothing happens inside */
8625 lastoffset = offset;
8626 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8628 case 0: /* errorType */
8629 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
8631 case 1: /* vendorID */
8632 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
8633 if (col_get_writable(pinfo->cinfo))
8634 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
8635 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
8637 case 2: /* serviceNumber */
8638 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
8639 if (col_get_writable(pinfo->cinfo))
8640 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
8641 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
8643 case 3: /* errorParameters */
8644 if (tag_is_opening(tag_info)) {
8645 tt = proto_tree_add_text(subtree, tvb, offset, 1,
8646 "error Parameters");
8647 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8648 propertyIdentifier = -1;
8649 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8650 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8651 } else if (tag_is_closing(tag_info)) {
8652 offset += fTagHeaderTree (tvb, subtree, offset,
8653 &tag_no, &tag_info, &lvt);
8656 /* error condition: let caller handle */
8663 if (offset == lastoffset) break; /* nothing happened, exit loop */
8669 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8671 guint lastoffset = 0;
8673 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8674 lastoffset = offset;
8675 switch (fTagNo(tvb, offset)) {
8676 case 0: /* errorType */
8677 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8679 case 1: /* firstFailedElementNumber */
8680 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
8685 if (offset == lastoffset) break; /* nothing happened, exit loop */
8691 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8693 /* Identical to CreateObjectError */
8694 return fCreateObjectError(tvb, pinfo, tree, offset);
8698 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8700 guint8 tag_no = 0, tag_info = 0;
8703 if (fTagNo(tvb, offset) == 0)
8706 offset = fContextTaggedError(tvb, pinfo, tree,offset);
8707 if (fTagNo(tvb, offset) == 1)
8709 /* listOfVTSessionIdentifiers [OPTIONAL] */
8710 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8711 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8712 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8715 /* should report bad packet if initial tag wasn't 0 */
8720 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8722 guint lastoffset = 0;
8723 guint8 tag_no = 0, tag_info = 0;
8726 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8727 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8728 lastoffset = offset;
8729 switch (fTagNo(tvb, offset)) {
8730 case 0: /* errorType */
8731 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8733 case 1: /* firstFailedWriteAttempt */
8734 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8735 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8736 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8741 if (offset == lastoffset) break; /* nothing happened, exit loop */
8747 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8749 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8750 "error Class: ", BACnetErrorClass, 64);
8751 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8752 "error Code: ", BACnetErrorCode, 256);
8756 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
8759 case 8: /* no break here !!!! */
8761 offset = fChangeListError (tvb, pinfo, tree, offset);
8764 offset = fCreateObjectError (tvb, pinfo, tree, offset);
8767 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
8770 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
8773 offset = fVTCloseError (tvb, pinfo, tree, offset);
8776 return fError (tvb, pinfo, tree, offset);
8782 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8783 { /* BACnet-Error-PDU */
8784 /* ASHRAE 135-2001 20.1.7 */
8786 proto_item *tc, *tt;
8787 proto_tree *bacapp_tree_control;
8790 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8791 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8793 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8795 tmp = tvb_get_guint8(tvb, offset);
8796 tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8798 /* Error Handling follows... */
8799 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
8803 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8804 { /* BACnet-Reject-PDU */
8805 /* ASHRAE 135-2001 20.1.8 */
8808 proto_tree *bacapp_tree_control;
8810 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8811 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8813 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8815 proto_tree_add_item(bacapp_tree, hf_BACnetRejectReason, tvb,
8821 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8822 { /* BACnet-Abort-PDU */
8823 /* ASHRAE 135-2001 20.1.9 */
8826 proto_tree *bacapp_tree_control;
8828 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8829 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8831 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8832 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8834 proto_tree_add_item(bacapp_tree, hf_BACnetAbortReason, tvb,
8840 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8842 guint8 flag, bacapp_type;
8845 flag = (gint) tvb_get_guint8(tvb, 0);
8846 bacapp_type = (flag >> 4) & 0x0f;
8848 if (tvb == NULL || tree == NULL) {
8852 /* ASHRAE 135-2001 20.1.1 */
8853 switch (bacapp_type) {
8854 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
8855 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
8857 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
8858 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
8860 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
8861 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
8863 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
8864 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
8866 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
8867 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
8869 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
8870 offset = fErrorPDU(tvb, pinfo, tree, offset);
8872 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
8873 offset = fRejectPDU(tvb, pinfo, tree, offset);
8875 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
8876 offset = fAbortPDU(tvb, pinfo, tree, offset);
8883 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8885 guint8 flag, bacapp_type;
8886 guint save_fragmented = FALSE, data_offset = 0, bacapp_apdu_size = fGetMaxAPDUSize(0), fragment = FALSE;
8887 tvbuff_t* new_tvb = NULL;
8889 guint8 bacapp_seqno = 0;
8890 guint8 bacapp_service, bacapp_reason, bacapp_prop_win_size;
8891 guint8 bacapp_invoke_id = 0;
8893 proto_tree *bacapp_tree = NULL;
8899 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
8900 col_clear (pinfo->cinfo, COL_INFO);
8902 flag = tvb_get_guint8(tvb, 0);
8903 bacapp_type = (flag >> 4) & 0x0f;
8905 /* show some descriptive text in the INFO column */
8906 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
8907 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
8909 switch (bacapp_type)
8911 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
8912 /* segmented messages have 2 additional bytes */
8913 if (flag & BACAPP_SEGMENTED_REQUEST)
8917 bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); /* has 16 values, reserved are 50 Bytes */
8918 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
8919 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
8920 bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4);
8921 bacapp_service = tvb_get_guint8(tvb, offset + 5);
8926 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
8927 bacapp_service = tvb_get_guint8(tvb, offset + 3);
8929 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
8930 val_to_str(bacapp_service,
8931 BACnetConfirmedServiceChoice,
8932 bacapp_unknown_service_str),bacapp_invoke_id);
8934 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
8935 bacapp_service = tvb_get_guint8(tvb, offset + 1);
8936 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
8937 val_to_str(bacapp_service,
8938 BACnetUnconfirmedServiceChoice,
8939 bacapp_unknown_service_str));
8941 case BACAPP_TYPE_SIMPLE_ACK:
8942 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8943 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8944 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8945 val_to_str(bacapp_service,
8946 BACnetConfirmedServiceChoice,
8947 bacapp_unknown_service_str), bacapp_invoke_id);
8949 case BACAPP_TYPE_COMPLEX_ACK:
8950 /* segmented messages have 2 additional bytes */
8951 if (flag & BACAPP_SEGMENTED_REQUEST)
8955 bacapp_apdu_size = fGetMaxAPDUSize(0); /* has minimum of 50 Bytes */
8956 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8957 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
8958 bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3);
8959 bacapp_service = tvb_get_guint8(tvb, offset + 4);
8964 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8965 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8967 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8968 val_to_str(bacapp_service,
8969 BACnetConfirmedServiceChoice,
8970 bacapp_unknown_service_str), bacapp_invoke_id);
8972 case BACAPP_TYPE_SEGMENT_ACK:
8973 /* nothing more to add */
8975 case BACAPP_TYPE_ERROR:
8976 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8977 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8978 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8979 val_to_str(bacapp_service,
8980 BACnetConfirmedServiceChoice,
8981 bacapp_unknown_service_str), bacapp_invoke_id);
8983 case BACAPP_TYPE_REJECT:
8984 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8985 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
8986 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8987 val_to_split_str(bacapp_reason,
8990 ASHRAE_Reserved_Fmt,
8991 Vendor_Proprietary_Fmt), bacapp_invoke_id);
8993 case BACAPP_TYPE_ABORT:
8994 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8995 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
8996 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8997 val_to_split_str(bacapp_reason,
9000 ASHRAE_Reserved_Fmt,
9001 Vendor_Proprietary_Fmt), bacapp_invoke_id);
9005 /* nothing more to add */
9009 save_fragmented = pinfo->fragmented;
9013 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, FALSE);
9014 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
9017 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
9019 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
9020 /* not resetting the offset so the remaining can be done */
9023 if (fragment) { /* fragmented */
9024 fragment_data *frag_msg = NULL;
9027 pinfo->fragmented = TRUE;
9029 frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
9030 bacapp_invoke_id, /* ID for fragments belonging together */
9031 msg_fragment_table, /* list of message fragments */
9032 msg_reassembled_table, /* list of reassembled messages */
9033 bacapp_seqno, /* fragment sequence number */
9034 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
9035 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
9036 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
9037 "Reassembled BACapp", frag_msg, &msg_frag_items,
9040 if (new_tvb) { /* Reassembled */
9041 col_append_str(pinfo->cinfo, COL_INFO,
9042 " (Message Reassembled)");
9043 } else { /* Not last packet of reassembled Short Message */
9044 col_append_fstr(pinfo->cinfo, COL_INFO,
9045 " (Message fragment %u)", bacapp_seqno);
9047 if (new_tvb) { /* take it all */
9048 switch (bacapp_type)
9050 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
9051 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
9053 case BACAPP_TYPE_COMPLEX_ACK:
9054 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
9064 pinfo->fragmented = save_fragmented;
9069 bacapp_init_routine(void)
9071 fragment_table_init(&msg_fragment_table);
9072 reassembled_table_init(&msg_reassembled_table);
9076 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
9081 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
9082 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
9083 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
9086 g_iconv_close (icd);
9090 uni_to_string(in,*inbytesleft,out);
9091 out[*inbytesleft] = '\0';
9092 *outbytesleft -= *inbytesleft;
9099 uni_to_string(char * data, gsize str_length, char *dest_buf)
9103 gsize length_remaining = 0;
9105 length_remaining = str_length;
9111 for ( i = 0; i < (gint) str_length; i++ )
9114 if (c_char<0x20 || c_char>0x7e)
9119 dest_buf[i] = c_char & 0xff;
9129 dest_buf[i] = c_char & 0xff;
9133 if(length_remaining==0)
9135 dest_buf[i+1] = '\0';
9147 proto_register_bacapp(void)
9149 static hf_register_info hf[] = {
9151 { "APDU Type", "bacapp.type",
9152 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
9154 { &hf_bacapp_pduflags,
9155 { "PDU Flags", "bacapp.pduflags",
9156 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
9159 { "Segmented Request", "bacapp.segmented_request",
9160 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
9163 { "More Segments", "bacapp.more_segments",
9164 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
9167 { "SA", "bacapp.SA",
9168 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
9170 { &hf_bacapp_max_adpu_size,
9171 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
9172 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
9174 { &hf_bacapp_response_segments,
9175 { "Max Response Segments accepted", "bacapp.response_segments",
9176 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
9178 { &hf_bacapp_objectType,
9179 { "Object Type", "bacapp.objectType",
9180 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
9182 { &hf_bacapp_instanceNumber,
9183 { "Instance Number", "bacapp.instance_number",
9184 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
9186 { &hf_BACnetPropertyIdentifier,
9187 { "Property Identifier", "bacapp.property_identifier",
9188 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
9190 { &hf_BACnetVendorIdentifier,
9191 { "Vendor Identifier", "bacapp.vendor_identifier",
9192 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
9194 { &hf_BACnetRestartReason,
9195 { "Restart Reason", "bacapp.restart_reason",
9196 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
9198 { &hf_bacapp_invoke_id,
9199 { "Invoke ID", "bacapp.invoke_id",
9200 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9202 { &hf_bacapp_sequence_number,
9203 { "Sequence Number", "bacapp.sequence_number",
9204 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9206 { &hf_bacapp_window_size,
9207 { "Proposed Window Size", "bacapp.window_size",
9208 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9210 { &hf_bacapp_service,
9211 { "Service Choice", "bacapp.confirmed_service",
9212 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
9214 { &hf_bacapp_uservice,
9215 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
9216 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
9219 { "NAK", "bacapp.NAK",
9220 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
9223 { "SRV", "bacapp.SRV",
9224 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
9226 { &hf_BACnetRejectReason,
9227 { "Reject Reason", "bacapp.reject_reason",
9228 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
9230 { &hf_BACnetAbortReason,
9231 { "Abort Reason", "bacapp.abort_reason",
9232 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
9235 { "BACnet APDU variable part:", "bacapp.variable_part",
9236 FT_NONE, BASE_NONE, NULL, 0, "BACnet APDU variable part", HFILL }
9241 FT_BYTES, BASE_NONE, NULL, 0,
9244 { &hf_BACnetApplicationTagNumber,
9245 { "Application Tag Number",
9246 "bacapp.application_tag_number",
9247 FT_UINT8, BASE_DEC, VALS(&BACnetApplicationTagNumber), 0xF0,
9250 { &hf_BACnetContextTagNumber,
9251 { "Context Tag Number",
9252 "bacapp.context_tag_number",
9253 FT_UINT8, BASE_DEC, NULL, 0xF0,
9256 { &hf_BACnetExtendedTagNumber,
9257 { "Extended Tag Number",
9258 "bacapp.extended_tag_number",
9259 FT_UINT8, BASE_DEC, NULL, 0,
9262 { &hf_BACnetNamedTag,
9265 FT_UINT8, BASE_DEC, VALS(&BACnetTagNames), 0x07,
9268 { &hf_BACnetCharacterSet,
9269 { "String Character Set",
9270 "bacapp.string_character_set",
9271 FT_UINT8, BASE_DEC, VALS(&BACnetCharacterSet),0,
9274 { &hf_BACnetTagClass,
9275 { "Tag Class", "bacapp.tag_class",
9276 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
9278 { &hf_bacapp_tag_lvt,
9279 { "Length Value Type",
9281 FT_UINT8, BASE_DEC, NULL, 0,
9284 { &hf_bacapp_tag_value8,
9286 "bacapp.tag_value8",
9287 FT_UINT8, BASE_DEC, NULL, 0,
9290 { &hf_bacapp_tag_value16,
9291 { "Tag Value 16-bit",
9292 "bacapp.tag_value16",
9293 FT_UINT16, BASE_DEC, NULL, 0,
9296 { &hf_bacapp_tag_value32,
9297 { "Tag Value 32-bit",
9298 "bacapp.tag_value32",
9299 FT_UINT32, BASE_DEC, NULL, 0,
9302 { &hf_bacapp_tag_ProcessId,
9303 { "ProcessIdentifier", "bacapp.processId",
9304 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
9306 { &hf_bacapp_tag_IPV4,
9307 { "IPV4", "bacapp.IPV4",
9308 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
9310 { &hf_bacapp_tag_IPV6,
9311 { "IPV6", "bacapp.IPV6",
9312 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
9314 { &hf_bacapp_tag_PORT,
9315 { "Port", "bacapp.Port",
9316 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
9318 { &hf_bacapp_tag_initiatingObjectType,
9319 { "ObjectType", "bacapp.objectType",
9320 FT_UINT16, BASE_DEC, VALS(BACnetObjectType), 0x00, "Object Type", HFILL }
9323 {"Message fragments", "bacapp.fragments",
9324 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9326 {"Message fragment", "bacapp.fragment",
9327 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9328 {&hf_msg_fragment_overlap,
9329 {"Message fragment overlap", "bacapp.fragment.overlap",
9330 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9331 {&hf_msg_fragment_overlap_conflicts,
9332 {"Message fragment overlapping with conflicting data",
9333 "bacapp.fragment.overlap.conflicts",
9334 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9335 {&hf_msg_fragment_multiple_tails,
9336 {"Message has multiple tail fragments",
9337 "bacapp.fragment.multiple_tails",
9338 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9339 {&hf_msg_fragment_too_long_fragment,
9340 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
9341 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9342 {&hf_msg_fragment_error,
9343 {"Message defragmentation error", "bacapp.fragment.error",
9344 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9345 {&hf_msg_reassembled_in,
9346 {"Reassembled in", "bacapp.reassembled.in",
9347 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9348 {&hf_msg_reassembled_length,
9349 {"Reassembled BACapp length", "bacapp.reassembled.length",
9350 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
9352 static gint *ett[] = {
9354 &ett_bacapp_control,
9363 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
9364 "BACapp", "bacapp");
9366 proto_register_field_array(proto_bacapp, hf, array_length(hf));
9367 proto_register_subtree_array(ett, array_length(ett));
9368 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
9369 register_init_routine (&bacapp_init_routine);
9371 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
9372 "BACapp Vendor Identifier",
9373 FT_UINT8, BASE_HEX);
9378 proto_reg_handoff_bacapp(void)
9380 data_handle = find_dissector("data");