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, 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);
1818 * BACnetSessionKey ::= SEQUENCE {
1819 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1820 * peerAddress BACnetAddress
1825 * @return modified offset
1826 * @todo check if checksum is displayed correctly
1829 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1833 * BACnetSpecialEvent ::= SEQUENCE {
1835 * calendarEntry [0] BACnetCalendarEntry,
1836 * calendarRefernce [1] BACnetObjectIdentifier
1838 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1839 * eventPriority [3] Unsigned (1..16)
1845 * @return modified offset
1848 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1851 * BACnetTimeStamp ::= CHOICE {
1853 * sequenceNumber [1] Unsigned (0..65535),
1854 * dateTime [2] BACnetDateTime
1860 * @return modified offset
1863 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1866 * BACnetTimeValue ::= SEQUENCE {
1868 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1874 * @return modified offset
1877 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1881 * BACnetVTSession ::= SEQUENCE {
1882 * local-vtSessionID Unsigned8,
1883 * remote-vtSessionID Unsigned8,
1884 * remote-vtAddress BACnetAddress
1889 * @return modified offset
1892 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1896 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1897 * -- first octet month (1..12) January = 1, X'FF' = any month
1898 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1899 * -- 2 = days numbered 8-14
1900 * -- 3 = days numbered 15-21
1901 * -- 4 = days numbered 22-28
1902 * -- 5 = days numbered 29-31
1903 * -- 6 = last 7 days of this month
1904 * -- X'FF' = any week of this month
1905 * -- third octet dayOfWeek (1..7) where 1 = Monday
1907 * -- X'FF' = any day of week
1911 * @return modified offset
1914 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
1917 * ReadAccessResult ::= SEQUENCE {
1918 * objectIdentifier [0] BACnetObjectIdentifier,
1919 * listOfResults [1] SEQUENCE OF SEQUENCE {
1920 * propertyIdentifier [2] BACnetPropertyIdentifier,
1921 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1922 * readResult CHOICE {
1923 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1924 * propertyAccessError [5] Error
1932 * @return modified offset
1935 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1938 * ReadAccessSpecification ::= SEQUENCE {
1939 * objectIdentifier [0] BACnetObjectIdentifier,
1940 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
1946 * @return modified offset
1949 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1952 * WriteAccessSpecification ::= SEQUENCE {
1953 * objectIdentifier [0] BACnetObjectIdentifier,
1954 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
1960 * @return modified offset
1963 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1966 /********************************************************* Helper functions *******************************************/
1969 * extracts the tag number from the tag header.
1970 * @param tvb "TestyVirtualBuffer"
1971 * @param offset in actual tvb
1972 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
1975 fTagNo (tvbuff_t *tvb, guint offset);
1978 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
1979 * @param tvb = "TestyVirtualBuffer"
1980 * @param offset = offset in actual tvb
1981 * @return tag_no BACnet 20.2.1.2 Tag Number
1982 * @return class_tag BACnet 20.2.1.1 Class
1983 * @return lvt BACnet 20.2.1.3 Length/Value/Type
1984 * @return offs = length of this header
1988 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
1992 * adds processID with max 32Bit unsigned Integer Value to tree
1996 * @return modified offset
1999 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
2002 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2006 * @return modified offset
2009 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2012 * BACnet Application PDUs chapter 21
2013 * BACnetPropertyIdentifier::= ENUMERATED {
2014 * @see bacapp_property_identifier
2020 * @param tt returnvalue of this item
2021 * @return modified offset
2024 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2027 * BACnet Application PDUs chapter 21
2028 * BACnetPropertyArrayIndex::= ENUMERATED {
2029 * @see bacapp_property_array_index
2034 * @param tt returnvalue of this item
2035 * @return modified offset
2038 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
2041 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2042 * objectIdentifier [0] BACnetObjectIdentifier,
2043 * eventState [1] BACnetEventState,
2044 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2045 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2046 * notifyType [4] BACnetNotifyType,
2047 * eventEnable [5] BACnetEventTransitionBits,
2048 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2054 * @return modified offset
2057 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2060 * SelectionCriteria ::= SEQUENCE {
2061 * propertyIdentifier [0] BACnetPropertyIdentifier,
2062 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2063 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2064 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2070 * @return modified offset
2073 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2076 * objectSelectionCriteria ::= SEQUENCE {
2077 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2078 * listOfSelectionCriteria [1] SelectionCriteria
2084 * @return modified offset
2087 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2090 * BACnet-Error ::= SEQUENCE {
2091 * error-class ENUMERATED {},
2092 * error-code ENUMERATED {}
2099 * @return modified offset
2102 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2105 * Generic handler for context tagged values. Mostly for handling
2106 * vendor-defined properties and services.
2110 * @return modified offset
2111 * @todo beautify this ugly construct
2114 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2117 * realizes some ABSTRACT-SYNTAX.&Type
2122 * @return modified offset
2123 * @todo beautify this ugly construct
2126 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2130 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2131 const value_string *src);
2137 proto_register_bacapp(void);
2140 * proto_reg_handoff_bacapp
2143 proto_reg_handoff_bacapp(void);
2146 * converts XXX coded strings to UTF-8
2147 * else 'in' is copied to 'out'
2148 * @param in -- pointer to string
2149 * @param inbytesleft
2150 * @param out -- pointer to string
2151 * @param outbytesleft
2153 * @return count of modified characters of returned string, -1 for errors
2156 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2159 uni_to_string(char * data, gsize str_length, char *dest_buf);
2161 /* <<<< formerly bacapp.h */
2163 /* some hashes for segmented messages */
2164 static GHashTable *msg_fragment_table = NULL;
2165 static GHashTable *msg_reassembled_table = NULL;
2167 /* some necessary forward function prototypes */
2169 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2170 const gchar *label, const value_string *vs);
2172 static const char *bacapp_unknown_service_str = "unknown service";
2173 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2174 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2176 static const value_string
2177 BACnetTypeName[] = {
2178 {0, "Confirmed-REQ"},
2179 {1, "Unconfirmed-REQ"},
2189 static const true_false_string segments_follow = {
2190 "Segmented Request",
2191 "Unsegmented Request"
2194 static const true_false_string more_follow = {
2195 "More Segments Follow",
2196 "No More Segments Follow"
2199 static const true_false_string segmented_accept = {
2200 "Segmented Response accepted",
2201 "Segmented Response not accepted"
2204 static const true_false_string
2206 "Context Specific Tag",
2210 static const value_string
2211 BACnetMaxSegmentsAccepted [] = {
2219 {7,"Greater than 64 segments"},
2223 static const value_string
2224 BACnetMaxAPDULengthAccepted [] = {
2225 {0,"Up to MinimumMessageSize (50 octets)"},
2226 {1,"Up to 128 octets"},
2227 {2,"Up to 206 octets (fits in a LonTalk frame)"},
2228 {3,"Up to 480 octets (fits in an ARCNET frame)"},
2229 {4,"Up to 1024 octets"},
2230 {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2231 {6,"reserved by ASHRAE"},
2232 {7,"reserved by ASHRAE"},
2233 {8,"reserved by ASHRAE"},
2234 {9,"reserved by ASHRAE"},
2235 {10,"reserved by ASHRAE"},
2236 {11,"reserved by ASHRAE"},
2237 {12,"reserved by ASHRAE"},
2238 {13,"reserved by ASHRAE"},
2239 {14,"reserved by ASHRAE"},
2240 {15,"reserved by ASHRAE"},
2244 static const value_string
2245 BACnetRejectReason [] = {
2247 {1,"buffer-overflow"},
2248 {2,"inconsistent-parameters"},
2249 {3,"invalid-parameter-data-type"},
2251 {5,"missing-required-parameter"},
2252 {6,"parameter-out-of-range"},
2253 {7,"too-many-arguments"},
2254 {8,"undefined-enumeration"},
2255 {9,"unrecognized-service"},
2259 static const value_string
2260 BACnetRestartReason [] = {
2264 {3,"detected-power-lost"},
2265 {4,"detected-powered-off"},
2266 {5,"hardware-watchdog"},
2267 {6,"software-watchdog"},
2272 static const value_string
2273 BACnetApplicationTagNumber [] = {
2276 {2,"Unsigned Integer"},
2277 {3,"Signed Integer (2's complement notation)"},
2278 {4,"Real (ANSI/IEE-754 floating point)"},
2279 {5,"Double (ANSI/IEE-754 double precision floating point)"},
2281 {7,"Character String"},
2286 {12,"BACnetObjectIdentifier"},
2287 {13,"reserved by ASHRAE"},
2288 {14,"reserved by ASHRAE"},
2289 {15,"reserved by ASHRAE"},
2293 static const value_string
2300 static const value_string
2301 BACnetFileAccessMethod [] = {
2302 {0,"record-access"},
2303 {1,"stream-access"},
2307 /* For some reason, BACnet defines the choice parameter
2308 in the file read and write services backwards from the
2309 BACnetFileAccessMethod enumeration.
2311 static const value_string
2312 BACnetFileAccessOption [] = {
2313 {0,"stream access"},
2314 {1,"record access"},
2318 static const value_string
2319 BACnetFileStartOption [] = {
2320 {0, "File Start Position: "},
2321 {1, "File Start Record: "},
2325 static const value_string
2326 BACnetFileRequestCount [] = {
2327 {0, "Requested Octet Count: "},
2328 {1, "Requested Record Count: "},
2332 static const value_string
2333 BACnetFileWriteInfo [] = {
2335 {1, "Record Count: "},
2339 static const value_string
2340 BACnetAbortReason [] = {
2342 {1,"buffer-overflow"},
2343 {2,"invalid-apdu-in-this-state"},
2344 {3,"preempted-by-higher-priority-task"},
2345 {4,"segmentation-not-supported"},
2349 static const value_string
2350 BACnetLifeSafetyMode [] = {
2361 {10,"disconnected"},
2364 {13,"atomic-release-disabled"},
2367 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2368 Enumerated values 256-65535 may be used by others subject to
2369 procedures and constraints described in Clause 23. */
2372 static const value_string
2373 BACnetLifeSafetyOperation [] = {
2376 {2,"silence-audible"},
2377 {3,"silence-visual"},
2382 {8,"unsilence-audible"},
2383 {9,"unsilence-visual"},
2385 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2386 Enumerated values 64-65535 may be used by others subject to
2387 procedures and constraints described in Clause 23. */
2390 static const value_string
2391 BACnetLimitEnable [] = {
2392 {0,"lowLimitEnable"},
2393 {1,"highLimitEnable"},
2397 static const value_string
2398 BACnetLifeSafetyState [] = {
2403 {4,"fault-pre-alarm"},
2411 {12,"test-fault-alarm"},
2414 {15,"tamper-alarm"},
2416 {17,"emergency-power"},
2420 {21,"general-alarm"},
2422 {23,"test-supervisory"},
2424 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2425 Enumerated values 256-65535 may be used by others subject to
2426 procedures and constraints described in Clause 23. */
2429 static const value_string
2430 BACnetConfirmedServiceChoice [] = {
2431 {0,"acknowledgeAlarm"},
2432 {1,"confirmedCOVNotification"},
2433 {2,"confirmedEventNotification"},
2434 {3,"getAlarmSummary"},
2435 {4,"getEnrollmentSummary"},
2437 {6,"atomicReadFile"},
2438 {7,"atomicWriteFile"},
2439 {8,"addListElement"},
2440 {9,"removeListElement"},
2441 {10,"createObject"},
2442 {11,"deleteObject"},
2443 {12,"readProperty"},
2444 {13,"readPropertyConditional"},
2445 {14,"readPropertyMultiple"},
2446 {15,"writeProperty"},
2447 {16,"writePropertyMultiple"},
2448 {17,"deviceCommunicationControl"},
2449 {18,"confirmedPrivateTransfer"},
2450 {19,"confirmedTextMessage"},
2451 {20,"reinitializeDevice"},
2455 {24,"authenticate"},
2458 {27,"lifeSafetyOperation"},
2459 {28,"subscribeCOVProperty"},
2460 {29,"getEventInformation"},
2461 {30,"reserved by ASHRAE"},
2465 static const value_string
2466 BACnetReliability [] = {
2467 {0,"no-fault-detected"},
2474 {7,"unreliable-other"},
2475 {8,"process-error"},
2476 {9,"multi-state-fault"},
2480 static const value_string
2481 BACnetUnconfirmedServiceChoice [] = {
2484 {2,"unconfirmedCOVNotification"},
2485 {3,"unconfirmedEventNotification"},
2486 {4,"unconfirmedPrivateTransfer"},
2487 {5,"unconfirmedTextMessage"},
2488 {6,"timeSynchronization"},
2491 {9,"utcTimeSynchonization"},
2495 static const value_string
2496 BACnetUnconfirmedServiceRequest [] = {
2498 {1,"i-Have-Request"},
2499 {2,"unconfirmedCOVNotification-Request"},
2500 {3,"unconfirmedEventNotification-Request"},
2501 {4,"unconfirmedPrivateTransfer-Request"},
2502 {5,"unconfirmedTextMessage-Request"},
2503 {6,"timeSynchronization-Request"},
2504 {7,"who-Has-Request"},
2505 {8,"who-Is-Request"},
2506 {9,"utcTimeSynchonization-Request"},
2510 static const value_string
2511 BACnetObjectType [] = {
2513 {1,"analog-output"},
2516 {4,"binary-output"},
2521 {9,"event-enrollment"},
2525 {13,"multi-state-input"},
2526 {14,"multi-state-output"},
2527 {15,"notification-class"},
2531 {19,"multi-state-value"},
2533 {21,"life-safety-point"},
2534 {22,"life-safety-zone"},
2536 {24,"pulse-converter"},
2538 {26,"global-group"},
2539 {27,"trend-log-multiple"},
2540 {28,"load-control"},
2541 {29,"structured-view"},
2544 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2545 Enumerated values 128-1023 may be used by others subject to
2546 the procedures and constraints described in Clause 23. */
2549 static const value_string
2550 BACnetEngineeringUnits [] = {
2560 {9,"Kilovolt Amperes"},
2561 {10,"Megavolt Amperes"},
2562 {11,"Volt Amperes Reactive"},
2563 {12,"Kilovolt Amperes Reactive"},
2564 {13,"Megavolt Amperes Reactive"},
2565 {14,"Degrees Phase"},
2566 {15,"Power Factor"},
2570 {19,"Kilowatt Hours"},
2574 {23,"Joules Per Kg Dry Air"},
2575 {24,"BTUs Per Pound Dry Air"},
2576 {25,"Cycles Per Hour"},
2577 {26,"Cycles Per Minute"},
2579 {28,"Grams Of Water Per Kilogram Dry Air"},
2580 {29,"Relative Humidity"},
2585 {34,"Watts Per Sq Foot"},
2586 {35,"Watts Per Sq meter"},
2589 {38,"Foot Candles"},
2593 {42,"Kgs per Second"},
2594 {43,"Kgs Per Minute"},
2595 {44,"Kgs Per Hour"},
2596 {45,"Pounds Mass Per Minute"},
2597 {46,"Pounds Mass Per Hour"},
2601 {50,"BTUs Per Hour"},
2603 {52,"Tons Refrigeration"},
2607 {56,"Pounds Force Per Square Inch"},
2608 {57,"Centimeters Of Water"},
2609 {58,"Inches Of Water"},
2610 {59,"Millimeters Of Mercury"},
2611 {60,"Centimeters Of Mercury"},
2612 {61,"Inches Of Mercury"},
2613 {62,"Degrees Celsius"},
2614 {63,"Degrees Kelvin"},
2615 {64,"Degrees Fahrenheit"},
2616 {65,"Degree Days Celsius"},
2617 {66,"Degree Days Fahrenheit"},
2625 {74,"Meters Per Second"},
2626 {75,"Kilometers Per Hour"},
2627 {76,"Feed Per Second"},
2628 {77,"Feet Per Minute"},
2629 {78,"Miles Per Hour"},
2631 {80,"Cubic Meters"},
2632 {81,"Imperial Gallons"},
2635 {84,"Cubic Feet Per Minute"},
2636 {85,"Cubic Meters Per Second"},
2637 {86,"Imperial Gallons Per Minute"},
2638 {87,"Liters Per Second"},
2639 {88,"Liters Per Minute"},
2640 {89,"US Gallons Per Minute"},
2641 {90,"Degrees Angular"},
2642 {91,"Degrees Celsius Per Hour"},
2643 {92,"Degrees Celsius Per Minute"},
2644 {93,"Degrees Fahrenheit Per Hour"},
2645 {94,"Degrees Fahrenheit Per Minute"},
2647 {96,"Parts Per Million"},
2648 {97,"Parts Per Billion"},
2650 {99,"Pecent Per Second"},
2653 {102,"Psi Per Degree Fahrenheit"},
2655 {104,"Revolutions Per Min"},
2667 {116,"Sq Centimeters"},
2668 {117,"BTUs Per Pound"},
2669 {118,"Centimeters"},
2670 {119,"Pounds Mass Per Second"},
2671 {120,"Delta Degrees Fahrenheit"},
2672 {121,"Delta Degrees Kelvin"},
2676 {125,"Kilojoules Per Kg"},
2678 {127,"Joules Per Degree Kelvin"},
2679 {128,"Joules Per Kg Degree Kelvin"},
2684 {133,"Hectopascals"},
2686 {135,"Cubic Meters Per Hour"},
2687 {136,"Liters Per Hour"},
2688 {137,"KWatt Hours Per Square Meter"},
2689 {138,"KWatt Hours Per Square Foot"},
2690 {139,"Megajoules Per Square Meter"},
2691 {140,"Megajoules Per Square Foot"},
2692 {141,"Watts Per Sq Meter Degree Kelvin"},
2693 {142,"Cubic Feet Per Second"},
2694 {143,"Percent Obstruction Per Foot"},
2695 {144,"Percent Obstruction Per Meter"},
2697 {146,"megawatt-hours"},
2700 {149,"kilojoules-per-kilogram-dry-air"},
2701 {150,"megajoules-per-kilogram-dry-air"},
2702 {151,"kilojoules-per-degree-Kelvin"},
2703 {152,"megajoules-per-degree-Kelvin"},
2705 {154,"grams-per-second"},
2706 {155,"grams-per-minute"},
2707 {156,"tons-per-hour"},
2708 {157,"kilo-btus-per-hour"},
2709 {158,"hundredths-seconds"},
2710 {159,"milliseconds"},
2711 {160,"newton-meters"},
2712 {161,"millimeters-per-second"},
2713 {162,"millimeters-per-minute"},
2714 {163,"meters-per-minute"},
2715 {164,"meters-per-hour"},
2716 {165,"cubic-meters-per-minute"},
2717 {166,"meters-per-second-per-second"},
2718 {167,"amperes-per-meter"},
2719 {168,"amperes-per-square-meter"},
2720 {169,"ampere-square-meters"},
2725 {174,"siemens-per-meter"},
2727 {176,"volts-per-degree-Kelvin"},
2728 {177,"volts-per-meter"},
2731 {180,"candelas-per-square-meter"},
2732 {181,"degrees-Kelvin-per-hour"},
2733 {182,"degrees-Kelvin-per-minute"},
2734 {183,"joule-seconds"},
2735 {184,"radians-per-second"},
2736 {185,"square-meters-per-Newton"},
2737 {186,"kilograms-per-cubic-meter"},
2738 {187,"newton-seconds"},
2739 {188,"newtons-per-meter"},
2740 {189,"watts-per-meter-per-degree-Kelvin"},
2742 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2743 Enumerated values 256-65535 may be used by others subject to
2744 the procedures and constraints described in Clause 23. */
2747 static const value_string
2748 BACnetErrorCode [] = {
2750 {1,"authentication-failed"},
2751 {2,"configuration-in-progress"},
2753 {4,"dynamic-creation-not-supported"},
2754 {5,"file-access-denied"},
2755 {6,"incompatible-security-levels"},
2756 {7,"inconsistent-parameters"},
2757 {8,"inconsistent-selection-criterion"},
2758 {9,"invalid-data-type"},
2759 {10,"invalid-file-access-method"},
2760 {11,"invalid-file-start-position"},
2761 {12,"invalid-operator-name"},
2762 {13,"invalid-parameter-data-type"},
2763 {14,"invalid-time-stamp"},
2764 {15,"key-generation-error"},
2765 {16,"missing-required-parameter"},
2766 {17,"no-objects-of-specified-type"},
2767 {18,"no-space-for-object"},
2768 {19,"no-space-to-add-list-element"},
2769 {20,"no-space-to-write-property"},
2770 {21,"no-vt-sessions-available"},
2771 {22,"property-is-not-a-list"},
2772 {23,"object-deletion-not-permitted"},
2773 {24,"object-identifier-already-exists"},
2774 {25,"operational-problem"},
2775 {26,"password-failure"},
2776 {27,"read-access-denied"},
2777 {28,"security-not-supported"},
2778 {29,"service-request-denied"},
2780 {31,"unknown-object"},
2781 {32,"unknown-property"},
2782 {33,"removed enumeration"},
2783 {34,"unknown-vt-class"},
2784 {35,"unknown-vt-session"},
2785 {36,"unsupported-object-type"},
2786 {37,"value-out-of-range"},
2787 {38,"vt-session-already-closed"},
2788 {39,"vt-session-termination-failure"},
2789 {40,"write-access-denied"},
2790 {41,"character-set-not-supported"},
2791 {42,"invalid-array-index"},
2792 {43,"cov-subscription-failed"},
2793 {44,"not-cov-property"},
2794 {45,"optional-functionality-not-supported"},
2795 {46,"invalid-configuration-data"},
2796 {47,"datatype-not-supported"},
2797 {48,"duplicate-name"},
2798 {49,"duplicate-object-id"},
2799 {50,"property-is-not-an-array"},
2800 {73,"invalid-event-state"},
2801 {74,"no-alarm-configured"},
2803 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2804 Enumerated values 256-65535 may be used by others subject to the
2805 procedures and constraints described in Clause 23. */
2808 static const value_string
2809 BACnetPropertyIdentifier [] = {
2810 {0,"acked-transition"},
2815 {5,"active-vt-session"},
2819 {9,"all-write-successful"},
2820 {10,"apdu-segment-timeout"},
2821 {11,"apdu-timeout"},
2822 {12,"application-software-version"},
2825 {15,"change-of-state-count"},
2826 {16,"change-of-state-time"},
2827 {17,"notification-class"},
2828 {18,"the property in this place was deleted"},
2829 {19,"controlled-variable-reference"},
2830 {20,"controlled-variable-units"},
2831 {21,"controlled-variable-value"},
2832 {22,"cov-increment"},
2834 {24,"daylights-savings-status"},
2836 {26,"derivative-constant"},
2837 {27,"derivative-constant-units"},
2839 {29,"description-of-halt"},
2840 {30,"device-address-binding"},
2842 {32,"effective-period"},
2843 {33,"elapsed-active-time"},
2845 {35,"event-enable"},
2848 {38,"exception-schedule"},
2849 {39,"fault-values"},
2850 {40,"feedback-value"},
2851 {41,"file-access-method"},
2854 {44,"firmware-revision"},
2856 {46,"inactive-text"},
2859 {49,"integral-constant"},
2860 {50,"integral-constant-units"},
2861 {51,"issue-confirmed-notifications"},
2862 {52,"limit-enable"},
2863 {53,"list-of-group-members"},
2864 {54,"list-of-object-property-references"},
2865 {55,"list-of-session-keys"},
2870 {60,"manipulated-variable-reference"},
2871 {61,"maximum-output"},
2872 {62,"max-apdu-length-accepted"},
2873 {63,"max-info-frames"},
2875 {65,"max-pres-value"},
2876 {66,"minimum-off-time"},
2877 {67,"minimum-on-time"},
2878 {68,"minimum-output"},
2879 {69,"min-pres-value"},
2881 {71,"modification-date"},
2883 {73,"number-of-APDU-retries"},
2884 {74,"number-of-states"},
2885 {75,"object-identifier"},
2888 {78,"object-property-reference"},
2891 {81,"out-of-service"},
2892 {82,"output-units"},
2893 {83,"event-parameters"},
2895 {85,"present-value"},
2897 {87,"priority-array"},
2898 {88,"priority-for-writing"},
2899 {89,"process-identifier"},
2900 {90,"program-change"},
2901 {91,"program-location"},
2902 {92,"program-state"},
2903 {93,"proportional-constant"},
2904 {94,"proportional-constant-units"},
2905 {95,"protocol-conformance-class"},
2906 {96,"protocol-object-types-supported"},
2907 {97,"protocol-services-supported"},
2908 {98,"protocol-version"},
2910 {100,"reason-for-halt"},
2912 {102,"recipient-list"},
2913 {103,"reliability"},
2914 {104,"relinquish-default"},
2917 {107,"segmentation-supported"},
2919 {109,"setpoint-reference"},
2921 {111,"status-flags"},
2922 {112,"system-status"},
2924 {114,"time-of-active-time-reset"},
2925 {115,"time-of-state-count-reset"},
2926 {116,"time-synchronization-recipients"},
2928 {118,"update-interval"},
2930 {120,"vendor-identifier"},
2931 {121,"vendor-name"},
2932 {122,"vt-class-supported"},
2933 {123,"weekly-schedule"},
2934 {124,"attempted-samples"},
2935 {125,"average-value"},
2936 {126,"buffer-size"},
2937 {127,"client-cov-increment"},
2938 {128,"cov-resubscription-interval"},
2939 {129,"current-notify-time"},
2940 {130,"event-time-stamp"},
2942 {132,"log-device-object-property"},
2943 {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
2944 {134,"log-interval"},
2945 {135,"maximum-value"},
2946 {136,"minimum-value"},
2947 {137,"notification-threshold"},
2948 {138,"previous-notify-time"},
2949 {139,"protocol-revision"},
2950 {140,"records-since-notification"},
2951 {141,"record-count"},
2954 {144,"stop-when-full"},
2955 {145,"total-record-count"},
2956 {146,"valid-samples"},
2957 {147,"window-interval"},
2958 {148,"window-samples"},
2959 {149,"maximum-value-time-stamp"},
2960 {150,"minimum-value-time-stamp"},
2961 {151,"variance-value"},
2962 {152,"active-cov-subscriptions"},
2963 {153,"backup-failure-timeout"},
2964 {154,"configuration-files"},
2965 {155,"database-revision"},
2966 {156,"direct-reading"},
2967 {157,"last-restore-time"},
2968 {158,"maintenance-required"},
2971 {161,"operation-expected"},
2974 {164,"tracking-value"},
2975 {165,"zone-members"},
2976 {166,"life-safety-alarm-values"},
2977 {167,"max-segments-accepted"},
2978 {168,"profile-name"},
2979 {169,"auto-slave-discovery"},
2980 {170,"manual-slave-address-binding"},
2981 {171,"slave-address-binding"},
2982 {172,"slave-proxy-enable"},
2983 {173,"last-notify-record"}, /* bug 4117 */
2984 {174,"schedule-default"},
2985 {175,"accepted-modes"},
2986 {176,"adjust-value"},
2988 {178,"count-before-change"},
2989 {179,"count-change-time"},
2991 {181,"input-reference"},
2992 {182,"limit-monitoring-interval"},
2993 {183,"logging-device"},
2994 {184,"logging-record"},
2998 {188,"scale-factor"},
2999 {189,"update-time"},
3000 {190,"value-before-change"},
3002 {192,"value-change-time"},
3003 {193,"align-intervals"},
3004 {194,"group-member-names"},
3005 {195,"interval-offset"},
3006 {196,"last-restart-reason"},
3007 {197,"logging-type"},
3008 {198,"member-status-flags"},
3009 {199,"notification-period"},
3010 {200,"previous-notify-record"},
3011 {201,"requested-update-interval"},
3012 {202,"restart-notification-recipients"},
3013 {203,"time-of-device-restart"},
3014 {204,"time-synchronization-recipients"},
3016 {206,"UTC-time-synchronization-recipients"},
3017 {207,"node-subtype"},
3019 {209,"structured-object-list"},
3020 {210,"subordinate-annotations"},
3021 {211,"subordinate-list"},
3022 {212,"actual-shed-level"},
3023 {213,"duty-window"},
3024 {214,"expected-shed-level"},
3025 {215,"full-duty-baseline"},
3026 {216,"node-subtype"},
3028 {218,"requested-shed-level"},
3029 {219,"shed-duration"},
3030 {220,"shed-level-descriptions"},
3031 {221,"shed-levels"},
3032 {222,"state-description"},
3033 {226,"door-alarm-state"},
3034 {227,"door-extended-pulse-time"},
3035 {228,"door-members"},
3036 {229,"door-open-too-long-time"},
3037 {230,"door-pulse-time"},
3038 {231,"door-status"},
3039 {232,"door-unlock-delay-time"},
3040 {233,"lock-status"},
3041 {234,"masked-alarm-values"},
3042 {235,"secured-status"},
3044 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3045 Enumerated values 512-4194303 may be used by others subject to
3046 the procedures and constraints described in Clause 23. */
3049 static const value_string
3050 BACnetBinaryPV [] = {
3058 #define IBM_MS_DBCS 1
3059 #define JIS_C_6226 2
3060 #define ISO_10646_UCS4 3
3061 #define ISO_10646_UCS2 4
3062 #define ISO_18859_1 5
3063 static const value_string
3064 BACnetCharacterSet [] = {
3065 {ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3066 {IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3067 {JIS_C_6226, "JIS C 6226"},
3068 {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3069 {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3070 {ISO_18859_1, "ISO 18859-1"},
3074 static const value_string
3075 BACnetStatusFlags [] = {
3079 {3,"out-of-service"},
3083 static const value_string
3084 BACnetMessagePriority [] = {
3090 static const value_string
3091 BACnetAcknowledgementFilter [] = {
3098 static const value_string
3099 BACnetResultFlags [] = {
3106 static const value_string
3107 BACnetRelationSpecifier [] = {
3112 {4,"less-than-or-equal"},
3113 {5,"greater-than-or-equal"},
3117 static const value_string
3118 BACnetSelectionLogic [] = {
3125 static const value_string
3126 BACnetEventStateFilter [] = {
3135 static const value_string
3136 BACnetEventTransitionBits [] = {
3143 static const value_string
3144 BACnetSegmentation [] = {
3145 {0,"segmented-both"},
3146 {1,"segmented-transmit"},
3147 {2,"segmented-receive"},
3148 {3,"no-segmentation"},
3152 static const value_string
3153 BACnetSilencedState [] = {
3155 {1,"audible-silenced"},
3156 {2,"visible-silenced"},
3161 static const value_string
3162 BACnetDeviceStatus [] = {
3164 {1,"operational-read-only"},
3165 {2,"download-required"},
3166 {3,"download-in-progress"},
3167 {4,"non-operational"},
3168 {5,"backup-in-progress"},
3172 static const value_string
3173 BACnetEnableDisable [] = {
3176 {2,"disable-initiation"},
3180 static const value_string
3198 static const value_string
3200 {1,"days numbered 1-7" },
3201 {2,"days numbered 8-14" },
3202 {3,"days numbered 15-21" },
3203 {4,"days numbered 22-28" },
3204 {5,"days numbered 29-31" },
3205 {6,"last 7 days of this month" },
3206 {255,"any week of this month" },
3210 /* note: notification class object recipient-list uses
3211 different day-of-week enum */
3212 static const value_string
3221 {255,"any day of week" },
3225 static const value_string
3226 BACnetErrorClass [] = {
3235 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3236 Enumerated values64-65535 may be used by others subject to
3237 the procedures and constraints described in Clause 23. */
3240 static const value_string
3241 BACnetVTClass [] = {
3242 {0,"default-terminal" },
3252 static const value_string
3253 BACnetEventType [] = {
3254 {0,"change-of-bitstring" },
3255 {1,"change-of-state" },
3256 {2,"change-of-value" },
3257 {3,"command-failure" },
3258 {4,"floating-limit" },
3259 {5,"out-of-range" },
3260 {6,"complex-event-type" },
3261 {7,"buffer-ready" },
3262 {8,"change-of-life-safety" },
3264 {10,"buffer-ready" },
3265 {11,"unsigned-range" },
3267 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3268 Enumerated values 64-65535 may be used by others subject to
3269 the procedures and constraints described in Clause 23.
3270 It is expected that these enumerated values will correspond
3271 to the use of the complex-event-type CHOICE [6] of the
3272 BACnetNotificationParameters production. */
3275 static const value_string
3276 BACnetEventState [] = {
3282 {5,"life-safety-alarm" },
3284 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3285 Enumerated values 64-65535 may be used by others subject to
3286 the procedures and constraints described in Clause 23. */
3289 static const value_string
3290 BACnetLogStatus [] = {
3291 {0,"log-disabled" },
3292 {1,"buffer-purged" },
3296 static const value_string
3297 BACnetMaintenance [] = {
3299 {1,"periodic-test" },
3300 {2,"need-service-operational" },
3301 {3,"need-service-inoperative" },
3305 static const value_string
3306 BACnetNotifyType [] = {
3309 {2,"ack-notification" },
3313 static const value_string
3314 BACnetServicesSupported [] = {
3315 {0,"acknowledgeAlarm"},
3316 {1,"confirmedCOVNotification"},
3317 {2,"confirmedEventNotification"},
3318 {3,"getAlarmSummary"},
3319 {4,"getEnrollmentSummary"},
3321 {6,"atomicReadFile"},
3322 {7,"atomicWriteFile"},
3323 {8,"addListElement"},
3324 {9,"removeListElement"},
3325 {10,"createObject"},
3326 {11,"deleteObject"},
3327 {12,"readProperty"},
3328 {13,"readPropertyConditional"},
3329 {14,"readPropertyMultiple"},
3330 {15,"writeProperty"},
3331 {16,"writePropertyMultiple"},
3332 {17,"deviceCommunicationControl"},
3333 {18,"confirmedPrivateTransfer"},
3334 {19,"confirmedTextMessage"},
3335 {20,"reinitializeDevice"},
3339 {24,"authenticate"},
3343 {28,"unconfirmedCOVNotification"},
3344 {29,"unconfirmedEventNotification"},
3345 {30,"unconfirmedPrivateTransfer"},
3346 {31,"unconfirmedTextMessage"},
3347 {32,"timeSynchronization"},
3351 {36,"utcTimeSynchronization"},
3352 {37,"lifeSafetyOperation"},
3353 {38,"subscribeCOVProperty"},
3354 {39,"getEventInformation"},
3358 static const value_string
3359 BACnetPropertyStates [] = {
3360 {0,"boolean-value"},
3364 {4,"program-change"},
3365 {5,"program-state"},
3366 {6,"reason-for-halt"},
3369 {9,"system-status"},
3371 {11,"unsigned-value"},
3372 {12,"life-safety-mode"},
3373 {13,"life-safety-state"},
3374 {14,"door-alarm-state"},
3376 /* Tag values 0-63 are reserved for definition by ASHRAE.
3377 Tag values of 64-254 may be used by others to accommodate
3378 vendor specific properties that have discrete or enumerated values,
3379 subject to the constraints described in Clause 23. */
3382 static const value_string
3383 BACnetProgramError [] = {
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 BACnetProgramRequest [] = {
3406 static const value_string
3407 BACnetProgramState [] = {
3417 static const value_string
3418 BACnetReinitializedStateOfDevice [] = {
3429 static const value_string
3430 BACnetPolarity [] = {
3436 static const value_string
3437 BACnetTagNames[] = {
3438 { 5, "Extended Value" },
3439 { 6, "Opening Tag" },
3440 { 7, "Closing Tag" },
3444 static const value_string
3445 BACnetReadRangeOptions[] = {
3446 { 3, "range byPosition" },
3447 { 4, "range byTime" },
3448 { 5, "range timeRange" },
3449 { 6, "range bySequenceNumber" },
3450 { 7, "range byTime" },
3454 /* Present_Value for Load Control Object */
3455 static const value_string
3456 BACnetShedState[] = {
3457 { 0, "shed-inactive" },
3458 { 1, "shed-request-pending" },
3459 { 2, "shed-compliant" },
3460 { 3, "shed-non-compliant" },
3464 static const value_string
3465 BACnetVendorIdentifiers [] = {
3468 { 2, "The Trane Company" },
3469 { 3, "McQuay International" },
3471 { 5, "Johnson Controls, Inc." },
3472 { 6, "American Auto-Matrix" },
3473 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3474 { 8, "Delta Controls" },
3475 { 9, "Siemens Building Technologies, Inc." },
3476 { 10, "Tour Andover Controls Corporation" },
3478 { 12, "Orion Analysis Corporation" },
3479 { 13, "Teletrol Systems Inc." },
3480 { 14, "Cimetrics Technology" },
3481 { 15, "Cornell University" },
3482 { 16, "United Technologies Carrier" },
3483 { 17, "Honeywell Inc." },
3484 { 18, "Alerton / Honeywell" },
3486 { 20, "Hewlett-Packard Company" },
3487 { 21, "Dorsette's Inc." },
3488 { 22, "Cerberus AG" },
3489 { 23, "York Controls Group" },
3490 { 24, "Automated Logic Corporation" },
3491 { 25, "CSI Control Systems International" },
3492 { 26, "Phoenix Controls Corporation" },
3493 { 27, "Innovex Technologies, Inc." },
3494 { 28, "KMC Controls, Inc." },
3495 { 29, "Xn Technologies, Inc." },
3496 { 30, "Hyundai Information Technology Co., Ltd." },
3497 { 31, "Tokimec Inc." },
3499 { 33, "North Communications Limited" },
3501 { 35, "Reliable Controls Corporation" },
3502 { 36, "Tridium Inc." },
3503 { 37, "Sierra Monitor Corp." },
3504 { 38, "Silicon Energy" },
3505 { 39, "Kieback & Peter GmbH & Co KG" },
3506 { 40, "Anacon Systems, Inc." },
3507 { 41, "Systems Controls & Instruments, LLC" },
3508 { 42, "Lithonia Lighting" },
3509 { 43, "Micropower Manufacturing" },
3510 { 44, "Matrix Controls" },
3511 { 45, "METALAIRE" },
3512 { 46, "ESS Engineering" },
3513 { 47, "Sphere Systems Pty Ltd." },
3514 { 48, "Walker Technologies Corporation" },
3515 { 49, "H I Solutions, Inc." },
3517 { 51, "SAMSON AG" },
3518 { 52, "Badger Meter Inc." },
3519 { 53, "DAIKIN Industries Ltd." },
3520 { 54, "NARA Controls Inc." },
3521 { 55, "Mammoth Inc." },
3522 { 56, "Liebert Corporation" },
3523 { 57, "SEMCO Incorporated" },
3524 { 58, "Air Monitor Corporation" },
3525 { 59, "TRIATEK, Inc." },
3527 { 61, "Multistack" },
3528 { 62, "TSI Incorporated" },
3529 { 63, "Weather-Rite, Inc." },
3530 { 64, "Dunham-Bush" },
3531 { 65, "Reliance Electric" },
3533 { 67, "Regulator Australia PTY Ltd." },
3534 { 68, "Touch-Plate Lighting Controls" },
3535 { 69, "Amann GmbH" },
3536 { 70, "RLE Technologies" },
3537 { 71, "Cardkey Systems" },
3538 { 72, "SECOM Co., Ltd." },
3539 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3540 { 74, "KNX Association cvba" },
3541 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3542 { 76, "Nohmi Bosai, Ltd." },
3543 { 77, "Carel S.p.A." },
3544 { 78, "AirSense Technology, Inc." },
3545 { 79, "Hochiki Corporation" },
3546 { 80, "Fr. Sauter AG" },
3547 { 81, "Matsushita Electric Works, Ltd." },
3548 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3549 { 83, "Mitsubishi Heavy Industries, Ltd." },
3550 { 84, "ITT Bell & Gossett" },
3551 { 85, "Yamatake Building Systems Co., Ltd." },
3552 { 86, "The Watt Stopper, Inc." },
3553 { 87, "Aichi Tokei Denki Co., Ltd." },
3554 { 88, "Activation Technologies, LLC" },
3555 { 89, "Saia-Burgess Controls, Ltd." },
3556 { 90, "Hitachi, Ltd." },
3557 { 91, "Novar Corp./Trend Control Systems Ltd." },
3558 { 92, "Mitsubishi Electric Lighting Corporation" },
3559 { 93, "Argus Control Systems, Ltd." },
3560 { 94, "Kyuki Corporation" },
3561 { 95, "Richards-Zeta Building Intelligence, Inc." },
3562 { 96, "Scientech R&D, Inc." },
3563 { 97, "VCI Controls, Inc." },
3564 { 98, "Toshiba Corporation" },
3565 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3566 { 100, "Custom Mechanical Equipment, LLC" },
3567 { 101, "ClimateMaster" },
3568 { 102, "ICP Panel-Tec, Inc." },
3569 { 103, "D-Tek Controls" },
3570 { 104, "NEC Engineering, Ltd." },
3571 { 105, "PRIVA BV" },
3572 { 106, "Meidensha Corporation" },
3573 { 107, "JCI Systems Integration Services" },
3574 { 108, "Freedom Corporation" },
3575 { 109, "Neuberger Gebaudeautomation GmbH" },
3576 { 110, "Sitronix" },
3577 { 111, "Leviton Manufacturing" },
3578 { 112, "Fujitsu Limited" },
3579 { 113, "Emerson Network Power" },
3580 { 114, "S. A. Armstrong, Ltd." },
3581 { 115, "Visonet AG" },
3582 { 116, "M&M Systems, Inc." },
3583 { 117, "Custom Software Engineering" },
3584 { 118, "Nittan Company, Limited" },
3585 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3586 { 120, "Pacom Systems Pty., Ltd." },
3587 { 121, "Unico, Inc." },
3588 { 122, "Ebtron, Inc." },
3589 { 123, "Scada Engine" },
3590 { 124, "AC Technology Corporation" },
3591 { 125, "Eagle Technology" },
3592 { 126, "Data Aire, Inc." },
3593 { 127, "ABB, Inc." },
3594 { 128, "Transbit Sp. z o. o." },
3595 { 129, "Toshiba Carrier Corporation" },
3596 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
3597 { 131, "Tokai Soft" },
3599 { 133, "Veris Industries" },
3600 { 134, "Centaurus Prime" },
3601 { 135, "Sand Network Systems" },
3602 { 136, "Regulvar, Inc." },
3603 { 137, "Fastek International, Ltd." },
3604 { 138, "PowerCold Comfort Air Solutions, Inc." },
3605 { 139, "I Controls" },
3606 { 140, "Viconics Electronics, Inc." },
3607 { 141, "Yaskawa Electric America, Inc." },
3608 { 142, "Plueth Regelsysteme" },
3609 { 143, "Digitale Mess- und Steuersysteme AG" },
3610 { 144, "Fujitsu General Limited" },
3611 { 145, "Project Engineering S.r.l." },
3612 { 146, "Sanyo Electric Co., Ltd." },
3613 { 147, "Integrated Information Systems, Inc." },
3614 { 148, "Temco Controls, Ltd." },
3615 { 149, "Airtek Technologies, Inc." },
3616 { 150, "Advantech Corporation" },
3617 { 151, "Titan Products, Ltd." },
3618 { 152, "Regel Partners" },
3619 { 153, "National Environmental Product" },
3620 { 154, "Unitec Corporation" },
3621 { 155, "Kanden Engineering Company" },
3622 { 156, "Messner Gebaudetechnik GmbH" },
3623 { 157, "Integrated.CH" },
3624 { 158, "EH Price Limited" },
3625 { 159, "SE-Elektronic GmbH" },
3626 { 160, "Rockwell Automation" },
3627 { 161, "Enflex Corp." },
3628 { 162, "ASI Controls" },
3629 { 163, "SysMik GmbH Dresden" },
3630 { 164, "HSC Regelungstechnik GmbH" },
3631 { 165, "Smart Temp Australia Pty. Ltd." },
3632 { 166, "PCI Lighting Control Systems" },
3633 { 167, "Duksan Mecasys Co., Ltd." },
3634 { 168, "Fuji IT Co., Ltd." },
3635 { 169, "Vacon Plc" },
3636 { 170, "Leader Controls" },
3637 { 171, "Cylon Controls, Ltd." },
3639 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
3640 { 174, "Building Control Integrators" },
3641 { 175, "ITG Worldwide (M) Sdn Bhd" },
3642 { 176, "Lutron Electronics Co., Inc." },
3643 { 177, "Cooper-Atkins Corporation" },
3644 { 178, "LOYTEC Electronics GmbH" },
3646 { 180, "Mega Controls Limited" },
3647 { 181, "Micro Control Systems, Inc." },
3648 { 182, "Kiyon, Inc." },
3649 { 183, "Dust Networks" },
3650 { 184, "Advanced Building Automation Systems" },
3651 { 185, "Hermos AG" },
3654 { 188, "Lynxspring" },
3655 { 189, "Schneider Toshiba Inverter Europe" },
3656 { 190, "Danfoss Drives A/S" },
3657 { 191, "Eaton Corporation" },
3658 { 192, "Matyca S.A." },
3659 { 193, "Botech AB" },
3660 { 194, "Noveo, Inc." },
3662 { 196, "Yokogawa Electric Corporation" },
3663 { 197, "GFR Gesellschaft fur Regelungstechnik" },
3664 { 198, "Exact Logic" },
3665 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
3666 { 200, "Kandenko Co., Ltd." },
3667 { 201, "DTF, Daten-Technik Fries" },
3668 { 202, "Klimasoft, Ltd." },
3669 { 203, "Toshiba Schneider Inverter Corporation" },
3670 { 204, "Control Applications, Ltd." },
3671 { 205, "KDT Systems Co., Ltd." },
3672 { 206, "Onicon Incorporated" },
3673 { 207, "Automation Displays, Inc." },
3674 { 208, "Control Solutions, Inc." },
3675 { 209, "Remsdaq Limited" },
3676 { 210, "NTT Facilities, Inc." },
3677 { 211, "VIPA GmbH" },
3678 { 212, "TSC21 Association of Japan" },
3679 { 213, "BBP Energie Ltee" },
3680 { 214, "HRW Limited" },
3681 { 215, "Lighting Control & Design, Inc." },
3682 { 216, "Mercy Electronic and Electrical Industries" },
3683 { 217, "Samsung SDS Co., Ltd" },
3684 { 218, "Impact Facility Solutions, Inc." },
3685 { 219, "Aircuity" },
3686 { 220, "Control Techniques, Ltd." },
3687 { 221, "Evolve Control Systems, LLC" },
3688 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
3689 { 223, "Cerus Industrial" },
3690 { 224, "Chloride Power Protection Company" },
3691 { 225, "Computrols, Inc." },
3692 { 226, "Phoenix Contact GmbH & Co. KG" },
3693 { 227, "Grundfos Management A/S" },
3694 { 228, "Ridder Drive Systems" },
3695 { 229, "Soft Device SDN BHD" },
3696 { 230, "Integrated Control Technology Limited" },
3697 { 231, "AIRxpert Systems, Inc." },
3698 { 232, "Microtrol Limited" },
3699 { 233, "Red Lion Controls" },
3700 { 234, "Digital Electronics Corporation" },
3701 { 235, "Ennovatis GmbH" },
3702 { 236, "Serotonin Software Technologies, Inc." },
3703 { 237, "LS Industrial Systems Co., Ltd." },
3704 { 238, "Square D Company" },
3705 { 239, "S Squared Innovations, Inc." },
3706 { 240, "Aricent Ltd." },
3707 { 241, "EtherMetrics, LLC" },
3708 { 242, "Industrial Control Communications, Inc." },
3709 { 243, "Paragon Controls, Inc." },
3710 { 244, "A. O. Smith Corporation" },
3711 { 245, "Contemporary Control Systems, Inc." },
3712 { 246, "Intesis Software SL" },
3713 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
3714 { 248, "Heat-Timer Corporation" },
3715 { 249, "Ingrasys Technology, Inc." },
3716 { 250, "Costerm Building Automation" },
3718 { 252, "Embedia Technologies Corp." },
3719 { 253, "Technilog" },
3720 { 254, "HR Controls Ltd. & Co. KG" },
3721 { 255, "Lennox International, Inc." },
3722 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
3723 { 257, "Thermomax, Ltd." },
3724 { 258, "ELCON Electronic Control, Ltd." },
3725 { 259, "Larmia Control AB" },
3726 { 260, "BACnet Stack at SourceForge" },
3727 { 261, "G4S Security Services A/S" },
3728 { 262, "Sitek S.p.A." },
3729 { 263, "Cristal Controles" },
3730 { 264, "Regin AB" },
3731 { 265, "Dimension Software, Inc. " },
3732 { 266, "SynapSense Corporation" },
3733 { 267, "Beijing Nantree Electronic Co., Ltd." },
3734 { 268, "Camus Hydronics Ltd." },
3735 { 269, "Kawasaki Heavy Industries, Ltd. " },
3736 { 270, "Critical Environment Technologies" },
3737 { 271, "ILSHIN IBS Co., Ltd." },
3738 { 272, "ELESTA Energy Control AG" },
3739 { 273, "KROPMAN Installatietechniek" },
3740 { 274, "Baldor Electric Company" },
3741 { 275, "INGA mbH" },
3742 { 276, "GE Consumer & Industrial" },
3743 { 277, "Functional Devices, Inc." },
3745 { 279, "M-System Co., Ltd." },
3746 { 280, "Yokota Co., Ltd." },
3747 { 281, "Hitranse Technology Co., LTD" },
3748 { 282, "Federspiel Controls" },
3749 { 283, "Kele, Inc." },
3750 { 284, "Opera Electronics, Inc." },
3752 { 286, "Embedded Science Labs, LLC" },
3753 { 287, "Parker Hannifin Corporation" },
3754 { 288, "MaCaPS International Limited" },
3755 { 289, "Link4 Corporation" },
3756 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
3757 { 291, "Pribusin, Inc." },
3758 { 292, "Advantage Controls" },
3759 { 293, "Critical Room Control" },
3761 { 295, "Tongdy Control Technology Co., Ltd." },
3762 { 296, "ISSARO Integrierte Systemtechnik" },
3763 { 297, "Pro-Dev Industries" },
3764 { 298, "DRI-STEEM" },
3765 { 299, "Creative Electronic GmbH" },
3766 { 300, "Swegon AB" },
3767 { 301, "Jan Brachacek" },
3768 { 302, "Hitachi Appliances, Inc." },
3769 { 303, "Real Time Automation, Inc." },
3770 { 304, "ITEC Hankyu-Hanshin Co." },
3771 { 305, "Cyrus E&M Engineering Co., Ltd." },
3772 { 306, "Racine Federated, Inc." },
3773 { 307, "Verari Systems, Inc." },
3774 { 308, "Elesta GmbH Building Automation" },
3775 { 309, "Securiton" },
3776 { 310, "OSlsoft, Inc." },
3777 { 311, "Hanazeder Electronic GmbH" },
3778 { 312, "Honeywell Security Deutschland, Novar GmbH" },
3779 { 313, "Siemens Energy & Automation, Inc." },
3780 { 314, "ETM Professional Control GmbH" },
3781 { 315, "Meitav-tec, Ltd." },
3782 { 316, "Janitza Electronics GmbH" },
3783 { 317, "MKS Nordhausen" },
3784 { 318, "De Gier Drive Systems B.V." },
3785 { 319, "Cypress Envirosystems" },
3786 { 320, "SMARTron s.r.o." },
3787 { 321, "Verari Systems, Inc." },
3788 { 322, "K-W Electronic Service, Inc." },
3789 { 323, "ALFA-SMART Energy Management" },
3790 { 324, "Telkonet, Inc." },
3791 { 325, "Securiton GmbH" },
3792 { 326, "Cemtrex, Inc." },
3793 { 327, "Performance Technologies, Inc." },
3794 { 328, "Xtralis (Aust) Pty Ltd" },
3795 { 329, "TROX GmbH" },
3796 { 330, "Beijing Hysine Technology Co., Ltd" },
3797 { 331, "RCK Controls, Inc." },
3799 { 333, "Novar/Honeywell" },
3800 { 334, "The S4 Group, Inc." },
3801 { 335, "Schneider Electric" },
3802 { 336, "LHA Systems" },
3803 { 337, "GHM engineering Group, Inc." },
3804 { 338, "Cllimalux S.A." },
3805 { 339, "VAISALA Oyj" },
3806 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
3807 { 342, "POWERPEG NSI Limited" },
3808 { 343, "BACnet Interoperability Testing Services, Inc." },
3809 { 344, "Teco a.s." },
3813 static int proto_bacapp = -1;
3814 static int hf_bacapp_type = -1;
3815 static int hf_bacapp_pduflags = -1;
3816 static int hf_bacapp_SEG = -1;
3817 static int hf_bacapp_MOR = -1;
3818 static int hf_bacapp_SA = -1;
3819 static int hf_bacapp_response_segments = -1;
3820 static int hf_bacapp_max_adpu_size = -1;
3821 static int hf_bacapp_invoke_id = -1;
3822 static int hf_bacapp_objectType = -1;
3823 static int hf_bacapp_instanceNumber = -1;
3824 static int hf_bacapp_sequence_number = -1;
3825 static int hf_bacapp_window_size = -1;
3826 static int hf_bacapp_service = -1;
3827 static int hf_bacapp_NAK = -1;
3828 static int hf_bacapp_SRV = -1;
3829 static int hf_BACnetRejectReason = -1;
3830 static int hf_BACnetAbortReason = -1;
3831 static int hf_BACnetApplicationTagNumber = -1;
3832 static int hf_BACnetContextTagNumber = -1;
3833 static int hf_BACnetExtendedTagNumber = -1;
3834 static int hf_BACnetNamedTag = -1;
3835 static int hf_BACnetTagClass = -1;
3836 static int hf_BACnetCharacterSet = -1;
3837 static int hf_bacapp_tag = -1;
3838 static int hf_bacapp_tag_lvt = -1;
3839 static int hf_bacapp_tag_value8 = -1;
3840 static int hf_bacapp_tag_value16 = -1;
3841 static int hf_bacapp_tag_value32 = -1;
3842 static int hf_bacapp_tag_ProcessId = -1;
3843 static int hf_bacapp_tag_initiatingObjectType = -1;
3844 static int hf_bacapp_vpart = -1;
3845 static int hf_bacapp_uservice = -1;
3846 static int hf_BACnetPropertyIdentifier = -1;
3847 static int hf_BACnetVendorIdentifier = -1;
3848 static int hf_BACnetRestartReason = -1;
3849 static int hf_bacapp_tag_IPV4 = -1;
3850 static int hf_bacapp_tag_IPV6 = -1;
3851 static int hf_bacapp_tag_PORT = -1;
3852 /* some more variables for segmented messages */
3853 static int hf_msg_fragments = -1;
3854 static int hf_msg_fragment = -1;
3855 static int hf_msg_fragment_overlap = -1;
3856 static int hf_msg_fragment_overlap_conflicts = -1;
3857 static int hf_msg_fragment_multiple_tails = -1;
3858 static int hf_msg_fragment_too_long_fragment = -1;
3859 static int hf_msg_fragment_error = -1;
3860 static int hf_msg_reassembled_in = -1;
3861 static int hf_msg_reassembled_length = -1;
3863 static gint ett_msg_fragment = -1;
3864 static gint ett_msg_fragments = -1;
3866 static gint ett_bacapp = -1;
3867 static gint ett_bacapp_control = -1;
3868 static gint ett_bacapp_tag = -1;
3869 static gint ett_bacapp_list = -1;
3870 static gint ett_bacapp_value = -1;
3872 static dissector_handle_t data_handle;
3873 static gint32 propertyIdentifier = -1;
3874 static gint32 propertyArrayIndex = -1;
3875 static guint32 object_type = 4096;
3877 static guint8 bacapp_flags = 0;
3878 static guint8 bacapp_seq = 0;
3880 static const fragment_items msg_frag_items = {
3881 /* Fragment subtrees */
3884 /* Fragment fields */
3887 &hf_msg_fragment_overlap,
3888 &hf_msg_fragment_overlap_conflicts,
3889 &hf_msg_fragment_multiple_tails,
3890 &hf_msg_fragment_too_long_fragment,
3891 &hf_msg_fragment_error,
3892 /* Reassembled in field */
3893 &hf_msg_reassembled_in,
3894 /* Reassembled length field */
3895 &hf_msg_reassembled_length,
3900 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
3901 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
3904 fGetMaxAPDUSize(guint8 idx)
3906 /* only 16 values are defined, so use & 0x0f */
3907 /* check the size of the Array, deliver either the entry
3908 or the first entry if idx is outside of the array (bug 3736 comment#7) */
3909 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
3910 return MaxAPDUSize[0];
3912 return MaxAPDUSize[idx & 0x0f];
3915 /* Used when there are ranges of reserved and proprietary enumerations */
3917 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
3918 const char *fmt, const char *split_fmt)
3920 if (val < split_val)
3921 return val_to_str(val, vs, fmt);
3923 return val_to_str(val, vs, split_fmt);
3926 /* from clause 20.2.1.3.2 Constructed Data */
3927 /* returns true if the extended value is used */
3929 tag_is_extended_value(guint8 tag)
3931 return (tag & 0x07) == 5;
3935 tag_is_opening(guint8 tag)
3937 return (tag & 0x07) == 6;
3941 tag_is_closing(guint8 tag)
3943 return (tag & 0x07) == 7;
3946 /* from clause 20.2.1.1 Class
3947 class bit shall be one for context specific tags */
3948 /* returns true if the tag is context specific */
3950 tag_is_context_specific(guint8 tag)
3952 return (tag & 0x08) != 0;
3956 tag_is_extended_tag_number(guint8 tag)
3958 return ((tag & 0xF0) == 0xF0);
3962 object_id_type(guint32 object_identifier)
3964 return ((object_identifier >> 22) & 0x3FF);
3968 object_id_instance(guint32 object_identifier)
3970 return (object_identifier & 0x3FFFFF);
3974 fTagNo (tvbuff_t *tvb, guint offset)
3976 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
3980 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
3982 gboolean valid = TRUE;
3986 *val = tvb_get_guint8(tvb, offset);
3989 *val = tvb_get_ntohs(tvb, offset);
3992 *val = tvb_get_ntoh24(tvb, offset);
3995 *val = tvb_get_ntohl(tvb, offset);
4006 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4008 gboolean valid = FALSE;
4012 if (lvt && (lvt <= 8)) {
4014 data = tvb_get_guint8(tvb, offset);
4015 for (i = 0; i < lvt; i++) {
4016 data = tvb_get_guint8(tvb, offset+i);
4017 value = (value << 8) + data;
4025 /* BACnet Signed Value uses 2's compliment notation, but with a twist:
4026 All signed integers shall be encoded in the smallest number of octets
4027 possible. That is, the first octet of any multi-octet encoded value
4028 shall not be X'00' if the most significant bit (bit 7) of the second
4029 octet is 0, and the first octet shall not be X'FF' if the most
4030 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4032 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4034 gboolean valid = FALSE;
4038 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4039 if (lvt && (lvt <= 7)) {
4041 data = tvb_get_guint8(tvb, offset);
4042 if ((data & 0x80) != 0)
4043 value = (-1 << 8) | data;
4046 for (i = 1; i < lvt; i++) {
4047 data = tvb_get_guint8(tvb, offset+i);
4048 value = (value << 8) + data;
4057 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
4058 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4063 guint lvt_len = 1; /* used for tree display of lvt */
4064 guint lvt_offset; /* used for tree display of lvt */
4066 proto_tree *subtree;
4068 lvt_offset = offset;
4069 tag = tvb_get_guint8(tvb, offset);
4072 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4073 /* can mean open/close tag or length of 6/7 after the length is */
4074 /* computed below - store whole tag info, not just context bit. */
4075 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4077 if (tag_is_extended_tag_number(tag)) {
4078 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4080 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4081 lvt_offset += tag_len;
4082 value = tvb_get_guint8(tvb, lvt_offset);
4084 if (value == 254) { /* length is encoded with 16 Bits */
4085 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4088 } else if (value == 255) { /* length is encoded with 32 Bits */
4089 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4097 if (tag_is_opening(tag))
4098 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4099 else if (tag_is_closing(tag))
4100 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4101 else if (tag_is_context_specific(tag)) {
4102 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4103 "Context Tag: %u, Length/Value/Type: %u",
4106 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4107 "Application Tag: %s, Length/Value/Type: %u",
4109 BACnetApplicationTagNumber,
4110 ASHRAE_Reserved_Fmt),
4113 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4114 /* details if needed */
4115 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, FALSE);
4116 if (tag_is_extended_tag_number(tag)) {
4117 proto_tree_add_uint_format(subtree,
4118 hf_BACnetContextTagNumber,
4119 tvb, offset, 1, tag,
4120 "Extended Tag Number");
4121 proto_tree_add_item(subtree,
4122 hf_BACnetExtendedTagNumber,
4123 tvb, offset + 1, 1, FALSE);
4125 if (tag_is_context_specific(tag))
4126 proto_tree_add_item(subtree,
4127 hf_BACnetContextTagNumber,
4128 tvb, offset, 1, FALSE);
4130 proto_tree_add_item(subtree,
4131 hf_BACnetApplicationTagNumber,
4132 tvb, offset, 1, FALSE);
4134 if (tag_is_closing(tag) || tag_is_opening(tag))
4135 proto_tree_add_item(subtree,
4137 tvb, offset, 1, FALSE);
4138 else if (tag_is_extended_value(tag)) {
4139 proto_tree_add_item(subtree,
4141 tvb, offset, 1, FALSE);
4142 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4143 tvb, lvt_offset, lvt_len, *lvt);
4145 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4146 tvb, lvt_offset, lvt_len, *lvt);
4153 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
4156 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
4160 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4162 guint8 tag_no, tag_info;
4165 proto_tree *subtree;
4167 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4168 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4169 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4175 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4177 guint8 tag_no, tag_info;
4181 proto_tree *subtree;
4184 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4185 if (tag_info && lvt == 1)
4187 lvt = tvb_get_guint8(tvb, offset+1);
4191 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
4192 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
4193 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4194 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4196 return offset + bool_len;
4200 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4203 guint8 tag_no, tag_info;
4207 proto_tree *subtree;
4209 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4210 /* only support up to an 8 byte (64-bit) integer */
4211 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
4212 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4213 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
4215 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4216 "%s - %u octets (Unsigned)", label, lvt);
4217 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4218 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4220 return offset+tag_len+lvt;
4223 /* set split_val to zero when not needed */
4225 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4226 const value_string *vs, guint32 split_val)
4229 guint8 tag_no, tag_info;
4233 proto_tree *subtree;
4235 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4236 /* only support up to a 4 byte (32-bit) enumeration */
4237 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
4239 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4240 "%s %s", label, val_to_split_str(val, split_val, vs,
4241 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
4243 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4244 "%s %u", label, val);
4246 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4247 "%s - %u octets (enumeration)", label, lvt);
4249 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4250 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4252 return offset+tag_len+lvt;
4256 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4257 const value_string *vs)
4259 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
4263 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4266 guint8 tag_no, tag_info;
4270 proto_tree *subtree;
4272 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4273 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
4274 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4275 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
4277 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4278 "%s - %u octets (Signed)", label, lvt);
4279 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4280 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4282 return offset+tag_len+lvt;
4286 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4288 guint8 tag_no, tag_info;
4293 proto_tree *subtree;
4295 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4296 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
4297 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
4298 "%s%f (Real)", label, f_val);
4299 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4300 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4302 return offset+tag_len+4;
4306 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4308 guint8 tag_no, tag_info;
4313 proto_tree *subtree;
4315 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4316 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
4317 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
4318 "%s%f (Double)", label, d_val);
4319 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4320 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4322 return offset+tag_len+8;
4326 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
4328 guint32 val = 0, lvt;
4329 guint8 tag_no, tag_info;
4331 proto_tree *subtree;
4334 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4335 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4336 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
4337 tvb, offset, lvt+tag_len, val);
4339 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4340 "Process Identifier - %u octets (Signed)", lvt);
4341 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4342 offset += tag_len + lvt;
4348 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4350 guint32 val = 0, lvt;
4351 guint8 tag_no, tag_info;
4353 proto_tree *subtree;
4356 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4357 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4358 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4359 "%s (hh.mm.ss): %d.%02d.%02d%s",
4361 (val / 3600), ((val % 3600) / 60), (val % 60),
4362 val == 0 ? " (indefinite)" : "");
4364 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4365 "%s - %u octets (Signed)", label, lvt);
4366 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4367 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4369 return offset+tag_len+lvt;
4373 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
4375 guint32 month, weekOfMonth, dayOfWeek;
4376 guint8 tag_no, tag_info;
4380 proto_tree *subtree;
4382 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4383 month = tvb_get_guint8(tvb, offset+tag_len);
4384 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
4385 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
4386 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
4387 val_to_str(month, months, "month (%d) not found"),
4388 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
4389 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
4390 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4391 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4393 return offset+tag_len+lvt;
4397 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4399 guint32 year, month, day, weekday;
4400 guint8 tag_no, tag_info;
4404 proto_tree *subtree;
4406 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4407 year = tvb_get_guint8(tvb, offset+tag_len);
4408 month = tvb_get_guint8(tvb, offset+tag_len+1);
4409 day = tvb_get_guint8(tvb, offset+tag_len+2);
4410 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
4411 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255))
4413 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4416 else if (year != 255)
4419 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4420 "%s%s %d, %d, (Day of Week = %s)",
4421 label, val_to_str(month,
4423 "month (%d) not found"),
4424 day, year, val_to_str(weekday,
4430 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4431 "%s%s %d, any year, (Day of Week = %s)",
4432 label, val_to_str(month, months, "month (%d) not found"),
4433 day, val_to_str(weekday, day_of_week, "(%d) not found"));
4435 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4436 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4438 return offset+tag_len+lvt;
4442 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4444 guint32 hour, minute, second, msec, lvt;
4445 guint8 tag_no, tag_info;
4448 proto_tree *subtree;
4450 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4451 hour = tvb_get_guint8(tvb, offset+tag_len);
4452 minute = tvb_get_guint8(tvb, offset+tag_len+1);
4453 second = tvb_get_guint8(tvb, offset+tag_len+2);
4454 msec = tvb_get_guint8(tvb, offset+tag_len+3);
4455 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
4456 ti = proto_tree_add_text(tree, tvb, offset,
4457 lvt+tag_len, "%sany", label);
4459 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4460 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
4462 hour > 12 ? hour - 12 : hour,
4463 minute, second, msec,
4464 hour >= 12 ? "P.M." : "A.M.",
4465 hour, minute, second, msec);
4466 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4467 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4469 return offset+tag_len+lvt;
4473 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4475 proto_tree *subtree = tree;
4478 if (label != NULL) {
4479 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
4480 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4482 offset = fDate (tvb,subtree,offset,"Date: ");
4483 return fTime (tvb,subtree,offset,"Time: ");
4487 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4489 guint lastoffset = 0;
4490 guint8 tag_no, tag_info;
4493 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4494 lastoffset = offset;
4495 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4496 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
4499 offset = fTime (tvb,tree,offset,"Time: ");
4500 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
4502 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
4508 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
4510 guint8 tag_no, tag_info;
4513 switch (fTagNo(tvb, offset)) {
4515 offset = fDate (tvb, tree, offset, "Date: ");
4517 case 1: /* dateRange */
4518 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4519 offset = fDateRange (tvb, tree, offset);
4520 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4522 case 2: /* BACnetWeekNDay */
4523 offset = fWeekNDay (tvb, tree, offset);
4532 static guint fTimeStamp (tvbuff_t *tvb, proto_tree *tree,
4533 guint offset, const gchar *label)
4535 guint8 tag_no = 0, tag_info = 0;
4538 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
4539 switch (fTagNo(tvb, offset)) {
4541 offset = fTime (tvb, tree, offset, label?label:"timestamp: ");
4543 case 1: /* sequenceNumber */
4544 offset = fUnsignedTag (tvb, tree, offset,
4545 label?label:"sequence Number: ");
4547 case 2: /* dateTime */
4548 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4549 offset = fDateTime (tvb, tree, offset, label?label:"timestamp: ");
4550 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4562 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4564 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4565 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
4570 static const value_string
4571 BACnetDaysOfWeek [] = {
4583 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4585 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4586 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
4587 "valid Days: ", BACnetDaysOfWeek);
4588 offset = fTime (tvb,tree,offset,"from time: ");
4589 offset = fTime (tvb,tree,offset,"to time: ");
4590 offset = fRecipient (tvb,pinfo,tree,offset);
4591 offset = fProcessId (tvb,tree,offset);
4592 offset = fApplicationTypes (tvb,pinfo,tree,offset,
4593 "issue confirmed notifications: ");
4594 offset = fBitStringTagVS (tvb,tree,offset,
4595 "transitions: ", BACnetEventTransitionBits);
4602 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4605 guint start = offset;
4606 guint8 tag_no, tag_info;
4607 proto_tree* subtree = tree;
4610 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4614 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4615 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
4620 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4622 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4628 fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4631 guint start = offset;
4632 guint8 tag_no, tag_info;
4633 proto_tree* subtree = tree;
4636 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4638 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
4642 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
4644 guint32 ip = tvb_get_ipv4(tvb, offset);
4645 guint16 port = tvb_get_ntohs(tvb, offset+4);
4647 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
4648 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
4651 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
4652 struct e_in6_addr addr;
4653 guint16 port = tvb_get_ntohs(tvb, offset+16);
4654 tvb_get_ipv6(tvb, offset, &addr);
4656 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
4657 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
4659 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
4660 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4661 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
4668 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4670 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4676 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
4678 guint8 tag_no, tag_info;
4682 offset = fUnsignedTag (tvb, tree, offset, "network-number");
4683 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4685 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
4688 offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
4694 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
4696 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
4697 return fAddress (tvb,tree,offset);
4701 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4703 guint8 tag_no, tag_info;
4707 proto_tree *subtree;
4710 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4711 object_id = tvb_get_ntohl(tvb,offset+tag_length);
4712 object_type = object_id_type(object_id);
4713 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
4714 "ObjectIdentifier: %s, %u",
4715 val_to_split_str(object_type,
4718 ASHRAE_Reserved_Fmt,
4719 Vendor_Proprietary_Fmt),
4720 object_id_instance(object_id));
4721 if (col_get_writable(pinfo->cinfo))
4722 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
4723 val_to_split_str(object_type,
4726 ASHRAE_Reserved_Fmt,
4727 Vendor_Proprietary_Fmt),
4728 object_id_instance(object_id));
4730 /* here are the details of how we arrived at the above text */
4731 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4732 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4733 offset += tag_length;
4734 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, FALSE);
4735 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, FALSE);
4742 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4744 guint8 tag_no, tag_info;
4747 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4749 if (tag_no == 0) { /* device */
4750 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
4752 else { /* address */
4753 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4754 offset = fAddress (tvb, tree, offset);
4755 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4762 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4764 guint lastoffset = 0;
4765 guint8 tag_no, tag_info;
4768 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4769 lastoffset = offset;
4771 switch (fTagNo(tvb, offset)) {
4772 case 0: /* recipient */
4773 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4774 offset = fRecipient (tvb, pinfo, tree, offset);
4775 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4777 case 1: /* processId */
4778 offset = fProcessId (tvb, tree, offset);
4779 lastoffset = offset;
4784 if (offset == lastoffset) break; /* nothing happened, exit loop */
4790 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4792 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
4793 return fAddress (tvb, tree, offset);
4797 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
4799 guint lastoffset = 0;
4800 guint8 tag_no, tag_info;
4802 proto_tree *subtree = tree;
4804 /* set the optional global properties to indicate not-used */
4805 propertyArrayIndex = -1;
4806 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4807 lastoffset = offset;
4808 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4809 if (tag_is_closing(tag_info) ) {
4810 if (tag_no == tag_match) {
4813 offset += fTagHeaderTree (tvb, subtree, offset,
4814 &tag_no, &tag_info, &lvt);
4820 case 0: /* deviceIdentifier */
4821 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
4823 case 1: /* objectIdentifier */
4824 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
4826 case 2: /* propertyIdentifier */
4827 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
4829 case 3: /* propertyArrayIndex */
4830 offset = fPropertyArrayIndex (tvb, subtree, offset);
4832 case 4: /* propertyValue */
4833 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
4835 case 5: /* priority */
4836 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
4838 case 6: /* postDelay */
4839 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
4841 case 7: /* quitOnFailure */
4842 offset = fBooleanTag(tvb, subtree, offset,
4843 "Quit On Failure: ");
4845 case 8: /* writeSuccessful */
4846 offset = fBooleanTag(tvb, subtree, offset,
4847 "Write Successful: ");
4852 if (offset == lastoffset) break; /* nothing happened, exit loop */
4857 /* BACnetActionList ::= SEQUENCE{
4858 action [0] SEQUENCE OF BACnetActionCommand
4862 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4864 guint lastoffset = 0;
4865 guint8 tag_no, tag_info;
4867 proto_tree *subtree = tree;
4870 while (tvb_reported_length_remaining(tvb, offset)) {
4871 lastoffset = offset;
4872 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4873 if (tag_is_closing(tag_info)) {
4874 offset += fTagHeaderTree (tvb, subtree, offset,
4875 &tag_no, &tag_info, &lvt);
4879 if (tag_is_opening(tag_info)) {
4880 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
4881 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4882 offset += fTagHeaderTree (tvb, subtree, offset,
4883 &tag_no, &tag_info, &lvt);
4886 case 0: /* BACnetActionCommand */
4887 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
4892 if (offset == lastoffset) break; /* nothing happened, exit loop */
4898 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4900 guint8 tag_no, tag_info;
4904 proto_tree *subtree;
4905 const gchar *label = "Property Identifier";
4907 propertyIdentifier = 0; /* global Variable */
4908 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4909 /* can we decode this value? */
4910 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
4911 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4912 "%s: %s (%u)", label,
4913 val_to_split_str(propertyIdentifier, 512,
4914 BACnetPropertyIdentifier,
4915 ASHRAE_Reserved_Fmt,
4916 Vendor_Proprietary_Fmt), propertyIdentifier);
4917 if (col_get_writable(pinfo->cinfo))
4918 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
4919 val_to_split_str(propertyIdentifier, 512,
4920 BACnetPropertyIdentifier,
4921 ASHRAE_Reserved_Fmt,
4922 Vendor_Proprietary_Fmt));
4924 /* property identifiers cannot be larger than 22-bits */
4927 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4928 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4929 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
4930 offset+tag_len, lvt, FALSE);
4932 return offset+tag_len+lvt;
4936 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
4938 guint8 tag_no, tag_info;
4942 proto_tree *subtree;
4944 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4945 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
4946 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4947 "property Array Index (Unsigned) %u", propertyArrayIndex);
4949 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4950 "property Array Index - %u octets (Unsigned)", lvt);
4951 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4952 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4954 return offset+tag_len+lvt;
4958 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4960 guint8 tag_no, tag_info, character_set;
4962 gsize inbytesleft, outbytesleft = 512;
4963 guint offs, extra = 1;
4966 guint8 bf_arr[512], *out = &bf_arr[0];
4968 proto_tree *subtree;
4969 guint start = offset;
4971 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4973 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4975 character_set = tvb_get_guint8(tvb, offset+offs);
4976 /* Account for code page if DBCS */
4977 if (character_set == 1)
4981 offset += (offs+extra);
4985 inbytesleft = l = MIN(lvt, 255);
4987 * XXX - are we guaranteed that these encoding
4988 * names correspond, on *all* platforms with
4989 * iconv(), to the encodings we want?
4990 * If not (and perhaps even if so), we should
4991 * perhaps have our own iconv() implementation,
4992 * with a different name, so that we control the
4993 * encodings it supports and the names of those
4996 * We should also handle that in the general
4997 * string handling code, rather than making it
4998 * specific to the BACAPP dissector, as many
4999 * other dissectors need to handle various
5000 * character encodings.
5002 str_val = tvb_get_ephemeral_string(tvb, offset, l);
5003 /** this decoding may be not correct for multi-byte characters, Lka */
5004 switch (character_set) {
5006 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ANSI_X3.4");
5007 coding = "ANSI X3.4";
5011 coding = "IBM MS DBCS";
5015 coding = "JIS C 6226";
5017 case ISO_10646_UCS4:
5018 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5019 coding = "ISO 10646 UCS-4";
5021 case ISO_10646_UCS2:
5022 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5023 coding = "ISO 10646 UCS-2";
5026 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5027 coding = "ISO 8859-1";
5034 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s'%s'", label, coding, out);
5039 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5041 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
5042 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, FALSE);
5044 if (character_set == 1)
5046 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5053 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5054 const value_string *src)
5056 guint8 tag_no, tag_info, tmp;
5057 gint j, unused, skip;
5058 guint start = offset;
5060 guint32 lvt, i, numberOfBytes;
5062 proto_tree* subtree = tree;
5065 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5066 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
5068 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
5069 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
5073 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5075 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5076 proto_tree_add_text(subtree, tvb, offset, 1,
5080 for (i = 0; i < numberOfBytes; i++) {
5081 tmp = tvb_get_guint8(tvb, (offset)+i+1);
5082 if (i == numberOfBytes-1) { skip = unused; }
5083 for (j = 0; j < 8-skip; j++) {
5085 if (tmp & (1 << (7 - j)))
5086 proto_tree_add_text(subtree, tvb,
5089 val_to_str((guint) (i*8 +j),
5091 ASHRAE_Reserved_Fmt));
5093 proto_tree_add_text(subtree, tvb,
5096 val_to_str((guint) (i*8 +j),
5098 ASHRAE_Reserved_Fmt));
5100 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
5107 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
5108 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
5117 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5119 return fBitStringTagVS (tvb, tree, offset, label, NULL);
5122 /* handles generic application types, as well as enumerated and enumerations
5123 with reserved and proprietarty ranges (split) */
5125 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5126 const gchar *label, const value_string *src, guint32 split_val)
5128 guint8 tag_no, tag_info;
5132 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5134 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5135 if (!tag_is_context_specific(tag_info))
5138 case 0: /** NULL 20.2.2 */
5139 offset = fNullTag(tvb, tree, offset, label);
5141 case 1: /** BOOLEAN 20.2.3 */
5142 offset = fBooleanTag(tvb, tree, offset, label);
5144 case 2: /** Unsigned Integer 20.2.4 */
5145 offset = fUnsignedTag(tvb, tree, offset, label);
5147 case 3: /** Signed Integer 20.2.5 */
5148 offset = fSignedTag(tvb, tree, offset, label);
5150 case 4: /** Real 20.2.6 */
5151 offset = fRealTag(tvb, tree, offset, label);
5153 case 5: /** Double 20.2.7 */
5154 offset = fDoubleTag(tvb, tree, offset, label);
5156 case 6: /** Octet String 20.2.8 */
5157 offset = fOctetString (tvb, tree, offset, label, lvt);
5159 case 7: /** Character String 20.2.9 */
5160 offset = fCharacterString (tvb,tree,offset,label);
5162 case 8: /** Bit String 20.2.10 */
5163 offset = fBitStringTagVS (tvb, tree, offset, label, src);
5165 case 9: /** Enumerated 20.2.11 */
5166 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
5168 case 10: /** Date 20.2.12 */
5169 offset = fDate (tvb, tree, offset, label);
5171 case 11: /** Time 20.2.13 */
5172 offset = fTime (tvb, tree, offset, label);
5174 case 12: /** BACnetObjectIdentifier 20.2.14 */
5175 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5177 case 13: /* reserved for ASHRAE */
5180 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
5181 offset+=lvt+tag_len;
5193 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
5195 guint lastoffset = 0;
5197 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5198 lastoffset = offset;
5200 switch (fTagNo(tvb,offset)) {
5201 case 0: /* percent */
5202 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
5205 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
5207 case 2: /* amount */
5208 offset = fRealTag(tvb, tree, offset, "shed amount: ");
5213 if (offset == lastoffset) break; /* nothing happened, exit loop */
5219 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5220 const gchar *label, const value_string *vs)
5222 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
5226 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5229 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
5233 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5235 guint8 tag_no, tag_info;
5239 proto_tree *subtree;
5243 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5244 /* cap the the suggested length in case of bad data */
5245 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
5246 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt))
5250 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
5251 "Context Value (as %u DATA octets)", lvt);
5253 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5254 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5256 return offset + tag_len + lvt;
5260 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5262 guint8 tag_no, tag_info;
5264 guint lastoffset = 0, depth = 0;
5267 if (propertyIdentifier >= 0)
5269 g_snprintf (ar, sizeof(ar), "%s: ",
5270 val_to_split_str(propertyIdentifier, 512,
5271 BACnetPropertyIdentifier,
5272 ASHRAE_Reserved_Fmt,
5273 Vendor_Proprietary_Fmt));
5277 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
5279 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5280 lastoffset = offset;
5281 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5282 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
5283 if (depth <= 0) return offset;
5286 /* Application Tags */
5287 switch (propertyIdentifier) {
5288 case 2: /* action */
5289 /* loop object is application tagged,
5290 command object is context tagged */
5291 if (tag_is_context_specific(tag_info)) {
5292 /* BACnetActionList */
5293 offset = fActionList (tvb, pinfo, tree,offset);
5296 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5300 case 30: /* BACnetAddressBinding */
5301 offset = fAddressBinding (tvb,pinfo,tree,offset);
5303 case 54: /* list of object property reference */
5304 offset = fLOPR (tvb, pinfo, tree,offset);
5306 case 55: /* list-of-session-keys */
5307 fSessionKey (tvb, tree, offset);
5309 case 79: /* object-type */
5310 case 96: /* protocol-object-types-supported */
5311 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
5312 BACnetObjectType, 128);
5314 case 97: /* Protocol-Services-Supported */
5315 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5316 BACnetServicesSupported);
5318 case 102: /* recipient-list */
5319 offset = fDestination (tvb, pinfo, tree, offset);
5321 case 107: /* segmentation-supported */
5322 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5323 BACnetSegmentation);
5325 case 111: /* Status-Flags */
5326 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5329 case 112: /* System-Status */
5330 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5331 BACnetDeviceStatus);
5333 case 117: /* units */
5334 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5335 BACnetEngineeringUnits);
5337 case 87: /* priority-array -- accessed as a BACnetARRAY */
5338 if (propertyArrayIndex == 0) {
5339 /* BACnetARRAY index 0 refers to the length
5340 of the array, not the elements of the array */
5341 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5343 offset = fPriorityArray (tvb, pinfo, tree, offset);
5346 case 38: /* exception-schedule */
5347 if (object_type < 128)
5349 if (propertyArrayIndex == 0) {
5350 /* BACnetARRAY index 0 refers to the length
5351 of the array, not the elements of the array */
5352 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5354 offset = fSpecialEvent (tvb,pinfo,tree,offset);
5358 case 19: /* controlled-variable-reference */
5359 case 60: /* manipulated-variable-reference */
5360 case 109: /* Setpoint-Reference */
5361 case 132: /* log-device-object-property */
5362 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
5364 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
5365 if (object_type < 128)
5367 if (propertyArrayIndex == 0) {
5368 /* BACnetARRAY index 0 refers to the length
5369 of the array, not the elements of the array */
5370 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5372 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
5376 case 127: /* client COV increment */
5377 offset = fClientCOV (tvb, pinfo, tree, offset);
5379 case 131: /* log-buffer */
5380 offset = fLogRecord (tvb, pinfo, tree, offset);
5382 case 159: /* member-of */
5383 case 165: /* zone-members */
5384 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
5386 case 196: /* last-restart-reason */
5387 offset = fRestartReason (tvb, pinfo, tree, offset);
5389 case 212: /* actual-shed-level */
5390 case 214: /* expected-shed-level */
5391 case 218: /* requested-shed-level */
5392 offset = fShedLevel (tvb, tree, offset);
5397 if (tag_is_opening(tag_info))
5400 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5402 else if (tag_is_closing(tag_info))
5405 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5409 offset = fContextTaggedValue(tvb, tree, offset, ar);
5414 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5418 if (offset == lastoffset) break; /* nothing happened, exit loop */
5425 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
5430 if (tag_is_opening(tag_info)) {
5431 offset += fTagHeaderTree(tvb, tree, offset,
5432 &tag_no, &tag_info, &lvt);
5433 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
5434 if (tvb_length_remaining(tvb, offset) > 0) {
5435 offset += fTagHeaderTree(tvb, tree, offset,
5436 &tag_no, &tag_info, &lvt);
5439 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
5440 "expected Opening Tag!"); \
5441 offset = tvb_length(tvb);
5449 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
5451 guint lastoffset = offset;
5452 guint8 tag_no, tag_info;
5455 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
5456 if (offset > lastoffset)
5458 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5459 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
5460 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
5467 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5469 guint lastoffset = 0;
5470 guint8 tag_no, tag_info;
5473 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5474 lastoffset = offset;
5475 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
5476 if (offset > lastoffset)
5478 /* detect optional priority
5479 by looking to see if the next tag is context tag number 3 */
5480 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5481 if (tag_is_context_specific(tag_info) && (tag_no == 3))
5482 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
5484 if (offset == lastoffset) break; /* nothing happened, exit loop */
5490 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5492 guint lastoffset = 0;
5493 guint8 tag_no, tag_info;
5495 proto_tree *subtree = tree;
5498 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5499 lastoffset = offset;
5500 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5501 if (tag_is_closing(tag_info)) {
5502 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5508 case 0: /* ProcessId */
5509 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
5511 case 1: /* monitored ObjectId */
5512 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5514 case 2: /* issueConfirmedNotifications */
5515 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
5517 case 3: /* life time */
5518 offset = fTimeSpan (tvb,tree,offset,"life time");
5520 case 4: /* monitoredPropertyIdentifier */
5521 if (tag_is_opening(tag_info)) {
5522 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
5524 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5526 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5527 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
5532 case 5: /* covIncrement */
5533 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5538 if (offset == lastoffset) break; /* nothing happened, exit loop */
5544 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5546 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
5550 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5552 guint lastoffset = 0;
5554 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5555 lastoffset = offset;
5557 switch (fTagNo(tvb, offset)) {
5558 case 0: /* deviceInstanceLowLimit */
5559 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
5561 case 1: /* deviceInstanceHighLimit */
5562 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
5564 case 2: /* BACnetObjectId */
5565 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5567 case 3: /* messageText */
5568 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
5573 if (offset == lastoffset) break; /* nothing happened, exit loop */
5580 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
5582 guint lastoffset = 0;
5583 guint8 tag_no, tag_info;
5586 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5587 if (tag_is_opening(tag_info) && tag_no == 0)
5589 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
5590 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5591 lastoffset = offset;
5592 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5593 if (tag_is_closing(tag_info)) {
5594 /* should be closing context tag 0 */
5595 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5599 offset = fTimeValue (tvb, pinfo, subtree, offset);
5600 if (offset == lastoffset) break; /* nothing happened, exit loop */
5603 else if (tag_no == 0 && lvt == 0)
5605 /* not sure null (empty array element) is legal */
5606 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5612 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5614 guint lastoffset = 0;
5615 guint8 tag_no, tag_info;
5617 guint i = 1; /* day of week array index */
5618 proto_tree *subtree = tree;
5621 if (propertyArrayIndex > 0) {
5622 /* BACnetARRAY index 0 refers to the length
5623 of the array, not the elements of the array.
5624 BACnetARRAY index -1 is our internal flag that
5625 the optional index was not used.
5626 BACnetARRAY refers to this as all elements of the array.
5627 If the optional index is specified for a BACnetARRAY,
5628 then that specific array element is referenced. */
5629 i = propertyArrayIndex;
5631 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5632 lastoffset = offset;
5633 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5634 if (tag_is_closing(tag_info)) {
5635 return offset; /* outer encoding will print out closing tag */
5637 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
5638 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5639 offset = fDailySchedule (tvb, pinfo, subtree, offset);
5640 if (offset == lastoffset) break; /* nothing happened, exit loop */
5647 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5649 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5652 return fDateTime (tvb, tree, offset, "UTC-Time: ");
5656 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5658 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5661 return fDateTime (tvb, tree, offset, NULL);
5665 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
5667 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5669 offset = fDate (tvb,tree,offset,"Start Date: ");
5670 return fDate (tvb, tree, offset, "End Date: ");
5674 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5677 guint8 tag_no, tag_info;
5681 proto_tree *subtree;
5682 const gchar *label = "Vendor ID";
5684 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5685 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
5686 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5687 "%s: %s (%u)", label,
5688 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
5690 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5691 "%s - %u octets (Unsigned)", label, lvt);
5692 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5693 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5695 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
5696 proto_item *expert_item;
5697 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
5698 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
5699 PROTO_ITEM_SET_GENERATED(expert_item);
5700 return offset+tag_len+lvt;
5703 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
5704 offset+tag_len, lvt, FALSE);
5706 return offset+tag_len+lvt;
5710 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5713 guint8 tag_no, tag_info;
5717 proto_tree *subtree;
5718 const gchar *label = "Restart Reason";
5720 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5721 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
5722 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5723 "%s: %s (%u)", label,
5724 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
5726 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5727 "%s - %u octets (Unsigned)", label, lvt);
5728 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5729 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5732 proto_item *expert_item;
5733 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
5734 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
5735 PROTO_ITEM_SET_GENERATED(expert_item);
5736 return offset+tag_len+lvt;
5739 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
5740 offset+tag_len, lvt, FALSE);
5742 return offset+tag_len+lvt;
5746 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5748 guint lastoffset = 0;
5750 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5751 lastoffset = offset;
5752 switch (fTagNo(tvb, offset)) {
5754 case 0: /* textMessageSourceDevice */
5755 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5757 case 1: /* messageClass */
5758 switch (fTagNo(tvb, offset)) {
5759 case 0: /* numeric */
5760 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
5762 case 1: /* character */
5763 offset = fCharacterString (tvb, tree, offset, "message Class: ");
5767 case 2: /* messagePriority */
5768 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
5769 BACnetMessagePriority);
5771 case 3: /* message */
5772 offset = fCharacterString (tvb, tree, offset, "message: ");
5777 if (offset == lastoffset) break; /* nothing happened, exit loop */
5783 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5785 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
5789 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5791 guint lastoffset = 0;
5792 guint8 tag_no, tag_info;
5794 proto_tree *subtree = tree;
5797 /* exit loop if nothing happens inside */
5798 while (tvb_reported_length_remaining(tvb, offset)) {
5799 lastoffset = offset;
5800 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5801 if (tag_is_closing(tag_info)) {
5802 if (tag_no == 2) /* Make sure it's the expected tag */
5804 offset += fTagHeaderTree (tvb, subtree, offset,
5805 &tag_no, &tag_info, &lvt);
5811 break; /* End loop if incorrect closing tag */
5816 case 0: /* vendorID */
5817 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
5819 case 1: /* serviceNumber */
5820 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
5822 case 2: /*serviceParameters */
5823 if (tag_is_opening(tag_info)) {
5824 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
5825 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5826 propertyIdentifier = -1;
5827 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
5835 if (offset == lastoffset) break; /* nothing happened, exit loop */
5841 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5843 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
5847 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5849 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
5853 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5855 guint lastoffset = 0;
5856 guint8 tag_no, tag_info;
5858 proto_tree *subtree = tree;
5861 if (label != NULL) {
5862 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
5863 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5866 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5867 lastoffset = offset;
5868 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5871 case 0: /* subscriberProcessId */
5872 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
5874 case 1: /* requestingSource */
5875 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
5877 case 2: /* request */
5878 offset = fEnumeratedTagSplit (tvb, tree, offset,
5879 "request: ", BACnetLifeSafetyOperation, 64);
5881 case 3: /* objectId */
5882 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5887 if (offset == lastoffset) break; /* nothing happened, exit loop */
5893 fBACnetPropertyStates(tvbuff_t *tvb, proto_tree *tree, guint offset)
5895 switch (fTagNo(tvb, offset))
5898 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
5901 offset = fEnumeratedTagSplit (tvb, tree, offset,
5902 "binary-value: ", BACnetBinaryPV, 2);
5905 offset = fEnumeratedTagSplit (tvb, tree, offset,
5906 "event-type: ", BACnetEventType, 12);
5909 offset = fEnumeratedTagSplit (tvb, tree, offset,
5910 "polarity: ", BACnetPolarity, 2);
5913 offset = fEnumeratedTagSplit (tvb, tree, offset,
5914 "program-change: ", BACnetProgramRequest, 5);
5917 offset = fEnumeratedTagSplit (tvb, tree, offset,
5918 "program-state: ", BACnetProgramState, 5);
5921 offset = fEnumeratedTagSplit (tvb, tree, offset,
5922 "reason-for-halt: ", BACnetProgramError, 5);
5925 offset = fEnumeratedTagSplit (tvb, tree, offset,
5926 "reliability: ", BACnetReliability, 10);
5929 offset = fEnumeratedTagSplit (tvb, tree, offset,
5930 "state: ", BACnetEventState, 64);
5933 offset = fEnumeratedTagSplit (tvb, tree, offset,
5934 "system-status: ", BACnetDeviceStatus, 64);
5937 offset = fEnumeratedTagSplit (tvb, tree, offset,
5938 "units: ", BACnetEngineeringUnits, 2);
5941 offset = fUnsignedTag(tvb, tree, offset, "unsigned-value: ");
5944 offset = fEnumeratedTagSplit (tvb, tree, offset,
5945 "life-safety-mode: ", BACnetLifeSafetyMode, 64);
5948 offset = fEnumeratedTagSplit (tvb, tree, offset,
5949 "life-safety-state: ", BACnetLifeSafetyState, 64);
5959 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
5960 deviceIdentifier [0] BACnetObjectIdentifier,
5961 objectIdentifier [1] BACnetObjectIdentifier,
5962 propertyIdentifier [2] BACnetPropertyIdentifier,
5963 arrayIndex [3] Unsigned OPTIONAL,
5964 value [4] ABSTRACT-SYNTAX.&Type
5968 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5970 guint lastoffset = 0;
5971 guint8 tag_no, tag_info;
5974 while (tvb_reported_length_remaining(tvb, offset)) {
5975 lastoffset = offset;
5976 /* check the tag. A closing tag means we are done */
5977 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5978 if (tag_is_closing(tag_info)) {
5982 case 0: /* deviceIdentifier */
5983 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5985 case 1: /* objectIdentifier */
5986 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5988 case 2: /* propertyIdentifier */
5989 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
5991 case 3: /* arrayIndex - OPTIONAL */
5992 offset = fUnsignedTag (tvb, tree, offset,
5996 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5997 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
5998 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6003 if (offset == lastoffset) break; /* nothing happened, exit loop */
6010 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
6011 objectIdentifier [0] BACnetObjectIdentifier,
6012 propertyIdentifier [1] BACnetPropertyIdentifier,
6013 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
6014 -- if omitted with an array then
6015 -- the entire array is referenced
6016 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
6020 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6022 guint lastoffset = 0;
6023 guint8 tag_no, tag_info;
6026 while (tvb_reported_length_remaining(tvb, offset)) {
6027 lastoffset = offset;
6028 /* check the tag. A closing tag means we are done */
6029 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6030 if (tag_is_closing(tag_info)) {
6034 case 0: /* objectIdentifier */
6035 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6037 case 1: /* propertyIdentifier */
6038 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6040 case 2: /* arrayIndex - OPTIONAL */
6041 offset = fUnsignedTag (tvb, tree, offset,
6044 case 3: /* deviceIdentifier - OPTIONAL */
6045 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6050 if (offset == lastoffset) break; /* nothing happened, exit loop */
6056 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6058 guint lastoffset = offset;
6059 guint8 tag_no, tag_info;
6061 proto_tree *subtree = tree;
6064 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6065 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
6066 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
6067 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6068 /* Opening tag for parameter choice */
6069 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6072 case 0: /* change-of-bitstring */
6073 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6074 lastoffset = offset;
6075 switch (fTagNo(tvb, offset)) {
6077 offset = fBitStringTag (tvb, subtree, offset,
6078 "referenced-bitstring: ");
6081 offset = fBitStringTagVS (tvb, subtree, offset,
6082 "status-flags: ", BACnetStatusFlags);
6083 lastoffset = offset;
6088 if (offset == lastoffset) break; /* nothing happened, exit loop */
6091 case 1: /* change-of-state */
6092 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6093 lastoffset = offset;
6094 switch (fTagNo(tvb, offset)) {
6096 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6097 offset = fBACnetPropertyStates(tvb, subtree, offset);
6098 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6101 offset = fBitStringTagVS (tvb, subtree, offset,
6102 "status-flags: ", BACnetStatusFlags);
6103 lastoffset = offset;
6108 if (offset == lastoffset) break; /* nothing happened, exit loop */
6111 case 2: /* change-of-value */
6112 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6113 lastoffset = offset;
6114 switch (fTagNo(tvb, offset)) {
6116 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6117 switch (fTagNo(tvb, offset)) {
6119 offset = fBitStringTag (tvb, subtree, offset,
6123 offset = fRealTag (tvb, subtree, offset,
6129 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6132 offset = fBitStringTagVS (tvb, subtree, offset,
6133 "status-flags: ", BACnetStatusFlags);
6134 lastoffset = offset;
6139 if (offset == lastoffset) break; /* nothing happened, exit loop */
6142 case 3: /* command-failure */
6143 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6144 lastoffset = offset;
6145 switch (fTagNo(tvb, offset)) {
6146 case 0: /* "command-value: " */
6147 /* from BACnet Table 13-3,
6148 Standard Object Property Values Returned in Notifications */
6149 propertyIdentifier = 85; /* PRESENT_VALUE */
6150 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6151 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6152 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6155 offset = fBitStringTagVS (tvb, subtree, offset,
6156 "status-flags: ", BACnetStatusFlags);
6158 case 2: /* "feedback-value: " */
6159 propertyIdentifier = 40; /* FEEDBACK_VALUE */
6160 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6161 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6162 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6163 lastoffset = offset;
6168 if (offset == lastoffset) break; /* nothing happened, exit loop */
6171 case 4: /* floating-limit */
6172 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6173 lastoffset = offset;
6174 switch (fTagNo(tvb, offset)) {
6176 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
6179 offset = fBitStringTagVS (tvb, subtree, offset,
6180 "status-flags: ", BACnetStatusFlags);
6183 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
6186 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
6187 lastoffset = offset;
6192 if (offset == lastoffset) break; /* nothing happened, exit loop */
6195 case 5: /* out-of-range */
6196 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6197 lastoffset = offset;
6198 switch (fTagNo(tvb, offset)) {
6200 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
6203 offset = fBitStringTagVS (tvb, subtree, offset,
6204 "status-flags: ", BACnetStatusFlags);
6207 offset = fRealTag (tvb, subtree, offset, "deadband: ");
6210 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
6211 lastoffset = offset;
6216 if (offset == lastoffset) break; /* nothing happened, exit loop */
6220 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6221 lastoffset = offset;
6222 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
6223 if (offset == lastoffset) break; /* nothing happened, exit loop */
6226 case 7: /* buffer-ready */
6227 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6228 lastoffset = offset;
6229 switch (fTagNo(tvb, offset)) {
6231 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
6234 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
6237 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6238 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
6239 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6242 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6243 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
6244 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6245 lastoffset = offset;
6250 if (offset == lastoffset) break; /* nothing happened, exit loop */
6253 case 8: /* change-of-life-safety */
6254 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6255 lastoffset = offset;
6256 switch (fTagNo(tvb, offset)) {
6258 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6259 "new-state: ", BACnetLifeSafetyState, 256);
6262 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6263 "new-mode: ", BACnetLifeSafetyMode, 256);
6266 offset = fBitStringTagVS (tvb, subtree, offset,
6267 "status-flags: ", BACnetStatusFlags);
6270 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6271 "operation-expected: ", BACnetLifeSafetyOperation, 64);
6272 lastoffset = offset;
6277 if (offset == lastoffset) break; /* nothing happened, exit loop */
6280 case 9: /* extended */
6281 while (tvb_reported_length_remaining(tvb, offset)) {
6282 lastoffset = offset;
6283 switch (fTagNo(tvb, offset)) {
6285 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6288 offset = fUnsignedTag (tvb, subtree, offset,
6289 "extended-event-type: ");
6291 case 2: /* parameters */
6292 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6293 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
6294 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
6295 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6296 lastoffset = offset;
6301 if (offset == lastoffset) break; /* nothing happened, exit loop */
6304 case 10: /* buffer ready */
6305 while (tvb_reported_length_remaining(tvb, offset)) {
6306 lastoffset = offset;
6307 switch (fTagNo(tvb, offset)) {
6308 case 0: /* buffer-property */
6309 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6310 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
6311 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6314 offset = fUnsignedTag (tvb, subtree, offset,
6315 "previous-notification: ");
6318 offset = fUnsignedTag (tvb, subtree, offset,
6319 "current-notification: ");
6320 lastoffset = offset;
6325 if (offset == lastoffset) break; /* nothing happened, exit loop */
6328 case 11: /* unsigned range */
6329 while (tvb_reported_length_remaining(tvb, offset)) {
6330 lastoffset = offset;
6331 switch (fTagNo(tvb, offset)) {
6333 offset = fUnsignedTag (tvb, subtree, offset,
6334 "exceeding-value: ");
6337 offset = fBitStringTagVS (tvb, subtree, offset,
6338 "status-flags: ", BACnetStatusFlags);
6341 offset = fUnsignedTag (tvb, subtree, offset,
6342 "exceeded-limit: ");
6343 lastoffset = offset;
6348 if (offset == lastoffset) break; /* nothing happened, exit loop */
6355 /* Closing tag for parameter choice */
6356 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6363 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset)
6365 guint lastoffset = 0;
6367 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6368 lastoffset = offset;
6369 switch (fTagNo(tvb, offset)) {
6370 case 0: /* change-of-bitstring */
6371 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6372 lastoffset = offset;
6373 switch (fTagNo(tvb, offset)) {
6375 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6378 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6380 case 2: /* SEQUENCE OF BIT STRING */
6381 offset = fBitStringTagVS (tvb, tree, offset,
6382 "bitstring value: ", BACnetEventTransitionBits);
6389 case 1: /* change-of-state */
6390 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6391 lastoffset = offset;
6392 switch (fTagNo(tvb, offset)) {
6394 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6396 case 1: /* SEQUENCE OF BACnetPropertyStates */
6397 offset = fEnumeratedTagSplit (tvb, tree, offset,
6398 "value: ", BACnetPropertyStates, 64);
6405 case 2: /* change-of-value */
6406 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6407 lastoffset = offset;
6408 switch (fTagNo(tvb, offset)) {
6410 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6412 case 1: /* don't loop it, it's a CHOICE */
6413 switch (fTagNo(tvb, offset)) {
6415 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6418 offset = fRealTag (tvb, tree, offset,
6419 "referenced Property Increment: ");
6429 case 3: /* command-failure */
6430 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6431 lastoffset = offset;
6432 switch (fTagNo(tvb, offset)) {
6434 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6437 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6443 case 4: /* floating-limit */
6444 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6445 lastoffset = offset;
6446 switch (fTagNo(tvb, offset)) {
6448 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6451 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6454 offset = fRealTag (tvb, tree, offset, "low diff limit: ");
6457 offset = fRealTag (tvb, tree, offset, "high diff limit: ");
6460 offset = fRealTag (tvb, tree, offset, "deadband: ");
6467 case 5: /* out-of-range */
6468 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6469 lastoffset = offset;
6470 switch (fTagNo(tvb, offset)) {
6472 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6475 offset = fRealTag (tvb, tree, offset, "low limit: ");
6478 offset = fRealTag (tvb, tree, offset, "high limit: ");
6481 offset = fRealTag (tvb, tree, offset, "deadband: ");
6489 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
6491 case 7: /* buffer-ready */
6492 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6493 lastoffset = offset;
6494 switch (fTagNo(tvb, offset)) {
6496 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
6499 offset = fUnsignedTag (tvb,tree,offset,
6500 "previous notification count: ");
6507 case 8: /* change-of-life-safety */
6508 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6509 lastoffset = offset;
6510 switch (fTagNo(tvb, offset)) {
6512 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6515 offset = fEnumeratedTagSplit (tvb, tree, offset,
6516 "life safety alarm value: ", BACnetLifeSafetyState, 256);
6519 offset = fEnumeratedTagSplit (tvb, tree, offset,
6520 "alarm value: ", BACnetLifeSafetyState, 256);
6523 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6539 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6541 guint lastoffset = 0;
6542 guint8 tag_no, tag_info;
6545 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6546 lastoffset = offset;
6547 switch (fTagNo(tvb, offset)) {
6548 case 0: /* timestamp */
6549 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6550 offset = fDate (tvb,tree,offset,"Date: ");
6551 offset = fTime (tvb,tree,offset,"Time: ");
6552 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6554 case 1: /* logDatum: don't loop, it's a CHOICE */
6555 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6556 switch (fTagNo(tvb, offset)) {
6557 case 0: /* logStatus */
6558 offset = fEnumeratedTag (tvb, tree, offset,
6559 "log status: ", BACnetLogStatus);
6562 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6565 offset = fRealTag (tvb, tree, offset, "real value: ");
6568 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
6571 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
6574 offset = fSignedTag (tvb, tree, offset, "signed value: ");
6577 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
6580 offset = fNullTag(tvb, tree, offset, "null value: ");
6583 offset = fError (tvb, pinfo, tree, offset);
6586 offset = fRealTag (tvb, tree, offset, "time change: ");
6588 case 10: /* any Value */
6589 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6590 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6591 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6596 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6599 offset = fEnumeratedTag (tvb, tree, offset,
6600 "Status Flags: ", BACnetStatusFlags);
6605 if (offset == lastoffset) break; /* nothing happened, exit loop */
6612 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6614 guint lastoffset = 0;
6615 guint8 tag_no, tag_info;
6618 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6619 lastoffset = offset;
6621 switch (fTagNo(tvb,offset)) {
6622 case 0: /* ProcessId */
6623 offset = fProcessId (tvb,tree,offset);
6625 case 1: /* initiating ObjectId */
6626 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6628 case 2: /* event ObjectId */
6629 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6631 case 3: /* time stamp */
6632 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6633 offset = fTimeStamp (tvb, tree, offset, NULL);
6634 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6636 case 4: /* notificationClass */
6637 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
6639 case 5: /* Priority */
6640 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
6642 case 6: /* EventType */
6643 offset = fEnumeratedTagSplit (tvb, tree, offset,
6644 "Event Type: ", BACnetEventType, 64);
6646 case 7: /* messageText */
6647 offset = fCharacterString (tvb, tree, offset, "message Text: ");
6649 case 8: /* NotifyType */
6650 offset = fEnumeratedTag (tvb, tree, offset,
6651 "Notify Type: ", BACnetNotifyType);
6653 case 9: /* ackRequired */
6654 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
6656 case 10: /* fromState */
6657 offset = fEnumeratedTagSplit (tvb, tree, offset,
6658 "from State: ", BACnetEventState, 64);
6660 case 11: /* toState */
6661 offset = fEnumeratedTagSplit (tvb, tree, offset,
6662 "to State: ", BACnetEventState, 64);
6664 case 12: /* NotificationParameters */
6665 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6666 offset = fNotificationParameters (tvb, pinfo, tree, offset);
6667 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6672 if (offset == lastoffset) break; /* nothing happened, exit loop */
6678 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6680 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
6684 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6686 guint lastoffset = 0;
6687 guint8 tag_no, tag_info;
6689 proto_tree *subtree = tree;
6692 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6693 lastoffset = offset;
6694 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6695 if (tag_is_closing(tag_info)) {
6696 offset += fTagHeaderTree (tvb, subtree, offset,
6697 &tag_no, &tag_info, &lvt);
6698 lastoffset = offset;
6704 case 0: /* ProcessId */
6705 offset = fProcessId (tvb,tree,offset);
6707 case 1: /* initiating DeviceId */
6708 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6710 case 2: /* monitored ObjectId */
6711 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6713 case 3: /* time remaining */
6714 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
6716 case 4: /* List of Values */
6717 if (tag_is_opening(tag_info)) {
6718 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
6719 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6720 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6721 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
6729 if (offset == lastoffset) break; /* nothing happened, exit loop */
6735 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6737 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
6741 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6743 guint lastoffset = 0;
6744 guint8 tag_no = 0, tag_info = 0;
6747 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6748 lastoffset = offset;
6749 switch (fTagNo(tvb, offset)) {
6750 case 0: /* acknowledgingProcessId */
6751 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
6753 case 1: /* eventObjectId */
6754 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6756 case 2: /* eventStateAcknowledged */
6757 offset = fEnumeratedTagSplit (tvb, tree, offset,
6758 "event State Acknowledged: ", BACnetEventState, 64);
6760 case 3: /* timeStamp */
6761 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6762 offset = fTimeStamp(tvb, tree, offset, NULL);
6763 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6765 case 4: /* acknowledgementSource */
6766 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
6768 case 5: /* timeOfAcknowledgement */
6769 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6770 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
6771 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6776 if (offset == lastoffset) break; /* nothing happened, exit loop */
6782 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6784 guint lastoffset = 0;
6786 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6787 lastoffset = offset;
6788 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
6789 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
6790 "alarm State: ", BACnetEventState, 64);
6791 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
6792 "acknowledged Transitions: ", BACnetEventTransitionBits);
6793 if (offset == lastoffset) break; /* nothing happened, exit loop */
6799 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6801 guint lastoffset = 0;
6802 guint8 tag_no, tag_info;
6805 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6806 lastoffset = offset;
6807 switch (fTagNo(tvb, offset)) {
6808 case 0: /* acknowledgmentFilter */
6809 offset = fEnumeratedTag (tvb, tree, offset,
6810 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
6812 case 1: /* eventObjectId - OPTIONAL */
6813 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6814 offset = fRecipientProcess (tvb, pinfo, tree, offset);
6815 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6817 case 2: /* eventStateFilter */
6818 offset = fEnumeratedTag (tvb, tree, offset,
6819 "event State Filter: ", BACnetEventStateFilter);
6821 case 3: /* eventTypeFilter - OPTIONAL */
6822 offset = fEnumeratedTag (tvb, tree, offset,
6823 "event Type Filter: ", BACnetEventType);
6825 case 4: /* priorityFilter */
6826 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6827 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
6828 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
6829 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6831 case 5: /* notificationClassFilter - OPTIONAL */
6832 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
6837 if (offset == lastoffset) break; /* nothing happened, exit loop */
6843 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6845 guint lastoffset = 0;
6847 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6848 lastoffset = offset;
6849 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
6850 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
6851 "event Type: ", BACnetEventType, 64);
6852 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
6853 "event State: ", BACnetEventState);
6854 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
6855 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
6856 if (offset == lastoffset) break; /* nothing happened, exit loop */
6863 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6865 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6866 if (fTagNo(tvb, offset) == 0) {
6867 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6874 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6876 guint lastoffset = 0;
6877 guint8 tag_no, tag_info;
6879 proto_tree* subtree = tree;
6882 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6883 lastoffset = offset;
6884 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6885 /* we are finished here if we spot a closing tag */
6886 if (tag_is_closing(tag_info)) {
6890 case 0: /* ObjectId */
6891 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6893 case 1: /* eventState */
6894 offset = fEnumeratedTag (tvb, tree, offset,
6895 "event State: ", BACnetEventState);
6897 case 2: /* acknowledgedTransitions */
6898 offset = fBitStringTagVS (tvb, tree, offset,
6899 "acknowledged Transitions: ", BACnetEventTransitionBits);
6901 case 3: /* eventTimeStamps */
6902 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
6904 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6906 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6907 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
6908 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
6909 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
6910 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6912 case 4: /* notifyType */
6913 offset = fEnumeratedTag (tvb, tree, offset,
6914 "Notify Type: ", BACnetNotifyType);
6916 case 5: /* eventEnable */
6917 offset = fBitStringTagVS (tvb, tree, offset,
6918 "event Enable: ", BACnetEventTransitionBits);
6920 case 6: /* eventPriorities */
6921 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
6923 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6925 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6926 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
6927 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
6928 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
6929 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6934 if (offset == lastoffset) break; /* nothing happened, exit loop */
6940 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6942 guint lastoffset = 0;
6943 guint8 tag_no, tag_info;
6946 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
6947 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6948 lastoffset = offset;
6949 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6950 /* we are finished here if we spot a closing tag */
6951 if (tag_is_closing(tag_info)) {
6954 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
6955 if (offset == lastoffset) break; /* nothing happened, exit loop */
6961 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6963 guint lastoffset = 0;
6964 guint8 tag_no, tag_info;
6967 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6968 lastoffset = offset;
6969 switch (fTagNo(tvb, offset)) {
6970 case 0: /* listOfEventSummaries */
6971 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6972 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
6973 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6975 case 1: /* moreEvents */
6976 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
6981 if (offset == lastoffset) break; /* nothing happened, exit loop */
6987 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6989 guint lastoffset = 0;
6990 guint8 tag_no, tag_info;
6992 proto_tree *subtree = tree;
6995 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
6997 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6998 lastoffset = offset;
6999 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7000 if (tag_is_closing(tag_info)) {
7001 offset += fTagHeaderTree (tvb, subtree, offset,
7002 &tag_no, &tag_info, &lvt);
7008 case 0: /* ObjectId */
7009 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
7011 case 3: /* listOfElements */
7012 if (tag_is_opening(tag_info)) {
7013 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
7014 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7015 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7016 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7024 if (offset == lastoffset) break; /* nothing happened, exit loop */
7030 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7032 return fObjectIdentifier (tvb, pinfo, tree, offset);
7036 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7038 guint lastoffset = 0;
7040 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7041 lastoffset = offset;
7043 switch (fTagNo(tvb, offset)) {
7044 case 0: /* timeDuration */
7045 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
7047 case 1: /* enable-disable */
7048 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
7049 BACnetEnableDisable);
7051 case 2: /* password - OPTIONAL */
7052 offset = fCharacterString (tvb, tree, offset, "Password: ");
7057 if (offset == lastoffset) break; /* nothing happened, exit loop */
7063 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7065 guint lastoffset = 0;
7067 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7068 lastoffset = offset;
7070 switch (fTagNo(tvb, offset)) {
7071 case 0: /* reinitializedStateOfDevice */
7072 offset = fEnumeratedTag (tvb, tree, offset,
7073 "reinitialized State Of Device: ",
7074 BACnetReinitializedStateOfDevice);
7076 case 1: /* password - OPTIONAL */
7077 offset = fCharacterString (tvb, tree, offset, "Password: ");
7082 if (offset == lastoffset) break; /* nothing happened, exit loop */
7088 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7090 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7091 "vtClass: ", BACnetVTClass);
7092 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
7096 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7098 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7102 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7104 guint lastoffset = 0;
7106 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7107 lastoffset = offset;
7108 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7109 if (offset == lastoffset) break; /* nothing happened, exit loop */
7115 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7117 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
7118 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
7119 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
7123 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
7125 guint lastoffset = 0;
7127 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7128 lastoffset = offset;
7130 switch (fTagNo(tvb,offset)) {
7131 case 0: /* BOOLEAN */
7132 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
7134 case 1: /* Unsigned OPTIONAL */
7135 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
7140 if (offset == lastoffset) break; /* nothing happened, exit loop */
7146 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
7148 guint lastoffset = 0;
7150 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7151 lastoffset = offset;
7153 switch (fTagNo(tvb,offset)) {
7154 case 0: /* Unsigned32 */
7155 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
7157 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
7158 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
7160 case 2: /* Chararacter String OPTIONAL */
7161 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
7163 case 3: /* Chararacter String OPTIONAL */
7164 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
7166 case 4: /* Boolean OPTIONAL */
7167 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
7172 if (offset == lastoffset) break; /* nothing happened, exit loop */
7178 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7180 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
7184 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7186 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
7187 offset = fAddress (tvb, tree, offset);
7188 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
7189 return fAddress (tvb, tree, offset);
7193 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7195 /* Same as AddListElement request after service choice */
7196 return fAddListElementRequest(tvb, pinfo, tree, offset);
7200 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7202 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
7206 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7208 guint lastoffset = 0;
7209 guint8 tag_no, tag_info;
7211 proto_tree *subtree = tree;
7213 /* set the optional global properties to indicate not-used */
7214 propertyArrayIndex = -1;
7215 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7216 lastoffset = offset;
7217 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7218 if (tag_is_closing(tag_info)) {
7219 offset += fTagHeaderTree (tvb, tree, offset,
7220 &tag_no, &tag_info, &lvt);
7225 case 0: /* objectIdentifier */
7226 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7228 case 1: /* propertyIdentifier */
7229 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7231 case 2: /* propertyArrayIndex */
7232 offset = fPropertyArrayIndex (tvb, subtree, offset);
7234 case 3: /* propertyValue */
7235 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7240 if (offset == lastoffset) break; /* nothing happened, exit loop */
7246 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7248 guint lastoffset = 0;
7249 guint8 tag_no, tag_info;
7251 proto_tree *subtree = tree;
7253 /* set the optional global properties to indicate not-used */
7254 propertyArrayIndex = -1;
7255 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7256 lastoffset = offset;
7257 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7258 if (tag_is_closing(tag_info)) {
7259 offset += fTagHeaderTree (tvb, subtree, offset,
7260 &tag_no, &tag_info, &lvt);
7266 case 0: /* objectIdentifier */
7267 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7269 case 1: /* propertyIdentifier */
7270 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7272 case 2: /* propertyArrayIndex */
7273 offset = fPropertyArrayIndex (tvb, subtree, offset);
7275 case 3: /* propertyValue */
7276 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7278 case 4: /* Priority (only used for write) */
7279 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7284 if (offset == lastoffset) break; /* nothing happened, exit loop */
7290 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7292 guint lastoffset = 0;
7293 guint8 tag_no, tag_info;
7296 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7297 lastoffset = offset;
7298 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7299 if (tag_is_closing(tag_info)) {
7300 offset += fTagHeaderTree (tvb, subtree, offset,
7301 &tag_no, &tag_info, &lvt);
7306 case 0: /* objectIdentifier */
7307 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7309 case 1: /* listOfPropertyValues */
7310 if (tag_is_opening(tag_info)) {
7311 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7312 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7320 if (offset == lastoffset) break; /* nothing happened, exit loop */
7326 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7328 if (offset >= tvb_reported_length(tvb))
7331 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7332 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
7336 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
7338 guint lastoffset = 0;
7339 guint8 tag_no, tag_info;
7342 /* set the optional global properties to indicate not-used */
7343 propertyArrayIndex = -1;
7344 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7345 lastoffset = offset;
7346 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7347 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
7349 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
7352 switch (tag_no-tagoffset) {
7353 case 0: /* PropertyIdentifier */
7354 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7356 case 1: /* propertyArrayIndex */
7357 offset = fPropertyArrayIndex (tvb, tree, offset);
7358 if (list != 0) break; /* Continue decoding if this may be a list */
7360 lastoffset = offset; /* Set loop end condition */
7363 if (offset == lastoffset) break; /* nothing happened, exit loop */
7369 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
7371 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7372 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
7376 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7378 guint lastoffset = 0;
7380 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7381 lastoffset = offset;
7383 switch (fTagNo(tvb,offset)) {
7384 case 0: /* ObjectIdentifier */
7385 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7387 case 1: /* PropertyIdentifier and propertyArrayIndex */
7388 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
7389 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7391 lastoffset = offset; /* Set loop end condition */
7394 if (offset == lastoffset) break; /* nothing happened, exit loop */
7401 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
7403 guint lastoffset = 0;
7404 guint8 tag_no, tag_info;
7406 proto_tree* subtree = tree;
7409 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7410 lastoffset = offset;
7411 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7412 if (tag_is_closing(tag_info)) {
7413 offset += fTagHeaderTree (tvb, subtree, offset,
7414 &tag_no, &tag_info, &lvt);
7418 case 0: /* ObjectIdentifier */
7419 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7421 case 1: /* PropertyIdentifier */
7422 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7424 case 2: /* propertyArrayIndex */
7425 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
7428 offset = fPropertyValue (tvb, subtree, offset, tag_info);
7430 case 4: /* Priority */
7431 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7442 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7444 char i = 1, ar[256];
7445 guint lastoffset = 0;
7447 if (propertyArrayIndex > 0) {
7448 /* BACnetARRAY index 0 refers to the length
7449 of the array, not the elements of the array.
7450 BACnetARRAY index -1 is our internal flag that
7451 the optional index was not used.
7452 BACnetARRAY refers to this as all elements of the array.
7453 If the optional index is specified for a BACnetARRAY,
7454 then that specific array element is referenced. */
7455 i = propertyArrayIndex;
7457 while (tvb_reported_length_remaining(tvb, offset)) {
7458 /* exit loop if nothing happens inside */
7459 lastoffset = offset;
7460 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
7461 val_to_split_str(87 , 512,
7462 BACnetPropertyIdentifier,
7463 ASHRAE_Reserved_Fmt,
7464 Vendor_Proprietary_Fmt),
7466 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
7467 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
7468 /* there are only 16 priority array elements */
7472 if (offset == lastoffset) break; /* nothing happened, exit loop */
7479 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7481 guint lastoffset = 0;
7483 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7484 lastoffset = offset;
7486 switch (fTagNo(tvb,offset)) {
7487 case 0: /* deviceIdentifier - OPTIONAL */
7488 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7490 case 1: /* ObjectIdentifier */
7491 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7496 if (offset == lastoffset) break; /* nothing happened, exit loop */
7502 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7504 guint8 tag_no, tag_info;
7506 guint lastoffset = 0;
7508 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7509 lastoffset = offset;
7510 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7511 if (tag_is_closing(tag_info)) {
7516 case 0: /* calendaryEntry */
7517 if (tag_is_opening(tag_info))
7519 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7520 offset = fCalendaryEntry (tvb, subtree, offset);
7521 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7524 case 1: /* calendarReference */
7525 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7527 case 2: /* list of BACnetTimeValue */
7528 if (tag_is_opening(tag_info)) {
7529 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7530 offset = fTimeValue (tvb, pinfo, subtree, offset);
7531 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7536 case 3: /* eventPriority */
7537 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
7542 if (offset == lastoffset) break; /* nothing happened, exit loop */
7548 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7550 guint lastoffset = 0;
7551 guint8 tag_no, tag_info;
7554 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7555 lastoffset = offset;
7556 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7557 if (tag_is_closing(tag_info)) { /* stop when we hit outer closing tag */
7561 switch (fTagNo(tvb,offset)) {
7562 case 0: /* propertyIdentifier */
7563 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7565 case 1: /* propertyArrayIndex */
7566 offset = fPropertyArrayIndex (tvb, tree, offset);
7568 case 2: /* relationSpecifier */
7569 offset = fEnumeratedTag (tvb, tree, offset,
7570 "relation Specifier: ", BACnetRelationSpecifier);
7572 case 3: /* comparisonValue */
7573 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7574 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7575 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7580 if (offset == lastoffset) break; /* nothing happened, exit loop */
7586 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7588 guint lastoffset = 0;
7589 guint8 tag_no, tag_info;
7592 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7593 lastoffset = offset;
7594 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7595 if (tag_is_closing(tag_info)) { /* stop when we hit outer closing tag */
7600 case 0: /* selectionLogic */
7601 offset = fEnumeratedTag (tvb, subtree, offset,
7602 "selection Logic: ", BACnetSelectionLogic);
7604 case 1: /* listOfSelectionCriteria */
7605 if (tag_is_opening(tag_info)) {
7606 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7607 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
7608 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7616 if (offset == lastoffset) break; /* nothing happened, exit loop */
7623 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
7625 guint lastoffset = 0;
7626 guint8 tag_no, tag_info;
7629 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7630 lastoffset = offset;
7631 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7633 if (tag_is_opening(tag_info) && tag_no < 2) {
7634 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7636 case 0: /* objectSelectionCriteria */
7637 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
7639 case 1: /* listOfPropertyReferences */
7640 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
7645 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7647 if (offset == lastoffset) break; /* nothing happened, exit loop */
7653 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7655 guint lastoffset = 0;
7656 guint8 tag_no, tag_info;
7659 proto_tree *subtree = tree;
7661 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7662 lastoffset = offset;
7663 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7665 case 0: /* objectIdentifier */
7666 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7668 case 1: /* listOfPropertyReferences */
7669 if (tag_is_opening(tag_info)) {
7670 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
7671 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7672 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7673 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
7674 } else if (tag_is_closing(tag_info)) {
7675 offset += fTagHeaderTree (tvb, subtree, offset,
7676 &tag_no, &tag_info, &lvt);
7679 /* error condition: let caller handle */
7686 if (offset == lastoffset) break; /* nothing happened, exit loop */
7692 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7694 guint lastoffset = 0;
7698 proto_tree *subtree = tree;
7701 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7702 lastoffset = offset;
7703 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7704 if (tag_is_closing(tag_info)) {
7705 offset += fTagHeaderTree (tvb, subtree, offset,
7706 &tag_no, &tag_info, &lvt);
7707 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
7712 case 0: /* objectSpecifier */
7713 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7715 case 1: /* list of Results */
7716 if (tag_is_opening(tag_info)) {
7717 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
7718 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7719 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7724 case 2: /* propertyIdentifier */
7725 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
7727 case 5: /* propertyAccessError */
7728 if (tag_is_opening(tag_info)) {
7729 tt = proto_tree_add_text(tree, tvb, offset, 1, "propertyAccessError");
7730 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7731 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7732 /* Error Code follows */
7733 offset = fError(tvb, pinfo, subtree, offset);
7741 if (offset == lastoffset) break; /* nothing happened, exit loop */
7748 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7750 /* listOfReadAccessResults */
7751 return fReadAccessResult (tvb, pinfo, tree, offset);
7756 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7758 guint lastoffset = 0;
7759 guint8 tag_no, tag_info;
7762 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7763 lastoffset = offset;
7764 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7768 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7770 case 0: /* objectSpecifier */
7771 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
7772 case 0: /* objectType */
7773 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
7775 case 1: /* objectIdentifier */
7776 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7782 case 1: /* propertyValue */
7783 if (tag_is_opening(tag_info)) {
7784 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7792 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7794 if (offset == lastoffset) break; /* nothing happened, exit loop */
7800 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7802 return fObjectIdentifier (tvb, pinfo, tree, offset);
7806 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7808 guint8 tag_no, tag_info;
7810 proto_tree *subtree = tree;
7813 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
7815 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7816 /* optional range choice */
7817 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7818 if (tag_is_opening(tag_info)) {
7819 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
7820 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7821 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7823 case 3: /* range byPosition */
7824 case 6: /* range bySequenceNumber, 2004 spec */
7825 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
7826 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
7828 case 4: /* range byTime - deprecated in 2004 */
7829 case 7: /* 2004 spec */
7830 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
7831 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
7833 case 5: /* range timeRange - deprecated in 2004 */
7834 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
7835 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
7840 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7847 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7849 guint8 tag_no, tag_info;
7851 proto_tree *subtree = tree;
7854 /* set the optional global properties to indicate not-used */
7855 propertyArrayIndex = -1;
7856 /* objectIdentifier, propertyIdentifier, and
7857 OPTIONAL propertyArrayIndex */
7858 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
7859 /* resultFlags => BACnetResultFlags ::= BIT STRING */
7860 offset = fBitStringTagVS (tvb, tree, offset,
7864 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
7866 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7867 if (tag_is_opening(tag_info)) {
7868 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7869 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
7870 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7871 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7872 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7873 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7875 /* firstSequenceNumber - OPTIONAL */
7876 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7877 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
7884 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7886 guint lastoffset = 0;
7888 guint8 tag_no, tag_info;
7890 proto_tree* subtree = NULL;
7892 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7894 if (tag_is_opening(tag_info))
7896 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
7897 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7898 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7899 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
7900 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
7904 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset))
7905 { /* exit loop if nothing happens inside */
7906 lastoffset = offset;
7907 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
7911 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0)
7913 /* More Flag is not set, so we can look for closing tag in this segment */
7914 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7915 if (tag_is_closing(tag_info)) {
7916 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7924 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7926 guint8 tag_no, tag_info;
7928 proto_tree *subtree = tree;
7931 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7933 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7935 if (tag_is_opening(tag_info))
7937 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
7938 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7939 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7940 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
7941 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
7942 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7948 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7951 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
7952 offset = fAccessMethod(tvb, pinfo, tree, offset);
7958 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
7960 guint tag_no = fTagNo(tvb, offset);
7961 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
7965 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7967 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
7968 offset = fAccessMethod(tvb,pinfo, tree, offset);
7974 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7976 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7977 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
7981 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7983 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7984 return fReadAccessResult (tvb,pinfo,tree,offset);
7988 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
7990 if (tvb_reported_length_remaining(tvb,offset) <= 0)
7993 switch (service_choice) {
7994 case 0: /* acknowledgeAlarm */
7995 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
7997 case 1: /* confirmedCOVNotification */
7998 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8000 case 2: /* confirmedEventNotification */
8001 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8003 case 3: /* confirmedGetAlarmSummary conveys no parameters */
8005 case 4: /* getEnrollmentSummaryRequest */
8006 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
8008 case 5: /* subscribeCOVRequest */
8009 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
8011 case 6: /* atomicReadFile-Request */
8012 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
8014 case 7: /* atomicWriteFile-Request */
8015 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
8017 case 8: /* AddListElement-Request */
8018 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
8020 case 9: /* removeListElement-Request */
8021 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
8023 case 10: /* createObjectRequest */
8024 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
8026 case 11: /* deleteObject */
8027 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
8030 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
8033 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
8036 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
8039 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
8042 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
8045 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
8048 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8051 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8054 offset = fReinitializeDeviceRequest(tvb, tree, offset);
8057 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
8060 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8063 offset = fVtDataRequest (tvb, pinfo, tree, offset);
8066 offset = fAuthenticateRequest (tvb, tree, offset);
8069 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
8072 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
8075 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
8078 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
8081 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
8090 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8092 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8095 switch (service_choice) {
8096 case 3: /* confirmedEventNotificationAck */
8097 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
8099 case 4: /* getEnrollmentSummaryAck */
8100 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
8102 case 6: /* atomicReadFile */
8103 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
8105 case 7: /* atomicReadFileAck */
8106 offset = fAtomicWriteFileAck (tvb, tree, offset);
8108 case 10: /* createObject */
8109 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
8112 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
8115 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
8118 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
8121 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
8124 offset = fVtOpenAck (tvb, pinfo, tree, offset);
8127 offset = fVtDataAck (tvb, tree, offset);
8130 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
8133 offset = fReadRangeAck (tvb, pinfo, tree, offset);
8136 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
8145 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8147 /* BACnetObjectIdentifier */
8148 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
8150 /* MaxAPDULengthAccepted */
8151 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
8153 /* segmentationSupported */
8154 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8155 "Segmentation Supported: ", BACnetSegmentation);
8158 return fVendorIdentifier (tvb, pinfo, tree, offset);
8162 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8164 /* BACnetDeviceIdentifier */
8165 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
8167 /* BACnetObjectIdentifier */
8168 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8171 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
8176 fWhoIsRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
8178 guint lastoffset = 0;
8180 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8181 lastoffset = offset;
8182 switch (fTagNo(tvb, offset)) {
8183 case 0: /* DeviceInstanceRangeLowLimit Optional */
8184 offset = fUnsignedTag (tvb, tree, offset, "Device Instance Range Low Limit: ");
8186 case 1: /* DeviceInstanceRangeHighLimit Optional but required if DeviceInstanceRangeLowLimit is there */
8187 offset = fUnsignedTag (tvb, tree, offset, "Device Instance Range High Limit: ");
8192 if (offset == lastoffset) break; /* nothing happened, exit loop */
8198 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8200 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8203 switch (service_choice) {
8204 case 0: /* I-Am-Request */
8205 offset = fIAmRequest (tvb, pinfo, tree, offset);
8207 case 1: /* i-Have Request */
8208 offset = fIHaveRequest (tvb, pinfo, tree, offset);
8210 case 2: /* unconfirmedCOVNotification */
8211 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8213 case 3: /* unconfirmedEventNotification */
8214 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8216 case 4: /* unconfirmedPrivateTransfer */
8217 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8219 case 5: /* unconfirmedTextMessage */
8220 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8222 case 6: /* timeSynchronization */
8223 offset = fTimeSynchronizationRequest (tvb, tree, offset);
8225 case 7: /* who-Has */
8226 offset = fWhoHas (tvb, pinfo, tree, offset);
8228 case 8: /* who-Is */
8229 offset = fWhoIsRequest (tvb, tree, offset);
8231 case 9: /* utcTimeSynchronization */
8232 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
8241 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
8242 gint *svc, proto_item **tt)
8245 proto_tree *bacapp_tree_control;
8246 gint tmp, bacapp_type;
8250 tmp = (gint) tvb_get_guint8(tvb, offset);
8251 bacapp_type = (tmp >> 4) & 0x0f;
8252 bacapp_flags = tmp & 0x0f;
8257 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
8258 if (bacapp_flags & 0x08)
8259 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
8261 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8262 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, TRUE);
8263 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
8265 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, TRUE);
8266 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, TRUE);
8267 if (ack == 0) /* The following are for ConfirmedRequest, not Complex ack */
8269 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, TRUE);
8270 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
8272 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
8276 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
8277 if (bacapp_flags & 0x08) {
8278 bacapp_seq = tvb_get_guint8(tvb, offset);
8279 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
8281 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
8284 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8290 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
8291 { /* BACnet-Confirmed-Request */
8292 /* ASHRAE 135-2001 20.1.2 */
8294 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
8298 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8299 { /* BACnet-Confirmed-Request */
8300 /* ASHRAE 135-2001 20.1.2 */
8304 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
8305 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
8309 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8310 { /* BACnet-Unconfirmed-Request-PDU */
8311 /* ASHRAE 135-2001 20.1.3 */
8315 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8317 tmp = tvb_get_guint8(tvb, offset);
8318 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
8320 /* Service Request follows... Variable Encoding 20.2ff */
8321 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
8325 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8326 { /* BACnet-Simple-Ack-PDU */
8327 /* ASHRAE 135-2001 20.1.4 */
8331 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8333 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8335 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8342 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
8343 { /* BACnet-Complex-Ack-PDU */
8344 /* ASHRAE 135-2001 20.1.5 */
8346 /* Service ACK follows... */
8347 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
8351 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8352 { /* BACnet-Complex-Ack-PDU */
8353 /* ASHRAE 135-2001 20.1.5 */
8357 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
8358 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
8362 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8363 { /* BACnet-SegmentAck-PDU */
8364 /* ASHRAE 135-2001 20.1.6 */
8367 proto_tree *bacapp_tree_control;
8369 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8370 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8372 proto_tree_add_item(bacapp_tree, hf_bacapp_NAK, tvb, offset, 1, TRUE);
8373 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8374 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8376 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
8378 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
8384 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8386 guint8 tag_info = 0;
8387 guint8 parsed_tag = 0;
8389 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8390 offset = fError(tvb, pinfo, tree, offset);
8391 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8395 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8397 guint lastoffset = 0;
8398 guint8 tag_no = 0, tag_info = 0;
8400 proto_tree *subtree = tree;
8403 while (tvb_reported_length_remaining(tvb, offset)) {
8404 /* exit loop if nothing happens inside */
8405 lastoffset = offset;
8406 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8408 case 0: /* errorType */
8409 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
8411 case 1: /* vendorID */
8412 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
8414 case 2: /* serviceNumber */
8415 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
8417 case 3: /* errorParameters */
8418 if (tag_is_opening(tag_info)) {
8419 tt = proto_tree_add_text(subtree, tvb, offset, 1,
8420 "error Parameters");
8421 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8422 propertyIdentifier = -1;
8423 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8424 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8425 } else if (tag_is_closing(tag_info)) {
8426 offset += fTagHeaderTree (tvb, subtree, offset,
8427 &tag_no, &tag_info, &lvt);
8430 /* error condition: let caller handle */
8437 if (offset == lastoffset) break; /* nothing happened, exit loop */
8443 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8445 guint lastoffset = 0;
8447 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8448 lastoffset = offset;
8449 switch (fTagNo(tvb, offset)) {
8450 case 0: /* errorType */
8451 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8453 case 1: /* firstFailedElementNumber */
8454 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
8459 if (offset == lastoffset) break; /* nothing happened, exit loop */
8465 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8467 /* Identical to CreateObjectError */
8468 return fCreateObjectError(tvb, pinfo, tree, offset);
8472 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8474 guint8 tag_no = 0, tag_info = 0;
8477 if (fTagNo(tvb, offset) == 0)
8480 offset = fContextTaggedError(tvb, pinfo, tree,offset);
8481 if (fTagNo(tvb, offset) == 1)
8483 /* listOfVTSessionIdentifiers [OPTIONAL] */
8484 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8485 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8486 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8489 /* should report bad packet if initial tag wasn't 0 */
8494 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8496 guint lastoffset = 0;
8497 guint8 tag_no = 0, tag_info = 0;
8500 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8501 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8502 lastoffset = offset;
8503 switch (fTagNo(tvb, offset)) {
8504 case 0: /* errorType */
8505 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8507 case 1: /* firstFailedWriteAttempt */
8508 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8509 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8510 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8515 if (offset == lastoffset) break; /* nothing happened, exit loop */
8521 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8523 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8524 "error Class: ", BACnetErrorClass, 64);
8525 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8526 "error Code: ", BACnetErrorCode, 256);
8530 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
8533 case 8: /* no break here !!!! */
8535 offset = fChangeListError (tvb, pinfo, tree, offset);
8538 offset = fCreateObjectError (tvb, pinfo, tree, offset);
8541 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
8544 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
8547 offset = fVTCloseError (tvb, pinfo, tree, offset);
8550 return fError (tvb, pinfo, tree, offset);
8556 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8557 { /* BACnet-Error-PDU */
8558 /* ASHRAE 135-2001 20.1.7 */
8560 proto_item *tc, *tt;
8561 proto_tree *bacapp_tree_control;
8564 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8565 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8567 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8569 tmp = tvb_get_guint8(tvb, offset);
8570 tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8572 /* Error Handling follows... */
8573 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
8577 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8578 { /* BACnet-Reject-PDU */
8579 /* ASHRAE 135-2001 20.1.8 */
8582 proto_tree *bacapp_tree_control;
8584 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8585 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8587 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8589 proto_tree_add_item(bacapp_tree, hf_BACnetRejectReason, tvb,
8595 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8596 { /* BACnet-Abort-PDU */
8597 /* ASHRAE 135-2001 20.1.9 */
8600 proto_tree *bacapp_tree_control;
8602 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8603 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8605 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8606 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8608 proto_tree_add_item(bacapp_tree, hf_BACnetAbortReason, tvb,
8614 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8616 guint8 flag, bacapp_type;
8619 flag = (gint) tvb_get_guint8(tvb, 0);
8620 bacapp_type = (flag >> 4) & 0x0f;
8622 if (tvb == NULL || tree == NULL) {
8626 /* ASHRAE 135-2001 20.1.1 */
8627 switch (bacapp_type) {
8628 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
8629 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
8631 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
8632 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
8634 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
8635 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
8637 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
8638 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
8640 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
8641 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
8643 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
8644 offset = fErrorPDU(tvb, pinfo, tree, offset);
8646 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
8647 offset = fRejectPDU(tvb, pinfo, tree, offset);
8649 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
8650 offset = fAbortPDU(tvb, pinfo, tree, offset);
8657 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8659 guint8 flag, bacapp_type;
8660 guint save_fragmented = FALSE, data_offset = 0, bacapp_apdu_size = fGetMaxAPDUSize(0), fragment = FALSE;
8661 tvbuff_t* new_tvb = NULL;
8663 guint8 bacapp_seqno = 0;
8664 guint8 bacapp_service, bacapp_reason, bacapp_prop_win_size;
8665 guint8 bacapp_invoke_id = 0;
8667 proto_tree *bacapp_tree = NULL;
8673 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
8674 col_clear (pinfo->cinfo, COL_INFO);
8676 flag = tvb_get_guint8(tvb, 0);
8677 bacapp_type = (flag >> 4) & 0x0f;
8679 /* show some descriptive text in the INFO column */
8680 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
8681 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
8683 switch (bacapp_type)
8685 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
8686 /* segmented messages have 2 additional bytes */
8687 if (flag & BACAPP_SEGMENTED_REQUEST)
8691 bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); /* has 16 values, reserved are 50 Bytes */
8692 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
8693 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
8694 bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4);
8695 bacapp_service = tvb_get_guint8(tvb, offset + 5);
8701 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
8702 bacapp_service = tvb_get_guint8(tvb, offset + 3);
8704 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
8705 val_to_str(bacapp_service,
8706 BACnetConfirmedServiceChoice,
8707 bacapp_unknown_service_str),bacapp_invoke_id);
8709 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
8710 bacapp_service = tvb_get_guint8(tvb, offset + 1);
8711 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
8712 val_to_str(bacapp_service,
8713 BACnetUnconfirmedServiceChoice,
8714 bacapp_unknown_service_str));
8716 case BACAPP_TYPE_SIMPLE_ACK:
8717 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8718 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8719 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8720 val_to_str(bacapp_service,
8721 BACnetConfirmedServiceChoice,
8722 bacapp_unknown_service_str), bacapp_invoke_id);
8724 case BACAPP_TYPE_COMPLEX_ACK:
8725 /* segmented messages have 2 additional bytes */
8726 if (flag & BACAPP_SEGMENTED_REQUEST)
8730 bacapp_apdu_size = fGetMaxAPDUSize(0); /* has minimum of 50 Bytes */
8731 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8732 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
8733 bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3);
8734 bacapp_service = tvb_get_guint8(tvb, offset + 4);
8739 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8740 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8742 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8743 val_to_str(bacapp_service,
8744 BACnetConfirmedServiceChoice,
8745 bacapp_unknown_service_str), bacapp_invoke_id);
8747 case BACAPP_TYPE_SEGMENT_ACK:
8748 /* nothing more to add */
8750 case BACAPP_TYPE_ERROR:
8751 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8752 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8753 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8754 val_to_str(bacapp_service,
8755 BACnetConfirmedServiceChoice,
8756 bacapp_unknown_service_str), bacapp_invoke_id);
8758 case BACAPP_TYPE_REJECT:
8759 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8760 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
8761 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8762 val_to_split_str(bacapp_reason,
8765 ASHRAE_Reserved_Fmt,
8766 Vendor_Proprietary_Fmt), bacapp_invoke_id);
8768 case BACAPP_TYPE_ABORT:
8769 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8770 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
8771 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8772 val_to_split_str(bacapp_reason,
8775 ASHRAE_Reserved_Fmt,
8776 Vendor_Proprietary_Fmt), bacapp_invoke_id);
8780 /* nothing more to add */
8784 save_fragmented = pinfo->fragmented;
8788 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, FALSE);
8789 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
8792 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
8794 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
8795 /* not resetting the offset so the remaining can be done */
8798 if (fragment) { /* fragmented */
8799 fragment_data *frag_msg = NULL;
8800 guint real_size = 0;
8803 pinfo->fragmented = TRUE;
8805 frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
8806 bacapp_invoke_id, /* ID for fragments belonging together */
8807 msg_fragment_table, /* list of message fragments */
8808 msg_reassembled_table, /* list of reassembled messages */
8809 bacapp_seqno, /* fragment sequence number */
8810 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
8811 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
8812 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
8813 "Reassembled BACapp", frag_msg, &msg_frag_items,
8816 if (new_tvb) { /* Reassembled */
8817 col_append_str(pinfo->cinfo, COL_INFO,
8818 " (Message Reassembled)");
8819 } else { /* Not last packet of reassembled Short Message */
8820 col_append_fstr(pinfo->cinfo, COL_INFO,
8821 " (Message fragment %u)", bacapp_seqno);
8823 if (new_tvb) { /* take it all */
8824 switch (bacapp_type)
8826 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
8827 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
8829 case BACAPP_TYPE_COMPLEX_ACK:
8830 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
8840 pinfo->fragmented = save_fragmented;
8845 bacapp_init_routine(void)
8847 fragment_table_init(&msg_fragment_table);
8848 reassembled_table_init(&msg_reassembled_table);
8852 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
8857 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
8858 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
8859 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
8862 g_iconv_close (icd);
8866 uni_to_string(in,*inbytesleft,out);
8867 out[*inbytesleft] = '\0';
8868 *outbytesleft -= *inbytesleft;
8875 uni_to_string(char * data, gsize str_length, char *dest_buf)
8879 gsize length_remaining = 0;
8881 length_remaining = str_length;
8887 for ( i = 0; i < (gint) str_length; i++ )
8890 if (c_char<0x20 || c_char>0x7e)
8895 dest_buf[i] = c_char & 0xff;
8905 dest_buf[i] = c_char & 0xff;
8909 if(length_remaining==0)
8911 dest_buf[i+1] = '\0';
8923 proto_register_bacapp(void)
8925 static hf_register_info hf[] = {
8927 { "APDU Type", "bacapp.type",
8928 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
8930 { &hf_bacapp_pduflags,
8931 { "PDU Flags", "bacapp.pduflags",
8932 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
8935 { "Segmented Request", "bacapp.segmented_request",
8936 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
8939 { "More Segments", "bacapp.more_segments",
8940 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
8943 { "SA", "bacapp.SA",
8944 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
8946 { &hf_bacapp_max_adpu_size,
8947 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
8948 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
8950 { &hf_bacapp_response_segments,
8951 { "Max Response Segments accepted", "bacapp.response_segments",
8952 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
8954 { &hf_bacapp_objectType,
8955 { "Object Type", "bacapp.objectType",
8956 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
8958 { &hf_bacapp_instanceNumber,
8959 { "Instance Number", "bacapp.instance_number",
8960 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
8962 { &hf_BACnetPropertyIdentifier,
8963 { "Property Identifier", "bacapp.property_identifier",
8964 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
8966 { &hf_BACnetVendorIdentifier,
8967 { "Vendor Identifier", "bacapp.vendor_identifier",
8968 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
8970 { &hf_BACnetRestartReason,
8971 { "Restart Reason", "bacapp.restart_reason",
8972 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
8974 { &hf_bacapp_invoke_id,
8975 { "Invoke ID", "bacapp.invoke_id",
8976 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
8978 { &hf_bacapp_sequence_number,
8979 { "Sequence Number", "bacapp.sequence_number",
8980 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
8982 { &hf_bacapp_window_size,
8983 { "Proposed Window Size", "bacapp.window_size",
8984 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
8986 { &hf_bacapp_service,
8987 { "Service Choice", "bacapp.confirmed_service",
8988 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
8990 { &hf_bacapp_uservice,
8991 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
8992 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
8995 { "NAK", "bacapp.NAK",
8996 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
8999 { "SRV", "bacapp.SRV",
9000 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
9002 { &hf_BACnetRejectReason,
9003 { "Reject Reason", "bacapp.reject_reason",
9004 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
9006 { &hf_BACnetAbortReason,
9007 { "Abort Reason", "bacapp.abort_reason",
9008 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
9011 { "BACnet APDU variable part:", "bacapp.variable_part",
9012 FT_NONE, BASE_NONE, NULL, 0, "BACnet APDU variable part", HFILL }
9017 FT_BYTES, BASE_NONE, NULL, 0,
9020 { &hf_BACnetApplicationTagNumber,
9021 { "Application Tag Number",
9022 "bacapp.application_tag_number",
9023 FT_UINT8, BASE_DEC, VALS(&BACnetApplicationTagNumber), 0xF0,
9026 { &hf_BACnetContextTagNumber,
9027 { "Context Tag Number",
9028 "bacapp.context_tag_number",
9029 FT_UINT8, BASE_DEC, NULL, 0xF0,
9032 { &hf_BACnetExtendedTagNumber,
9033 { "Extended Tag Number",
9034 "bacapp.extended_tag_number",
9035 FT_UINT8, BASE_DEC, NULL, 0,
9038 { &hf_BACnetNamedTag,
9041 FT_UINT8, BASE_DEC, VALS(&BACnetTagNames), 0x07,
9044 { &hf_BACnetCharacterSet,
9045 { "String Character Set",
9046 "bacapp.string_character_set",
9047 FT_UINT8, BASE_DEC, VALS(&BACnetCharacterSet),0,
9050 { &hf_BACnetTagClass,
9051 { "Tag Class", "bacapp.tag_class",
9052 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
9054 { &hf_bacapp_tag_lvt,
9055 { "Length Value Type",
9057 FT_UINT8, BASE_DEC, NULL, 0,
9060 { &hf_bacapp_tag_value8,
9062 "bacapp.tag_value8",
9063 FT_UINT8, BASE_DEC, NULL, 0,
9066 { &hf_bacapp_tag_value16,
9067 { "Tag Value 16-bit",
9068 "bacapp.tag_value16",
9069 FT_UINT16, BASE_DEC, NULL, 0,
9072 { &hf_bacapp_tag_value32,
9073 { "Tag Value 32-bit",
9074 "bacapp.tag_value32",
9075 FT_UINT32, BASE_DEC, NULL, 0,
9078 { &hf_bacapp_tag_ProcessId,
9079 { "ProcessIdentifier", "bacapp.processId",
9080 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
9082 { &hf_bacapp_tag_IPV4,
9083 { "IPV4", "bacapp.IPV4",
9084 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
9086 { &hf_bacapp_tag_IPV6,
9087 { "IPV6", "bacapp.IPV6",
9088 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
9090 { &hf_bacapp_tag_PORT,
9091 { "Port", "bacapp.Port",
9092 FT_UINT16, BASE_DEC, NULL, 0, "Port", HFILL }
9094 { &hf_bacapp_tag_initiatingObjectType,
9095 { "ObjectType", "bacapp.objectType",
9096 FT_UINT16, BASE_DEC, VALS(BACnetObjectType), 0x00, "Object Type", HFILL }
9099 {"Message fragments", "bacapp.fragments",
9100 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9102 {"Message fragment", "bacapp.fragment",
9103 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9104 {&hf_msg_fragment_overlap,
9105 {"Message fragment overlap", "bacapp.fragment.overlap",
9106 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9107 {&hf_msg_fragment_overlap_conflicts,
9108 {"Message fragment overlapping with conflicting data",
9109 "bacapp.fragment.overlap.conflicts",
9110 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9111 {&hf_msg_fragment_multiple_tails,
9112 {"Message has multiple tail fragments",
9113 "bacapp.fragment.multiple_tails",
9114 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9115 {&hf_msg_fragment_too_long_fragment,
9116 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
9117 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9118 {&hf_msg_fragment_error,
9119 {"Message defragmentation error", "bacapp.fragment.error",
9120 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9121 {&hf_msg_reassembled_in,
9122 {"Reassembled in", "bacapp.reassembled.in",
9123 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9124 {&hf_msg_reassembled_length,
9125 {"Reassembled BACapp length", "bacapp.reassembled.length",
9126 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
9128 static gint *ett[] = {
9130 &ett_bacapp_control,
9139 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
9140 "BACapp", "bacapp");
9142 proto_register_field_array(proto_bacapp, hf, array_length(hf));
9143 proto_register_subtree_array(ett, array_length(ett));
9144 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
9145 register_init_routine (&bacapp_init_routine);
9150 proto_reg_handoff_bacapp(void)
9152 data_handle = find_dissector("data");