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
6 * Enhanced by Felix Kraemer, 2010, <sauter-cumulus[AT]de.sauter-bc.com>,
7 * Sauter-Cumulus GmbH, Freiburg
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald[AT]wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * Copied from README.developer,v 1.23
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #include <epan/packet.h>
39 #include <epan/reassemble.h>
40 #include <epan/expert.h>
41 #include <epan/stats_tree.h>
42 #include "packet-bacapp.h"
44 static int bacapp_tap = -1;
46 /* formerly bacapp.h contains definitions and forward declarations */
49 #define FAULT proto_tree_add_text(subtree, tvb, offset, tvb_length(tvb) - offset, "something is going wrong here !!"); \
50 offset = tvb_length(tvb);
53 /* BACnet PDU Types */
54 #define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0
55 #define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1
56 #define BACAPP_TYPE_SIMPLE_ACK 2
57 #define BACAPP_TYPE_COMPLEX_ACK 3
58 #define BACAPP_TYPE_SEGMENT_ACK 4
59 #define BACAPP_TYPE_ERROR 5
60 #define BACAPP_TYPE_REJECT 6
61 #define BACAPP_TYPE_ABORT 7
62 #define MAX_BACAPP_TYPE 8
64 #define BACAPP_SEGMENTED_REQUEST 0x08
65 #define BACAPP_MORE_SEGMENTS 0x04
66 #define BACAPP_SEGMENTED_RESPONSE 0x02
67 #define BACAPP_SEGMENT_NAK 0x02
68 #define BACAPP_SENT_BY 0x01
72 * dissect_bacapp ::= CHOICE {
73 * confirmed-request-PDU [0] BACnet-Confirmed-Request-PDU,
74 * unconfirmed-request-PDU [1] BACnet-Unconfirmed-Request-PDU,
75 * simpleACK-PDU [2] BACnet-SimpleACK-PDU,
76 * complexACK-PDU [3] BACnet-ComplexACK-PDU,
77 * segmentACK-PDU [4] BACnet-SegmentACK-PDU,
78 * error-PDU [5] BACnet-Error-PDU,
79 * reject-PDU [6] BACnet-Reject-PDU,
80 * abort-PDU [7] BACnet-Abort-PDU
87 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
90 * ConfirmedRequest-PDU ::= SEQUENCE {
91 * pdu-type [0] Unsigned (0..15), -- 0 for this PDU Type
92 * segmentedMessage [1] BOOLEAN,
93 * moreFollows [2] BOOLEAN,
94 * segmented-response-accepted [3] BOOLEAN,
95 * reserved [4] Unsigned (0..3), -- must be set zero
96 * max-segments-accepted [5] Unsigned (0..7), -- as per 20.1.2.4
97 * max-APDU-length-accepted [5] Unsigned (0..15), -- as per 20.1.2.5
98 * invokeID [6] Unsigned (0..255),
99 * sequence-number [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
100 * proposed-window-size [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
101 * service-choice [9] BACnetConfirmedServiceChoice,
102 * service-request [10] BACnet-Confirmed-Service-Request OPTIONAL
108 * @return modified offset
111 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
118 * @param ack - indocates whether working on request or ack
119 * @param svc - output variable to return service choice
120 * @param tt - output varable to return service choice item
121 * @return modified offset
124 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 ack,
125 gint *svc, proto_item **tt);
128 * Unconfirmed-Request-PDU ::= SEQUENCE {
129 * pdu-type [0] Unsigned (0..15), -- 1 for this PDU type
130 * reserved [1] Unsigned (0..15), -- must be set zero
131 * service-choice [2] BACnetUnconfirmedServiceChoice,
132 * service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
138 * @return modified offset
141 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
144 * SimpleACK-PDU ::= SEQUENCE {
145 * pdu-type [0] Unsigned (0..15), -- 2 for this PDU type
146 * reserved [1] Unsigned (0..15), -- must be set zero
147 * invokeID [2] Unsigned (0..255),
148 * service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
154 * @return modified offset
157 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
160 * ComplexACK-PDU ::= SEQUENCE {
161 * pdu-type [0] Unsigned (0..15), -- 3 for this PDU Type
162 * segmentedMessage [1] BOOLEAN,
163 * moreFollows [2] BOOLEAN,
164 * reserved [3] Unsigned (0..3), -- must be set zero
165 * invokeID [4] Unsigned (0..255),
166 * sequence-number [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
167 * proposed-window-size [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
168 * service-ACK-choice [7] BACnetConfirmedServiceChoice,
169 * service-ACK [8] BACnet-Confirmed-Service-Request -- Context-specific tags 0..8 are NOT used in header encoding
175 * @return modified offset
178 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
181 * SegmentACK-PDU ::= SEQUENCE {
182 * pdu-type [0] Unsigned (0..15), -- 4 for this PDU Type
183 * reserved [1] Unsigned (0..3), -- must be set zero
184 * negative-ACK [2] BOOLEAN,
185 * server [3] BOOLEAN,
186 * original-invokeID [4] Unsigned (0..255),
187 * sequence-number [5] Unsigned (0..255),
188 * actual-window-size [6] Unsigned (0..127)
194 * @return modified offset
197 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
200 * Error-PDU ::= SEQUENCE {
201 * pdu-type [0] Unsigned (0..15), -- 5 for this PDU Type
202 * reserved [1] Unsigned (0..3), -- must be set zero
203 * original-invokeID [2] Unsigned (0..255),
204 * error-choice [3] BACnetConfirmedServiceChoice,
205 * error [4] BACnet-Error
211 * @return modified offset
214 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
217 * Reject-PDU ::= SEQUENCE {
218 * pdu-type [0] Unsigned (0..15), -- 6 for this PDU Type
219 * reserved [1] Unsigned (0..3), -- must be set zero
220 * original-invokeID [2] Unsigned (0..255),
221 * reject-reason [3] BACnetRejectReason
227 * @return modified offset
230 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
233 * Abort-PDU ::= SEQUENCE {
234 * pdu-type [0] Unsigned (0..15), -- 7 for this PDU Type
235 * reserved [1] Unsigned (0..3), -- must be set zero
236 * server [2] BOOLEAN,
237 * original-invokeID [3] Unsigned (0..255),
238 * abort-reason [4] BACnetAbortReason
244 * @return modified offset
247 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
250 * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree
255 * @return modified offset
258 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
261 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
266 * @return modified offset
269 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
272 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
277 * @param lvt length of String
278 * @return modified offset
281 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
284 * 20.2.12, adds the label with Date Value to tree
289 * @return modified offset
292 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
295 * 20.2.13, adds the label with Time Value to tree
300 * @return modified offset
303 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
306 * 20.2.14, adds Object Identifier to tree
307 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
312 * @return modified offset
315 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
318 * BACnet-Confirmed-Service-Request ::= CHOICE {
324 * @param service_choice
328 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
331 * BACnet-Confirmed-Service-ACK ::= CHOICE {
337 * @param service_choice
341 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
344 * AcknowledgeAlarm-Request ::= SEQUENCE {
345 * acknowledgingProcessIdentifier [0] Unsigned32,
346 * eventObjectIdentifier [1] BACnetObjectIdentifer,
347 * eventStateAcknowledge [2] BACnetEventState,
348 * timeStamp [3] BACnetTimeStamp,
349 * acknowledgementSource [4] Character String,
350 * timeOfAcknowledgement [5] BACnetTimeStamp
356 * @return modified offset
359 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
362 * ConfirmedCOVNotification-Request ::= SEQUENCE {
363 * subscriberProcessIdentifier [0] Unsigned32,
364 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
365 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
366 * timeRemaining [3] unsigned,
367 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
373 * @return modified offset
376 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
379 * ConfirmedEventNotification-Request ::= SEQUENCE {
380 * ProcessIdentifier [0] Unsigned32,
381 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
382 * eventObjectIdentifier [2] BACnetObjectIdentifer,
383 * timeStamp [3] BACnetTimeStamp,
384 * notificationClass [4] unsigned,
385 * priority [5] unsigned8,
386 * eventType [6] BACnetEventType,
387 * messageText [7] CharacterString OPTIONAL,
388 * notifyType [8] BACnetNotifyType,
389 * ackRequired [9] BOOLEAN OPTIONAL,
390 * fromState [10] BACnetEventState OPTIONAL,
391 * toState [11] BACnetEventState,
392 * eventValues [12] BACnetNotificationParameters OPTIONAL
398 * @return modified offset
401 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
404 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
405 * objectIdentifier BACnetObjectIdentifer,
406 * alarmState BACnetEventState,
407 * acknowledgedTransitions BACnetEventTransitionBits
413 * @return modified offset
416 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
419 * GetEnrollmentSummary-Request ::= SEQUENCE {
420 * acknowledgmentFilter [0] ENUMERATED {
425 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
426 * eventStateFilter [2] ENUMERATED {
433 * eventTypeFilter [3] BACnetEventType OPTIONAL,
434 * priorityFilter [4] SEQUENCE {
435 * minPriority [0] Unsigned8,
436 * maxPriority [1] Unsigned8
438 * notificationClassFilter [5] Unsigned OPTIONAL
444 * @return modified offset
447 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
450 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
451 * objectIdentifier BACnetObjectIdentifer,
452 * eventType BACnetEventType,
453 * eventState BACnetEventState,
454 * priority Unsigned8,
455 * notificationClass Unsigned OPTIONAL
461 * @return modified offset
464 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
467 * GetEventInformation-Request ::= SEQUENCE {
468 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
474 * @return modified offset
477 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
480 * GetEventInformation-ACK ::= SEQUENCE {
481 * listOfEventSummaries [0] listOfEventSummaries,
482 * moreEvents [1] BOOLEAN
488 * @return modified offset
491 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
494 * LifeSafetyOperation-Request ::= SEQUENCE {
495 * requestingProcessIdentifier [0] Unsigned32
496 * requestingSource [1] CharacterString
497 * request [2] BACnetLifeSafetyOperation
498 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
504 * @return modified offset
507 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
510 * SubscribeCOV-Request ::= SEQUENCE {
511 * subscriberProcessIdentifier [0] Unsigned32
512 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
513 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
514 * lifetime [3] Unsigned OPTIONAL
522 * @return modified offset
525 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
528 * SubscribeCOVProperty-Request ::= SEQUENCE {
529 * subscriberProcessIdentifier [0] Unsigned32
530 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
531 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
532 * lifetime [3] Unsigned OPTIONAL
533 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
534 * covIncrement [5] Unsigned OPTIONAL
540 * @return modified offset
543 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
546 * AtomicReadFile-Request ::= SEQUENCE {
547 * fileIdentifier BACnetObjectIdentifier,
548 * accessMethod CHOICE {
549 * streamAccess [0] SEQUENCE {
550 * fileStartPosition INTEGER,
551 * requestedOctetCount Unsigned
553 * recordAccess [1] SEQUENCE {
554 * fileStartRecord INTEGER,
555 * requestedRecordCount Unsigned
563 * @return modified offset
566 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
569 * AtomicWriteFile-ACK ::= SEQUENCE {
571 * accessMethod CHOICE {
572 * streamAccess [0] SEQUENCE {
573 * fileStartPosition INTEGER,
574 * fileData OCTET STRING
576 * recordAccess [1] SEQUENCE {
577 * fileStartRecord INTEGER,
578 * returnedRecordCount Unsigned,
579 * fileRecordData SEQUENCE OF OCTET STRING
587 * @return modified offset
590 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
593 * AtomicWriteFile-Request ::= SEQUENCE {
594 * fileIdentifier BACnetObjectIdentifier,
595 * accessMethod CHOICE {
596 * streamAccess [0] SEQUENCE {
597 * fileStartPosition INTEGER,
598 * fileData OCTET STRING
600 * recordAccess [1] SEQUENCE {
601 * fileStartRecord INTEGER,
602 * recordCount Unsigned,
603 * fileRecordData SEQUENCE OF OCTET STRING
611 * @return modified offset
614 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
617 * AtomicWriteFile-ACK ::= SEQUENCE {
618 * fileStartPosition [0] INTEGER,
619 * fileStartRecord [1] INTEGER,
624 * @return modified offset
627 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
630 * AddListElement-Request ::= SEQUENCE {
631 * objectIdentifier [0] BACnetObjectIdentifier,
632 * propertyIdentifier [1] BACnetPropertyIdentifier,
633 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
634 * listOfElements [3] ABSTRACT-SYNTAX.&Type
640 * @return modified offset
643 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
646 * CreateObject-Request ::= SEQUENCE {
647 * objectSpecifier [0] ObjectSpecifier,
648 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
654 * @return modified offset
657 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
660 * CreateObject-Request ::= BACnetObjectIdentifier
665 * @return modified offset
668 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
671 * DeleteObject-Request ::= SEQUENCE {
672 * ObjectIdentifier BACnetObjectIdentifer
678 * @return modified offset
681 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
684 * ReadProperty-Request ::= SEQUENCE {
685 * objectIdentifier [0] BACnetObjectIdentifier,
686 * propertyIdentifier [1] BACnetPropertyIdentifier,
687 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
693 * @return modified offset
696 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
699 * ReadProperty-ACK ::= SEQUENCE {
700 * objectIdentifier [0] BACnetObjectIdentifier,
701 * propertyIdentifier [1] BACnetPropertyIdentifier,
702 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
703 * propertyValue [3] ABSTRACT-SYNTAX.&Type
709 * @return modified offset
712 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
715 * ReadPropertyConditional-Request ::= SEQUENCE {
716 * objectSelectionCriteria [0] objectSelectionCriteria,
717 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
723 * @return modified offset
726 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
729 * ReadPropertyConditional-ACK ::= SEQUENCE {
730 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
736 * @return modified offset
739 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
742 * ReadPropertyMultiple-Request ::= SEQUENCE {
743 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
749 * @return offset modified
752 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
755 * ReadPropertyMultiple-Ack ::= SEQUENCE {
756 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
762 * @return offset modified
765 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
768 * ReadRange-Request ::= SEQUENCE {
769 * objectIdentifier [0] BACnetObjectIdentifier,
770 * propertyIdentifier [1] BACnetPropertyIdentifier,
771 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
773 * byPosition [3] SEQUENCE {
774 * referencedIndex Unsigned,
777 * byTime [4] SEQUENCE {
778 * referenceTime BACnetDateTime,
781 * timeRange [5] SEQUENCE {
782 * beginningTime BACnetDateTime,
783 * endingTime BACnetDateTime
791 * @return modified offset
794 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
797 * ReadRange-ACK ::= SEQUENCE {
798 * objectIdentifier [0] BACnetObjectIdentifier,
799 * propertyIdentifier [1] BACnetPropertyIdentifier,
800 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
801 * resultFlags [3] BACnetResultFlags,
802 * itemCount [4] Unsigned,
803 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
809 * @return modified offset
812 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
815 * RemoveListElement-Request ::= SEQUENCE {
816 * objectIdentifier [0] BACnetObjectIdentifier,
817 * propertyIdentifier [1] BACnetPropertyIdentifier,
818 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
819 * listOfElements [3] ABSTRACT-SYNTAX.&Type
825 * @return modified offset
828 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
831 * WriteProperty-Request ::= SEQUENCE {
832 * objectIdentifier [0] BACnetObjectIdentifier,
833 * propertyIdentifier [1] BACnetPropertyIdentifier,
834 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
835 * propertyValue [3] ABSTRACT-SYNTAX.&Type
836 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
842 * @return modified offset
845 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
848 * WritePropertyMultiple-Request ::= SEQUENCE {
849 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
855 * @return modified offset
858 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
861 * DeviceCommunicationControl-Request ::= SEQUENCE {
862 * timeDuration [0] Unsigned16 OPTIONAL,
863 * enable-disable [1] ENUMERATED {
867 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
872 * @return modified offset
875 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
878 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
879 * vendorID [0] Unsigned,
880 * serviceNumber [1] Unsigned,
881 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
887 * @return modified offset
890 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
893 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
894 * vendorID [0] Unsigned,
895 * serviceNumber [1] Unsigned,
896 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
902 * @return modified offset
905 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
908 * ConfirmedTextMessage-Request ::= SEQUENCE {
909 * textMessageSourceDevice [0] BACnetObjectIdentifier,
910 * messageClass [1] CHOICE {
911 * numeric [0] Unsigned,
912 * character [1] CharacterString
914 * messagePriority [2] ENUMERATED {
918 * message [3] CharacterString
924 * @return modified offset
927 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
930 * ReinitializeDevice-Request ::= SEQUENCE {
931 * reinitializedStateOfDevice [0] ENUMERATED {
940 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
945 * @return modified offset
948 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
951 * VTOpen-Request ::= SEQUENCE {
952 * vtClass BACnetVTClass,
953 * localVTSessionIdentifier Unsigned8
959 * @return modified offset
962 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
965 * VTOpen-ACK ::= SEQUENCE {
966 * remoteVTSessionIdentifier Unsigned8
972 * @return modified offset
975 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
978 * VTClose-Request ::= SEQUENCE {
979 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
985 * @return modified offset
988 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
991 * VTData-Request ::= SEQUENCE {
992 * vtSessionIdentifier Unsigned8,
993 * vtNewData OCTET STRING,
994 * vtDataFlag Unsigned (0..1)
1000 * @return modified offset
1003 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1006 * VTData-ACK ::= SEQUENCE {
1007 * allNewDataAccepted [0] BOOLEAN,
1008 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1013 * @return modified offset
1016 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
1019 * Authenticate-Request ::= SEQUENCE {
1020 * pseudoRandomNumber [0] Unsigned32,
1021 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1022 * operatorName [2] CharacterString OPTIONAL,
1023 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1024 * startEncypheredSession [4] BOOLEAN OPTIONAL
1029 * @return modified offset
1032 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1035 * Authenticate-ACK ::= SEQUENCE {
1036 * modifiedRandomNumber Unsigned32,
1042 * @return modified offset
1045 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1048 * RequestKey-Request ::= SEQUENCE {
1049 * requestingDeviceIdentifier BACnetObjectIdentifier,
1050 * requestingDeviceAddress BACnetAddress,
1051 * remoteDeviceIdentifier BACnetObjectIdentifier,
1052 * remoteDeviceAddress BACnetAddress
1058 * @return modified offset
1061 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1064 * Unconfirmed-Service-Request ::= CHOICE {
1070 * @param service_choice
1071 * @return modified offset
1074 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1077 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1078 * subscriberProcessIdentifier [0] Unsigned32,
1079 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1080 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1081 * timeRemaining [3] unsigned,
1082 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1088 * @return modified offset
1091 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1094 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1095 * ProcessIdentifier [0] Unsigned32,
1096 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1097 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1098 * timeStamp [3] BACnetTimeStamp,
1099 * notificationClass [4] unsigned,
1100 * priority [5] unsigned8,
1101 * eventType [6] BACnetEventType,
1102 * messageText [7] CharacterString OPTIONAL,
1103 * notifyType [8] BACnetNotifyType,
1104 * ackRequired [9] BOOLEAN OPTIONAL,
1105 * fromState [10] BACnetEventState OPTIONAL,
1106 * toState [11] BACnetEventState,
1107 * eventValues [12] BACnetNotificationParameters OPTIONAL
1113 * @return modified offset
1116 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1119 * I-Am-Request ::= SEQUENCE {
1120 * aAmDeviceIdentifier BACnetObjectIdentifier,
1121 * maxAPDULengthAccepted Unsigned,
1122 * segmentationSupported BACnetSegmentation,
1129 * @return modified offset
1132 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1136 * I-Have-Request ::= SEQUENCE {
1137 * deviceIdentifier BACnetObjectIdentifier,
1138 * objectIdentifier BACnetObjectIdentifier,
1139 * objectName CharacterString
1145 * @return modified offset
1148 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1151 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1152 * vendorID [0] Unsigned,
1153 * serviceNumber [1] Unsigned,
1154 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1160 * @return modified offset
1163 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1166 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1167 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1168 * messageClass [1] CHOICE {
1169 * numeric [0] Unsigned,
1170 * character [1] CharacterString
1172 * messagePriority [2] ENUMERATED {
1176 * message [3] CharacterString
1182 * @return modified offset
1185 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1188 * TimeSynchronization-Request ::= SEQUENCE {
1194 * @return modified offset
1197 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1200 * UTCTimeSynchronization-Request ::= SEQUENCE {
1206 * @return modified offset
1209 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1212 * Who-Has-Request ::= SEQUENCE {
1214 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1215 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1218 * objectIdentifier [2] BACnetObjectIdentifier,
1219 * objectName [3] CharacterString
1226 * @return modified offset
1229 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1232 * Who-Is-Request ::= SEQUENCE {
1233 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1234 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1239 * @return modified offset
1242 fWhoIsRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1245 * BACnet-Error ::= CHOICE {
1246 * addListElement [8] ChangeList-Error,
1247 * removeListElement [9] ChangeList-Error,
1248 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1249 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1250 * vtClose [22] VTClose-Error,
1251 * readRange [26] ObjectAccessService-Error
1259 * @return modified offset
1262 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1265 * Dissect a BACnetError in a context tag
1271 * @return modified offset
1273 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1276 * ChangeList-Error ::= SEQUENCE {
1277 * errorType [0] Error,
1278 * firstFailedElementNumber [1] Unsigned
1285 * @return modified offset
1288 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1291 * CreateObject-Error ::= SEQUENCE {
1292 * errorType [0] Error,
1293 * firstFailedElementNumber [1] Unsigned
1300 * @return modified offset
1303 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1306 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1307 * errorType [0] Error,
1308 * vendorID [1] Unsigned,
1309 * serviceNumber [2] Unsigned,
1310 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1317 * @return modified offset
1320 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1323 * WritePropertyMultiple-Error ::= SEQUENCE {
1324 * errorType [0] Error,
1325 * firstFailedWriteAttempt [1] Unsigned
1332 * @return modified offset
1335 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1338 * VTClose-Error ::= SEQUENCE {
1339 * errorType [0] Error,
1340 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1347 * @return modified offset
1350 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1353 * BACnet Application Types chapter 20.2.1
1359 * @return modified offset
1362 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1365 * BACnetActionCommand ::= SEQUENCE {
1366 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1367 * objectIdentifier [1] BACnetObjectIdentifier,
1368 * propertyIdentifier [2] BACnetPropertyIdentifier,
1369 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1370 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1371 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1372 * postDelay [6] Unsigned OPTIONAL,
1373 * quitOnFailure [7] BOOLEAN,
1374 * writeSuccessful [8] BOOLEAN
1380 * @param matching tag number
1381 * @return modified offset
1384 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1387 * BACnetActionList ::= SEQUENCE {
1388 * action [0] SEQUENCE of BACnetActionCommand
1394 * @return modified offset
1397 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1399 /** BACnetAddress ::= SEQUENCE {
1400 * network-number Unsigned16, -- A value 0 indicates the local network
1401 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1406 * @return modified offset
1409 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset);
1412 * BACnetAddressBinding ::= SEQUENCE {
1413 * deviceObjectID BACnetObjectIdentifier
1414 * deviceAddress BacnetAddress
1420 * @return modified offset
1423 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1426 * BACnetCalendaryEntry ::= CHOICE {
1428 * dateRange [1] BACnetDateRange,
1429 * weekNDay [2] BacnetWeekNday
1434 * @return modified offset
1437 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset);
1440 * BACnetClientCOV ::= CHOICE {
1441 * real-increment REAL,
1442 * default-increment NULL
1447 * @return modified offset
1450 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1454 * BACnetDailySchedule ::= SEQUENCE {
1455 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1461 * @return modified offset
1464 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1467 * BACnetWeeklySchedule ::= SEQUENCE {
1468 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1474 * @return modified offset
1477 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1480 * BACnetDateRange ::= SEQUENCE {
1487 * @return modified offset
1490 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset);
1493 * BACnetDateTime ::= SEQUENCE {
1501 * @return modified offset
1504 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1507 * BACnetDestination ::= SEQUENCE {
1508 * validDays BACnetDaysOfWeek,
1511 * recipient BACnetRecipient,
1512 * processIdentifier Unsigned32,
1513 * issueConfirmedNotifications BOOLEAN,
1514 * transitions BACnetEventTransitionBits
1520 * @return modified offset
1523 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1526 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1527 * objectIdentifier [0] BACnetObjectIdentifier,
1528 * propertyIdentifier [1] BACnetPropertyIdentifier,
1529 * propertyArrayIndex [2] Unsigend OPTIONAL,
1530 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1536 * @return modified offset
1539 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1542 * BACnetDeviceObjectReference ::= SEQUENCE {
1543 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1544 * objectIdentifier [1] BACnetObjectIdentifier
1550 * @return modified offset
1553 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1557 * BACnetEventParameter ::= CHOICE {
1558 * change-of-bitstring [0] SEQUENCE {
1559 * time-delay [0] Unsigned,
1560 * bitmask [1] BIT STRING,
1561 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1563 * change-of-state [1] SEQUENCE {
1564 * time-delay [0] Unsigned,
1565 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1567 * change-of-value [2] SEQUENCE {
1568 * time-delay [0] Unsigned,
1569 * cov-criteria [1] CHOICE {
1570 * bitmask [0] BIT STRING,
1571 * referenced-property-increment [1] REAL
1574 * command-failure [3] SEQUENCE {
1575 * time-delay [0] Unsigned,
1576 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1578 * floating-limit [4] SEQUENCE {
1579 * time-delay [0] Unsigned,
1580 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1581 * low-diff-limit [2] REAL,
1582 * high-diff-limit [3] REAL,
1585 * out-of-range [5] SEQUENCE {
1586 * time-delay [0] Unsigned,
1587 * low-limit [1] REAL,
1588 * high-limit [2] REAL,
1591 * buffer-ready [7] SEQUENCE {
1592 * notification-threshold [0] Unsigned,
1593 * previous-notification-count [1] Unsigned32
1595 * change-of-life-safety [8] SEQUENCE {
1596 * time-delay [0] Unsigned,
1597 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1598 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1599 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1605 * @return modified offset
1608 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset);
1614 * BACnetLogRecord ::= SEQUENCE {
1615 * timestamp [0] BACnetDateTime,
1616 * logDatum [1] CHOICE {
1617 * log-status [0] BACnetLogStatus,
1618 * boolean-value [1] BOOLEAN,
1619 * real-value [2] REAL,
1620 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1621 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1622 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1623 * bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
1624 * null-value [7] NULL,
1625 * failure [8] Error,
1626 * time-change [9] REAL,
1627 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1629 * statusFlags [2] BACnetStatusFlags OPTIONAL
1635 * @return modified offset
1638 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1642 * BACnetNotificationParameters ::= CHOICE {
1643 * change-of-bitstring [0] SEQUENCE {
1644 * referenced-bitstring [0] BIT STRING,
1645 * status-flags [1] BACnetStatusFlags
1647 * change-of-state [1] SEQUENCE {
1648 * new-state [0] BACnetPropertyStatus,
1649 * status-flags [1] BACnetStatusFlags
1651 * change-of-value [2] SEQUENCE {
1652 * new-value [0] CHOICE {
1653 * changed-bits [0] BIT STRING,
1654 * changed-value [1] REAL
1656 * status-flags [1] BACnetStatusFlags
1658 * command-failure [3] SEQUENCE {
1659 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1660 * status-flags [1] BACnetStatusFlags
1661 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1663 * floating-limit [4] SEQUENCE {
1664 * reference-value [0] REAL,
1665 * status-flags [1] BACnetStatusFlags
1666 * setpoint-value [2] REAL,
1667 * error-limit [3] REAL
1669 * out-of-range [5] SEQUENCE {
1670 * exceeding-value [0] REAL,
1671 * status-flags [1] BACnetStatusFlags
1672 * deadband [2] REAL,
1673 * exceeded-limit [0] REAL
1675 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1676 * buffer-ready [7] SEQUENCE {
1677 * buffer-device [0] BACnetObjectIdentifier,
1678 * buffer-object [1] BACnetObjectIdentifier
1679 * previous-notification [2] BACnetDateTime,
1680 * current-notification [3] BACnetDateTime
1682 * change-of-life-safety [8] SEQUENCE {
1683 * new-state [0] BACnetLifeSafetyState,
1684 * new-mode [1] BACnetLifeSafetyState
1685 * status-flags [2] BACnetStatusFlags,
1686 * operation-expected [3] BACnetLifeSafetyOperation
1693 * @return modified offset
1696 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1699 * BACnetObjectPropertyReference ::= SEQUENCE {
1700 * objectIdentifier [0] BACnetObjectIdentifier,
1701 * propertyIdentifier [1] BACnetPropertyIdentifier,
1702 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1708 * @return modified offset
1711 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1715 * BACnetObjectPropertyValue ::= SEQUENCE {
1716 * objectIdentifier [0] BACnetObjectIdentifier,
1717 * propertyIdentifier [1] BACnetPropertyIdentifier,
1718 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1719 * -- if omitted with an array the entire array is referenced
1720 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1721 * priority [4] Unsigned (1..16) OPTIONAL
1726 * @return modified offset
1729 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
1733 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1738 * @return modified offset
1741 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1744 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1747 * BACnetPropertyReference ::= SEQUENCE {
1748 * propertyIdentifier [0] BACnetPropertyIdentifier,
1749 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1755 * @return modified offset
1758 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1761 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1764 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1767 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1770 * BACnetPropertyValue ::= SEQUENCE {
1771 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1772 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1773 * -- if omitted with an array the entire array is referenced
1774 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1775 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1781 * @return modified offset
1784 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1787 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1790 * BACnet Application PDUs chapter 21
1791 * BACnetRecipient::= CHOICE {
1792 * device [0] BACnetObjectIdentifier
1793 * address [1] BACnetAddress
1799 * @return modified offset
1802 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1805 * BACnet Application PDUs chapter 21
1806 * BACnetRecipientProcess::= SEQUENCE {
1807 * recipient [0] BACnetRecipient
1808 * processID [1] Unsigned32
1814 * @return modified offset
1817 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1820 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1824 * BACnetSessionKey ::= SEQUENCE {
1825 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1826 * peerAddress BACnetAddress
1831 * @return modified offset
1832 * @todo check if checksum is displayed correctly
1835 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1839 * BACnetSpecialEvent ::= SEQUENCE {
1841 * calendarEntry [0] BACnetCalendarEntry,
1842 * calendarRefernce [1] BACnetObjectIdentifier
1844 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1845 * eventPriority [3] Unsigned (1..16)
1851 * @return modified offset
1854 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1857 * BACnetTimeStamp ::= CHOICE {
1859 * sequenceNumber [1] Unsigned (0..65535),
1860 * dateTime [2] BACnetDateTime
1866 * @return modified offset
1869 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1872 * BACnetTimeValue ::= SEQUENCE {
1874 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1880 * @return modified offset
1883 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1887 * BACnetVTSession ::= SEQUENCE {
1888 * local-vtSessionID Unsigned8,
1889 * remote-vtSessionID Unsigned8,
1890 * remote-vtAddress BACnetAddress
1895 * @return modified offset
1898 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1902 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1903 * -- first octet month (1..12) January = 1, X'FF' = any month
1904 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1905 * -- 2 = days numbered 8-14
1906 * -- 3 = days numbered 15-21
1907 * -- 4 = days numbered 22-28
1908 * -- 5 = days numbered 29-31
1909 * -- 6 = last 7 days of this month
1910 * -- X'FF' = any week of this month
1911 * -- third octet dayOfWeek (1..7) where 1 = Monday
1913 * -- X'FF' = any day of week
1917 * @return modified offset
1920 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
1923 * ReadAccessResult ::= SEQUENCE {
1924 * objectIdentifier [0] BACnetObjectIdentifier,
1925 * listOfResults [1] SEQUENCE OF SEQUENCE {
1926 * propertyIdentifier [2] BACnetPropertyIdentifier,
1927 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1928 * readResult CHOICE {
1929 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1930 * propertyAccessError [5] Error
1938 * @return modified offset
1941 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1944 * ReadAccessSpecification ::= SEQUENCE {
1945 * objectIdentifier [0] BACnetObjectIdentifier,
1946 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
1952 * @return modified offset
1955 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1958 * WriteAccessSpecification ::= SEQUENCE {
1959 * objectIdentifier [0] BACnetObjectIdentifier,
1960 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
1966 * @return modified offset
1969 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1972 /********************************************************* Helper functions *******************************************/
1975 * extracts the tag number from the tag header.
1976 * @param tvb "TestyVirtualBuffer"
1977 * @param offset in actual tvb
1978 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
1981 fTagNo (tvbuff_t *tvb, guint offset);
1984 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
1985 * @param tvb = "TestyVirtualBuffer"
1986 * @param offset = offset in actual tvb
1987 * @return tag_no BACnet 20.2.1.2 Tag Number
1988 * @return class_tag BACnet 20.2.1.1 Class
1989 * @return lvt BACnet 20.2.1.3 Length/Value/Type
1990 * @return offs = length of this header
1994 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
1998 * adds processID with max 32Bit unsigned Integer Value to tree
2002 * @return modified offset
2005 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
2008 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2012 * @return modified offset
2015 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2018 * BACnet Application PDUs chapter 21
2019 * BACnetPropertyIdentifier::= ENUMERATED {
2020 * @see bacapp_property_identifier
2026 * @param tt returnvalue of this item
2027 * @return modified offset
2030 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2033 * BACnet Application PDUs chapter 21
2034 * BACnetPropertyArrayIndex::= ENUMERATED {
2035 * @see bacapp_property_array_index
2040 * @param tt returnvalue of this item
2041 * @return modified offset
2044 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
2047 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2048 * objectIdentifier [0] BACnetObjectIdentifier,
2049 * eventState [1] BACnetEventState,
2050 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2051 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2052 * notifyType [4] BACnetNotifyType,
2053 * eventEnable [5] BACnetEventTransitionBits,
2054 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2060 * @return modified offset
2063 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2066 * SelectionCriteria ::= SEQUENCE {
2067 * propertyIdentifier [0] BACnetPropertyIdentifier,
2068 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2069 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2070 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2076 * @return modified offset
2079 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2082 * objectSelectionCriteria ::= SEQUENCE {
2083 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2084 * listOfSelectionCriteria [1] SelectionCriteria
2090 * @return modified offset
2093 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2096 * BACnet-Error ::= SEQUENCE {
2097 * error-class ENUMERATED {},
2098 * error-code ENUMERATED {}
2105 * @return modified offset
2108 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2111 * Generic handler for context tagged values. Mostly for handling
2112 * vendor-defined properties and services.
2116 * @return modified offset
2117 * @todo beautify this ugly construct
2120 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2123 * realizes some ABSTRACT-SYNTAX.&Type
2128 * @return modified offset
2129 * @todo beautify this ugly construct
2132 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2136 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2137 const value_string *src);
2143 proto_register_bacapp(void);
2146 * proto_reg_handoff_bacapp
2149 proto_reg_handoff_bacapp(void);
2152 * converts XXX coded strings to UTF-8
2153 * else 'in' is copied to 'out'
2154 * @param in -- pointer to string
2155 * @param inbytesleft
2156 * @param out -- pointer to string
2157 * @param outbytesleft
2159 * @return count of modified characters of returned string, -1 for errors
2162 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2165 uni_to_string(char * data, gsize str_length, char *dest_buf);
2167 /* <<<< formerly bacapp.h */
2169 /* some hashes for segmented messages */
2170 static GHashTable *msg_fragment_table = NULL;
2171 static GHashTable *msg_reassembled_table = NULL;
2173 /* some necessary forward function prototypes */
2175 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2176 const gchar *label, const value_string *vs);
2178 static const char *bacapp_unknown_service_str = "unknown service";
2179 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2180 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2182 static const value_string
2183 BACnetTypeName[] = {
2184 {0, "Confirmed-REQ"},
2185 {1, "Unconfirmed-REQ"},
2195 static const true_false_string segments_follow = {
2196 "Segmented Request",
2197 "Unsegmented Request"
2200 static const true_false_string more_follow = {
2201 "More Segments Follow",
2202 "No More Segments Follow"
2205 static const true_false_string segmented_accept = {
2206 "Segmented Response accepted",
2207 "Segmented Response not accepted"
2210 static const true_false_string
2212 "Context Specific Tag",
2216 static const value_string
2217 BACnetMaxSegmentsAccepted [] = {
2225 {7,"Greater than 64 segments"},
2229 static const value_string
2230 BACnetMaxAPDULengthAccepted [] = {
2231 {0,"Up to MinimumMessageSize (50 octets)"},
2232 {1,"Up to 128 octets"},
2233 {2,"Up to 206 octets (fits in a LonTalk frame)"},
2234 {3,"Up to 480 octets (fits in an ARCNET frame)"},
2235 {4,"Up to 1024 octets"},
2236 {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2237 {6,"reserved by ASHRAE"},
2238 {7,"reserved by ASHRAE"},
2239 {8,"reserved by ASHRAE"},
2240 {9,"reserved by ASHRAE"},
2241 {10,"reserved by ASHRAE"},
2242 {11,"reserved by ASHRAE"},
2243 {12,"reserved by ASHRAE"},
2244 {13,"reserved by ASHRAE"},
2245 {14,"reserved by ASHRAE"},
2246 {15,"reserved by ASHRAE"},
2250 static const value_string
2251 BACnetRejectReason [] = {
2253 {1,"buffer-overflow"},
2254 {2,"inconsistent-parameters"},
2255 {3,"invalid-parameter-data-type"},
2257 {5,"missing-required-parameter"},
2258 {6,"parameter-out-of-range"},
2259 {7,"too-many-arguments"},
2260 {8,"undefined-enumeration"},
2261 {9,"unrecognized-service"},
2265 static const value_string
2266 BACnetRestartReason [] = {
2270 {3,"detected-power-lost"},
2271 {4,"detected-powered-off"},
2272 {5,"hardware-watchdog"},
2273 {6,"software-watchdog"},
2278 static const value_string
2279 BACnetApplicationTagNumber [] = {
2282 {2,"Unsigned Integer"},
2283 {3,"Signed Integer (2's complement notation)"},
2284 {4,"Real (ANSI/IEE-754 floating point)"},
2285 {5,"Double (ANSI/IEE-754 double precision floating point)"},
2287 {7,"Character String"},
2292 {12,"BACnetObjectIdentifier"},
2293 {13,"reserved by ASHRAE"},
2294 {14,"reserved by ASHRAE"},
2295 {15,"reserved by ASHRAE"},
2299 static const value_string
2306 static const value_string
2307 BACnetFileAccessMethod [] = {
2308 {0,"record-access"},
2309 {1,"stream-access"},
2313 /* For some reason, BACnet defines the choice parameter
2314 in the file read and write services backwards from the
2315 BACnetFileAccessMethod enumeration.
2317 static const value_string
2318 BACnetFileAccessOption [] = {
2319 {0,"stream access"},
2320 {1,"record access"},
2324 static const value_string
2325 BACnetFileStartOption [] = {
2326 {0, "File Start Position: "},
2327 {1, "File Start Record: "},
2331 static const value_string
2332 BACnetFileRequestCount [] = {
2333 {0, "Requested Octet Count: "},
2334 {1, "Requested Record Count: "},
2338 static const value_string
2339 BACnetFileWriteInfo [] = {
2341 {1, "Record Count: "},
2345 static const value_string
2346 BACnetAbortReason [] = {
2348 {1,"buffer-overflow"},
2349 {2,"invalid-apdu-in-this-state"},
2350 {3,"preempted-by-higher-priority-task"},
2351 {4,"segmentation-not-supported"},
2355 static const value_string
2356 BACnetLifeSafetyMode [] = {
2367 {10,"disconnected"},
2370 {13,"atomic-release-disabled"},
2373 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2374 Enumerated values 256-65535 may be used by others subject to
2375 procedures and constraints described in Clause 23. */
2378 static const value_string
2379 BACnetLifeSafetyOperation [] = {
2382 {2,"silence-audible"},
2383 {3,"silence-visual"},
2388 {8,"unsilence-audible"},
2389 {9,"unsilence-visual"},
2391 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2392 Enumerated values 64-65535 may be used by others subject to
2393 procedures and constraints described in Clause 23. */
2396 static const value_string
2397 BACnetLimitEnable [] = {
2398 {0,"lowLimitEnable"},
2399 {1,"highLimitEnable"},
2403 static const value_string
2404 BACnetLifeSafetyState [] = {
2409 {4,"fault-pre-alarm"},
2417 {12,"test-fault-alarm"},
2420 {15,"tamper-alarm"},
2422 {17,"emergency-power"},
2426 {21,"general-alarm"},
2428 {23,"test-supervisory"},
2430 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2431 Enumerated values 256-65535 may be used by others subject to
2432 procedures and constraints described in Clause 23. */
2435 static const value_string
2436 BACnetConfirmedServiceChoice [] = {
2437 {0,"acknowledgeAlarm"},
2438 {1,"confirmedCOVNotification"},
2439 {2,"confirmedEventNotification"},
2440 {3,"getAlarmSummary"},
2441 {4,"getEnrollmentSummary"},
2443 {6,"atomicReadFile"},
2444 {7,"atomicWriteFile"},
2445 {8,"addListElement"},
2446 {9,"removeListElement"},
2447 {10,"createObject"},
2448 {11,"deleteObject"},
2449 {12,"readProperty"},
2450 {13,"readPropertyConditional"},
2451 {14,"readPropertyMultiple"},
2452 {15,"writeProperty"},
2453 {16,"writePropertyMultiple"},
2454 {17,"deviceCommunicationControl"},
2455 {18,"confirmedPrivateTransfer"},
2456 {19,"confirmedTextMessage"},
2457 {20,"reinitializeDevice"},
2461 {24,"authenticate"},
2464 {27,"lifeSafetyOperation"},
2465 {28,"subscribeCOVProperty"},
2466 {29,"getEventInformation"},
2467 {30,"reserved by ASHRAE"},
2471 static const value_string
2472 BACnetReliability [] = {
2473 {0,"no-fault-detected"},
2480 {7,"unreliable-other"},
2481 {8,"process-error"},
2482 {9,"multi-state-fault"},
2486 static const value_string
2487 BACnetUnconfirmedServiceChoice [] = {
2490 {2,"unconfirmedCOVNotification"},
2491 {3,"unconfirmedEventNotification"},
2492 {4,"unconfirmedPrivateTransfer"},
2493 {5,"unconfirmedTextMessage"},
2494 {6,"timeSynchronization"},
2497 {9,"utcTimeSynchonization"},
2501 static const value_string
2502 BACnetUnconfirmedServiceRequest [] = {
2504 {1,"i-Have-Request"},
2505 {2,"unconfirmedCOVNotification-Request"},
2506 {3,"unconfirmedEventNotification-Request"},
2507 {4,"unconfirmedPrivateTransfer-Request"},
2508 {5,"unconfirmedTextMessage-Request"},
2509 {6,"timeSynchronization-Request"},
2510 {7,"who-Has-Request"},
2511 {8,"who-Is-Request"},
2512 {9,"utcTimeSynchonization-Request"},
2516 static const value_string
2517 BACnetObjectType [] = {
2519 {1,"analog-output"},
2522 {4,"binary-output"},
2527 {9,"event-enrollment"},
2531 {13,"multi-state-input"},
2532 {14,"multi-state-output"},
2533 {15,"notification-class"},
2537 {19,"multi-state-value"},
2539 {21,"life-safety-point"},
2540 {22,"life-safety-zone"},
2542 {24,"pulse-converter"},
2544 {26,"global-group"},
2545 {27,"trend-log-multiple"},
2546 {28,"load-control"},
2547 {29,"structured-view"},
2548 {30,"access-door"}, /* 30-37 added with addanda 135-2008j */
2549 {32,"access-credential"},
2550 {33,"access-point"},
2551 {34,"access-rights"},
2554 {37,"credential-data-input"},
2555 {39,"bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2556 {40,"characterstring-value"},
2557 {41,"date-pattern-value"},
2559 {43,"datetime-pattern-value"},
2560 {44,"datetime-value"},
2561 {45,"integer-value"},
2562 {46,"large-analog-value"},
2563 {47,"octetstring-value"},
2564 {48,"positive-Integer-value"},
2565 {49,"time-pattern-value"},
2568 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2569 Enumerated values 128-1023 may be used by others subject to
2570 the procedures and constraints described in Clause 23. */
2573 static const value_string
2574 BACnetEngineeringUnits [] = {
2584 {9,"Kilovolt Amperes"},
2585 {10,"Megavolt Amperes"},
2586 {11,"Volt Amperes Reactive"},
2587 {12,"Kilovolt Amperes Reactive"},
2588 {13,"Megavolt Amperes Reactive"},
2589 {14,"Degrees Phase"},
2590 {15,"Power Factor"},
2594 {19,"Kilowatt Hours"},
2598 {23,"Joules Per Kg Dry Air"},
2599 {24,"BTUs Per Pound Dry Air"},
2600 {25,"Cycles Per Hour"},
2601 {26,"Cycles Per Minute"},
2603 {28,"Grams Of Water Per Kilogram Dry Air"},
2604 {29,"Relative Humidity"},
2609 {34,"Watts Per Sq Foot"},
2610 {35,"Watts Per Sq meter"},
2613 {38,"Foot Candles"},
2617 {42,"Kgs per Second"},
2618 {43,"Kgs Per Minute"},
2619 {44,"Kgs Per Hour"},
2620 {45,"Pounds Mass Per Minute"},
2621 {46,"Pounds Mass Per Hour"},
2625 {50,"BTUs Per Hour"},
2627 {52,"Tons Refrigeration"},
2631 {56,"Pounds Force Per Square Inch"},
2632 {57,"Centimeters Of Water"},
2633 {58,"Inches Of Water"},
2634 {59,"Millimeters Of Mercury"},
2635 {60,"Centimeters Of Mercury"},
2636 {61,"Inches Of Mercury"},
2637 {62,"Degrees Celsius"},
2638 {63,"Degrees Kelvin"},
2639 {64,"Degrees Fahrenheit"},
2640 {65,"Degree Days Celsius"},
2641 {66,"Degree Days Fahrenheit"},
2649 {74,"Meters Per Second"},
2650 {75,"Kilometers Per Hour"},
2651 {76,"Feed Per Second"},
2652 {77,"Feet Per Minute"},
2653 {78,"Miles Per Hour"},
2655 {80,"Cubic Meters"},
2656 {81,"Imperial Gallons"},
2659 {84,"Cubic Feet Per Minute"},
2660 {85,"Cubic Meters Per Second"},
2661 {86,"Imperial Gallons Per Minute"},
2662 {87,"Liters Per Second"},
2663 {88,"Liters Per Minute"},
2664 {89,"US Gallons Per Minute"},
2665 {90,"Degrees Angular"},
2666 {91,"Degrees Celsius Per Hour"},
2667 {92,"Degrees Celsius Per Minute"},
2668 {93,"Degrees Fahrenheit Per Hour"},
2669 {94,"Degrees Fahrenheit Per Minute"},
2671 {96,"Parts Per Million"},
2672 {97,"Parts Per Billion"},
2674 {99,"Pecent Per Second"},
2677 {102,"Psi Per Degree Fahrenheit"},
2679 {104,"Revolutions Per Min"},
2691 {116,"Sq Centimeters"},
2692 {117,"BTUs Per Pound"},
2693 {118,"Centimeters"},
2694 {119,"Pounds Mass Per Second"},
2695 {120,"Delta Degrees Fahrenheit"},
2696 {121,"Delta Degrees Kelvin"},
2700 {125,"Kilojoules Per Kg"},
2702 {127,"Joules Per Degree Kelvin"},
2703 {128,"Joules Per Kg Degree Kelvin"},
2708 {133,"Hectopascals"},
2710 {135,"Cubic Meters Per Hour"},
2711 {136,"Liters Per Hour"},
2712 {137,"KWatt Hours Per Square Meter"},
2713 {138,"KWatt Hours Per Square Foot"},
2714 {139,"Megajoules Per Square Meter"},
2715 {140,"Megajoules Per Square Foot"},
2716 {141,"Watts Per Sq Meter Degree Kelvin"},
2717 {142,"Cubic Feet Per Second"},
2718 {143,"Percent Obstruction Per Foot"},
2719 {144,"Percent Obstruction Per Meter"},
2721 {146,"megawatt-hours"},
2724 {149,"kilojoules-per-kilogram-dry-air"},
2725 {150,"megajoules-per-kilogram-dry-air"},
2726 {151,"kilojoules-per-degree-Kelvin"},
2727 {152,"megajoules-per-degree-Kelvin"},
2729 {154,"grams-per-second"},
2730 {155,"grams-per-minute"},
2731 {156,"tons-per-hour"},
2732 {157,"kilo-btus-per-hour"},
2733 {158,"hundredths-seconds"},
2734 {159,"milliseconds"},
2735 {160,"newton-meters"},
2736 {161,"millimeters-per-second"},
2737 {162,"millimeters-per-minute"},
2738 {163,"meters-per-minute"},
2739 {164,"meters-per-hour"},
2740 {165,"cubic-meters-per-minute"},
2741 {166,"meters-per-second-per-second"},
2742 {167,"amperes-per-meter"},
2743 {168,"amperes-per-square-meter"},
2744 {169,"ampere-square-meters"},
2749 {174,"siemens-per-meter"},
2751 {176,"volts-per-degree-Kelvin"},
2752 {177,"volts-per-meter"},
2755 {180,"candelas-per-square-meter"},
2756 {181,"degrees-Kelvin-per-hour"},
2757 {182,"degrees-Kelvin-per-minute"},
2758 {183,"joule-seconds"},
2759 {184,"radians-per-second"},
2760 {185,"square-meters-per-Newton"},
2761 {186,"kilograms-per-cubic-meter"},
2762 {187,"newton-seconds"},
2763 {188,"newtons-per-meter"},
2764 {189,"watts-per-meter-per-degree-Kelvin"},
2766 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2767 Enumerated values 256-65535 may be used by others subject to
2768 the procedures and constraints described in Clause 23. */
2771 static const value_string
2772 BACnetErrorCode [] = {
2774 {1,"authentication-failed"},
2775 {2,"configuration-in-progress"},
2777 {4,"dynamic-creation-not-supported"},
2778 {5,"file-access-denied"},
2779 {6,"incompatible-security-levels"},
2780 {7,"inconsistent-parameters"},
2781 {8,"inconsistent-selection-criterion"},
2782 {9,"invalid-data-type"},
2783 {10,"invalid-file-access-method"},
2784 {11,"invalid-file-start-position"},
2785 {12,"invalid-operator-name"},
2786 {13,"invalid-parameter-data-type"},
2787 {14,"invalid-time-stamp"},
2788 {15,"key-generation-error"},
2789 {16,"missing-required-parameter"},
2790 {17,"no-objects-of-specified-type"},
2791 {18,"no-space-for-object"},
2792 {19,"no-space-to-add-list-element"},
2793 {20,"no-space-to-write-property"},
2794 {21,"no-vt-sessions-available"},
2795 {22,"property-is-not-a-list"},
2796 {23,"object-deletion-not-permitted"},
2797 {24,"object-identifier-already-exists"},
2798 {25,"operational-problem"},
2799 {26,"password-failure"},
2800 {27,"read-access-denied"},
2801 {28,"security-not-supported"},
2802 {29,"service-request-denied"},
2804 {31,"unknown-object"},
2805 {32,"unknown-property"},
2806 {33,"removed enumeration"},
2807 {34,"unknown-vt-class"},
2808 {35,"unknown-vt-session"},
2809 {36,"unsupported-object-type"},
2810 {37,"value-out-of-range"},
2811 {38,"vt-session-already-closed"},
2812 {39,"vt-session-termination-failure"},
2813 {40,"write-access-denied"},
2814 {41,"character-set-not-supported"},
2815 {42,"invalid-array-index"},
2816 {43,"cov-subscription-failed"},
2817 {44,"not-cov-property"},
2818 {45,"optional-functionality-not-supported"},
2819 {46,"invalid-configuration-data"},
2820 {47,"datatype-not-supported"},
2821 {48,"duplicate-name"},
2822 {49,"duplicate-object-id"},
2823 {50,"property-is-not-an-array"},
2824 {73,"invalid-event-state"},
2825 {74,"no-alarm-configured"},
2827 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2828 Enumerated values 256-65535 may be used by others subject to the
2829 procedures and constraints described in Clause 23. */
2832 static const value_string
2833 BACnetPropertyIdentifier [] = {
2834 {0,"acked-transition"},
2839 {5,"active-vt-session"},
2843 {9,"all-write-successful"},
2844 {10,"apdu-segment-timeout"},
2845 {11,"apdu-timeout"},
2846 {12,"application-software-version"},
2849 {15,"change-of-state-count"},
2850 {16,"change-of-state-time"},
2851 {17,"notification-class"},
2852 {18,"the property in this place was deleted"},
2853 {19,"controlled-variable-reference"},
2854 {20,"controlled-variable-units"},
2855 {21,"controlled-variable-value"},
2856 {22,"cov-increment"},
2858 {24,"daylights-savings-status"},
2860 {26,"derivative-constant"},
2861 {27,"derivative-constant-units"},
2863 {29,"description-of-halt"},
2864 {30,"device-address-binding"},
2866 {32,"effective-period"},
2867 {33,"elapsed-active-time"},
2869 {35,"event-enable"},
2872 {38,"exception-schedule"},
2873 {39,"fault-values"},
2874 {40,"feedback-value"},
2875 {41,"file-access-method"},
2878 {44,"firmware-revision"},
2880 {46,"inactive-text"},
2883 {49,"integral-constant"},
2884 {50,"integral-constant-units"},
2885 {51,"issue-confirmed-notifications"},
2886 {52,"limit-enable"},
2887 {53,"list-of-group-members"},
2888 {54,"list-of-object-property-references"},
2889 {55,"list-of-session-keys"},
2894 {60,"manipulated-variable-reference"},
2895 {61,"maximum-output"},
2896 {62,"max-apdu-length-accepted"},
2897 {63,"max-info-frames"},
2899 {65,"max-pres-value"},
2900 {66,"minimum-off-time"},
2901 {67,"minimum-on-time"},
2902 {68,"minimum-output"},
2903 {69,"min-pres-value"},
2905 {71,"modification-date"},
2907 {73,"number-of-APDU-retries"},
2908 {74,"number-of-states"},
2909 {75,"object-identifier"},
2912 {78,"object-property-reference"},
2915 {81,"out-of-service"},
2916 {82,"output-units"},
2917 {83,"event-parameters"},
2919 {85,"present-value"},
2921 {87,"priority-array"},
2922 {88,"priority-for-writing"},
2923 {89,"process-identifier"},
2924 {90,"program-change"},
2925 {91,"program-location"},
2926 {92,"program-state"},
2927 {93,"proportional-constant"},
2928 {94,"proportional-constant-units"},
2929 {95,"protocol-conformance-class"},
2930 {96,"protocol-object-types-supported"},
2931 {97,"protocol-services-supported"},
2932 {98,"protocol-version"},
2934 {100,"reason-for-halt"},
2936 {102,"recipient-list"},
2937 {103,"reliability"},
2938 {104,"relinquish-default"},
2941 {107,"segmentation-supported"},
2943 {109,"setpoint-reference"},
2945 {111,"status-flags"},
2946 {112,"system-status"},
2948 {114,"time-of-active-time-reset"},
2949 {115,"time-of-state-count-reset"},
2950 {116,"time-synchronization-recipients"},
2952 {118,"update-interval"},
2954 {120,"vendor-identifier"},
2955 {121,"vendor-name"},
2956 {122,"vt-class-supported"},
2957 {123,"weekly-schedule"},
2958 {124,"attempted-samples"},
2959 {125,"average-value"},
2960 {126,"buffer-size"},
2961 {127,"client-cov-increment"},
2962 {128,"cov-resubscription-interval"},
2963 {129,"current-notify-time"},
2964 {130,"event-time-stamp"},
2966 {132,"log-device-object-property"},
2967 {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
2968 {134,"log-interval"},
2969 {135,"maximum-value"},
2970 {136,"minimum-value"},
2971 {137,"notification-threshold"},
2972 {138,"previous-notify-time"},
2973 {139,"protocol-revision"},
2974 {140,"records-since-notification"},
2975 {141,"record-count"},
2978 {144,"stop-when-full"},
2979 {145,"total-record-count"},
2980 {146,"valid-samples"},
2981 {147,"window-interval"},
2982 {148,"window-samples"},
2983 {149,"maximum-value-time-stamp"},
2984 {150,"minimum-value-time-stamp"},
2985 {151,"variance-value"},
2986 {152,"active-cov-subscriptions"},
2987 {153,"backup-failure-timeout"},
2988 {154,"configuration-files"},
2989 {155,"database-revision"},
2990 {156,"direct-reading"},
2991 {157,"last-restore-time"},
2992 {158,"maintenance-required"},
2995 {161,"operation-expected"},
2998 {164,"tracking-value"},
2999 {165,"zone-members"},
3000 {166,"life-safety-alarm-values"},
3001 {167,"max-segments-accepted"},
3002 {168,"profile-name"},
3003 {169,"auto-slave-discovery"},
3004 {170,"manual-slave-address-binding"},
3005 {171,"slave-address-binding"},
3006 {172,"slave-proxy-enable"},
3007 {173,"last-notify-record"}, /* bug 4117 */
3008 {174,"schedule-default"},
3009 {175,"accepted-modes"},
3010 {176,"adjust-value"},
3012 {178,"count-before-change"},
3013 {179,"count-change-time"},
3015 {181,"input-reference"},
3016 {182,"limit-monitoring-interval"},
3017 {183,"logging-device"},
3018 {184,"logging-record"},
3022 {188,"scale-factor"},
3023 {189,"update-time"},
3024 {190,"value-before-change"},
3026 {192,"value-change-time"},
3027 {193,"align-intervals"},
3028 {194,"group-member-names"},
3029 {195,"interval-offset"},
3030 {196,"last-restart-reason"},
3031 {197,"logging-type"},
3032 {198,"member-status-flags"},
3033 {199,"notification-period"},
3034 {200,"previous-notify-record"},
3035 {201,"requested-update-interval"},
3036 {202,"restart-notification-recipients"},
3037 {203,"time-of-device-restart"},
3038 {204,"time-synchronization-recipients"},
3040 {206,"UTC-time-synchronization-recipients"},
3041 {207,"node-subtype"},
3043 {209,"structured-object-list"},
3044 {210,"subordinate-annotations"},
3045 {211,"subordinate-list"},
3046 {212,"actual-shed-level"},
3047 {213,"duty-window"},
3048 {214,"expected-shed-level"},
3049 {215,"full-duty-baseline"},
3050 {216,"node-subtype"},
3052 {218,"requested-shed-level"},
3053 {219,"shed-duration"},
3054 {220,"shed-level-descriptions"},
3055 {221,"shed-levels"},
3056 {222,"state-description"},
3057 {226,"door-alarm-state"},
3058 {227,"door-extended-pulse-time"},
3059 {228,"door-members"},
3060 {229,"door-open-too-long-time"},
3061 {230,"door-pulse-time"},
3062 {231,"door-status"},
3063 {232,"door-unlock-delay-time"},
3064 {233,"lock-status"},
3065 {234,"masked-alarm-values"},
3066 {235,"secured-status"},
3067 {244,"absentee-limit"}, /* added with addenda 135-2008j */
3068 {245,"access-alarm-events"},
3069 {246,"access-doors"},
3070 {247,"access-event"},
3071 {248,"access-event-authentication-factor"},
3072 {249,"access-event-credential"},
3073 {250,"access-event-time"},
3074 {251,"access-transaction-events"},
3075 {252,"accompaniment"},
3076 {253,"accompaniment-time"},
3077 {254,"activation-time"},
3078 {255,"active-authentication-policy"},
3079 {256,"assigned-access-rights"},
3080 {257,"authentication-factors"},
3081 {258,"authentication-policy-list"},
3082 {259,"authentication-policy-names"},
3083 {260,"authentication-status"},
3084 {261,"authorization-mode"},
3086 {263,"credential-disable"},
3087 {264,"credential-status"},
3088 {265,"credentials"},
3089 {266,"credentials-in-zone"},
3090 {267,"days-remaining"},
3091 {268,"entry-points"},
3092 {269,"exit-points"},
3093 {270,"expiry-time"},
3094 {271,"extended-time-enable"},
3095 {272,"failed-attempt-events"},
3096 {273,"failed-attempts"},
3097 {274,"failed-attempts-time"},
3098 {275,"last-access-event"},
3099 {276,"last-access-point"},
3100 {277,"last-credential-added"},
3101 {278,"last-credential-added-time"},
3102 {279,"last-credential-removed"},
3103 {280,"last-credential-removed-time"},
3104 {281,"last-use-time"},
3106 {283,"lockout-relinquish-time"},
3107 {284,"master-exemption"},
3108 {285,"max-failed-attempts"},
3110 {287,"muster-point"},
3111 {288,"negative-access-rules"},
3112 {289,"number-of-authentication-policies"},
3113 {290,"occupancy-count"},
3114 {291,"occupancy-count-adjust"},
3115 {292,"occupancy-count-enable"},
3116 {293,"occupancy-exemption"},
3117 {294,"occupancy-lower-limit"},
3118 {295,"occupancy-lower-limit-enforced"},
3119 {296,"occupancy-state"},
3120 {297,"occupancy-upper-limit"},
3121 {298,"occupancy-upper-limit-enforced"},
3122 {299,"passback-exemption"},
3123 {300,"passback-mode"},
3124 {301,"passback-timeout"},
3125 {302,"positive-access-rules"},
3126 {303,"reason-for-disable"},
3127 {304,"supported-formats"},
3128 {305,"supported-format-classes"},
3129 {306,"threat-authority"},
3130 {307,"threat-level"},
3132 {309,"transaction-notification-class"},
3133 {310,"user-external-identifier"},
3134 {311,"user-information-reference"},
3135 /* enumeration values 312-316 reserved for future addenda */
3138 {319,"uses-remaining"},
3141 {322,"access-event-tag"},
3142 {323,"global-identifier"},
3143 /* enumeration values 324-325 reserved for future addenda */
3144 {326,"verification-time"},
3145 {342,"bit-mask"}, /* addenda 135-2008w */
3149 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3150 Enumerated values 512-4194303 may be used by others subject to
3151 the procedures and constraints described in Clause 23. */
3154 static const value_string
3155 BACnetBinaryPV [] = {
3163 #define IBM_MS_DBCS 1
3164 #define JIS_C_6226 2
3165 #define ISO_10646_UCS4 3
3166 #define ISO_10646_UCS2 4
3167 #define ISO_18859_1 5
3168 static const value_string
3169 BACnetCharacterSet [] = {
3170 {ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3171 {IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3172 {JIS_C_6226, "JIS C 6226"},
3173 {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3174 {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3175 {ISO_18859_1, "ISO 18859-1"},
3179 static const value_string
3180 BACnetStatusFlags [] = {
3184 {3,"out-of-service"},
3188 static const value_string
3189 BACnetMessagePriority [] = {
3195 static const value_string
3196 BACnetAcknowledgementFilter [] = {
3203 static const value_string
3204 BACnetResultFlags [] = {
3211 static const value_string
3212 BACnetRelationSpecifier [] = {
3217 {4,"less-than-or-equal"},
3218 {5,"greater-than-or-equal"},
3222 static const value_string
3223 BACnetSelectionLogic [] = {
3230 static const value_string
3231 BACnetEventStateFilter [] = {
3240 static const value_string
3241 BACnetEventTransitionBits [] = {
3248 static const value_string
3249 BACnetSegmentation [] = {
3250 {0,"segmented-both"},
3251 {1,"segmented-transmit"},
3252 {2,"segmented-receive"},
3253 {3,"no-segmentation"},
3257 static const value_string
3258 BACnetSilencedState [] = {
3260 {1,"audible-silenced"},
3261 {2,"visible-silenced"},
3266 static const value_string
3267 BACnetDeviceStatus [] = {
3269 {1,"operational-read-only"},
3270 {2,"download-required"},
3271 {3,"download-in-progress"},
3272 {4,"non-operational"},
3273 {5,"backup-in-progress"},
3277 static const value_string
3278 BACnetEnableDisable [] = {
3281 {2,"disable-initiation"},
3285 static const value_string
3303 static const value_string
3305 {1,"days numbered 1-7" },
3306 {2,"days numbered 8-14" },
3307 {3,"days numbered 15-21" },
3308 {4,"days numbered 22-28" },
3309 {5,"days numbered 29-31" },
3310 {6,"last 7 days of this month" },
3311 {255,"any week of this month" },
3315 /* note: notification class object recipient-list uses
3316 different day-of-week enum */
3317 static const value_string
3326 {255,"any day of week" },
3330 static const value_string
3331 BACnetErrorClass [] = {
3340 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3341 Enumerated values64-65535 may be used by others subject to
3342 the procedures and constraints described in Clause 23. */
3345 static const value_string
3346 BACnetVTClass [] = {
3347 {0,"default-terminal" },
3357 static const value_string
3358 BACnetEventType [] = {
3359 {0,"change-of-bitstring" },
3360 {1,"change-of-state" },
3361 {2,"change-of-value" },
3362 {3,"command-failure" },
3363 {4,"floating-limit" },
3364 {5,"out-of-range" },
3365 {6,"complex-event-type" },
3366 {7,"buffer-ready" },
3367 {8,"change-of-life-safety" },
3369 {10,"buffer-ready" },
3370 {11,"unsigned-range" },
3371 {14,"double-out-of-range"}, /* added with addenda 135-2008w */
3372 {15,"signed-out-of-range"},
3373 {16,"unsigned-out-of-range"},
3374 {17,"change-of-characterstring"},
3376 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3377 Enumerated values 64-65535 may be used by others subject to
3378 the procedures and constraints described in Clause 23.
3379 It is expected that these enumerated values will correspond
3380 to the use of the complex-event-type CHOICE [6] of the
3381 BACnetNotificationParameters production. */
3384 static const value_string
3385 BACnetEventState [] = {
3391 {5,"life-safety-alarm" },
3393 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3394 Enumerated values 64-65535 may be used by others subject to
3395 the procedures and constraints described in Clause 23. */
3398 static const value_string
3399 BACnetLogStatus [] = {
3400 {0,"log-disabled" },
3401 {1,"buffer-purged" },
3405 static const value_string
3406 BACnetMaintenance [] = {
3408 {1,"periodic-test" },
3409 {2,"need-service-operational" },
3410 {3,"need-service-inoperative" },
3414 static const value_string
3415 BACnetNotifyType [] = {
3418 {2,"ack-notification" },
3422 static const value_string
3423 BACnetServicesSupported [] = {
3424 {0,"acknowledgeAlarm"},
3425 {1,"confirmedCOVNotification"},
3426 {2,"confirmedEventNotification"},
3427 {3,"getAlarmSummary"},
3428 {4,"getEnrollmentSummary"},
3430 {6,"atomicReadFile"},
3431 {7,"atomicWriteFile"},
3432 {8,"addListElement"},
3433 {9,"removeListElement"},
3434 {10,"createObject"},
3435 {11,"deleteObject"},
3436 {12,"readProperty"},
3437 {13,"readPropertyConditional"},
3438 {14,"readPropertyMultiple"},
3439 {15,"writeProperty"},
3440 {16,"writePropertyMultiple"},
3441 {17,"deviceCommunicationControl"},
3442 {18,"confirmedPrivateTransfer"},
3443 {19,"confirmedTextMessage"},
3444 {20,"reinitializeDevice"},
3448 {24,"authenticate"},
3452 {28,"unconfirmedCOVNotification"},
3453 {29,"unconfirmedEventNotification"},
3454 {30,"unconfirmedPrivateTransfer"},
3455 {31,"unconfirmedTextMessage"},
3456 {32,"timeSynchronization"},
3460 {36,"utcTimeSynchronization"},
3461 {37,"lifeSafetyOperation"},
3462 {38,"subscribeCOVProperty"},
3463 {39,"getEventInformation"},
3467 static const value_string
3468 BACnetPropertyStates [] = {
3469 {0,"boolean-value"},
3473 {4,"program-change"},
3474 {5,"program-state"},
3475 {6,"reason-for-halt"},
3478 {9,"system-status"},
3480 {11,"unsigned-value"},
3481 {12,"life-safety-mode"},
3482 {13,"life-safety-state"},
3483 {14,"door-alarm-state"},
3485 /* Tag values 0-63 are reserved for definition by ASHRAE.
3486 Tag values of 64-254 may be used by others to accommodate
3487 vendor specific properties that have discrete or enumerated values,
3488 subject to the constraints described in Clause 23. */
3491 static const value_string
3492 BACnetProgramError [] = {
3499 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3500 Enumerated values 64-65535 may be used by others subject to
3501 the procedures and constraints described in Clause 23. */
3504 static const value_string
3505 BACnetProgramRequest [] = {
3515 static const value_string
3516 BACnetProgramState [] = {
3526 static const value_string
3527 BACnetReinitializedStateOfDevice [] = {
3538 static const value_string
3539 BACnetPolarity [] = {
3545 static const value_string
3546 BACnetTagNames[] = {
3547 { 5, "Extended Value" },
3548 { 6, "Opening Tag" },
3549 { 7, "Closing Tag" },
3553 static const value_string
3554 BACnetReadRangeOptions[] = {
3555 { 3, "range byPosition" },
3556 { 4, "range byTime" },
3557 { 5, "range timeRange" },
3558 { 6, "range bySequenceNumber" },
3559 { 7, "range byTime" },
3563 /* Present_Value for Load Control Object */
3564 static const value_string
3565 BACnetShedState[] = {
3566 { 0, "shed-inactive" },
3567 { 1, "shed-request-pending" },
3568 { 2, "shed-compliant" },
3569 { 3, "shed-non-compliant" },
3573 static const value_string
3574 BACnetVendorIdentifiers [] = {
3577 { 2, "The Trane Company" },
3578 { 3, "McQuay International" },
3580 { 5, "Johnson Controls, Inc." },
3581 { 6, "American Auto-Matrix" },
3582 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3583 { 8, "Delta Controls" },
3584 { 9, "Siemens Building Technologies, Inc." },
3585 { 10, "Tour Andover Controls Corporation" },
3587 { 12, "Orion Analysis Corporation" },
3588 { 13, "Teletrol Systems Inc." },
3589 { 14, "Cimetrics Technology" },
3590 { 15, "Cornell University" },
3591 { 16, "United Technologies Carrier" },
3592 { 17, "Honeywell Inc." },
3593 { 18, "Alerton / Honeywell" },
3595 { 20, "Hewlett-Packard Company" },
3596 { 21, "Dorsette's Inc." },
3597 { 22, "Cerberus AG" },
3598 { 23, "York Controls Group" },
3599 { 24, "Automated Logic Corporation" },
3600 { 25, "CSI Control Systems International" },
3601 { 26, "Phoenix Controls Corporation" },
3602 { 27, "Innovex Technologies, Inc." },
3603 { 28, "KMC Controls, Inc." },
3604 { 29, "Xn Technologies, Inc." },
3605 { 30, "Hyundai Information Technology Co., Ltd." },
3606 { 31, "Tokimec Inc." },
3608 { 33, "North Communications Limited" },
3610 { 35, "Reliable Controls Corporation" },
3611 { 36, "Tridium Inc." },
3612 { 37, "Sierra Monitor Corp." },
3613 { 38, "Silicon Energy" },
3614 { 39, "Kieback & Peter GmbH & Co KG" },
3615 { 40, "Anacon Systems, Inc." },
3616 { 41, "Systems Controls & Instruments, LLC" },
3617 { 42, "Lithonia Lighting" },
3618 { 43, "Micropower Manufacturing" },
3619 { 44, "Matrix Controls" },
3620 { 45, "METALAIRE" },
3621 { 46, "ESS Engineering" },
3622 { 47, "Sphere Systems Pty Ltd." },
3623 { 48, "Walker Technologies Corporation" },
3624 { 49, "H I Solutions, Inc." },
3626 { 51, "SAMSON AG" },
3627 { 52, "Badger Meter Inc." },
3628 { 53, "DAIKIN Industries Ltd." },
3629 { 54, "NARA Controls Inc." },
3630 { 55, "Mammoth Inc." },
3631 { 56, "Liebert Corporation" },
3632 { 57, "SEMCO Incorporated" },
3633 { 58, "Air Monitor Corporation" },
3634 { 59, "TRIATEK, Inc." },
3636 { 61, "Multistack" },
3637 { 62, "TSI Incorporated" },
3638 { 63, "Weather-Rite, Inc." },
3639 { 64, "Dunham-Bush" },
3640 { 65, "Reliance Electric" },
3642 { 67, "Regulator Australia PTY Ltd." },
3643 { 68, "Touch-Plate Lighting Controls" },
3644 { 69, "Amann GmbH" },
3645 { 70, "RLE Technologies" },
3646 { 71, "Cardkey Systems" },
3647 { 72, "SECOM Co., Ltd." },
3648 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3649 { 74, "KNX Association cvba" },
3650 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3651 { 76, "Nohmi Bosai, Ltd." },
3652 { 77, "Carel S.p.A." },
3653 { 78, "AirSense Technology, Inc." },
3654 { 79, "Hochiki Corporation" },
3655 { 80, "Fr. Sauter AG" },
3656 { 81, "Matsushita Electric Works, Ltd." },
3657 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3658 { 83, "Mitsubishi Heavy Industries, Ltd." },
3659 { 84, "ITT Bell & Gossett" },
3660 { 85, "Yamatake Building Systems Co., Ltd." },
3661 { 86, "The Watt Stopper, Inc." },
3662 { 87, "Aichi Tokei Denki Co., Ltd." },
3663 { 88, "Activation Technologies, LLC" },
3664 { 89, "Saia-Burgess Controls, Ltd." },
3665 { 90, "Hitachi, Ltd." },
3666 { 91, "Novar Corp./Trend Control Systems Ltd." },
3667 { 92, "Mitsubishi Electric Lighting Corporation" },
3668 { 93, "Argus Control Systems, Ltd." },
3669 { 94, "Kyuki Corporation" },
3670 { 95, "Richards-Zeta Building Intelligence, Inc." },
3671 { 96, "Scientech R&D, Inc." },
3672 { 97, "VCI Controls, Inc." },
3673 { 98, "Toshiba Corporation" },
3674 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3675 { 100, "Custom Mechanical Equipment, LLC" },
3676 { 101, "ClimateMaster" },
3677 { 102, "ICP Panel-Tec, Inc." },
3678 { 103, "D-Tek Controls" },
3679 { 104, "NEC Engineering, Ltd." },
3680 { 105, "PRIVA BV" },
3681 { 106, "Meidensha Corporation" },
3682 { 107, "JCI Systems Integration Services" },
3683 { 108, "Freedom Corporation" },
3684 { 109, "Neuberger Gebaudeautomation GmbH" },
3685 { 110, "Sitronix" },
3686 { 111, "Leviton Manufacturing" },
3687 { 112, "Fujitsu Limited" },
3688 { 113, "Emerson Network Power" },
3689 { 114, "S. A. Armstrong, Ltd." },
3690 { 115, "Visonet AG" },
3691 { 116, "M&M Systems, Inc." },
3692 { 117, "Custom Software Engineering" },
3693 { 118, "Nittan Company, Limited" },
3694 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3695 { 120, "Pacom Systems Pty., Ltd." },
3696 { 121, "Unico, Inc." },
3697 { 122, "Ebtron, Inc." },
3698 { 123, "Scada Engine" },
3699 { 124, "AC Technology Corporation" },
3700 { 125, "Eagle Technology" },
3701 { 126, "Data Aire, Inc." },
3702 { 127, "ABB, Inc." },
3703 { 128, "Transbit Sp. z o. o." },
3704 { 129, "Toshiba Carrier Corporation" },
3705 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
3706 { 131, "Tokai Soft" },
3708 { 133, "Veris Industries" },
3709 { 134, "Centaurus Prime" },
3710 { 135, "Sand Network Systems" },
3711 { 136, "Regulvar, Inc." },
3712 { 137, "Fastek International, Ltd." },
3713 { 138, "PowerCold Comfort Air Solutions, Inc." },
3714 { 139, "I Controls" },
3715 { 140, "Viconics Electronics, Inc." },
3716 { 141, "Yaskawa Electric America, Inc." },
3717 { 142, "Plueth Regelsysteme" },
3718 { 143, "Digitale Mess- und Steuersysteme AG" },
3719 { 144, "Fujitsu General Limited" },
3720 { 145, "Project Engineering S.r.l." },
3721 { 146, "Sanyo Electric Co., Ltd." },
3722 { 147, "Integrated Information Systems, Inc." },
3723 { 148, "Temco Controls, Ltd." },
3724 { 149, "Airtek Technologies, Inc." },
3725 { 150, "Advantech Corporation" },
3726 { 151, "Titan Products, Ltd." },
3727 { 152, "Regel Partners" },
3728 { 153, "National Environmental Product" },
3729 { 154, "Unitec Corporation" },
3730 { 155, "Kanden Engineering Company" },
3731 { 156, "Messner Gebaudetechnik GmbH" },
3732 { 157, "Integrated.CH" },
3733 { 158, "EH Price Limited" },
3734 { 159, "SE-Elektronic GmbH" },
3735 { 160, "Rockwell Automation" },
3736 { 161, "Enflex Corp." },
3737 { 162, "ASI Controls" },
3738 { 163, "SysMik GmbH Dresden" },
3739 { 164, "HSC Regelungstechnik GmbH" },
3740 { 165, "Smart Temp Australia Pty. Ltd." },
3741 { 166, "PCI Lighting Control Systems" },
3742 { 167, "Duksan Mecasys Co., Ltd." },
3743 { 168, "Fuji IT Co., Ltd." },
3744 { 169, "Vacon Plc" },
3745 { 170, "Leader Controls" },
3746 { 171, "Cylon Controls, Ltd." },
3748 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
3749 { 174, "Building Control Integrators" },
3750 { 175, "ITG Worldwide (M) Sdn Bhd" },
3751 { 176, "Lutron Electronics Co., Inc." },
3752 { 177, "Cooper-Atkins Corporation" },
3753 { 178, "LOYTEC Electronics GmbH" },
3755 { 180, "Mega Controls Limited" },
3756 { 181, "Micro Control Systems, Inc." },
3757 { 182, "Kiyon, Inc." },
3758 { 183, "Dust Networks" },
3759 { 184, "Advanced Building Automation Systems" },
3760 { 185, "Hermos AG" },
3763 { 188, "Lynxspring" },
3764 { 189, "Schneider Toshiba Inverter Europe" },
3765 { 190, "Danfoss Drives A/S" },
3766 { 191, "Eaton Corporation" },
3767 { 192, "Matyca S.A." },
3768 { 193, "Botech AB" },
3769 { 194, "Noveo, Inc." },
3771 { 196, "Yokogawa Electric Corporation" },
3772 { 197, "GFR Gesellschaft fur Regelungstechnik" },
3773 { 198, "Exact Logic" },
3774 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
3775 { 200, "Kandenko Co., Ltd." },
3776 { 201, "DTF, Daten-Technik Fries" },
3777 { 202, "Klimasoft, Ltd." },
3778 { 203, "Toshiba Schneider Inverter Corporation" },
3779 { 204, "Control Applications, Ltd." },
3780 { 205, "KDT Systems Co., Ltd." },
3781 { 206, "Onicon Incorporated" },
3782 { 207, "Automation Displays, Inc." },
3783 { 208, "Control Solutions, Inc." },
3784 { 209, "Remsdaq Limited" },
3785 { 210, "NTT Facilities, Inc." },
3786 { 211, "VIPA GmbH" },
3787 { 212, "TSC21 Association of Japan" },
3788 { 213, "BBP Energie Ltee" },
3789 { 214, "HRW Limited" },
3790 { 215, "Lighting Control & Design, Inc." },
3791 { 216, "Mercy Electronic and Electrical Industries" },
3792 { 217, "Samsung SDS Co., Ltd" },
3793 { 218, "Impact Facility Solutions, Inc." },
3794 { 219, "Aircuity" },
3795 { 220, "Control Techniques, Ltd." },
3796 { 221, "Evolve Control Systems, LLC" },
3797 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
3798 { 223, "Cerus Industrial" },
3799 { 224, "Chloride Power Protection Company" },
3800 { 225, "Computrols, Inc." },
3801 { 226, "Phoenix Contact GmbH & Co. KG" },
3802 { 227, "Grundfos Management A/S" },
3803 { 228, "Ridder Drive Systems" },
3804 { 229, "Soft Device SDN BHD" },
3805 { 230, "Integrated Control Technology Limited" },
3806 { 231, "AIRxpert Systems, Inc." },
3807 { 232, "Microtrol Limited" },
3808 { 233, "Red Lion Controls" },
3809 { 234, "Digital Electronics Corporation" },
3810 { 235, "Ennovatis GmbH" },
3811 { 236, "Serotonin Software Technologies, Inc." },
3812 { 237, "LS Industrial Systems Co., Ltd." },
3813 { 238, "Square D Company" },
3814 { 239, "S Squared Innovations, Inc." },
3815 { 240, "Aricent Ltd." },
3816 { 241, "EtherMetrics, LLC" },
3817 { 242, "Industrial Control Communications, Inc." },
3818 { 243, "Paragon Controls, Inc." },
3819 { 244, "A. O. Smith Corporation" },
3820 { 245, "Contemporary Control Systems, Inc." },
3821 { 246, "Intesis Software SL" },
3822 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
3823 { 248, "Heat-Timer Corporation" },
3824 { 249, "Ingrasys Technology, Inc." },
3825 { 250, "Costerm Building Automation" },
3827 { 252, "Embedia Technologies Corp." },
3828 { 253, "Technilog" },
3829 { 254, "HR Controls Ltd. & Co. KG" },
3830 { 255, "Lennox International, Inc." },
3831 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
3832 { 257, "Thermomax, Ltd." },
3833 { 258, "ELCON Electronic Control, Ltd." },
3834 { 259, "Larmia Control AB" },
3835 { 260, "BACnet Stack at SourceForge" },
3836 { 261, "G4S Security Services A/S" },
3837 { 262, "Sitek S.p.A." },
3838 { 263, "Cristal Controles" },
3839 { 264, "Regin AB" },
3840 { 265, "Dimension Software, Inc. " },
3841 { 266, "SynapSense Corporation" },
3842 { 267, "Beijing Nantree Electronic Co., Ltd." },
3843 { 268, "Camus Hydronics Ltd." },
3844 { 269, "Kawasaki Heavy Industries, Ltd. " },
3845 { 270, "Critical Environment Technologies" },
3846 { 271, "ILSHIN IBS Co., Ltd." },
3847 { 272, "ELESTA Energy Control AG" },
3848 { 273, "KROPMAN Installatietechniek" },
3849 { 274, "Baldor Electric Company" },
3850 { 275, "INGA mbH" },
3851 { 276, "GE Consumer & Industrial" },
3852 { 277, "Functional Devices, Inc." },
3854 { 279, "M-System Co., Ltd." },
3855 { 280, "Yokota Co., Ltd." },
3856 { 281, "Hitranse Technology Co., LTD" },
3857 { 282, "Federspiel Controls" },
3858 { 283, "Kele, Inc." },
3859 { 284, "Opera Electronics, Inc." },
3861 { 286, "Embedded Science Labs, LLC" },
3862 { 287, "Parker Hannifin Corporation" },
3863 { 288, "MaCaPS International Limited" },
3864 { 289, "Link4 Corporation" },
3865 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
3866 { 291, "Pribusin, Inc." },
3867 { 292, "Advantage Controls" },
3868 { 293, "Critical Room Control" },
3870 { 295, "Tongdy Control Technology Co., Ltd." },
3871 { 296, "ISSARO Integrierte Systemtechnik" },
3872 { 297, "Pro-Dev Industries" },
3873 { 298, "DRI-STEEM" },
3874 { 299, "Creative Electronic GmbH" },
3875 { 300, "Swegon AB" },
3876 { 301, "Jan Brachacek" },
3877 { 302, "Hitachi Appliances, Inc." },
3878 { 303, "Real Time Automation, Inc." },
3879 { 304, "ITEC Hankyu-Hanshin Co." },
3880 { 305, "Cyrus E&M Engineering Co., Ltd." },
3881 { 306, "Racine Federated, Inc." },
3882 { 307, "Verari Systems, Inc." },
3883 { 308, "Elesta GmbH Building Automation" },
3884 { 309, "Securiton" },
3885 { 310, "OSlsoft, Inc." },
3886 { 311, "Hanazeder Electronic GmbH" },
3887 { 312, "Honeywell Security Deutschland, Novar GmbH" },
3888 { 313, "Siemens Energy & Automation, Inc." },
3889 { 314, "ETM Professional Control GmbH" },
3890 { 315, "Meitav-tec, Ltd." },
3891 { 316, "Janitza Electronics GmbH" },
3892 { 317, "MKS Nordhausen" },
3893 { 318, "De Gier Drive Systems B.V." },
3894 { 319, "Cypress Envirosystems" },
3895 { 320, "SMARTron s.r.o." },
3896 { 321, "Verari Systems, Inc." },
3897 { 322, "K-W Electronic Service, Inc." },
3898 { 323, "ALFA-SMART Energy Management" },
3899 { 324, "Telkonet, Inc." },
3900 { 325, "Securiton GmbH" },
3901 { 326, "Cemtrex, Inc." },
3902 { 327, "Performance Technologies, Inc." },
3903 { 328, "Xtralis (Aust) Pty Ltd" },
3904 { 329, "TROX GmbH" },
3905 { 330, "Beijing Hysine Technology Co., Ltd" },
3906 { 331, "RCK Controls, Inc." },
3908 { 333, "Novar/Honeywell" },
3909 { 334, "The S4 Group, Inc." },
3910 { 335, "Schneider Electric" },
3911 { 336, "LHA Systems" },
3912 { 337, "GHM engineering Group, Inc." },
3913 { 338, "Cllimalux S.A." },
3914 { 339, "VAISALA Oyj" },
3915 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
3916 { 342, "POWERPEG NSI Limited" },
3917 { 343, "BACnet Interoperability Testing Services, Inc." },
3918 { 344, "Teco a.s." },
3922 static int proto_bacapp = -1;
3923 static int hf_bacapp_type = -1;
3924 static int hf_bacapp_pduflags = -1;
3925 static int hf_bacapp_SEG = -1;
3926 static int hf_bacapp_MOR = -1;
3927 static int hf_bacapp_SA = -1;
3928 static int hf_bacapp_response_segments = -1;
3929 static int hf_bacapp_max_adpu_size = -1;
3930 static int hf_bacapp_invoke_id = -1;
3931 static int hf_bacapp_objectType = -1;
3932 static int hf_bacapp_instanceNumber = -1;
3933 static int hf_bacapp_sequence_number = -1;
3934 static int hf_bacapp_window_size = -1;
3935 static int hf_bacapp_service = -1;
3936 static int hf_bacapp_NAK = -1;
3937 static int hf_bacapp_SRV = -1;
3938 static int hf_Device_Instance_Range_Low_Limit = -1;
3939 static int hf_Device_Instance_Range_High_Limit = -1;
3940 static int hf_BACnetRejectReason = -1;
3941 static int hf_BACnetAbortReason = -1;
3942 static int hf_BACnetApplicationTagNumber = -1;
3943 static int hf_BACnetContextTagNumber = -1;
3944 static int hf_BACnetExtendedTagNumber = -1;
3945 static int hf_BACnetNamedTag = -1;
3946 static int hf_BACnetTagClass = -1;
3947 static int hf_BACnetCharacterSet = -1;
3948 static int hf_bacapp_tag_lvt = -1;
3949 static int hf_bacapp_tag_ProcessId = -1;
3950 static int hf_bacapp_uservice = -1;
3951 static int hf_BACnetPropertyIdentifier = -1;
3952 static int hf_BACnetVendorIdentifier = -1;
3953 static int hf_BACnetRestartReason = -1;
3954 static int hf_bacapp_tag_IPV4 = -1;
3955 static int hf_bacapp_tag_IPV6 = -1;
3956 static int hf_bacapp_tag_PORT = -1;
3957 /* some more variables for segmented messages */
3958 static int hf_msg_fragments = -1;
3959 static int hf_msg_fragment = -1;
3960 static int hf_msg_fragment_overlap = -1;
3961 static int hf_msg_fragment_overlap_conflicts = -1;
3962 static int hf_msg_fragment_multiple_tails = -1;
3963 static int hf_msg_fragment_too_long_fragment = -1;
3964 static int hf_msg_fragment_error = -1;
3965 static int hf_msg_fragment_count = -1;
3966 static int hf_msg_reassembled_in = -1;
3967 static int hf_msg_reassembled_length = -1;
3969 static gint ett_msg_fragment = -1;
3970 static gint ett_msg_fragments = -1;
3972 static gint ett_bacapp = -1;
3973 static gint ett_bacapp_control = -1;
3974 static gint ett_bacapp_tag = -1;
3975 static gint ett_bacapp_list = -1;
3976 static gint ett_bacapp_value = -1;
3978 static dissector_handle_t data_handle;
3979 static gint32 propertyIdentifier = -1;
3980 static gint32 propertyArrayIndex = -1;
3981 static guint32 object_type = 4096;
3983 static guint8 bacapp_flags = 0;
3984 static guint8 bacapp_seq = 0;
3986 /* Defined to allow vendor identifier registration of private transfer dissectors */
3987 static dissector_table_t bacapp_dissector_table;
3990 /* Stat: BACnet Packets sorted by IP */
3991 bacapp_info_value_t bacinfo;
3993 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
3994 static const gchar* st_str_packets_by_ip_dst = "By Destination";
3995 static const gchar* st_str_packets_by_ip_src = "By Source";
3996 static int st_node_packets_by_ip = -1;
3997 static int st_node_packets_by_ip_dst = -1;
3998 static int st_node_packets_by_ip_src = -1;
4001 bacapp_packet_stats_tree_init(stats_tree* st)
4003 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4004 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4005 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4009 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4011 int packets_for_this_dst;
4012 int packets_for_this_src;
4013 int service_for_this_dst;
4014 int service_for_this_src;
4015 int src_for_this_dst;
4016 int dst_for_this_src;
4017 int objectid_for_this_dst;
4018 int objectid_for_this_src;
4019 int instanceid_for_this_dst;
4020 int instanceid_for_this_src;
4023 const bacapp_info_value_t *binfo = p;
4025 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4026 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4028 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4029 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4030 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4031 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4032 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4033 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4034 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4035 if (binfo->service_type) {
4036 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4037 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4038 if (binfo->object_ident) {
4039 instanceid_for_this_dst=tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4040 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4041 instanceid_for_this_src=tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4042 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4049 /* Stat: BACnet Packets sorted by Service */
4050 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4051 static int st_node_packets_by_service = -1;
4054 bacapp_service_stats_tree_init(stats_tree* st)
4056 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4060 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4068 const bacapp_info_value_t *binfo = p;
4070 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4071 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4073 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4074 if (binfo->service_type) {
4075 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4076 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4077 dst = tick_stat_node(st, dststr, src, TRUE);
4078 if (binfo->object_ident) {
4079 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4080 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4087 /* Stat: BACnet Packets sorted by Object Type */
4088 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
4089 static int st_node_packets_by_objectid = -1;
4092 bacapp_objectid_stats_tree_init(stats_tree* st)
4094 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
4098 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4106 const bacapp_info_value_t *binfo = p;
4108 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4109 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4111 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
4112 if (binfo->object_ident) {
4113 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
4114 src = tick_stat_node(st, srcstr, objectid, TRUE);
4115 dst = tick_stat_node(st, dststr, src, TRUE);
4116 if (binfo->service_type) {
4117 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4118 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
4125 /* Stat: BACnet Packets sorted by Instance No */
4126 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
4127 static int st_node_packets_by_instanceid = -1;
4130 bacapp_instanceid_stats_tree_init(stats_tree* st)
4132 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
4136 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4144 const bacapp_info_value_t *binfo = p;
4146 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4147 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4149 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
4150 if (binfo->object_ident) {
4151 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
4152 src = tick_stat_node(st, srcstr, instanceid, TRUE);
4153 dst = tick_stat_node(st, dststr, src, TRUE);
4154 if (binfo->service_type) {
4155 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4156 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
4163 /* register all BACnet Ststistic trees */
4165 register_bacapp_stat_trees(void)
4167 stats_tree_register("bacapp","bacapp_ip","BACnet/Packets sorted by IP", 0,
4168 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
4169 stats_tree_register("bacapp","bacapp_service","BACnet/Packets sorted by Service", 0,
4170 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
4171 stats_tree_register("bacapp","bacapp_objectid","BACnet/Packets sorted by Object Type", 0,
4172 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
4173 stats_tree_register("bacapp","bacapp_instanceid","BACnet/Packets sorted by Instance ID", 0,
4174 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
4177 /* 'data' must be ep_ allocated */
4179 updateBacnetInfoValue(gint whichval, gchar *data)
4181 if (whichval == BACINFO_SERVICE) {
4182 bacinfo.service_type = data;
4185 if (whichval == BACINFO_INVOKEID) {
4186 bacinfo.invoke_id = data;
4189 if (whichval == BACINFO_OBJECTID) {
4190 bacinfo.object_ident = data;
4193 if (whichval == BACINFO_INSTANCEID) {
4194 bacinfo.instance_ident = data;
4200 static const fragment_items msg_frag_items = {
4201 /* Fragment subtrees */
4204 /* Fragment fields */
4207 &hf_msg_fragment_overlap,
4208 &hf_msg_fragment_overlap_conflicts,
4209 &hf_msg_fragment_multiple_tails,
4210 &hf_msg_fragment_too_long_fragment,
4211 &hf_msg_fragment_error,
4212 &hf_msg_fragment_count,
4213 /* Reassembled in field */
4214 &hf_msg_reassembled_in,
4215 /* Reassembled length field */
4216 &hf_msg_reassembled_length,
4221 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
4222 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
4225 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
4227 fGetMaxAPDUSize(guint8 idx)
4229 /* only 16 values are defined, so use & 0x0f */
4230 /* check the size of the Array, deliver either the entry
4231 or the first entry if idx is outside of the array (bug 3736 comment#7) */
4233 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
4234 return MaxAPDUSize[0];
4236 return MaxAPDUSize[idx & 0x0f];
4241 /* Used when there are ranges of reserved and proprietary enumerations */
4243 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
4244 const char *fmt, const char *split_fmt)
4246 if (val < split_val)
4247 return val_to_str(val, vs, fmt);
4249 return val_to_str(val, vs, split_fmt);
4252 /* from clause 20.2.1.3.2 Constructed Data */
4253 /* returns true if the extended value is used */
4255 tag_is_extended_value(guint8 tag)
4257 return (tag & 0x07) == 5;
4261 tag_is_opening(guint8 tag)
4263 return (tag & 0x07) == 6;
4267 tag_is_closing(guint8 tag)
4269 return (tag & 0x07) == 7;
4272 /* from clause 20.2.1.1 Class
4273 class bit shall be one for context specific tags */
4274 /* returns true if the tag is context specific */
4276 tag_is_context_specific(guint8 tag)
4278 return (tag & 0x08) != 0;
4282 tag_is_extended_tag_number(guint8 tag)
4284 return ((tag & 0xF0) == 0xF0);
4288 object_id_type(guint32 object_identifier)
4290 return ((object_identifier >> 22) & 0x3FF);
4294 object_id_instance(guint32 object_identifier)
4296 return (object_identifier & 0x3FFFFF);
4300 fTagNo (tvbuff_t *tvb, guint offset)
4302 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
4306 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
4308 gboolean valid = TRUE;
4312 *val = tvb_get_guint8(tvb, offset);
4315 *val = tvb_get_ntohs(tvb, offset);
4318 *val = tvb_get_ntoh24(tvb, offset);
4321 *val = tvb_get_ntohl(tvb, offset);
4332 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4334 gboolean valid = FALSE;
4338 if (lvt && (lvt <= 8)) {
4340 data = tvb_get_guint8(tvb, offset);
4341 for (i = 0; i < lvt; i++) {
4342 data = tvb_get_guint8(tvb, offset+i);
4343 value = (value << 8) + data;
4351 /* BACnet Signed Value uses 2's complement notation, but with a twist:
4352 All signed integers shall be encoded in the smallest number of octets
4353 possible. That is, the first octet of any multi-octet encoded value
4354 shall not be X'00' if the most significant bit (bit 7) of the second
4355 octet is 0, and the first octet shall not be X'FF' if the most
4356 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4358 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4360 gboolean valid = FALSE;
4365 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4366 if (lvt && (lvt <= 7)) {
4368 data = tvb_get_guint8(tvb, offset);
4369 if ((data & 0x80) != 0)
4370 value = (-1 << 8) | data;
4373 for (i = 1; i < lvt; i++) {
4374 data = tvb_get_guint8(tvb, offset+i);
4375 value = (value << 8) + data;
4384 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
4385 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4390 guint lvt_len = 1; /* used for tree display of lvt */
4391 guint lvt_offset; /* used for tree display of lvt */
4393 proto_tree *subtree;
4395 lvt_offset = offset;
4396 tag = tvb_get_guint8(tvb, offset);
4399 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4400 /* can mean open/close tag or length of 6/7 after the length is */
4401 /* computed below - store whole tag info, not just context bit. */
4402 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4404 if (tag_is_extended_tag_number(tag)) {
4405 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4407 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4408 lvt_offset += tag_len;
4409 value = tvb_get_guint8(tvb, lvt_offset);
4411 if (value == 254) { /* length is encoded with 16 Bits */
4412 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4415 } else if (value == 255) { /* length is encoded with 32 Bits */
4416 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4424 if (tag_is_opening(tag))
4425 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4426 else if (tag_is_closing(tag))
4427 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4428 else if (tag_is_context_specific(tag)) {
4429 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4430 "Context Tag: %u, Length/Value/Type: %u",
4433 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4434 "Application Tag: %s, Length/Value/Type: %u",
4436 BACnetApplicationTagNumber,
4437 ASHRAE_Reserved_Fmt),
4440 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4441 /* details if needed */
4442 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, FALSE);
4443 if (tag_is_extended_tag_number(tag)) {
4444 proto_tree_add_uint_format(subtree,
4445 hf_BACnetContextTagNumber,
4446 tvb, offset, 1, tag,
4447 "Extended Tag Number");
4448 proto_tree_add_item(subtree,
4449 hf_BACnetExtendedTagNumber,
4450 tvb, offset + 1, 1, FALSE);
4452 if (tag_is_context_specific(tag))
4453 proto_tree_add_item(subtree,
4454 hf_BACnetContextTagNumber,
4455 tvb, offset, 1, FALSE);
4457 proto_tree_add_item(subtree,
4458 hf_BACnetApplicationTagNumber,
4459 tvb, offset, 1, FALSE);
4461 if (tag_is_closing(tag) || tag_is_opening(tag))
4462 proto_tree_add_item(subtree,
4464 tvb, offset, 1, FALSE);
4465 else if (tag_is_extended_value(tag)) {
4466 proto_tree_add_item(subtree,
4468 tvb, offset, 1, FALSE);
4469 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4470 tvb, lvt_offset, lvt_len, *lvt);
4472 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4473 tvb, lvt_offset, lvt_len, *lvt);
4480 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
4483 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
4487 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4489 guint8 tag_no, tag_info;
4492 proto_tree *subtree;
4494 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4495 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4496 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4502 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4504 guint8 tag_no, tag_info;
4507 proto_tree *subtree;
4510 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4511 if (tag_info && lvt == 1) {
4512 lvt = tvb_get_guint8(tvb, offset+1);
4516 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
4517 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
4518 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4519 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4521 return offset + bool_len;
4525 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4528 guint8 tag_no, tag_info;
4532 proto_tree *subtree;
4534 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4535 /* only support up to an 8 byte (64-bit) integer */
4536 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
4537 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4538 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
4540 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4541 "%s - %u octets (Unsigned)", label, lvt);
4542 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4543 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4545 return offset+tag_len+lvt;
4549 fDevice_Instance (tvbuff_t *tvb, proto_tree *tree, guint offset, int hf)
4551 guint8 tag_no, tag_info;
4555 proto_tree *subtree;
4557 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4558 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, lvt, TRUE);
4559 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4560 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4562 return offset+tag_len+lvt;
4565 /* set split_val to zero when not needed */
4567 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4568 const value_string *vs, guint32 split_val)
4571 guint8 tag_no, tag_info;
4575 proto_tree *subtree;
4577 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4578 /* only support up to a 4 byte (32-bit) enumeration */
4579 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
4581 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4582 "%s %s", label, val_to_split_str(val, split_val, vs,
4583 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
4585 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4586 "%s %u", label, val);
4588 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4589 "%s - %u octets (enumeration)", label, lvt);
4591 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4592 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4594 return offset+tag_len+lvt;
4598 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4599 const value_string *vs)
4601 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
4605 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4608 guint8 tag_no, tag_info;
4612 proto_tree *subtree;
4614 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4615 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
4616 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4617 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
4619 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4620 "%s - %u octets (Signed)", label, lvt);
4621 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4622 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4624 return offset+tag_len+lvt;
4628 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4630 guint8 tag_no, tag_info;
4635 proto_tree *subtree;
4637 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4638 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
4639 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
4640 "%s%f (Real)", label, f_val);
4641 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4642 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4644 return offset+tag_len+4;
4648 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4650 guint8 tag_no, tag_info;
4655 proto_tree *subtree;
4657 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4658 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
4659 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
4660 "%s%f (Double)", label, d_val);
4661 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4662 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4664 return offset+tag_len+8;
4668 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
4670 guint32 val = 0, lvt;
4671 guint8 tag_no, tag_info;
4673 proto_tree *subtree;
4676 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4677 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4678 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
4679 tvb, offset, lvt+tag_len, val);
4681 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4682 "Process Identifier - %u octets (Signed)", lvt);
4683 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4684 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4685 offset += tag_len + lvt;
4691 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4693 guint32 val = 0, lvt;
4694 guint8 tag_no, tag_info;
4696 proto_tree *subtree;
4699 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4700 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4701 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4702 "%s (hh.mm.ss): %d.%02d.%02d%s",
4704 (val / 3600), ((val % 3600) / 60), (val % 60),
4705 val == 0 ? " (indefinite)" : "");
4707 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4708 "%s - %u octets (Signed)", label, lvt);
4709 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4710 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4712 return offset+tag_len+lvt;
4716 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
4718 guint32 month, weekOfMonth, dayOfWeek;
4719 guint8 tag_no, tag_info;
4723 proto_tree *subtree;
4725 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4726 month = tvb_get_guint8(tvb, offset+tag_len);
4727 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
4728 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
4729 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
4730 val_to_str(month, months, "month (%d) not found"),
4731 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
4732 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
4733 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4734 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4736 return offset+tag_len+lvt;
4740 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4742 guint32 year, month, day, weekday;
4743 guint8 tag_no, tag_info;
4747 proto_tree *subtree;
4749 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4750 year = tvb_get_guint8(tvb, offset+tag_len);
4751 month = tvb_get_guint8(tvb, offset+tag_len+1);
4752 day = tvb_get_guint8(tvb, offset+tag_len+2);
4753 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
4754 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
4755 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4758 else if (year != 255) {
4760 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4761 "%s%s %d, %d, (Day of Week = %s)",
4762 label, val_to_str(month,
4764 "month (%d) not found"),
4765 day, year, val_to_str(weekday,
4769 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4770 "%s%s %d, any year, (Day of Week = %s)",
4771 label, val_to_str(month, months, "month (%d) not found"),
4772 day, val_to_str(weekday, day_of_week, "(%d) not found"));
4774 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4775 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4777 return offset+tag_len+lvt;
4781 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4783 guint32 hour, minute, second, msec, lvt;
4784 guint8 tag_no, tag_info;
4787 proto_tree *subtree;
4789 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4790 hour = tvb_get_guint8(tvb, offset+tag_len);
4791 minute = tvb_get_guint8(tvb, offset+tag_len+1);
4792 second = tvb_get_guint8(tvb, offset+tag_len+2);
4793 msec = tvb_get_guint8(tvb, offset+tag_len+3);
4794 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
4795 ti = proto_tree_add_text(tree, tvb, offset,
4796 lvt+tag_len, "%sany", label);
4798 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4799 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
4801 hour > 12 ? hour - 12 : hour,
4802 minute, second, msec,
4803 hour >= 12 ? "P.M." : "A.M.",
4804 hour, minute, second, msec);
4805 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4806 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4808 return offset+tag_len+lvt;
4812 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4814 proto_tree *subtree = tree;
4817 if (label != NULL) {
4818 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
4819 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4821 offset = fDate (tvb,subtree,offset,"Date: ");
4822 return fTime (tvb,subtree,offset,"Time: ");
4826 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4828 guint lastoffset = 0;
4829 guint8 tag_no, tag_info;
4832 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4833 lastoffset = offset;
4834 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4835 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
4838 offset = fTime (tvb,tree,offset,"Time: ");
4839 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
4841 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
4847 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
4849 guint8 tag_no, tag_info;
4852 switch (fTagNo(tvb, offset)) {
4854 offset = fDate (tvb, tree, offset, "Date: ");
4856 case 1: /* dateRange */
4857 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4858 offset = fDateRange (tvb, tree, offset);
4859 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4861 case 2: /* BACnetWeekNDay */
4862 offset = fWeekNDay (tvb, tree, offset);
4872 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4874 guint8 tag_no = 0, tag_info = 0;
4877 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
4878 switch (fTagNo(tvb, offset)) {
4880 offset = fTime (tvb, tree, offset, label?label:"timestamp: ");
4882 case 1: /* sequenceNumber */
4883 offset = fUnsignedTag (tvb, tree, offset,
4884 label?label:"sequence Number: ");
4886 case 2: /* dateTime */
4887 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4888 offset = fDateTime (tvb, tree, offset, label?label:"timestamp: ");
4889 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4901 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4903 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4904 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
4909 static const value_string
4910 BACnetDaysOfWeek [] = {
4922 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4924 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4925 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
4926 "valid Days: ", BACnetDaysOfWeek);
4927 offset = fTime (tvb,tree,offset,"from time: ");
4928 offset = fTime (tvb,tree,offset,"to time: ");
4929 offset = fRecipient (tvb,pinfo,tree,offset);
4930 offset = fProcessId (tvb,tree,offset);
4931 offset = fApplicationTypes (tvb,pinfo,tree,offset,
4932 "issue confirmed notifications: ");
4933 offset = fBitStringTagVS (tvb,tree,offset,
4934 "transitions: ", BACnetEventTransitionBits);
4941 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4944 guint start = offset;
4945 guint8 tag_no, tag_info;
4946 proto_tree* subtree = tree;
4949 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4952 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4953 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
4958 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4960 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4966 fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4969 guint start = offset;
4970 guint8 tag_no, tag_info;
4971 proto_tree* subtree = tree;
4974 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4976 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
4979 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
4981 guint32 ip = tvb_get_ipv4(tvb, offset);
4982 guint16 port = tvb_get_ntohs(tvb, offset+4);
4984 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
4985 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
4988 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
4989 struct e_in6_addr addr;
4990 guint16 port = tvb_get_ntohs(tvb, offset+16);
4991 tvb_get_ipv6(tvb, offset, &addr);
4993 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
4994 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
4996 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
4997 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4998 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
5005 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5007 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5013 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
5015 guint8 tag_no, tag_info;
5019 offset = fUnsignedTag (tvb, tree, offset, "network-number");
5020 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5022 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5025 offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
5031 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
5033 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
5034 return fAddress (tvb,tree,offset);
5038 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5040 guint8 tag_no, tag_info;
5044 proto_tree *subtree;
5047 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5048 object_id = tvb_get_ntohl(tvb,offset+tag_length);
5049 object_type = object_id_type(object_id);
5050 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
5051 "ObjectIdentifier: %s, %u",
5052 val_to_split_str(object_type,
5055 ASHRAE_Reserved_Fmt,
5056 Vendor_Proprietary_Fmt),
5057 object_id_instance(object_id));
5058 if (col_get_writable(pinfo->cinfo))
5059 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5060 val_to_split_str(object_type,
5063 ASHRAE_Reserved_Fmt,
5064 Vendor_Proprietary_Fmt),
5065 object_id_instance(object_id));
5067 /* update BACnet Statistics */
5068 updateBacnetInfoValue(BACINFO_OBJECTID,
5069 ep_strdup(val_to_split_str(object_type, 128,
5070 BACnetObjectType, ASHRAE_Reserved_Fmt,
5071 Vendor_Proprietary_Fmt)));
5072 updateBacnetInfoValue(BACINFO_INSTANCEID, ep_strdup_printf("Instance ID: %u",
5073 object_id_instance(object_id)));
5075 /* here are the details of how we arrived at the above text */
5076 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5077 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5078 offset += tag_length;
5079 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, FALSE);
5080 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, FALSE);
5087 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5089 guint8 tag_no, tag_info;
5092 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5094 if (tag_no == 0) { /* device */
5095 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5097 else { /* address */
5098 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5099 offset = fAddress (tvb, tree, offset);
5100 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5107 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5109 guint lastoffset = 0;
5110 guint8 tag_no, tag_info;
5112 proto_tree* orgtree = tree;
5114 proto_tree* subtree;
5116 /* beginning of new item - indent and label */
5117 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
5118 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5120 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5121 lastoffset = offset;
5123 switch (fTagNo(tvb, offset)) {
5124 case 0: /* recipient */
5125 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5126 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5127 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5128 offset = fRecipient (tvb, pinfo, subtree, offset);
5129 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5131 case 1: /* processId */
5132 offset = fProcessId (tvb, tree, offset);
5133 lastoffset = offset;
5138 if (offset == lastoffset) break; /* nothing happened, exit loop */
5144 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5146 guint lastoffset = 0;
5147 guint8 tag_no, tag_info;
5149 proto_tree* subtree;
5151 proto_tree* orgtree = tree;
5154 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5155 lastoffset = offset;
5156 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5157 if (tag_is_closing(tag_info) ) {
5162 case 0: /* recipient */
5163 /* beginning of new item in list */
5164 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
5165 itemno = itemno + 1;
5166 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5168 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5169 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5170 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5171 offset = fRecipientProcess (tvb, pinfo, subtree, offset);
5172 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5173 subtree = tree; /* done with this level - return to previous tree */
5175 case 1: /* MonitoredPropertyReference */
5176 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
5177 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5178 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5179 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
5180 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5183 case 2: /* IssueConfirmedNotifications - boolean */
5184 offset = fBooleanTag (tvb, tree, offset, "Issue Confirmed Notifications: ");
5186 case 3: /* TimeRemaining */
5187 offset = fUnsignedTag (tvb, tree, offset, "Time Remaining: ");
5189 case 4: /* COVIncrement */
5190 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5195 if (offset == lastoffset) break; /* nothing happened, exit loop */
5201 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5203 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5204 return fAddress (tvb, tree, offset);
5208 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
5210 guint lastoffset = 0, len;
5211 guint8 tag_no, tag_info;
5213 proto_tree *subtree = tree;
5215 /* set the optional global properties to indicate not-used */
5216 propertyArrayIndex = -1;
5217 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5218 lastoffset = offset;
5219 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5220 if (tag_is_closing(tag_info) ) {
5221 if (tag_no == tag_match) {
5230 case 0: /* deviceIdentifier */
5231 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5233 case 1: /* objectIdentifier */
5234 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5236 case 2: /* propertyIdentifier */
5237 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
5239 case 3: /* propertyArrayIndex */
5240 offset = fPropertyArrayIndex (tvb, subtree, offset);
5242 case 4: /* propertyValue */
5243 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
5245 case 5: /* priority */
5246 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
5248 case 6: /* postDelay */
5249 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
5251 case 7: /* quitOnFailure */
5252 offset = fBooleanTag(tvb, subtree, offset,
5253 "Quit On Failure: ");
5255 case 8: /* writeSuccessful */
5256 offset = fBooleanTag(tvb, subtree, offset,
5257 "Write Successful: ");
5262 if (offset == lastoffset) break; /* nothing happened, exit loop */
5267 /* BACnetActionList ::= SEQUENCE{
5268 action [0] SEQUENCE OF BACnetActionCommand
5272 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5274 guint lastoffset = 0, len;
5275 guint8 tag_no, tag_info;
5277 proto_tree *subtree = tree;
5280 while (tvb_reported_length_remaining(tvb, offset)) {
5281 lastoffset = offset;
5282 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5283 if (tag_is_closing(tag_info)) {
5288 if (tag_is_opening(tag_info)) {
5289 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
5290 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5291 offset += fTagHeaderTree (tvb, subtree, offset,
5292 &tag_no, &tag_info, &lvt);
5295 case 0: /* BACnetActionCommand */
5296 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
5301 if (offset == lastoffset) break; /* nothing happened, exit loop */
5307 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5309 guint8 tag_no, tag_info;
5313 proto_tree *subtree;
5314 const gchar *label = "Property Identifier";
5316 propertyIdentifier = 0; /* global Variable */
5317 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5318 /* can we decode this value? */
5319 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
5320 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5321 "%s: %s (%u)", label,
5322 val_to_split_str(propertyIdentifier, 512,
5323 BACnetPropertyIdentifier,
5324 ASHRAE_Reserved_Fmt,
5325 Vendor_Proprietary_Fmt), propertyIdentifier);
5326 if (col_get_writable(pinfo->cinfo))
5327 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
5328 val_to_split_str(propertyIdentifier, 512,
5329 BACnetPropertyIdentifier,
5330 ASHRAE_Reserved_Fmt,
5331 Vendor_Proprietary_Fmt));
5333 /* property identifiers cannot be larger than 22-bits */
5336 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5337 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5338 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
5339 offset+tag_len, lvt, FALSE);
5341 return offset+tag_len+lvt;
5345 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
5347 guint8 tag_no, tag_info;
5351 proto_tree *subtree;
5353 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5354 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
5355 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5356 "property Array Index (Unsigned) %u", propertyArrayIndex);
5358 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5359 "property Array Index - %u octets (Unsigned)", lvt);
5360 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5361 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5363 return offset+tag_len+lvt;
5367 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5369 guint8 tag_no, tag_info, character_set;
5371 gsize inbytesleft, outbytesleft = 512;
5372 guint offs, extra = 1;
5375 guint8 bf_arr[512], *out = &bf_arr[0];
5377 proto_tree *subtree;
5378 guint start = offset;
5380 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5382 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5384 character_set = tvb_get_guint8(tvb, offset+offs);
5385 /* Account for code page if DBCS */
5386 if (character_set == 1) {
5389 offset += (offs+extra);
5393 inbytesleft = l = MIN(lvt, 255);
5395 * XXX - are we guaranteed that these encoding
5396 * names correspond, on *all* platforms with
5397 * iconv(), to the encodings we want?
5398 * If not (and perhaps even if so), we should
5399 * perhaps have our own iconv() implementation,
5400 * with a different name, so that we control the
5401 * encodings it supports and the names of those
5404 * We should also handle that in the general
5405 * string handling code, rather than making it
5406 * specific to the BACAPP dissector, as many
5407 * other dissectors need to handle various
5408 * character encodings.
5410 str_val = tvb_get_ephemeral_string(tvb, offset, l);
5411 /** this decoding may be not correct for multi-byte characters, Lka */
5412 switch (character_set) {
5414 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ANSI_X3.4");
5415 coding = "ANSI X3.4";
5419 coding = "IBM MS DBCS";
5423 coding = "JIS C 6226";
5425 case ISO_10646_UCS4:
5426 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5427 coding = "ISO 10646 UCS-4";
5429 case ISO_10646_UCS2:
5430 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5431 coding = "ISO 10646 UCS-2";
5434 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5435 coding = "ISO 8859-1";
5442 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s '%s'", label, coding, out);
5447 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5449 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
5450 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, FALSE);
5452 if (character_set == 1) {
5453 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5455 /* XXX - put the string value here */
5461 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5462 const value_string *src)
5464 guint8 tag_no, tag_info, tmp;
5465 gint j, unused, skip;
5466 guint start = offset;
5468 guint32 lvt, i, numberOfBytes;
5470 proto_tree* subtree = tree;
5473 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5474 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
5476 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
5477 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
5481 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5483 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5484 proto_tree_add_text(subtree, tvb, offset, 1,
5488 for (i = 0; i < numberOfBytes; i++) {
5489 tmp = tvb_get_guint8(tvb, (offset)+i+1);
5490 if (i == numberOfBytes-1) { skip = unused; }
5491 for (j = 0; j < 8-skip; j++) {
5493 if (tmp & (1 << (7 - j)))
5494 proto_tree_add_text(subtree, tvb,
5497 val_to_str((guint) (i*8 +j),
5499 ASHRAE_Reserved_Fmt));
5501 proto_tree_add_text(subtree, tvb,
5504 val_to_str((guint) (i*8 +j),
5506 ASHRAE_Reserved_Fmt));
5508 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
5514 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
5515 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
5524 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5526 return fBitStringTagVS (tvb, tree, offset, label, NULL);
5529 /* handles generic application types, as well as enumerated and enumerations
5530 with reserved and proprietarty ranges (split) */
5532 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5533 const gchar *label, const value_string *src, guint32 split_val)
5535 guint8 tag_no, tag_info;
5539 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5541 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5542 if (!tag_is_context_specific(tag_info)) {
5544 case 0: /** NULL 20.2.2 */
5545 offset = fNullTag(tvb, tree, offset, label);
5547 case 1: /** BOOLEAN 20.2.3 */
5548 offset = fBooleanTag(tvb, tree, offset, label);
5550 case 2: /** Unsigned Integer 20.2.4 */
5551 offset = fUnsignedTag(tvb, tree, offset, label);
5553 case 3: /** Signed Integer 20.2.5 */
5554 offset = fSignedTag(tvb, tree, offset, label);
5556 case 4: /** Real 20.2.6 */
5557 offset = fRealTag(tvb, tree, offset, label);
5559 case 5: /** Double 20.2.7 */
5560 offset = fDoubleTag(tvb, tree, offset, label);
5562 case 6: /** Octet String 20.2.8 */
5563 offset = fOctetString (tvb, tree, offset, label, lvt);
5565 case 7: /** Character String 20.2.9 */
5566 offset = fCharacterString (tvb,tree,offset,label);
5568 case 8: /** Bit String 20.2.10 */
5569 offset = fBitStringTagVS (tvb, tree, offset, label, src);
5571 case 9: /** Enumerated 20.2.11 */
5572 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
5574 case 10: /** Date 20.2.12 */
5575 offset = fDate (tvb, tree, offset, label);
5577 case 11: /** Time 20.2.13 */
5578 offset = fTime (tvb, tree, offset, label);
5580 case 12: /** BACnetObjectIdentifier 20.2.14 */
5581 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5583 case 13: /* reserved for ASHRAE */
5586 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
5587 offset+=lvt+tag_len;
5599 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
5601 guint lastoffset = 0;
5603 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5604 lastoffset = offset;
5606 switch (fTagNo(tvb,offset)) {
5607 case 0: /* percent */
5608 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
5611 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
5613 case 2: /* amount */
5614 offset = fRealTag(tvb, tree, offset, "shed amount: ");
5619 if (offset == lastoffset) break; /* nothing happened, exit loop */
5625 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5626 const gchar *label, const value_string *vs)
5628 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
5632 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5635 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
5639 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5641 guint8 tag_no, tag_info;
5645 proto_tree *subtree;
5649 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5650 /* cap the the suggested length in case of bad data */
5651 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
5652 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
5655 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
5656 "Context Value (as %u DATA octets)", lvt);
5658 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5659 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5661 return offset + tag_len + lvt;
5665 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5667 guint8 tag_no, tag_info;
5669 guint lastoffset = 0, depth = 0;
5672 if (propertyIdentifier >= 0) {
5673 g_snprintf (ar, sizeof(ar), "%s: ",
5674 val_to_split_str(propertyIdentifier, 512,
5675 BACnetPropertyIdentifier,
5676 ASHRAE_Reserved_Fmt,
5677 Vendor_Proprietary_Fmt));
5679 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
5681 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5682 lastoffset = offset;
5683 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5684 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
5685 if (depth <= 0) return offset;
5688 /* Application Tags */
5689 switch (propertyIdentifier) {
5690 case 2: /* action */
5691 /* loop object is application tagged,
5692 command object is context tagged */
5693 if (tag_is_context_specific(tag_info)) {
5694 /* BACnetActionList */
5695 offset = fActionList (tvb, pinfo, tree,offset);
5698 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5702 case 30: /* BACnetAddressBinding */
5703 offset = fAddressBinding (tvb,pinfo,tree,offset);
5705 case 54: /* list of object property reference */
5706 offset = fLOPR (tvb, pinfo, tree,offset);
5708 case 55: /* list-of-session-keys */
5709 fSessionKey (tvb, tree, offset);
5711 case 79: /* object-type */
5712 case 96: /* protocol-object-types-supported */
5713 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
5714 BACnetObjectType, 128);
5716 case 97: /* Protocol-Services-Supported */
5717 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5718 BACnetServicesSupported);
5720 case 102: /* recipient-list */
5721 offset = fDestination (tvb, pinfo, tree, offset);
5723 case 107: /* segmentation-supported */
5724 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5725 BACnetSegmentation);
5727 case 111: /* Status-Flags */
5728 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5731 case 112: /* System-Status */
5732 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5733 BACnetDeviceStatus);
5735 case 117: /* units */
5736 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5737 BACnetEngineeringUnits);
5739 case 87: /* priority-array -- accessed as a BACnetARRAY */
5740 if (propertyArrayIndex == 0) {
5741 /* BACnetARRAY index 0 refers to the length
5742 of the array, not the elements of the array */
5743 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5745 offset = fPriorityArray (tvb, pinfo, tree, offset);
5748 case 38: /* exception-schedule */
5749 if (object_type < 128) {
5750 if (propertyArrayIndex == 0) {
5751 /* BACnetARRAY index 0 refers to the length
5752 of the array, not the elements of the array */
5753 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5755 offset = fSpecialEvent (tvb,pinfo,tree,offset);
5759 case 19: /* controlled-variable-reference */
5760 case 60: /* manipulated-variable-reference */
5761 case 109: /* Setpoint-Reference */
5762 case 132: /* log-device-object-property */
5763 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
5765 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
5766 if (object_type < 128) {
5767 if (propertyArrayIndex == 0) {
5768 /* BACnetARRAY index 0 refers to the length
5769 of the array, not the elements of the array */
5770 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5772 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
5776 case 127: /* client COV increment */
5777 offset = fClientCOV (tvb, pinfo, tree, offset);
5779 case 131: /* log-buffer */
5780 offset = fLogRecord (tvb, pinfo, tree, offset);
5782 case 159: /* member-of */
5783 case 165: /* zone-members */
5784 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
5786 case 196: /* last-restart-reason */
5787 offset = fRestartReason (tvb, pinfo, tree, offset);
5789 case 212: /* actual-shed-level */
5790 case 214: /* expected-shed-level */
5791 case 218: /* requested-shed-level */
5792 offset = fShedLevel (tvb, tree, offset);
5794 case 152: /* active-cov-subscriptions */
5795 offset = fCOVSubscription (tvb, pinfo, tree, offset);
5799 if (tag_is_opening(tag_info)) {
5801 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5802 } else if (tag_is_closing(tag_info)) {
5804 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5806 offset = fContextTaggedValue(tvb, tree, offset, ar);
5809 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5813 if (offset == lastoffset) break; /* nothing happened, exit loop */
5820 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
5825 if (tag_is_opening(tag_info)) {
5826 offset += fTagHeaderTree(tvb, tree, offset,
5827 &tag_no, &tag_info, &lvt);
5828 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
5829 if (tvb_length_remaining(tvb, offset) > 0) {
5830 offset += fTagHeaderTree(tvb, tree, offset,
5831 &tag_no, &tag_info, &lvt);
5834 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
5835 "expected Opening Tag!"); \
5836 offset = tvb_length(tvb);
5844 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
5846 guint lastoffset = offset;
5847 guint8 tag_no, tag_info;
5850 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
5851 if (offset > lastoffset) {
5852 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5853 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
5854 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
5861 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5863 guint lastoffset = 0;
5864 guint8 tag_no, tag_info;
5867 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5868 lastoffset = offset;
5869 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
5870 if (offset > lastoffset) {
5871 /* detect optional priority
5872 by looking to see if the next tag is context tag number 3 */
5873 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5874 if (tag_is_context_specific(tag_info) && (tag_no == 3))
5875 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
5877 if (offset == lastoffset) break; /* nothing happened, exit loop */
5883 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5885 guint lastoffset = 0, len;
5886 guint8 tag_no, tag_info;
5888 proto_tree *subtree = tree;
5891 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5892 lastoffset = offset;
5893 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5894 if (tag_is_closing(tag_info)) {
5901 case 0: /* ProcessId */
5902 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
5904 case 1: /* monitored ObjectId */
5905 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5907 case 2: /* issueConfirmedNotifications */
5908 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
5910 case 3: /* life time */
5911 offset = fTimeSpan (tvb,tree,offset,"life time");
5913 case 4: /* monitoredPropertyIdentifier */
5914 if (tag_is_opening(tag_info)) {
5915 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
5917 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5919 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5920 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
5925 case 5: /* covIncrement */
5926 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5931 if (offset == lastoffset) break; /* nothing happened, exit loop */
5937 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5939 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
5943 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5945 guint lastoffset = 0;
5947 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5948 lastoffset = offset;
5950 switch (fTagNo(tvb, offset)) {
5951 case 0: /* deviceInstanceLowLimit */
5952 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
5954 case 1: /* deviceInstanceHighLimit */
5955 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
5957 case 2: /* BACnetObjectId */
5958 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5960 case 3: /* messageText */
5961 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
5966 if (offset == lastoffset) break; /* nothing happened, exit loop */
5973 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
5975 guint lastoffset = 0;
5976 guint8 tag_no, tag_info;
5979 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5980 if (tag_is_opening(tag_info) && tag_no == 0) {
5981 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
5982 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5983 lastoffset = offset;
5984 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5985 if (tag_is_closing(tag_info)) {
5986 /* should be closing context tag 0 */
5987 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5991 offset = fTimeValue (tvb, pinfo, subtree, offset);
5992 if (offset == lastoffset) break; /* nothing happened, exit loop */
5994 } else if (tag_no == 0 && lvt == 0) {
5995 /* not sure null (empty array element) is legal */
5996 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6002 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6004 guint lastoffset = 0;
6005 guint8 tag_no, tag_info;
6007 guint i = 1; /* day of week array index */
6008 proto_tree *subtree = tree;
6011 if (propertyArrayIndex > 0) {
6012 /* BACnetARRAY index 0 refers to the length
6013 of the array, not the elements of the array.
6014 BACnetARRAY index -1 is our internal flag that
6015 the optional index was not used.
6016 BACnetARRAY refers to this as all elements of the array.
6017 If the optional index is specified for a BACnetARRAY,
6018 then that specific array element is referenced. */
6019 i = propertyArrayIndex;
6021 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6022 lastoffset = offset;
6023 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6024 if (tag_is_closing(tag_info)) {
6025 return offset; /* outer encoding will print out closing tag */
6027 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
6028 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6029 offset = fDailySchedule (tvb, pinfo, subtree, offset);
6030 if (offset == lastoffset) break; /* nothing happened, exit loop */
6037 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
6039 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6042 return fDateTime (tvb, tree, offset, "UTC-Time: ");
6046 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
6048 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6051 return fDateTime (tvb, tree, offset, NULL);
6055 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
6057 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6059 offset = fDate (tvb,tree,offset,"Start Date: ");
6060 return fDate (tvb, tree, offset, "End Date: ");
6064 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6067 guint8 tag_no, tag_info;
6071 proto_tree *subtree;
6072 const gchar *label = "Vendor ID";
6074 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6075 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6076 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6077 "%s: %s (%u)", label,
6078 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
6080 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6081 "%s - %u octets (Unsigned)", label, lvt);
6082 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6083 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6085 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
6086 proto_item *expert_item;
6087 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6088 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6089 PROTO_ITEM_SET_GENERATED(expert_item);
6090 return offset+tag_len+lvt;
6093 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
6094 offset+tag_len, lvt, FALSE);
6096 return offset+tag_len+lvt;
6100 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6103 guint8 tag_no, tag_info;
6107 proto_tree *subtree;
6108 const gchar *label = "Restart Reason";
6110 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6111 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6112 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6113 "%s: %s (%u)", label,
6114 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
6116 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6117 "%s - %u octets (Unsigned)", label, lvt);
6118 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6119 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6122 proto_item *expert_item;
6123 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
6124 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
6125 PROTO_ITEM_SET_GENERATED(expert_item);
6126 return offset+tag_len+lvt;
6129 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
6130 offset+tag_len, lvt, FALSE);
6132 return offset+tag_len+lvt;
6136 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6138 guint lastoffset = 0;
6140 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6141 lastoffset = offset;
6142 switch (fTagNo(tvb, offset)) {
6144 case 0: /* textMessageSourceDevice */
6145 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6147 case 1: /* messageClass */
6148 switch (fTagNo(tvb, offset)) {
6149 case 0: /* numeric */
6150 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
6152 case 1: /* character */
6153 offset = fCharacterString (tvb, tree, offset, "message Class: ");
6157 case 2: /* messagePriority */
6158 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
6159 BACnetMessagePriority);
6161 case 3: /* message */
6162 offset = fCharacterString (tvb, tree, offset, "message: ");
6167 if (offset == lastoffset) break; /* nothing happened, exit loop */
6173 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6175 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
6179 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6181 guint lastoffset = 0, len;
6182 guint8 tag_no, tag_info;
6184 proto_tree *subtree = tree;
6187 guint vendor_identifier = 0;
6188 guint service_number = 0;
6190 lastoffset = offset;
6191 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6192 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
6193 if (col_get_writable(pinfo->cinfo))
6194 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
6195 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6197 next_tvb = tvb_new_subset_remaining(tvb,offset);
6198 if (dissector_try_uint(bacapp_dissector_table,
6199 vendor_identifier, next_tvb, pinfo, tree)) {
6200 /* we parsed it so skip over length and we are done */
6201 offset += tvb_length(next_tvb);
6205 /* Not handled by vendor dissector */
6207 /* exit loop if nothing happens inside */
6208 while (tvb_reported_length_remaining(tvb, offset)) {
6209 lastoffset = offset;
6210 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6211 if (tag_is_closing(tag_info)) {
6212 if (tag_no == 2) { /* Make sure it's the expected tag */
6217 break; /* End loop if incorrect closing tag */
6222 /* vendorID is now parsed above */
6223 case 1: /* serviceNumber */
6224 fUnsigned32(tvb, offset+len, lvt, &service_number);
6225 if (col_get_writable(pinfo->cinfo))
6226 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
6227 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
6229 case 2: /*serviceParameters */
6230 if (tag_is_opening(tag_info)) {
6231 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
6232 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6233 propertyIdentifier = -1;
6234 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6242 if (offset == lastoffset) break; /* nothing happened, exit loop */
6249 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6251 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
6255 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6257 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
6261 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6263 guint lastoffset = 0;
6264 guint8 tag_no, tag_info;
6266 proto_tree *subtree = tree;
6269 if (label != NULL) {
6270 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
6271 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6274 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6275 lastoffset = offset;
6276 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6279 case 0: /* subscriberProcessId */
6280 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
6282 case 1: /* requestingSource */
6283 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
6285 case 2: /* request */
6286 offset = fEnumeratedTagSplit (tvb, tree, offset,
6287 "request: ", BACnetLifeSafetyOperation, 64);
6289 case 3: /* objectId */
6290 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6295 if (offset == lastoffset) break; /* nothing happened, exit loop */
6301 fBACnetPropertyStates(tvbuff_t *tvb, proto_tree *tree, guint offset)
6303 switch (fTagNo(tvb, offset))
6306 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6309 offset = fEnumeratedTagSplit (tvb, tree, offset,
6310 "binary-value: ", BACnetBinaryPV, 2);
6313 offset = fEnumeratedTagSplit (tvb, tree, offset,
6314 "event-type: ", BACnetEventType, 12);
6317 offset = fEnumeratedTagSplit (tvb, tree, offset,
6318 "polarity: ", BACnetPolarity, 2);
6321 offset = fEnumeratedTagSplit (tvb, tree, offset,
6322 "program-change: ", BACnetProgramRequest, 5);
6325 offset = fEnumeratedTagSplit (tvb, tree, offset,
6326 "program-state: ", BACnetProgramState, 5);
6329 offset = fEnumeratedTagSplit (tvb, tree, offset,
6330 "reason-for-halt: ", BACnetProgramError, 5);
6333 offset = fEnumeratedTagSplit (tvb, tree, offset,
6334 "reliability: ", BACnetReliability, 10);
6337 offset = fEnumeratedTagSplit (tvb, tree, offset,
6338 "state: ", BACnetEventState, 64);
6341 offset = fEnumeratedTagSplit (tvb, tree, offset,
6342 "system-status: ", BACnetDeviceStatus, 64);
6345 offset = fEnumeratedTagSplit (tvb, tree, offset,
6346 "units: ", BACnetEngineeringUnits, 2);
6349 offset = fUnsignedTag(tvb, tree, offset, "unsigned-value: ");
6352 offset = fEnumeratedTagSplit (tvb, tree, offset,
6353 "life-safety-mode: ", BACnetLifeSafetyMode, 64);
6356 offset = fEnumeratedTagSplit (tvb, tree, offset,
6357 "life-safety-state: ", BACnetLifeSafetyState, 64);
6367 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
6368 deviceIdentifier [0] BACnetObjectIdentifier,
6369 objectIdentifier [1] BACnetObjectIdentifier,
6370 propertyIdentifier [2] BACnetPropertyIdentifier,
6371 arrayIndex [3] Unsigned OPTIONAL,
6372 value [4] ABSTRACT-SYNTAX.&Type
6376 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6378 guint lastoffset = 0;
6379 guint8 tag_no, tag_info;
6382 while (tvb_reported_length_remaining(tvb, offset)) {
6383 lastoffset = offset;
6384 /* check the tag. A closing tag means we are done */
6385 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6386 if (tag_is_closing(tag_info)) {
6390 case 0: /* deviceIdentifier */
6391 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6393 case 1: /* objectIdentifier */
6394 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6396 case 2: /* propertyIdentifier */
6397 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6399 case 3: /* arrayIndex - OPTIONAL */
6400 offset = fUnsignedTag (tvb, tree, offset,
6404 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6405 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6406 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6411 if (offset == lastoffset) break; /* nothing happened, exit loop */
6418 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
6419 objectIdentifier [0] BACnetObjectIdentifier,
6420 propertyIdentifier [1] BACnetPropertyIdentifier,
6421 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
6422 -- if omitted with an array then
6423 -- the entire array is referenced
6424 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
6428 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6430 guint lastoffset = 0;
6431 guint8 tag_no, tag_info;
6434 while (tvb_reported_length_remaining(tvb, offset)) {
6435 lastoffset = offset;
6436 /* check the tag. A closing tag means we are done */
6437 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6438 if (tag_is_closing(tag_info)) {
6442 case 0: /* objectIdentifier */
6443 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6445 case 1: /* propertyIdentifier */
6446 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6448 case 2: /* arrayIndex - OPTIONAL */
6449 offset = fUnsignedTag (tvb, tree, offset,
6452 case 3: /* deviceIdentifier - OPTIONAL */
6453 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6458 if (offset == lastoffset) break; /* nothing happened, exit loop */
6464 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6466 guint lastoffset = offset;
6467 guint8 tag_no, tag_info;
6469 proto_tree *subtree = tree;
6472 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6473 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
6474 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
6475 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6476 /* Opening tag for parameter choice */
6477 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6480 case 0: /* change-of-bitstring */
6481 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6482 lastoffset = offset;
6483 switch (fTagNo(tvb, offset)) {
6485 offset = fBitStringTag (tvb, subtree, offset,
6486 "referenced-bitstring: ");
6489 offset = fBitStringTagVS (tvb, subtree, offset,
6490 "status-flags: ", BACnetStatusFlags);
6491 lastoffset = offset;
6496 if (offset == lastoffset) break; /* nothing happened, exit loop */
6499 case 1: /* change-of-state */
6500 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6501 lastoffset = offset;
6502 switch (fTagNo(tvb, offset)) {
6504 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6505 offset = fBACnetPropertyStates(tvb, subtree, offset);
6506 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6509 offset = fBitStringTagVS (tvb, subtree, offset,
6510 "status-flags: ", BACnetStatusFlags);
6511 lastoffset = offset;
6516 if (offset == lastoffset) break; /* nothing happened, exit loop */
6519 case 2: /* change-of-value */
6520 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6521 lastoffset = offset;
6522 switch (fTagNo(tvb, offset)) {
6524 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6525 switch (fTagNo(tvb, offset)) {
6527 offset = fBitStringTag (tvb, subtree, offset,
6531 offset = fRealTag (tvb, subtree, offset,
6537 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6540 offset = fBitStringTagVS (tvb, subtree, offset,
6541 "status-flags: ", BACnetStatusFlags);
6542 lastoffset = offset;
6547 if (offset == lastoffset) break; /* nothing happened, exit loop */
6550 case 3: /* command-failure */
6551 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6552 lastoffset = offset;
6553 switch (fTagNo(tvb, offset)) {
6554 case 0: /* "command-value: " */
6555 /* from BACnet Table 13-3,
6556 Standard Object Property Values Returned in Notifications */
6557 propertyIdentifier = 85; /* PRESENT_VALUE */
6558 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6559 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6560 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6563 offset = fBitStringTagVS (tvb, subtree, offset,
6564 "status-flags: ", BACnetStatusFlags);
6566 case 2: /* "feedback-value: " */
6567 propertyIdentifier = 40; /* FEEDBACK_VALUE */
6568 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6569 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6570 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6571 lastoffset = offset;
6576 if (offset == lastoffset) break; /* nothing happened, exit loop */
6579 case 4: /* floating-limit */
6580 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6581 lastoffset = offset;
6582 switch (fTagNo(tvb, offset)) {
6584 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
6587 offset = fBitStringTagVS (tvb, subtree, offset,
6588 "status-flags: ", BACnetStatusFlags);
6591 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
6594 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
6595 lastoffset = offset;
6600 if (offset == lastoffset) break; /* nothing happened, exit loop */
6603 case 5: /* out-of-range */
6604 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6605 lastoffset = offset;
6606 switch (fTagNo(tvb, offset)) {
6608 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
6611 offset = fBitStringTagVS (tvb, subtree, offset,
6612 "status-flags: ", BACnetStatusFlags);
6615 offset = fRealTag (tvb, subtree, offset, "deadband: ");
6618 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
6619 lastoffset = offset;
6624 if (offset == lastoffset) break; /* nothing happened, exit loop */
6628 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6629 lastoffset = offset;
6630 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
6631 if (offset == lastoffset) break; /* nothing happened, exit loop */
6634 case 7: /* buffer-ready */
6635 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6636 lastoffset = offset;
6637 switch (fTagNo(tvb, offset)) {
6639 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
6642 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
6645 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6646 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
6647 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6650 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6651 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
6652 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6653 lastoffset = offset;
6658 if (offset == lastoffset) break; /* nothing happened, exit loop */
6661 case 8: /* change-of-life-safety */
6662 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6663 lastoffset = offset;
6664 switch (fTagNo(tvb, offset)) {
6666 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6667 "new-state: ", BACnetLifeSafetyState, 256);
6670 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6671 "new-mode: ", BACnetLifeSafetyMode, 256);
6674 offset = fBitStringTagVS (tvb, subtree, offset,
6675 "status-flags: ", BACnetStatusFlags);
6678 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6679 "operation-expected: ", BACnetLifeSafetyOperation, 64);
6680 lastoffset = offset;
6685 if (offset == lastoffset) break; /* nothing happened, exit loop */
6688 case 9: /* extended */
6689 while (tvb_reported_length_remaining(tvb, offset)) {
6690 lastoffset = offset;
6691 switch (fTagNo(tvb, offset)) {
6693 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6696 offset = fUnsignedTag (tvb, subtree, offset,
6697 "extended-event-type: ");
6699 case 2: /* parameters */
6700 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6701 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
6702 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
6703 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6704 lastoffset = offset;
6709 if (offset == lastoffset) break; /* nothing happened, exit loop */
6712 case 10: /* buffer ready */
6713 while (tvb_reported_length_remaining(tvb, offset)) {
6714 lastoffset = offset;
6715 switch (fTagNo(tvb, offset)) {
6716 case 0: /* buffer-property */
6717 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6718 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
6719 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6722 offset = fUnsignedTag (tvb, subtree, offset,
6723 "previous-notification: ");
6726 offset = fUnsignedTag (tvb, subtree, offset,
6727 "current-notification: ");
6728 lastoffset = offset;
6733 if (offset == lastoffset) break; /* nothing happened, exit loop */
6736 case 11: /* unsigned range */
6737 while (tvb_reported_length_remaining(tvb, offset)) {
6738 lastoffset = offset;
6739 switch (fTagNo(tvb, offset)) {
6741 offset = fUnsignedTag (tvb, subtree, offset,
6742 "exceeding-value: ");
6745 offset = fBitStringTagVS (tvb, subtree, offset,
6746 "status-flags: ", BACnetStatusFlags);
6749 offset = fUnsignedTag (tvb, subtree, offset,
6750 "exceeded-limit: ");
6751 lastoffset = offset;
6756 if (offset == lastoffset) break; /* nothing happened, exit loop */
6763 /* Closing tag for parameter choice */
6764 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6771 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset)
6773 guint lastoffset = 0;
6775 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6776 lastoffset = offset;
6777 switch (fTagNo(tvb, offset)) {
6778 case 0: /* change-of-bitstring */
6779 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6780 lastoffset = offset;
6781 switch (fTagNo(tvb, offset)) {
6783 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6786 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6788 case 2: /* SEQUENCE OF BIT STRING */
6789 offset = fBitStringTagVS (tvb, tree, offset,
6790 "bitstring value: ", BACnetEventTransitionBits);
6797 case 1: /* change-of-state */
6798 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6799 lastoffset = offset;
6800 switch (fTagNo(tvb, offset)) {
6802 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6804 case 1: /* SEQUENCE OF BACnetPropertyStates */
6805 offset = fEnumeratedTagSplit (tvb, tree, offset,
6806 "value: ", BACnetPropertyStates, 64);
6813 case 2: /* change-of-value */
6814 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6815 lastoffset = offset;
6816 switch (fTagNo(tvb, offset)) {
6818 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6820 case 1: /* don't loop it, it's a CHOICE */
6821 switch (fTagNo(tvb, offset)) {
6823 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6826 offset = fRealTag (tvb, tree, offset,
6827 "referenced Property Increment: ");
6837 case 3: /* command-failure */
6838 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6839 lastoffset = offset;
6840 switch (fTagNo(tvb, offset)) {
6842 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6845 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6851 case 4: /* floating-limit */
6852 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6853 lastoffset = offset;
6854 switch (fTagNo(tvb, offset)) {
6856 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6859 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6862 offset = fRealTag (tvb, tree, offset, "low diff limit: ");
6865 offset = fRealTag (tvb, tree, offset, "high diff limit: ");
6868 offset = fRealTag (tvb, tree, offset, "deadband: ");
6875 case 5: /* out-of-range */
6876 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6877 lastoffset = offset;
6878 switch (fTagNo(tvb, offset)) {
6880 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6883 offset = fRealTag (tvb, tree, offset, "low limit: ");
6886 offset = fRealTag (tvb, tree, offset, "high limit: ");
6889 offset = fRealTag (tvb, tree, offset, "deadband: ");
6897 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
6899 case 7: /* buffer-ready */
6900 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6901 lastoffset = offset;
6902 switch (fTagNo(tvb, offset)) {
6904 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
6907 offset = fUnsignedTag (tvb,tree,offset,
6908 "previous notification count: ");
6915 case 8: /* change-of-life-safety */
6916 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6917 lastoffset = offset;
6918 switch (fTagNo(tvb, offset)) {
6920 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6923 offset = fEnumeratedTagSplit (tvb, tree, offset,
6924 "life safety alarm value: ", BACnetLifeSafetyState, 256);
6927 offset = fEnumeratedTagSplit (tvb, tree, offset,
6928 "alarm value: ", BACnetLifeSafetyState, 256);
6931 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6947 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6949 guint lastoffset = 0;
6950 guint8 tag_no, tag_info;
6953 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6954 lastoffset = offset;
6955 switch (fTagNo(tvb, offset)) {
6956 case 0: /* timestamp */
6957 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6958 offset = fDate (tvb,tree,offset,"Date: ");
6959 offset = fTime (tvb,tree,offset,"Time: ");
6960 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6962 case 1: /* logDatum: don't loop, it's a CHOICE */
6963 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6964 switch (fTagNo(tvb, offset)) {
6965 case 0: /* logStatus */
6966 offset = fEnumeratedTag (tvb, tree, offset,
6967 "log status: ", BACnetLogStatus);
6970 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6973 offset = fRealTag (tvb, tree, offset, "real value: ");
6976 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
6979 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
6982 offset = fSignedTag (tvb, tree, offset, "signed value: ");
6985 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
6988 offset = fNullTag(tvb, tree, offset, "null value: ");
6991 offset = fError (tvb, pinfo, tree, offset);
6994 offset = fRealTag (tvb, tree, offset, "time change: ");
6996 case 10: /* any Value */
6997 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6998 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6999 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7004 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7007 offset = fEnumeratedTag (tvb, tree, offset,
7008 "Status Flags: ", BACnetStatusFlags);
7013 if (offset == lastoffset) break; /* nothing happened, exit loop */
7020 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7022 guint lastoffset = 0;
7023 guint8 tag_no, tag_info;
7026 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7027 lastoffset = offset;
7029 switch (fTagNo(tvb,offset)) {
7030 case 0: /* ProcessId */
7031 offset = fProcessId (tvb,tree,offset);
7033 case 1: /* initiating ObjectId */
7034 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7036 case 2: /* event ObjectId */
7037 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7039 case 3: /* time stamp */
7040 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7041 offset = fTimeStamp (tvb, tree, offset, NULL);
7042 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7044 case 4: /* notificationClass */
7045 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
7047 case 5: /* Priority */
7048 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
7050 case 6: /* EventType */
7051 offset = fEnumeratedTagSplit (tvb, tree, offset,
7052 "Event Type: ", BACnetEventType, 64);
7054 case 7: /* messageText */
7055 offset = fCharacterString (tvb, tree, offset, "message Text: ");
7057 case 8: /* NotifyType */
7058 offset = fEnumeratedTag (tvb, tree, offset,
7059 "Notify Type: ", BACnetNotifyType);
7061 case 9: /* ackRequired */
7062 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
7064 case 10: /* fromState */
7065 offset = fEnumeratedTagSplit (tvb, tree, offset,
7066 "from State: ", BACnetEventState, 64);
7068 case 11: /* toState */
7069 offset = fEnumeratedTagSplit (tvb, tree, offset,
7070 "to State: ", BACnetEventState, 64);
7072 case 12: /* NotificationParameters */
7073 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7074 offset = fNotificationParameters (tvb, pinfo, tree, offset);
7075 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7080 if (offset == lastoffset) break; /* nothing happened, exit loop */
7086 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7088 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
7092 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7094 guint lastoffset = 0, len;
7095 guint8 tag_no, tag_info;
7097 proto_tree *subtree = tree;
7100 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7101 lastoffset = offset;
7102 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7103 if (tag_is_closing(tag_info)) {
7110 case 0: /* ProcessId */
7111 offset = fProcessId (tvb,tree,offset);
7113 case 1: /* initiating DeviceId */
7114 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7116 case 2: /* monitored ObjectId */
7117 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7119 case 3: /* time remaining */
7120 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
7122 case 4: /* List of Values */
7123 if (tag_is_opening(tag_info)) {
7124 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
7125 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7126 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7127 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7135 if (offset == lastoffset) break; /* nothing happened, exit loop */
7141 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7143 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
7147 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7149 guint lastoffset = 0;
7150 guint8 tag_no = 0, tag_info = 0;
7153 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7154 lastoffset = offset;
7155 switch (fTagNo(tvb, offset)) {
7156 case 0: /* acknowledgingProcessId */
7157 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
7159 case 1: /* eventObjectId */
7160 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7162 case 2: /* eventStateAcknowledged */
7163 offset = fEnumeratedTagSplit (tvb, tree, offset,
7164 "event State Acknowledged: ", BACnetEventState, 64);
7166 case 3: /* timeStamp */
7167 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7168 offset = fTimeStamp(tvb, tree, offset, NULL);
7169 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7171 case 4: /* acknowledgementSource */
7172 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
7174 case 5: /* timeOfAcknowledgement */
7175 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7176 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
7177 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7182 if (offset == lastoffset) break; /* nothing happened, exit loop */
7188 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7190 guint lastoffset = 0;
7192 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7193 lastoffset = offset;
7194 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
7195 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
7196 "alarm State: ", BACnetEventState, 64);
7197 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7198 "acknowledged Transitions: ", BACnetEventTransitionBits);
7199 if (offset == lastoffset) break; /* nothing happened, exit loop */
7205 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7207 guint lastoffset = 0;
7208 guint8 tag_no, tag_info;
7211 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7212 lastoffset = offset;
7213 switch (fTagNo(tvb, offset)) {
7214 case 0: /* acknowledgmentFilter */
7215 offset = fEnumeratedTag (tvb, tree, offset,
7216 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
7218 case 1: /* eventObjectId - OPTIONAL */
7219 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7220 offset = fRecipientProcess (tvb, pinfo, tree, offset);
7221 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7223 case 2: /* eventStateFilter */
7224 offset = fEnumeratedTag (tvb, tree, offset,
7225 "event State Filter: ", BACnetEventStateFilter);
7227 case 3: /* eventTypeFilter - OPTIONAL */
7228 offset = fEnumeratedTag (tvb, tree, offset,
7229 "event Type Filter: ", BACnetEventType);
7231 case 4: /* priorityFilter */
7232 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7233 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
7234 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
7235 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7237 case 5: /* notificationClassFilter - OPTIONAL */
7238 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
7243 if (offset == lastoffset) break; /* nothing happened, exit loop */
7249 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7251 guint lastoffset = 0;
7253 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7254 lastoffset = offset;
7255 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
7256 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
7257 "event Type: ", BACnetEventType, 64);
7258 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7259 "event State: ", BACnetEventState);
7260 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
7261 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
7262 if (offset == lastoffset) break; /* nothing happened, exit loop */
7269 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7271 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7272 if (fTagNo(tvb, offset) == 0) {
7273 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7280 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7282 guint lastoffset = 0;
7283 guint8 tag_no, tag_info;
7285 proto_tree* subtree = tree;
7288 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7289 lastoffset = offset;
7290 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7291 /* we are finished here if we spot a closing tag */
7292 if (tag_is_closing(tag_info)) {
7296 case 0: /* ObjectId */
7297 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7299 case 1: /* eventState */
7300 offset = fEnumeratedTag (tvb, tree, offset,
7301 "event State: ", BACnetEventState);
7303 case 2: /* acknowledgedTransitions */
7304 offset = fBitStringTagVS (tvb, tree, offset,
7305 "acknowledged Transitions: ", BACnetEventTransitionBits);
7307 case 3: /* eventTimeStamps */
7308 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
7310 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7312 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7313 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
7314 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
7315 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
7316 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7318 case 4: /* notifyType */
7319 offset = fEnumeratedTag (tvb, tree, offset,
7320 "Notify Type: ", BACnetNotifyType);
7322 case 5: /* eventEnable */
7323 offset = fBitStringTagVS (tvb, tree, offset,
7324 "event Enable: ", BACnetEventTransitionBits);
7326 case 6: /* eventPriorities */
7327 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
7329 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7331 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7332 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
7333 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
7334 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
7335 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7340 if (offset == lastoffset) break; /* nothing happened, exit loop */
7346 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7348 guint lastoffset = 0;
7349 guint8 tag_no, tag_info;
7352 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7353 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7354 lastoffset = offset;
7355 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7356 /* we are finished here if we spot a closing tag */
7357 if (tag_is_closing(tag_info)) {
7360 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7361 if (offset == lastoffset) break; /* nothing happened, exit loop */
7367 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7369 guint lastoffset = 0;
7370 guint8 tag_no, tag_info;
7373 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7374 lastoffset = offset;
7375 switch (fTagNo(tvb, offset)) {
7376 case 0: /* listOfEventSummaries */
7377 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7378 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
7379 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7381 case 1: /* moreEvents */
7382 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
7387 if (offset == lastoffset) break; /* nothing happened, exit loop */
7393 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7395 guint lastoffset = 0, len;
7396 guint8 tag_no, tag_info;
7398 proto_tree *subtree = tree;
7401 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7403 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7404 lastoffset = offset;
7405 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7406 if (tag_is_closing(tag_info)) {
7413 case 0: /* ObjectId */
7414 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
7416 case 3: /* listOfElements */
7417 if (tag_is_opening(tag_info)) {
7418 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
7419 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7420 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7421 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7429 if (offset == lastoffset) break; /* nothing happened, exit loop */
7435 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7437 return fObjectIdentifier (tvb, pinfo, tree, offset);
7441 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7443 guint lastoffset = 0;
7445 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7446 lastoffset = offset;
7448 switch (fTagNo(tvb, offset)) {
7449 case 0: /* timeDuration */
7450 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
7452 case 1: /* enable-disable */
7453 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
7454 BACnetEnableDisable);
7456 case 2: /* password - OPTIONAL */
7457 offset = fCharacterString (tvb, tree, offset, "Password: ");
7462 if (offset == lastoffset) break; /* nothing happened, exit loop */
7468 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7470 guint lastoffset = 0;
7472 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7473 lastoffset = offset;
7475 switch (fTagNo(tvb, offset)) {
7476 case 0: /* reinitializedStateOfDevice */
7477 offset = fEnumeratedTag (tvb, tree, offset,
7478 "reinitialized State Of Device: ",
7479 BACnetReinitializedStateOfDevice);
7481 case 1: /* password - OPTIONAL */
7482 offset = fCharacterString (tvb, tree, offset, "Password: ");
7487 if (offset == lastoffset) break; /* nothing happened, exit loop */
7493 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7495 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7496 "vtClass: ", BACnetVTClass);
7497 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
7501 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7503 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7507 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7509 guint lastoffset = 0;
7511 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7512 lastoffset = offset;
7513 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7514 if (offset == lastoffset) break; /* nothing happened, exit loop */
7520 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7522 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
7523 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
7524 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
7528 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
7530 guint lastoffset = 0;
7532 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7533 lastoffset = offset;
7535 switch (fTagNo(tvb,offset)) {
7536 case 0: /* BOOLEAN */
7537 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
7539 case 1: /* Unsigned OPTIONAL */
7540 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
7545 if (offset == lastoffset) break; /* nothing happened, exit loop */
7551 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
7553 guint lastoffset = 0;
7555 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7556 lastoffset = offset;
7558 switch (fTagNo(tvb,offset)) {
7559 case 0: /* Unsigned32 */
7560 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
7562 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
7563 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
7565 case 2: /* Chararacter String OPTIONAL */
7566 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
7568 case 3: /* Chararacter String OPTIONAL */
7569 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
7571 case 4: /* Boolean OPTIONAL */
7572 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
7577 if (offset == lastoffset) break; /* nothing happened, exit loop */
7583 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7585 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
7589 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7591 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
7592 offset = fAddress (tvb, tree, offset);
7593 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
7594 return fAddress (tvb, tree, offset);
7598 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7600 /* Same as AddListElement request after service choice */
7601 return fAddListElementRequest(tvb, pinfo, tree, offset);
7605 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7607 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
7611 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7613 guint lastoffset = 0, len;
7614 guint8 tag_no, tag_info;
7616 proto_tree *subtree = tree;
7618 /* set the optional global properties to indicate not-used */
7619 propertyArrayIndex = -1;
7620 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7621 lastoffset = offset;
7622 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7623 if (tag_is_closing(tag_info)) {
7629 case 0: /* objectIdentifier */
7630 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7632 case 1: /* propertyIdentifier */
7633 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7635 case 2: /* propertyArrayIndex */
7636 offset = fPropertyArrayIndex (tvb, subtree, offset);
7638 case 3: /* propertyValue */
7639 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7644 if (offset == lastoffset) break; /* nothing happened, exit loop */
7650 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7652 guint lastoffset = 0;
7653 guint8 tag_no, tag_info;
7655 proto_tree *subtree = tree;
7657 /* set the optional global properties to indicate not-used */
7658 propertyArrayIndex = -1;
7659 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7660 lastoffset = offset;
7661 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7662 /* quit loop if we spot a closing tag */
7663 if (tag_is_closing(tag_info)) {
7669 case 0: /* objectIdentifier */
7670 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7672 case 1: /* propertyIdentifier */
7673 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7675 case 2: /* propertyArrayIndex */
7676 offset = fPropertyArrayIndex (tvb, subtree, offset);
7678 case 3: /* propertyValue */
7679 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7681 case 4: /* Priority (only used for write) */
7682 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7687 if (offset == lastoffset) break; /* nothing happened, exit loop */
7693 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7695 guint lastoffset = 0, len;
7696 guint8 tag_no, tag_info;
7699 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7700 lastoffset = offset;
7701 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7702 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
7703 if (tag_is_closing(tag_info)) {
7709 case 0: /* objectIdentifier */
7710 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7712 case 1: /* listOfPropertyValues */
7713 if (tag_is_opening(tag_info)) {
7714 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7715 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7723 if (offset == lastoffset) break; /* nothing happened, exit loop */
7729 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7731 if (offset >= tvb_reported_length(tvb))
7734 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7735 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
7739 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
7741 guint lastoffset = 0;
7742 guint8 tag_no, tag_info;
7745 /* set the optional global properties to indicate not-used */
7746 propertyArrayIndex = -1;
7747 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7748 lastoffset = offset;
7749 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7750 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
7752 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
7755 switch (tag_no-tagoffset) {
7756 case 0: /* PropertyIdentifier */
7757 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7759 case 1: /* propertyArrayIndex */
7760 offset = fPropertyArrayIndex (tvb, tree, offset);
7761 if (list != 0) break; /* Continue decoding if this may be a list */
7763 lastoffset = offset; /* Set loop end condition */
7766 if (offset == lastoffset) break; /* nothing happened, exit loop */
7772 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
7774 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7775 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
7779 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7781 guint lastoffset = 0;
7783 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7784 lastoffset = offset;
7786 switch (fTagNo(tvb,offset)) {
7787 case 0: /* ObjectIdentifier */
7788 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7790 case 1: /* PropertyIdentifier and propertyArrayIndex */
7791 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
7792 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7794 lastoffset = offset; /* Set loop end condition */
7797 if (offset == lastoffset) break; /* nothing happened, exit loop */
7804 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
7806 guint lastoffset = 0;
7807 guint8 tag_no, tag_info;
7809 proto_tree* subtree = tree;
7812 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7813 lastoffset = offset;
7814 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7815 if (tag_is_closing(tag_info)) {
7816 offset += fTagHeaderTree (tvb, subtree, offset,
7817 &tag_no, &tag_info, &lvt);
7821 case 0: /* ObjectIdentifier */
7822 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7824 case 1: /* PropertyIdentifier */
7825 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7827 case 2: /* propertyArrayIndex */
7828 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
7831 offset = fPropertyValue (tvb, subtree, offset, tag_info);
7833 case 4: /* Priority */
7834 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7845 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7847 char i = 1, ar[256];
7848 guint lastoffset = 0;
7850 if (propertyArrayIndex > 0) {
7851 /* BACnetARRAY index 0 refers to the length
7852 of the array, not the elements of the array.
7853 BACnetARRAY index -1 is our internal flag that
7854 the optional index was not used.
7855 BACnetARRAY refers to this as all elements of the array.
7856 If the optional index is specified for a BACnetARRAY,
7857 then that specific array element is referenced. */
7858 i = propertyArrayIndex;
7860 while (tvb_reported_length_remaining(tvb, offset)) {
7861 /* exit loop if nothing happens inside */
7862 lastoffset = offset;
7863 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
7864 val_to_split_str(87 , 512,
7865 BACnetPropertyIdentifier,
7866 ASHRAE_Reserved_Fmt,
7867 Vendor_Proprietary_Fmt),
7869 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
7870 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
7871 /* there are only 16 priority array elements */
7875 if (offset == lastoffset) break; /* nothing happened, exit loop */
7882 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7884 guint lastoffset = 0;
7886 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7887 lastoffset = offset;
7889 switch (fTagNo(tvb,offset)) {
7890 case 0: /* deviceIdentifier - OPTIONAL */
7891 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7893 case 1: /* ObjectIdentifier */
7894 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7899 if (offset == lastoffset) break; /* nothing happened, exit loop */
7905 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7907 guint8 tag_no, tag_info;
7909 guint lastoffset = 0, len;
7911 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7912 lastoffset = offset;
7913 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7914 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
7915 if (tag_is_closing(tag_info)) {
7921 case 0: /* calendaryEntry */
7922 if (tag_is_opening(tag_info)) {
7923 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7924 offset = fCalendaryEntry (tvb, subtree, offset);
7925 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7928 case 1: /* calendarReference */
7929 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7931 case 2: /* list of BACnetTimeValue */
7932 if (tag_is_opening(tag_info)) {
7933 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7934 offset = fTimeValue (tvb, pinfo, subtree, offset);
7935 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7940 case 3: /* eventPriority */
7941 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
7946 if (offset == lastoffset) break; /* nothing happened, exit loop */
7952 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7954 guint lastoffset = 0, len;
7955 guint8 tag_no, tag_info;
7958 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7959 lastoffset = offset;
7960 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7961 /* maybe a listOfSelectionCriteria if we spot a closing tag */
7962 if (tag_is_closing(tag_info)) {
7967 switch (fTagNo(tvb,offset)) {
7968 case 0: /* propertyIdentifier */
7969 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7971 case 1: /* propertyArrayIndex */
7972 offset = fPropertyArrayIndex (tvb, tree, offset);
7974 case 2: /* relationSpecifier */
7975 offset = fEnumeratedTag (tvb, tree, offset,
7976 "relation Specifier: ", BACnetRelationSpecifier);
7978 case 3: /* comparisonValue */
7979 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7980 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7981 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7986 if (offset == lastoffset) break; /* nothing happened, exit loop */
7992 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7994 guint lastoffset = 0;
7995 guint8 tag_no, tag_info;
7998 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7999 lastoffset = offset;
8000 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8001 /* quit loop if we spot a closing tag */
8002 if (tag_is_closing(tag_info)) {
8007 case 0: /* selectionLogic */
8008 offset = fEnumeratedTag (tvb, subtree, offset,
8009 "selection Logic: ", BACnetSelectionLogic);
8011 case 1: /* listOfSelectionCriteria */
8012 if (tag_is_opening(tag_info)) {
8013 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8014 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
8015 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8023 if (offset == lastoffset) break; /* nothing happened, exit loop */
8030 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
8032 guint lastoffset = 0;
8033 guint8 tag_no, tag_info;
8036 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8037 lastoffset = offset;
8038 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8040 if (tag_is_opening(tag_info) && tag_no < 2) {
8041 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8043 case 0: /* objectSelectionCriteria */
8044 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
8046 case 1: /* listOfPropertyReferences */
8047 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
8052 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8054 if (offset == lastoffset) break; /* nothing happened, exit loop */
8060 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8062 guint lastoffset = 0;
8063 guint8 tag_no, tag_info;
8066 proto_tree *subtree = tree;
8068 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8069 lastoffset = offset;
8070 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8072 case 0: /* objectIdentifier */
8073 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8075 case 1: /* listOfPropertyReferences */
8076 if (tag_is_opening(tag_info)) {
8077 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
8078 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8079 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8080 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
8081 } else if (tag_is_closing(tag_info)) {
8082 offset += fTagHeaderTree (tvb, subtree, offset,
8083 &tag_no, &tag_info, &lvt);
8086 /* error condition: let caller handle */
8093 if (offset == lastoffset) break; /* nothing happened, exit loop */
8099 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8101 guint lastoffset = 0, len;
8105 proto_tree *subtree = tree;
8108 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8109 lastoffset = offset;
8110 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8111 /* maybe a listOfReadAccessResults if we spot a closing tag here */
8112 if (tag_is_closing(tag_info)) {
8114 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
8119 case 0: /* objectSpecifier */
8120 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8122 case 1: /* list of Results */
8123 if (tag_is_opening(tag_info)) {
8124 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
8125 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8126 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8131 case 2: /* propertyIdentifier */
8132 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
8134 case 5: /* propertyAccessError */
8135 if (tag_is_opening(tag_info)) {
8136 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
8137 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8138 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8139 /* Error Code follows */
8140 offset = fError(tvb, pinfo, subtree, offset);
8148 if (offset == lastoffset) break; /* nothing happened, exit loop */
8155 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8157 /* listOfReadAccessResults */
8158 return fReadAccessResult (tvb, pinfo, tree, offset);
8163 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8165 guint lastoffset = 0;
8166 guint8 tag_no, tag_info;
8169 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8170 lastoffset = offset;
8171 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8174 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8176 case 0: /* objectSpecifier */
8177 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
8178 case 0: /* objectType */
8179 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
8181 case 1: /* objectIdentifier */
8182 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8188 case 1: /* propertyValue */
8189 if (tag_is_opening(tag_info)) {
8190 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8198 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8200 if (offset == lastoffset) break; /* nothing happened, exit loop */
8206 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8208 return fObjectIdentifier (tvb, pinfo, tree, offset);
8212 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8214 guint8 tag_no, tag_info;
8216 proto_tree *subtree = tree;
8219 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
8221 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8222 /* optional range choice */
8223 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8224 if (tag_is_opening(tag_info)) {
8225 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
8226 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8227 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8229 case 3: /* range byPosition */
8230 case 6: /* range bySequenceNumber, 2004 spec */
8231 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
8232 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
8234 case 4: /* range byTime - deprecated in 2004 */
8235 case 7: /* 2004 spec */
8236 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
8237 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
8239 case 5: /* range timeRange - deprecated in 2004 */
8240 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
8241 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
8246 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8253 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8255 guint8 tag_no, tag_info;
8257 proto_tree *subtree = tree;
8260 /* set the optional global properties to indicate not-used */
8261 propertyArrayIndex = -1;
8262 /* objectIdentifier, propertyIdentifier, and
8263 OPTIONAL propertyArrayIndex */
8264 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
8265 /* resultFlags => BACnetResultFlags ::= BIT STRING */
8266 offset = fBitStringTagVS (tvb, tree, offset,
8270 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
8272 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8273 if (tag_is_opening(tag_info)) {
8274 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8275 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
8276 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8277 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8278 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8279 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8281 /* firstSequenceNumber - OPTIONAL */
8282 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8283 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
8290 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8292 guint lastoffset = 0;
8294 guint8 tag_no, tag_info;
8296 proto_tree* subtree = NULL;
8298 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8300 if (tag_is_opening(tag_info)) {
8301 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
8302 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8303 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8304 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
8305 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
8308 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
8309 /* exit loop if nothing happens inside */
8310 lastoffset = offset;
8311 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
8315 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
8316 /* More Flag is not set, so we can look for closing tag in this segment */
8317 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8318 if (tag_is_closing(tag_info)) {
8319 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8327 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8329 guint8 tag_no, tag_info;
8331 proto_tree *subtree = tree;
8334 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8336 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8338 if (tag_is_opening(tag_info)) {
8339 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
8340 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8341 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8342 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
8343 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
8344 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8350 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8353 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
8354 offset = fAccessMethod(tvb, pinfo, tree, offset);
8360 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
8362 guint tag_no = fTagNo(tvb, offset);
8363 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
8367 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8369 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
8370 offset = fAccessMethod(tvb,pinfo, tree, offset);
8376 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8378 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8379 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
8383 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8385 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8386 return fReadAccessResult (tvb,pinfo,tree,offset);
8390 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8392 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8395 switch (service_choice) {
8396 case 0: /* acknowledgeAlarm */
8397 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
8399 case 1: /* confirmedCOVNotification */
8400 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8402 case 2: /* confirmedEventNotification */
8403 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8405 case 3: /* confirmedGetAlarmSummary conveys no parameters */
8407 case 4: /* getEnrollmentSummaryRequest */
8408 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
8410 case 5: /* subscribeCOVRequest */
8411 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
8413 case 6: /* atomicReadFile-Request */
8414 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
8416 case 7: /* atomicWriteFile-Request */
8417 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
8419 case 8: /* AddListElement-Request */
8420 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
8422 case 9: /* removeListElement-Request */
8423 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
8425 case 10: /* createObjectRequest */
8426 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
8428 case 11: /* deleteObject */
8429 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
8432 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
8435 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
8438 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
8441 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
8444 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
8447 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
8450 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8453 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8456 offset = fReinitializeDeviceRequest(tvb, tree, offset);
8459 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
8462 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8465 offset = fVtDataRequest (tvb, pinfo, tree, offset);
8468 offset = fAuthenticateRequest (tvb, tree, offset);
8471 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
8474 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
8477 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
8480 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
8483 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
8492 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8494 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8497 switch (service_choice) {
8498 case 3: /* confirmedEventNotificationAck */
8499 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
8501 case 4: /* getEnrollmentSummaryAck */
8502 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
8504 case 6: /* atomicReadFile */
8505 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
8507 case 7: /* atomicReadFileAck */
8508 offset = fAtomicWriteFileAck (tvb, tree, offset);
8510 case 10: /* createObject */
8511 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
8514 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
8517 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
8520 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
8523 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
8526 offset = fVtOpenAck (tvb, pinfo, tree, offset);
8529 offset = fVtDataAck (tvb, tree, offset);
8532 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
8535 offset = fReadRangeAck (tvb, pinfo, tree, offset);
8538 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
8547 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8549 /* BACnetObjectIdentifier */
8550 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
8552 /* MaxAPDULengthAccepted */
8553 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
8555 /* segmentationSupported */
8556 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8557 "Segmentation Supported: ", BACnetSegmentation);
8560 return fVendorIdentifier (tvb, pinfo, tree, offset);
8564 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8566 /* BACnetDeviceIdentifier */
8567 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
8569 /* BACnetObjectIdentifier */
8570 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8573 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
8578 fWhoIsRequest (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
8580 guint lastoffset = 0;
8584 guint8 tag_no, tag_info;
8587 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8588 lastoffset = offset;
8590 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8594 /* DeviceInstanceRangeLowLimit Optional */
8595 fUnsigned32(tvb, offset+tag_len, lvt, &val);
8596 if (col_get_writable(pinfo->cinfo))
8597 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
8598 offset = fDevice_Instance (tvb, tree, offset,
8599 hf_Device_Instance_Range_Low_Limit);
8602 /* DeviceInstanceRangeHighLimit Optional but
8603 required if DeviceInstanceRangeLowLimit is there */
8604 fUnsigned32(tvb, offset+tag_len, lvt, &val);
8605 if (col_get_writable(pinfo->cinfo))
8606 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
8607 offset = fDevice_Instance (tvb, tree, offset,
8608 hf_Device_Instance_Range_High_Limit);
8613 if (offset == lastoffset) break; /* nothing happened, exit loop */
8619 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8621 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8624 switch (service_choice) {
8625 case 0: /* I-Am-Request */
8626 offset = fIAmRequest (tvb, pinfo, tree, offset);
8628 case 1: /* i-Have Request */
8629 offset = fIHaveRequest (tvb, pinfo, tree, offset);
8631 case 2: /* unconfirmedCOVNotification */
8632 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8634 case 3: /* unconfirmedEventNotification */
8635 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8637 case 4: /* unconfirmedPrivateTransfer */
8638 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8640 case 5: /* unconfirmedTextMessage */
8641 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8643 case 6: /* timeSynchronization */
8644 offset = fTimeSynchronizationRequest (tvb, tree, offset);
8646 case 7: /* who-Has */
8647 offset = fWhoHas (tvb, pinfo, tree, offset);
8649 case 8: /* who-Is */
8650 offset = fWhoIsRequest (tvb, pinfo, tree, offset);
8652 case 9: /* utcTimeSynchronization */
8653 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
8662 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
8663 gint *svc, proto_item **tt)
8666 proto_tree *bacapp_tree_control;
8671 tmp = (gint) tvb_get_guint8(tvb, offset);
8672 bacapp_flags = tmp & 0x0f;
8677 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
8678 if (bacapp_flags & 0x08)
8679 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
8681 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8682 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, TRUE);
8683 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
8685 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, TRUE);
8686 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, TRUE);
8687 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
8688 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, TRUE);
8689 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
8691 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
8695 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
8696 if (bacapp_flags & 0x08) {
8697 bacapp_seq = tvb_get_guint8(tvb, offset);
8698 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
8700 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
8703 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8709 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
8710 { /* BACnet-Confirmed-Request */
8711 /* ASHRAE 135-2001 20.1.2 */
8713 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
8717 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8718 { /* BACnet-Confirmed-Request */
8719 /* ASHRAE 135-2001 20.1.2 */
8723 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
8724 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
8728 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8729 { /* BACnet-Unconfirmed-Request-PDU */
8730 /* ASHRAE 135-2001 20.1.3 */
8734 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8736 tmp = tvb_get_guint8(tvb, offset);
8737 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
8739 /* Service Request follows... Variable Encoding 20.2ff */
8740 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
8744 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8745 { /* BACnet-Simple-Ack-PDU */
8746 /* ASHRAE 135-2001 20.1.4 */
8748 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8750 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8752 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8759 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
8760 { /* BACnet-Complex-Ack-PDU */
8761 /* ASHRAE 135-2001 20.1.5 */
8763 /* Service ACK follows... */
8764 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
8768 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8769 { /* BACnet-Complex-Ack-PDU */
8770 /* ASHRAE 135-2001 20.1.5 */
8774 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
8775 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
8779 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8780 { /* BACnet-SegmentAck-PDU */
8781 /* ASHRAE 135-2001 20.1.6 */
8784 proto_tree *bacapp_tree_control;
8786 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8787 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8789 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, TRUE);
8790 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8791 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
8793 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
8795 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
8801 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8803 guint8 tag_info = 0;
8804 guint8 parsed_tag = 0;
8806 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8807 offset = fError(tvb, pinfo, tree, offset);
8808 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8812 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8814 guint lastoffset = 0;
8815 guint8 tag_no = 0, tag_info = 0;
8817 proto_tree *subtree = tree;
8820 guint vendor_identifier = 0;
8821 guint service_number = 0;
8824 while (tvb_reported_length_remaining(tvb, offset)) {
8825 /* exit loop if nothing happens inside */
8826 lastoffset = offset;
8827 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8829 case 0: /* errorType */
8830 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
8832 case 1: /* vendorID */
8833 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
8834 if (col_get_writable(pinfo->cinfo))
8835 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
8836 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
8838 case 2: /* serviceNumber */
8839 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
8840 if (col_get_writable(pinfo->cinfo))
8841 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
8842 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
8844 case 3: /* errorParameters */
8845 if (tag_is_opening(tag_info)) {
8846 tt = proto_tree_add_text(subtree, tvb, offset, 1,
8847 "error Parameters");
8848 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8849 propertyIdentifier = -1;
8850 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8851 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8852 } else if (tag_is_closing(tag_info)) {
8853 offset += fTagHeaderTree (tvb, subtree, offset,
8854 &tag_no, &tag_info, &lvt);
8857 /* error condition: let caller handle */
8864 if (offset == lastoffset) break; /* nothing happened, exit loop */
8870 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8872 guint lastoffset = 0;
8874 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8875 lastoffset = offset;
8876 switch (fTagNo(tvb, offset)) {
8877 case 0: /* errorType */
8878 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8880 case 1: /* firstFailedElementNumber */
8881 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
8886 if (offset == lastoffset) break; /* nothing happened, exit loop */
8892 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8894 /* Identical to CreateObjectError */
8895 return fCreateObjectError(tvb, pinfo, tree, offset);
8899 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8901 guint8 tag_no = 0, tag_info = 0;
8904 if (fTagNo(tvb, offset) == 0) {
8906 offset = fContextTaggedError(tvb, pinfo, tree,offset);
8907 if (fTagNo(tvb, offset) == 1) {
8908 /* listOfVTSessionIdentifiers [OPTIONAL] */
8909 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8910 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8911 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8914 /* should report bad packet if initial tag wasn't 0 */
8919 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8921 guint lastoffset = 0;
8922 guint8 tag_no = 0, tag_info = 0;
8925 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8926 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8927 lastoffset = offset;
8928 switch (fTagNo(tvb, offset)) {
8929 case 0: /* errorType */
8930 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8932 case 1: /* firstFailedWriteAttempt */
8933 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8934 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8935 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8940 if (offset == lastoffset) break; /* nothing happened, exit loop */
8946 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8948 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8949 "error Class: ", BACnetErrorClass, 64);
8950 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8951 "error Code: ", BACnetErrorCode, 256);
8955 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
8958 case 8: /* no break here !!!! */
8960 offset = fChangeListError (tvb, pinfo, tree, offset);
8963 offset = fCreateObjectError (tvb, pinfo, tree, offset);
8966 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
8969 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
8972 offset = fVTCloseError (tvb, pinfo, tree, offset);
8975 return fError (tvb, pinfo, tree, offset);
8981 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8982 { /* BACnet-Error-PDU */
8983 /* ASHRAE 135-2001 20.1.7 */
8986 proto_tree *bacapp_tree_control;
8989 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8990 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8992 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
8994 tmp = tvb_get_guint8(tvb, offset);
8995 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
8997 /* Error Handling follows... */
8998 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
9002 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9003 { /* BACnet-Reject-PDU */
9004 /* ASHRAE 135-2001 20.1.8 */
9007 proto_tree *bacapp_tree_control;
9009 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
9010 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9012 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9014 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
9020 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9021 { /* BACnet-Abort-PDU */
9022 /* ASHRAE 135-2001 20.1.9 */
9025 proto_tree *bacapp_tree_control;
9027 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
9028 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9030 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
9031 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9033 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
9039 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
9041 guint8 flag, bacapp_type;
9044 flag = (gint) tvb_get_guint8(tvb, 0);
9045 bacapp_type = (flag >> 4) & 0x0f;
9051 /* ASHRAE 135-2001 20.1.1 */
9052 switch (bacapp_type) {
9053 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
9054 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
9056 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
9057 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
9059 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
9060 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
9062 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
9063 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
9065 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
9066 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
9068 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
9069 offset = fErrorPDU(tvb, pinfo, tree, offset);
9071 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
9072 offset = fRejectPDU(tvb, pinfo, tree, offset);
9074 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
9075 offset = fAbortPDU(tvb, pinfo, tree, offset);
9082 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
9084 guint8 flag, bacapp_type;
9085 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
9086 tvbuff_t* new_tvb = NULL;
9088 guint8 bacapp_seqno = 0;
9089 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
9090 guint8 bacapp_invoke_id = 0;
9092 proto_tree *bacapp_tree = NULL;
9098 /* Strings for BACnet Statistics */
9099 const gchar errstr[]="ERROR: ";
9100 const gchar rejstr[]="REJECTED: ";
9101 const gchar abortstr[]="ABORTED: ";
9102 const gchar sackstr[]=" (SimpleAck)";
9103 const gchar cackstr[]=" (ComplexAck)";
9104 const gchar uconfsreqstr[]=" (Unconfirmed Service Request)";
9105 const gchar confsreqstr[]=" (Confirmed Service Request)";
9107 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
9108 col_clear (pinfo->cinfo, COL_INFO);
9110 flag = tvb_get_guint8(tvb, 0);
9111 bacapp_type = (flag >> 4) & 0x0f;
9113 /* show some descriptive text in the INFO column */
9114 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
9115 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
9117 bacinfo.service_type = NULL;
9118 bacinfo.invoke_id = NULL;
9119 bacinfo.instance_ident = NULL;
9120 bacinfo.object_ident = NULL;
9122 switch (bacapp_type)
9124 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
9125 /* segmented messages have 2 additional bytes */
9126 if (flag & BACAPP_SEGMENTED_REQUEST) {
9129 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
9130 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
9131 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
9132 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
9133 bacapp_service = tvb_get_guint8(tvb, offset + 5);
9136 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
9137 bacapp_service = tvb_get_guint8(tvb, offset + 3);
9139 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
9140 val_to_str(bacapp_service,
9141 BACnetConfirmedServiceChoice,
9142 bacapp_unknown_service_str),bacapp_invoke_id);
9144 updateBacnetInfoValue(BACINFO_INVOKEID,
9145 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9147 updateBacnetInfoValue(BACINFO_SERVICE,
9148 ep_strconcat(val_to_str(bacapp_service,
9149 BACnetConfirmedServiceChoice,
9150 bacapp_unknown_service_str),
9151 confsreqstr, NULL));
9153 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
9154 bacapp_service = tvb_get_guint8(tvb, offset + 1);
9155 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
9156 val_to_str(bacapp_service,
9157 BACnetUnconfirmedServiceChoice,
9158 bacapp_unknown_service_str));
9160 updateBacnetInfoValue(BACINFO_SERVICE,
9161 ep_strconcat(val_to_str(bacapp_service,
9162 BACnetUnconfirmedServiceChoice,
9163 bacapp_unknown_service_str),
9164 uconfsreqstr, NULL));
9166 case BACAPP_TYPE_SIMPLE_ACK:
9167 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9168 bacapp_service = tvb_get_guint8(tvb, offset + 2);
9169 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9170 val_to_str(bacapp_service,
9171 BACnetConfirmedServiceChoice,
9172 bacapp_unknown_service_str), bacapp_invoke_id);
9174 updateBacnetInfoValue(BACINFO_INVOKEID,
9175 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9177 updateBacnetInfoValue(BACINFO_SERVICE,
9178 ep_strconcat(val_to_str(bacapp_service,
9179 BACnetConfirmedServiceChoice,
9180 bacapp_unknown_service_str),
9183 case BACAPP_TYPE_COMPLEX_ACK:
9184 /* segmented messages have 2 additional bytes */
9185 if (flag & BACAPP_SEGMENTED_REQUEST) {
9188 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
9189 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9190 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
9191 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
9192 bacapp_service = tvb_get_guint8(tvb, offset + 4);
9195 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9196 bacapp_service = tvb_get_guint8(tvb, offset + 2);
9198 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9199 val_to_str(bacapp_service,
9200 BACnetConfirmedServiceChoice,
9201 bacapp_unknown_service_str), bacapp_invoke_id);
9203 updateBacnetInfoValue(BACINFO_INVOKEID,
9204 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9206 updateBacnetInfoValue(BACINFO_SERVICE,
9207 ep_strconcat(val_to_str(bacapp_service,
9208 BACnetConfirmedServiceChoice,
9209 bacapp_unknown_service_str),
9212 case BACAPP_TYPE_SEGMENT_ACK:
9213 /* nothing more to add */
9215 case BACAPP_TYPE_ERROR:
9216 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9217 bacapp_service = tvb_get_guint8(tvb, offset + 2);
9218 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9219 val_to_str(bacapp_service,
9220 BACnetConfirmedServiceChoice,
9221 bacapp_unknown_service_str), bacapp_invoke_id);
9223 updateBacnetInfoValue(BACINFO_INVOKEID,
9224 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9226 updateBacnetInfoValue(BACINFO_SERVICE,
9227 ep_strconcat(errstr,
9228 val_to_str(bacapp_service,
9229 BACnetConfirmedServiceChoice,
9230 bacapp_unknown_service_str),
9233 case BACAPP_TYPE_REJECT:
9234 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9235 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
9236 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9237 val_to_split_str(bacapp_reason,
9240 ASHRAE_Reserved_Fmt,
9241 Vendor_Proprietary_Fmt), bacapp_invoke_id);
9243 updateBacnetInfoValue(BACINFO_INVOKEID,
9244 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9246 updateBacnetInfoValue(BACINFO_SERVICE,
9247 ep_strconcat(rejstr,
9248 val_to_split_str(bacapp_reason, 64,
9250 ASHRAE_Reserved_Fmt,
9251 Vendor_Proprietary_Fmt),
9254 case BACAPP_TYPE_ABORT:
9255 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9256 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
9257 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9258 val_to_split_str(bacapp_reason,
9261 ASHRAE_Reserved_Fmt,
9262 Vendor_Proprietary_Fmt), bacapp_invoke_id);
9264 updateBacnetInfoValue(BACINFO_INVOKEID,
9265 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9267 updateBacnetInfoValue(BACINFO_SERVICE,
9268 ep_strconcat(abortstr,
9269 val_to_split_str(bacapp_reason,
9272 ASHRAE_Reserved_Fmt,
9273 Vendor_Proprietary_Fmt),
9278 /* nothing more to add */
9282 save_fragmented = pinfo->fragmented;
9284 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, FALSE);
9285 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
9288 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
9290 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
9291 /* not resetting the offset so the remaining can be done */
9293 if (fragment) { /* fragmented */
9294 fragment_data *frag_msg = NULL;
9297 pinfo->fragmented = TRUE;
9299 frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
9300 bacapp_invoke_id, /* ID for fragments belonging together */
9301 msg_fragment_table, /* list of message fragments */
9302 msg_reassembled_table, /* list of reassembled messages */
9303 bacapp_seqno, /* fragment sequence number */
9304 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
9305 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
9306 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
9307 "Reassembled BACapp", frag_msg, &msg_frag_items,
9310 if (new_tvb) { /* Reassembled */
9311 col_append_str(pinfo->cinfo, COL_INFO,
9312 " (Message Reassembled)");
9313 } else { /* Not last packet of reassembled Short Message */
9314 col_append_fstr(pinfo->cinfo, COL_INFO,
9315 " (Message fragment %u)", bacapp_seqno);
9317 if (new_tvb) { /* take it all */
9318 switch (bacapp_type)
9320 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
9321 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
9323 case BACAPP_TYPE_COMPLEX_ACK:
9324 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
9334 pinfo->fragmented = save_fragmented;
9337 tap_queue_packet(bacapp_tap,pinfo,&bacinfo);
9341 bacapp_init_routine(void)
9343 fragment_table_init(&msg_fragment_table);
9344 reassembled_table_init(&msg_reassembled_table);
9348 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
9353 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
9354 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
9355 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
9358 g_iconv_close (icd);
9362 uni_to_string(in,*inbytesleft,out);
9363 out[*inbytesleft] = '\0';
9364 *outbytesleft -= *inbytesleft;
9371 uni_to_string(char * data, gsize str_length, char *dest_buf)
9375 gsize length_remaining = 0;
9377 length_remaining = str_length;
9379 if(str_length == 0) {
9382 for ( i = 0; i < (gint) str_length; i++ ) {
9384 if (c_char<0x20 || c_char>0x7e) {
9385 if (c_char != 0x00) {
9387 dest_buf[i] = c_char & 0xff;
9393 dest_buf[i] = c_char & 0xff;
9397 if(length_remaining==0) {
9398 dest_buf[i+1] = '\0';
9410 proto_register_bacapp(void)
9412 static hf_register_info hf[] = {
9414 { "APDU Type", "bacapp.type",
9415 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
9417 { &hf_bacapp_pduflags,
9418 { "PDU Flags", "bacapp.pduflags",
9419 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
9422 { "Segmented Request", "bacapp.segmented_request",
9423 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
9426 { "More Segments", "bacapp.more_segments",
9427 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
9430 { "SA", "bacapp.SA",
9431 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
9433 { &hf_bacapp_max_adpu_size,
9434 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
9435 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
9437 { &hf_bacapp_response_segments,
9438 { "Max Response Segments accepted", "bacapp.response_segments",
9439 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
9441 { &hf_bacapp_objectType,
9442 { "Object Type", "bacapp.objectType",
9443 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
9445 { &hf_bacapp_instanceNumber,
9446 { "Instance Number", "bacapp.instance_number",
9447 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
9449 { &hf_BACnetPropertyIdentifier,
9450 { "Property Identifier", "bacapp.property_identifier",
9451 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
9453 { &hf_BACnetVendorIdentifier,
9454 { "Vendor Identifier", "bacapp.vendor_identifier",
9455 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
9457 { &hf_BACnetRestartReason,
9458 { "Restart Reason", "bacapp.restart_reason",
9459 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
9461 { &hf_bacapp_invoke_id,
9462 { "Invoke ID", "bacapp.invoke_id",
9463 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9465 { &hf_bacapp_sequence_number,
9466 { "Sequence Number", "bacapp.sequence_number",
9467 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9469 { &hf_bacapp_window_size,
9470 { "Proposed Window Size", "bacapp.window_size",
9471 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9473 { &hf_bacapp_service,
9474 { "Service Choice", "bacapp.confirmed_service",
9475 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
9477 { &hf_bacapp_uservice,
9478 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
9479 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
9482 { "NAK", "bacapp.NAK",
9483 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
9486 { "SRV", "bacapp.SRV",
9487 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
9489 { &hf_Device_Instance_Range_Low_Limit,
9490 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
9491 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
9493 { &hf_Device_Instance_Range_High_Limit,
9494 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
9495 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
9497 { &hf_BACnetRejectReason,
9498 { "Reject Reason", "bacapp.reject_reason",
9499 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
9501 { &hf_BACnetAbortReason,
9502 { "Abort Reason", "bacapp.abort_reason",
9503 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
9505 { &hf_BACnetApplicationTagNumber,
9506 { "Application Tag Number",
9507 "bacapp.application_tag_number",
9508 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
9511 { &hf_BACnetContextTagNumber,
9512 { "Context Tag Number",
9513 "bacapp.context_tag_number",
9514 FT_UINT8, BASE_DEC, NULL, 0xF0,
9517 { &hf_BACnetExtendedTagNumber,
9518 { "Extended Tag Number",
9519 "bacapp.extended_tag_number",
9520 FT_UINT8, BASE_DEC, NULL, 0,
9523 { &hf_BACnetNamedTag,
9526 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
9529 { &hf_BACnetCharacterSet,
9530 { "String Character Set",
9531 "bacapp.string_character_set",
9532 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet),0,
9535 { &hf_BACnetTagClass,
9536 { "Tag Class", "bacapp.tag_class",
9537 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
9539 { &hf_bacapp_tag_lvt,
9540 { "Length Value Type",
9542 FT_UINT8, BASE_DEC, NULL, 0,
9545 { &hf_bacapp_tag_ProcessId,
9546 { "ProcessIdentifier", "bacapp.processId",
9547 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
9549 { &hf_bacapp_tag_IPV4,
9550 { "IPV4", "bacapp.IPV4",
9551 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
9553 { &hf_bacapp_tag_IPV6,
9554 { "IPV6", "bacapp.IPV6",
9555 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
9557 { &hf_bacapp_tag_PORT,
9558 { "Port", "bacapp.Port",
9559 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
9562 {"Message fragments", "bacapp.fragments",
9563 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9565 {"Message fragment", "bacapp.fragment",
9566 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9567 {&hf_msg_fragment_overlap,
9568 {"Message fragment overlap", "bacapp.fragment.overlap",
9569 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9570 {&hf_msg_fragment_overlap_conflicts,
9571 {"Message fragment overlapping with conflicting data",
9572 "bacapp.fragment.overlap.conflicts",
9573 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9574 {&hf_msg_fragment_multiple_tails,
9575 {"Message has multiple tail fragments",
9576 "bacapp.fragment.multiple_tails",
9577 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9578 {&hf_msg_fragment_too_long_fragment,
9579 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
9580 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9581 {&hf_msg_fragment_error,
9582 {"Message defragmentation error", "bacapp.fragment.error",
9583 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9584 {&hf_msg_fragment_count,
9585 {"Message fragment count", "bacapp.fragment.count",
9586 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
9587 {&hf_msg_reassembled_in,
9588 {"Reassembled in", "bacapp.reassembled.in",
9589 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9590 {&hf_msg_reassembled_length,
9591 {"Reassembled BACapp length", "bacapp.reassembled.length",
9592 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
9594 static gint *ett[] = {
9596 &ett_bacapp_control,
9605 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
9606 "BACapp", "bacapp");
9608 proto_register_field_array(proto_bacapp, hf, array_length(hf));
9609 proto_register_subtree_array(ett, array_length(ett));
9610 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
9611 register_init_routine (&bacapp_init_routine);
9613 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
9614 "BACapp Vendor Identifier",
9615 FT_UINT8, BASE_HEX);
9617 /* Register BACnet Statistic trees */
9618 register_bacapp_stat_trees();
9619 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
9623 proto_reg_handoff_bacapp(void)
9625 data_handle = find_dissector("data");