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 * BACnetCalendarEntry ::= CHOICE {
1428 * dateRange [1] BACnetDateRange,
1429 * weekNDay [2] BacnetWeekNday
1434 * @return modified offset
1437 fCalendarEntry (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 * BACnetObjectPropertyReference ::= SEQUENCE {
1543 * objectIdentifier [0] BACnetObjectIdentifier,
1544 * propertyIdentifier [1] BACnetPropertyIdentifier,
1545 * propertyArrayIndex [2] Unsigend OPTIONAL,
1551 * @return modified offset
1554 fObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1557 * BACnetDeviceObjectReference ::= SEQUENCE {
1558 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1559 * objectIdentifier [1] BACnetObjectIdentifier
1565 * @return modified offset
1568 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1571 * BACnetEventParameter ::= CHOICE {
1572 * change-of-bitstring [0] SEQUENCE {
1573 * time-delay [0] Unsigned,
1574 * bitmask [1] BIT STRING,
1575 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1577 * change-of-state [1] SEQUENCE {
1578 * time-delay [0] Unsigned,
1579 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1581 * change-of-value [2] SEQUENCE {
1582 * time-delay [0] Unsigned,
1583 * cov-criteria [1] CHOICE {
1584 * bitmask [0] BIT STRING,
1585 * referenced-property-increment [1] REAL
1588 * command-failure [3] SEQUENCE {
1589 * time-delay [0] Unsigned,
1590 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1592 * floating-limit [4] SEQUENCE {
1593 * time-delay [0] Unsigned,
1594 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1595 * low-diff-limit [2] REAL,
1596 * high-diff-limit [3] REAL,
1599 * out-of-range [5] SEQUENCE {
1600 * time-delay [0] Unsigned,
1601 * low-limit [1] REAL,
1602 * high-limit [2] REAL,
1605 * buffer-ready [7] SEQUENCE {
1606 * notification-threshold [0] Unsigned,
1607 * previous-notification-count [1] Unsigned32
1609 * change-of-life-safety [8] SEQUENCE {
1610 * time-delay [0] Unsigned,
1611 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1612 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1613 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1619 * @return modified offset
1622 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1627 * BACnetLogRecord ::= SEQUENCE {
1628 * timestamp [0] BACnetDateTime,
1629 * logDatum [1] CHOICE {
1630 * log-status [0] BACnetLogStatus,
1631 * boolean-value [1] BOOLEAN,
1632 * real-value [2] REAL,
1633 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1634 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1635 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1636 * bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
1637 * null-value [7] NULL,
1638 * failure [8] Error,
1639 * time-change [9] REAL,
1640 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1642 * statusFlags [2] BACnetStatusFlags OPTIONAL
1648 * @return modified offset
1651 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1654 * BACnetEventLogRecord ::= SEQUENCE {
1655 * timestamp [0] BACnetDateTime,
1656 * logDatum [1] CHOICE {
1657 * log-status [0] BACnetLogStatus,
1658 * notification [1] ConfirmedEventNotification-Request,
1659 * time-change [2] REAL,
1666 * @return modified offset
1669 fEventLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1672 fLogMultipleRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1675 * BACnetNotificationParameters ::= CHOICE {
1676 * change-of-bitstring [0] SEQUENCE {
1677 * referenced-bitstring [0] BIT STRING,
1678 * status-flags [1] BACnetStatusFlags
1680 * change-of-state [1] SEQUENCE {
1681 * new-state [0] BACnetPropertyStatus,
1682 * status-flags [1] BACnetStatusFlags
1684 * change-of-value [2] SEQUENCE {
1685 * new-value [0] CHOICE {
1686 * changed-bits [0] BIT STRING,
1687 * changed-value [1] REAL
1689 * status-flags [1] BACnetStatusFlags
1691 * command-failure [3] SEQUENCE {
1692 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1693 * status-flags [1] BACnetStatusFlags
1694 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1696 * floating-limit [4] SEQUENCE {
1697 * reference-value [0] REAL,
1698 * status-flags [1] BACnetStatusFlags
1699 * setpoint-value [2] REAL,
1700 * error-limit [3] REAL
1702 * out-of-range [5] SEQUENCE {
1703 * exceeding-value [0] REAL,
1704 * status-flags [1] BACnetStatusFlags
1705 * deadband [2] REAL,
1706 * exceeded-limit [0] REAL
1708 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1709 * buffer-ready [7] SEQUENCE {
1710 * buffer-device [0] BACnetObjectIdentifier,
1711 * buffer-object [1] BACnetObjectIdentifier
1712 * previous-notification [2] BACnetDateTime,
1713 * current-notification [3] BACnetDateTime
1715 * change-of-life-safety [8] SEQUENCE {
1716 * new-state [0] BACnetLifeSafetyState,
1717 * new-mode [1] BACnetLifeSafetyState
1718 * status-flags [2] BACnetStatusFlags,
1719 * operation-expected [3] BACnetLifeSafetyOperation
1726 * @return modified offset
1729 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1732 * BACnetObjectPropertyReference ::= SEQUENCE {
1733 * objectIdentifier [0] BACnetObjectIdentifier,
1734 * propertyIdentifier [1] BACnetPropertyIdentifier,
1735 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1741 * @return modified offset
1744 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1748 * BACnetObjectPropertyValue ::= SEQUENCE {
1749 * objectIdentifier [0] BACnetObjectIdentifier,
1750 * propertyIdentifier [1] BACnetPropertyIdentifier,
1751 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1752 * -- if omitted with an array the entire array is referenced
1753 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1754 * priority [4] Unsigned (1..16) OPTIONAL
1759 * @return modified offset
1762 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
1766 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1771 * @return modified offset
1774 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1777 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1780 * BACnetPropertyReference ::= SEQUENCE {
1781 * propertyIdentifier [0] BACnetPropertyIdentifier,
1782 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1788 * @return modified offset
1791 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1794 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1797 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1800 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1803 * BACnetPropertyValue ::= SEQUENCE {
1804 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1805 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1806 * -- if omitted with an array the entire array is referenced
1807 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1808 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1814 * @return modified offset
1817 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1820 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1823 * BACnet Application PDUs chapter 21
1824 * BACnetRecipient::= CHOICE {
1825 * device [0] BACnetObjectIdentifier
1826 * address [1] BACnetAddress
1832 * @return modified offset
1835 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1838 * BACnet Application PDUs chapter 21
1839 * BACnetRecipientProcess::= SEQUENCE {
1840 * recipient [0] BACnetRecipient
1841 * processID [1] Unsigned32
1847 * @return modified offset
1850 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1853 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1857 * BACnetSessionKey ::= SEQUENCE {
1858 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1859 * peerAddress BACnetAddress
1864 * @return modified offset
1865 * @todo check if checksum is displayed correctly
1868 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1872 * BACnetSpecialEvent ::= SEQUENCE {
1874 * calendarEntry [0] BACnetCalendarEntry,
1875 * calendarRefernce [1] BACnetObjectIdentifier
1877 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1878 * eventPriority [3] Unsigned (1..16)
1884 * @return modified offset
1887 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1890 * BACnetTimeStamp ::= CHOICE {
1892 * sequenceNumber [1] Unsigned (0..65535),
1893 * dateTime [2] BACnetDateTime
1899 * @return modified offset
1902 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1905 fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1908 * BACnetTimeValue ::= SEQUENCE {
1910 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1916 * @return modified offset
1919 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1923 * BACnetVTSession ::= SEQUENCE {
1924 * local-vtSessionID Unsigned8,
1925 * remote-vtSessionID Unsigned8,
1926 * remote-vtAddress BACnetAddress
1931 * @return modified offset
1934 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1938 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1939 * -- first octet month (1..12) January = 1, X'FF' = any month
1940 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1941 * -- 2 = days numbered 8-14
1942 * -- 3 = days numbered 15-21
1943 * -- 4 = days numbered 22-28
1944 * -- 5 = days numbered 29-31
1945 * -- 6 = last 7 days of this month
1946 * -- X'FF' = any week of this month
1947 * -- third octet dayOfWeek (1..7) where 1 = Monday
1949 * -- X'FF' = any day of week
1953 * @return modified offset
1956 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
1959 * ReadAccessResult ::= SEQUENCE {
1960 * objectIdentifier [0] BACnetObjectIdentifier,
1961 * listOfResults [1] SEQUENCE OF SEQUENCE {
1962 * propertyIdentifier [2] BACnetPropertyIdentifier,
1963 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1964 * readResult CHOICE {
1965 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1966 * propertyAccessError [5] Error
1974 * @return modified offset
1977 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1980 * ReadAccessSpecification ::= SEQUENCE {
1981 * objectIdentifier [0] BACnetObjectIdentifier,
1982 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
1988 * @return modified offset
1991 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1994 * WriteAccessSpecification ::= SEQUENCE {
1995 * objectIdentifier [0] BACnetObjectIdentifier,
1996 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
2002 * @return modified offset
2005 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2008 /********************************************************* Helper functions *******************************************/
2011 * extracts the tag number from the tag header.
2012 * @param tvb "TestyVirtualBuffer"
2013 * @param offset in actual tvb
2014 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
2017 fTagNo (tvbuff_t *tvb, guint offset);
2020 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
2021 * @param tvb = "TestyVirtualBuffer"
2022 * @param offset = offset in actual tvb
2023 * @return tag_no BACnet 20.2.1.2 Tag Number
2024 * @return class_tag BACnet 20.2.1.1 Class
2025 * @return lvt BACnet 20.2.1.3 Length/Value/Type
2026 * @return offs = length of this header
2030 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
2034 * adds processID with max 32Bit unsigned Integer Value to tree
2038 * @return modified offset
2041 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
2044 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2048 * @return modified offset
2051 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2054 * BACnet Application PDUs chapter 21
2055 * BACnetPropertyIdentifier::= ENUMERATED {
2056 * @see bacapp_property_identifier
2062 * @param tt returnvalue of this item
2063 * @return modified offset
2066 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2069 * BACnet Application PDUs chapter 21
2070 * BACnetPropertyArrayIndex::= ENUMERATED {
2071 * @see bacapp_property_array_index
2076 * @param tt returnvalue of this item
2077 * @return modified offset
2080 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
2083 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2084 * objectIdentifier [0] BACnetObjectIdentifier,
2085 * eventState [1] BACnetEventState,
2086 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2087 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2088 * notifyType [4] BACnetNotifyType,
2089 * eventEnable [5] BACnetEventTransitionBits,
2090 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2096 * @return modified offset
2099 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2102 * SelectionCriteria ::= SEQUENCE {
2103 * propertyIdentifier [0] BACnetPropertyIdentifier,
2104 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2105 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2106 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2112 * @return modified offset
2115 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2118 * objectSelectionCriteria ::= SEQUENCE {
2119 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2120 * listOfSelectionCriteria [1] SelectionCriteria
2126 * @return modified offset
2129 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2132 * BACnet-Error ::= SEQUENCE {
2133 * error-class ENUMERATED {},
2134 * error-code ENUMERATED {}
2141 * @return modified offset
2144 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2147 * Generic handler for context tagged values. Mostly for handling
2148 * vendor-defined properties and services.
2152 * @return modified offset
2153 * @todo beautify this ugly construct
2156 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2159 * realizes some ABSTRACT-SYNTAX.&Type
2164 * @return modified offset
2165 * @todo beautify this ugly construct
2168 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2172 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2173 const value_string *src);
2179 proto_register_bacapp(void);
2182 * proto_reg_handoff_bacapp
2185 proto_reg_handoff_bacapp(void);
2188 * converts XXX coded strings to UTF-8
2189 * else 'in' is copied to 'out'
2190 * @param in -- pointer to string
2191 * @param inbytesleft
2192 * @param out -- pointer to string
2193 * @param outbytesleft
2195 * @return count of modified characters of returned string, -1 for errors
2198 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2201 uni_to_string(char * data, gsize str_length, char *dest_buf);
2203 /* <<<< formerly bacapp.h */
2205 /* some hashes for segmented messages */
2206 static GHashTable *msg_fragment_table = NULL;
2207 static GHashTable *msg_reassembled_table = NULL;
2209 /* some necessary forward function prototypes */
2211 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2212 const gchar *label, const value_string *vs);
2214 static const char *bacapp_unknown_service_str = "unknown service";
2215 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2216 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2218 static const value_string
2219 BACnetTypeName[] = {
2220 {0, "Confirmed-REQ"},
2221 {1, "Unconfirmed-REQ"},
2231 static const true_false_string segments_follow = {
2232 "Segmented Request",
2233 "Unsegmented Request"
2236 static const true_false_string more_follow = {
2237 "More Segments Follow",
2238 "No More Segments Follow"
2241 static const true_false_string segmented_accept = {
2242 "Segmented Response accepted",
2243 "Segmented Response not accepted"
2246 static const true_false_string
2248 "Context Specific Tag",
2252 static const value_string
2253 BACnetMaxSegmentsAccepted [] = {
2261 {7,"Greater than 64 segments"},
2265 static const value_string
2266 BACnetMaxAPDULengthAccepted [] = {
2267 {0,"Up to MinimumMessageSize (50 octets)"},
2268 {1,"Up to 128 octets"},
2269 {2,"Up to 206 octets (fits in a LonTalk frame)"},
2270 {3,"Up to 480 octets (fits in an ARCNET frame)"},
2271 {4,"Up to 1024 octets"},
2272 {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2273 {6,"reserved by ASHRAE"},
2274 {7,"reserved by ASHRAE"},
2275 {8,"reserved by ASHRAE"},
2276 {9,"reserved by ASHRAE"},
2277 {10,"reserved by ASHRAE"},
2278 {11,"reserved by ASHRAE"},
2279 {12,"reserved by ASHRAE"},
2280 {13,"reserved by ASHRAE"},
2281 {14,"reserved by ASHRAE"},
2282 {15,"reserved by ASHRAE"},
2286 static const value_string
2287 BACnetRejectReason [] = {
2289 {1,"buffer-overflow"},
2290 {2,"inconsistent-parameters"},
2291 {3,"invalid-parameter-data-type"},
2293 {5,"missing-required-parameter"},
2294 {6,"parameter-out-of-range"},
2295 {7,"too-many-arguments"},
2296 {8,"undefined-enumeration"},
2297 {9,"unrecognized-service"},
2301 static const value_string
2302 BACnetRestartReason [] = {
2306 {3,"detected-power-lost"},
2307 {4,"detected-powered-off"},
2308 {5,"hardware-watchdog"},
2309 {6,"software-watchdog"},
2314 static const value_string
2315 BACnetApplicationTagNumber [] = {
2318 {2,"Unsigned Integer"},
2319 {3,"Signed Integer (2's complement notation)"},
2320 {4,"Real (ANSI/IEE-754 floating point)"},
2321 {5,"Double (ANSI/IEE-754 double precision floating point)"},
2323 {7,"Character String"},
2328 {12,"BACnetObjectIdentifier"},
2329 {13,"reserved by ASHRAE"},
2330 {14,"reserved by ASHRAE"},
2331 {15,"reserved by ASHRAE"},
2335 static const value_string
2342 static const value_string
2343 BACnetFileAccessMethod [] = {
2344 {0,"record-access"},
2345 {1,"stream-access"},
2349 /* For some reason, BACnet defines the choice parameter
2350 in the file read and write services backwards from the
2351 BACnetFileAccessMethod enumeration.
2353 static const value_string
2354 BACnetFileAccessOption [] = {
2355 {0,"stream access"},
2356 {1,"record access"},
2360 static const value_string
2361 BACnetFileStartOption [] = {
2362 {0, "File Start Position: "},
2363 {1, "File Start Record: "},
2367 static const value_string
2368 BACnetFileRequestCount [] = {
2369 {0, "Requested Octet Count: "},
2370 {1, "Requested Record Count: "},
2374 static const value_string
2375 BACnetFileWriteInfo [] = {
2377 {1, "Record Count: "},
2381 static const value_string
2382 BACnetAbortReason [] = {
2384 {1,"buffer-overflow"},
2385 {2,"invalid-apdu-in-this-state"},
2386 {3,"preempted-by-higher-priority-task"},
2387 {4,"segmentation-not-supported"},
2391 static const value_string
2392 BACnetLifeSafetyMode [] = {
2403 {10,"disconnected"},
2406 {13,"atomic-release-disabled"},
2409 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2410 Enumerated values 256-65535 may be used by others subject to
2411 procedures and constraints described in Clause 23. */
2414 static const value_string
2415 BACnetLifeSafetyOperation [] = {
2418 {2,"silence-audible"},
2419 {3,"silence-visual"},
2424 {8,"unsilence-audible"},
2425 {9,"unsilence-visual"},
2427 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2428 Enumerated values 64-65535 may be used by others subject to
2429 procedures and constraints described in Clause 23. */
2432 static const value_string
2433 BACnetLimitEnable [] = {
2434 {0,"lowLimitEnable"},
2435 {1,"highLimitEnable"},
2439 static const value_string
2440 BACnetLifeSafetyState [] = {
2445 {4,"fault-pre-alarm"},
2453 {12,"test-fault-alarm"},
2456 {15,"tamper-alarm"},
2458 {17,"emergency-power"},
2462 {21,"general-alarm"},
2464 {23,"test-supervisory"},
2466 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2467 Enumerated values 256-65535 may be used by others subject to
2468 procedures and constraints described in Clause 23. */
2471 static const value_string
2472 BACnetConfirmedServiceChoice [] = {
2473 {0,"acknowledgeAlarm"},
2474 {1,"confirmedCOVNotification"},
2475 {2,"confirmedEventNotification"},
2476 {3,"getAlarmSummary"},
2477 {4,"getEnrollmentSummary"},
2479 {6,"atomicReadFile"},
2480 {7,"atomicWriteFile"},
2481 {8,"addListElement"},
2482 {9,"removeListElement"},
2483 {10,"createObject"},
2484 {11,"deleteObject"},
2485 {12,"readProperty"},
2486 {13,"readPropertyConditional"},
2487 {14,"readPropertyMultiple"},
2488 {15,"writeProperty"},
2489 {16,"writePropertyMultiple"},
2490 {17,"deviceCommunicationControl"},
2491 {18,"confirmedPrivateTransfer"},
2492 {19,"confirmedTextMessage"},
2493 {20,"reinitializeDevice"},
2497 {24,"authenticate"},
2500 {27,"lifeSafetyOperation"},
2501 {28,"subscribeCOVProperty"},
2502 {29,"getEventInformation"},
2503 {30,"reserved by ASHRAE"},
2507 static const value_string
2508 BACnetReliability [] = {
2509 {0,"no-fault-detected"},
2516 {7,"unreliable-other"},
2517 {8,"process-error"},
2518 {9,"multi-state-fault"},
2519 {10,"configuration-error"},
2520 /* enumeration value 11 is reserved for a future addendum */
2521 {12,"communication-failure"},
2522 {13,"member-fault"},
2526 static const value_string
2527 BACnetUnconfirmedServiceChoice [] = {
2530 {2,"unconfirmedCOVNotification"},
2531 {3,"unconfirmedEventNotification"},
2532 {4,"unconfirmedPrivateTransfer"},
2533 {5,"unconfirmedTextMessage"},
2534 {6,"timeSynchronization"},
2537 {9,"utcTimeSynchonization"},
2541 static const value_string
2542 BACnetUnconfirmedServiceRequest [] = {
2544 {1,"i-Have-Request"},
2545 {2,"unconfirmedCOVNotification-Request"},
2546 {3,"unconfirmedEventNotification-Request"},
2547 {4,"unconfirmedPrivateTransfer-Request"},
2548 {5,"unconfirmedTextMessage-Request"},
2549 {6,"timeSynchronization-Request"},
2550 {7,"who-Has-Request"},
2551 {8,"who-Is-Request"},
2552 {9,"utcTimeSynchonization-Request"},
2556 static const value_string
2557 BACnetObjectType [] = {
2559 {1,"analog-output"},
2562 {4,"binary-output"},
2567 {9,"event-enrollment"},
2571 {13,"multi-state-input"},
2572 {14,"multi-state-output"},
2573 {15,"notification-class"},
2577 {19,"multi-state-value"},
2579 {21,"life-safety-point"},
2580 {22,"life-safety-zone"},
2582 {24,"pulse-converter"},
2584 {26,"global-group"},
2585 {27,"trend-log-multiple"},
2586 {28,"load-control"},
2587 {29,"structured-view"},
2588 {30,"access-door"}, /* 30-37 added with addanda 135-2008j */
2589 /* value 31 is unassigned */
2590 {32,"access-credential"},
2591 {33,"access-point"},
2592 {34,"access-rights"},
2595 {37,"credential-data-input"},
2596 {38,"network-security"},
2597 {39,"bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2598 {40,"characterstring-value"},
2599 {41,"date-pattern-value"},
2601 {43,"datetime-pattern-value"},
2602 {44,"datetime-value"},
2603 {45,"integer-value"},
2604 {46,"large-analog-value"},
2605 {47,"octetstring-value"},
2606 {48,"positive-integer-value"},
2607 {49,"time-pattern-value"},
2610 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2611 Enumerated values 128-1023 may be used by others subject to
2612 the procedures and constraints described in Clause 23. */
2615 static const value_string
2616 BACnetEngineeringUnits [] = {
2626 {9,"Kilovolt Amperes"},
2627 {10,"Megavolt Amperes"},
2628 {11,"Volt Amperes Reactive"},
2629 {12,"Kilovolt Amperes Reactive"},
2630 {13,"Megavolt Amperes Reactive"},
2631 {14,"Degrees Phase"},
2632 {15,"Power Factor"},
2636 {19,"Kilowatt Hours"},
2640 {23,"Joules Per Kg Dry Air"},
2641 {24,"BTUs Per Pound Dry Air"},
2642 {25,"Cycles Per Hour"},
2643 {26,"Cycles Per Minute"},
2645 {28,"Grams Of Water Per Kilogram Dry Air"},
2646 {29,"Relative Humidity"},
2651 {34,"Watts Per Sq Foot"},
2652 {35,"Watts Per Sq meter"},
2655 {38,"Foot Candles"},
2659 {42,"Kgs per Second"},
2660 {43,"Kgs Per Minute"},
2661 {44,"Kgs Per Hour"},
2662 {45,"Pounds Mass Per Minute"},
2663 {46,"Pounds Mass Per Hour"},
2667 {50,"BTUs Per Hour"},
2669 {52,"Tons Refrigeration"},
2673 {56,"Pounds Force Per Square Inch"},
2674 {57,"Centimeters Of Water"},
2675 {58,"Inches Of Water"},
2676 {59,"Millimeters Of Mercury"},
2677 {60,"Centimeters Of Mercury"},
2678 {61,"Inches Of Mercury"},
2679 {62,"Degrees Celsius"},
2680 {63,"Degrees Kelvin"},
2681 {64,"Degrees Fahrenheit"},
2682 {65,"Degree Days Celsius"},
2683 {66,"Degree Days Fahrenheit"},
2691 {74,"Meters Per Second"},
2692 {75,"Kilometers Per Hour"},
2693 {76,"Feed Per Second"},
2694 {77,"Feet Per Minute"},
2695 {78,"Miles Per Hour"},
2697 {80,"Cubic Meters"},
2698 {81,"Imperial Gallons"},
2701 {84,"Cubic Feet Per Minute"},
2702 {85,"Cubic Meters Per Second"},
2703 {86,"Imperial Gallons Per Minute"},
2704 {87,"Liters Per Second"},
2705 {88,"Liters Per Minute"},
2706 {89,"US Gallons Per Minute"},
2707 {90,"Degrees Angular"},
2708 {91,"Degrees Celsius Per Hour"},
2709 {92,"Degrees Celsius Per Minute"},
2710 {93,"Degrees Fahrenheit Per Hour"},
2711 {94,"Degrees Fahrenheit Per Minute"},
2713 {96,"Parts Per Million"},
2714 {97,"Parts Per Billion"},
2716 {99,"Pecent Per Second"},
2719 {102,"Psi Per Degree Fahrenheit"},
2721 {104,"Revolutions Per Min"},
2733 {116,"Sq Centimeters"},
2734 {117,"BTUs Per Pound"},
2735 {118,"Centimeters"},
2736 {119,"Pounds Mass Per Second"},
2737 {120,"Delta Degrees Fahrenheit"},
2738 {121,"Delta Degrees Kelvin"},
2742 {125,"Kilojoules Per Kg"},
2744 {127,"Joules Per Degree Kelvin"},
2745 {128,"Joules Per Kg Degree Kelvin"},
2750 {133,"Hectopascals"},
2752 {135,"Cubic Meters Per Hour"},
2753 {136,"Liters Per Hour"},
2754 {137,"KWatt Hours Per Square Meter"},
2755 {138,"KWatt Hours Per Square Foot"},
2756 {139,"Megajoules Per Square Meter"},
2757 {140,"Megajoules Per Square Foot"},
2758 {141,"Watts Per Sq Meter Degree Kelvin"},
2759 {142,"Cubic Feet Per Second"},
2760 {143,"Percent Obstruction Per Foot"},
2761 {144,"Percent Obstruction Per Meter"},
2763 {146,"megawatt-hours"},
2766 {149,"kilojoules-per-kilogram-dry-air"},
2767 {150,"megajoules-per-kilogram-dry-air"},
2768 {151,"kilojoules-per-degree-Kelvin"},
2769 {152,"megajoules-per-degree-Kelvin"},
2771 {154,"grams-per-second"},
2772 {155,"grams-per-minute"},
2773 {156,"tons-per-hour"},
2774 {157,"kilo-btus-per-hour"},
2775 {158,"hundredths-seconds"},
2776 {159,"milliseconds"},
2777 {160,"newton-meters"},
2778 {161,"millimeters-per-second"},
2779 {162,"millimeters-per-minute"},
2780 {163,"meters-per-minute"},
2781 {164,"meters-per-hour"},
2782 {165,"cubic-meters-per-minute"},
2783 {166,"meters-per-second-per-second"},
2784 {167,"amperes-per-meter"},
2785 {168,"amperes-per-square-meter"},
2786 {169,"ampere-square-meters"},
2791 {174,"siemens-per-meter"},
2793 {176,"volts-per-degree-Kelvin"},
2794 {177,"volts-per-meter"},
2797 {180,"candelas-per-square-meter"},
2798 {181,"degrees-Kelvin-per-hour"},
2799 {182,"degrees-Kelvin-per-minute"},
2800 {183,"joule-seconds"},
2801 {184,"radians-per-second"},
2802 {185,"square-meters-per-Newton"},
2803 {186,"kilograms-per-cubic-meter"},
2804 {187,"newton-seconds"},
2805 {188,"newtons-per-meter"},
2806 {189,"watts-per-meter-per-degree-Kelvin"},
2807 {190,"micro-siemens"},
2808 {191,"cubic-feet-per-hour"},
2809 {192,"us-gallons-per-hour"},
2811 {194,"micrometers"},
2814 {197,"milliliters"},
2815 {198,"milliliters-per-second"},
2817 {200,"decibels-millivolt"},
2818 {201,"decibels-volt"},
2819 {202,"millisiemens"},
2820 {203,"watt-hours-reactive"},
2821 {204,"kilowatt-hours-reactive"},
2822 {205,"megawatt-hours-reactive"},
2823 {206,"millimeters-of-water"},
2825 {208,"grams-per-gram"},
2826 {209,"kilograms-per-kilogram"},
2827 {210,"grams-per-kilogram"},
2828 {211,"milligrams-per-gram"},
2829 {212,"milligrams-per-kilogram"},
2830 {213,"grams-per-milliliter"},
2831 {214,"grams-per-liter"},
2832 {215,"milligrams-per-liter"},
2833 {216,"micrograms-per-liter"},
2834 {217,"grams-per-cubic-meter"},
2835 {218,"milligrams-per-cubic-meter"},
2836 {219,"micrograms-per-cubic-meter"},
2837 {220,"nanograms-per-cubic-meter"},
2838 {221,"grams-per-cubic-centimeter"},
2840 {223,"kilobecquerels"},
2841 {224,"megabecquerels"},
2846 {229,"millisieverts"},
2847 {230,"microsieverts"},
2848 {231,"microsieverts-per-hour"},
2850 {233,"nephelometric-turbidity-unit"},
2852 {235,"grams-per-square-meter"},
2853 {236,"minutes-per-degree-kelvin"},
2855 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2856 Enumerated values 256-65535 may be used by others subject to
2857 the procedures and constraints described in Clause 23. */
2860 static const value_string
2861 BACnetErrorCode [] = {
2863 {1,"authentication-failed"},
2864 {2,"configuration-in-progress"},
2866 {4,"dynamic-creation-not-supported"},
2867 {5,"file-access-denied"},
2868 {6,"incompatible-security-levels"},
2869 {7,"inconsistent-parameters"},
2870 {8,"inconsistent-selection-criterion"},
2871 {9,"invalid-data-type"},
2872 {10,"invalid-file-access-method"},
2873 {11,"invalid-file-start-position"},
2874 {12,"invalid-operator-name"},
2875 {13,"invalid-parameter-data-type"},
2876 {14,"invalid-time-stamp"},
2877 {15,"key-generation-error"},
2878 {16,"missing-required-parameter"},
2879 {17,"no-objects-of-specified-type"},
2880 {18,"no-space-for-object"},
2881 {19,"no-space-to-add-list-element"},
2882 {20,"no-space-to-write-property"},
2883 {21,"no-vt-sessions-available"},
2884 {22,"property-is-not-a-list"},
2885 {23,"object-deletion-not-permitted"},
2886 {24,"object-identifier-already-exists"},
2887 {25,"operational-problem"},
2888 {26,"password-failure"},
2889 {27,"read-access-denied"},
2890 {28,"security-not-supported"},
2891 {29,"service-request-denied"},
2893 {31,"unknown-object"},
2894 {32,"unknown-property"},
2895 {33,"removed enumeration"},
2896 {34,"unknown-vt-class"},
2897 {35,"unknown-vt-session"},
2898 {36,"unsupported-object-type"},
2899 {37,"value-out-of-range"},
2900 {38,"vt-session-already-closed"},
2901 {39,"vt-session-termination-failure"},
2902 {40,"write-access-denied"},
2903 {41,"character-set-not-supported"},
2904 {42,"invalid-array-index"},
2905 {43,"cov-subscription-failed"},
2906 {44,"not-cov-property"},
2907 {45,"optional-functionality-not-supported"},
2908 {46,"invalid-configuration-data"},
2909 {47,"datatype-not-supported"},
2910 {48,"duplicate-name"},
2911 {49,"duplicate-object-id"},
2912 {50,"property-is-not-an-array"},
2913 {73,"invalid-event-state"},
2914 {74,"no-alarm-configured"},
2915 {75,"log-buffer-full"},
2916 {76,"logged-value-purged"},
2917 {77,"no-property-specified"},
2918 {78,"not-configured-for-triggered-logging"},
2919 {79,"unknown-subscription"},
2920 {80,"parameter-out-of-range"},
2921 {81,"list-element-not-found"},
2923 {83,"communication-disabled"},
2925 {85,"access-denied"},
2926 {86,"bad-destination-address"},
2927 {87,"bad-destination-device-id"},
2928 {88,"bad-signature"},
2929 {89,"bad-source-address"},
2930 {90,"bad-timestamp"},
2931 {91,"cannot-use-key"},
2932 {92,"cannot-verify-message-id"},
2933 {93,"correct-key-revision"},
2934 {94,"destination-device-id-required"},
2935 {95,"duplicate-message"},
2936 {96,"encryption-not-configured"},
2937 {97,"encryption-required"},
2938 {98,"incorrect-key"},
2939 {99,"invalid-key-data"},
2940 {100,"key-update-in-progress"},
2941 {101,"malformed-message"},
2942 {102,"not-key-server"},
2943 {103,"security-not-configured"},
2944 {104,"source-security-required"},
2945 {105,"too-many-keys"},
2946 {106,"unknown-authentication-type"},
2947 {107,"unknown-key"},
2948 {108,"unknown-key-revision"},
2949 {109,"unknown-source-message"},
2950 {110,"not-router-to-dnet"},
2951 {111,"router-busy"},
2952 {112,"unknown-network-message"},
2953 {113,"message-too-long"},
2954 {114,"security-error"},
2955 {115,"addressing-error"},
2956 {116,"write-bdt-failed"},
2957 {117,"read-bdt-failed"},
2958 {118,"register-foreign-device-failed"},
2959 {119,"read-fdt-failed"},
2960 {120,"delete-fdt-entry-failed"},
2961 {121,"distribute-broadcast-failed"},
2962 {122,"unknown-file-size"},
2963 {123,"abort-apdu-too-long"},
2964 {124,"abort-application-exceeded-reply-time"},
2965 {125,"abort-out-of-resources"},
2966 {126,"abort-tsm-timeout"},
2967 {127,"abort-window-size-out-of-range"},
2969 {129,"inconsistent-configuration"},
2970 {130,"inconsistent-object-type"},
2971 {131,"internal-error"},
2972 {132,"not-configured"},
2973 {133,"out-of-memory"},
2974 {134,"value-too-long"},
2975 {135,"abort-insufficient-security"},
2976 {136,"abort-security-error"},
2978 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2979 Enumerated values 256-65535 may be used by others subject to the
2980 procedures and constraints described in Clause 23. */
2983 static const value_string
2984 BACnetPropertyIdentifier [] = {
2985 {0,"acked-transition"},
2990 {5,"active-vt-session"},
2994 {9,"all-write-successful"},
2995 {10,"apdu-segment-timeout"},
2996 {11,"apdu-timeout"},
2997 {12,"application-software-version"},
3000 {15,"change-of-state-count"},
3001 {16,"change-of-state-time"},
3002 {17,"notification-class"},
3003 {18,"the property in this place was deleted"},
3004 {19,"controlled-variable-reference"},
3005 {20,"controlled-variable-units"},
3006 {21,"controlled-variable-value"},
3007 {22,"cov-increment"},
3009 {24,"daylights-savings-status"},
3011 {26,"derivative-constant"},
3012 {27,"derivative-constant-units"},
3014 {29,"description-of-halt"},
3015 {30,"device-address-binding"},
3017 {32,"effective-period"},
3018 {33,"elapsed-active-time"},
3020 {35,"event-enable"},
3023 {38,"exception-schedule"},
3024 {39,"fault-values"},
3025 {40,"feedback-value"},
3026 {41,"file-access-method"},
3029 {44,"firmware-revision"},
3031 {46,"inactive-text"},
3034 {49,"integral-constant"},
3035 {50,"integral-constant-units"},
3036 {51,"issue-confirmed-notifications"},
3037 {52,"limit-enable"},
3038 {53,"list-of-group-members"},
3039 {54,"list-of-object-property-references"},
3040 {55,"list-of-session-keys"},
3045 {60,"manipulated-variable-reference"},
3046 {61,"maximum-output"},
3047 {62,"max-apdu-length-accepted"},
3048 {63,"max-info-frames"},
3050 {65,"max-pres-value"},
3051 {66,"minimum-off-time"},
3052 {67,"minimum-on-time"},
3053 {68,"minimum-output"},
3054 {69,"min-pres-value"},
3056 {71,"modification-date"},
3058 {73,"number-of-APDU-retries"},
3059 {74,"number-of-states"},
3060 {75,"object-identifier"},
3063 {78,"object-property-reference"},
3066 {81,"out-of-service"},
3067 {82,"output-units"},
3068 {83,"event-parameters"},
3070 {85,"present-value"},
3072 {87,"priority-array"},
3073 {88,"priority-for-writing"},
3074 {89,"process-identifier"},
3075 {90,"program-change"},
3076 {91,"program-location"},
3077 {92,"program-state"},
3078 {93,"proportional-constant"},
3079 {94,"proportional-constant-units"},
3080 {95,"protocol-conformance-class"},
3081 {96,"protocol-object-types-supported"},
3082 {97,"protocol-services-supported"},
3083 {98,"protocol-version"},
3085 {100,"reason-for-halt"},
3087 {102,"recipient-list"},
3088 {103,"reliability"},
3089 {104,"relinquish-default"},
3092 {107,"segmentation-supported"},
3094 {109,"setpoint-reference"},
3096 {111,"status-flags"},
3097 {112,"system-status"},
3099 {114,"time-of-active-time-reset"},
3100 {115,"time-of-state-count-reset"},
3101 {116,"time-synchronization-recipients"},
3103 {118,"update-interval"},
3105 {120,"vendor-identifier"},
3106 {121,"vendor-name"},
3107 {122,"vt-class-supported"},
3108 {123,"weekly-schedule"},
3109 {124,"attempted-samples"},
3110 {125,"average-value"},
3111 {126,"buffer-size"},
3112 {127,"client-cov-increment"},
3113 {128,"cov-resubscription-interval"},
3114 {129,"current-notify-time"},
3115 {130,"event-time-stamp"},
3117 {132,"log-device-object-property"},
3118 {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
3119 {134,"log-interval"},
3120 {135,"maximum-value"},
3121 {136,"minimum-value"},
3122 {137,"notification-threshold"},
3123 {138,"previous-notify-time"},
3124 {139,"protocol-revision"},
3125 {140,"records-since-notification"},
3126 {141,"record-count"},
3129 {144,"stop-when-full"},
3130 {145,"total-record-count"},
3131 {146,"valid-samples"},
3132 {147,"window-interval"},
3133 {148,"window-samples"},
3134 {149,"maximum-value-time-stamp"},
3135 {150,"minimum-value-time-stamp"},
3136 {151,"variance-value"},
3137 {152,"active-cov-subscriptions"},
3138 {153,"backup-failure-timeout"},
3139 {154,"configuration-files"},
3140 {155,"database-revision"},
3141 {156,"direct-reading"},
3142 {157,"last-restore-time"},
3143 {158,"maintenance-required"},
3146 {161,"operation-expected"},
3149 {164,"tracking-value"},
3150 {165,"zone-members"},
3151 {166,"life-safety-alarm-values"},
3152 {167,"max-segments-accepted"},
3153 {168,"profile-name"},
3154 {169,"auto-slave-discovery"},
3155 {170,"manual-slave-address-binding"},
3156 {171,"slave-address-binding"},
3157 {172,"slave-proxy-enable"},
3158 {173,"last-notify-record"}, /* bug 4117 */
3159 {174,"schedule-default"},
3160 {175,"accepted-modes"},
3161 {176,"adjust-value"},
3163 {178,"count-before-change"},
3164 {179,"count-change-time"},
3166 {181,"input-reference"},
3167 {182,"limit-monitoring-interval"},
3168 {183,"logging-device"},
3169 {184,"logging-record"},
3173 {188,"scale-factor"},
3174 {189,"update-time"},
3175 {190,"value-before-change"},
3177 {192,"value-change-time"},
3178 {193,"align-intervals"},
3179 {194,"group-member-names"},
3180 {195,"interval-offset"},
3181 {196,"last-restart-reason"},
3182 {197,"logging-type"},
3183 {198,"member-status-flags"},
3184 {199,"notification-period"},
3185 {200,"previous-notify-record"},
3186 {201,"requested-update-interval"},
3187 {202,"restart-notification-recipients"},
3188 {203,"time-of-device-restart"},
3189 {204,"time-synchronization-interval"},
3191 {206,"UTC-time-synchronization-recipients"},
3192 {207,"node-subtype"},
3194 {209,"structured-object-list"},
3195 {210,"subordinate-annotations"},
3196 {211,"subordinate-list"},
3197 {212,"actual-shed-level"},
3198 {213,"duty-window"},
3199 {214,"expected-shed-level"},
3200 {215,"full-duty-baseline"},
3201 {216,"node-subtype"},
3203 {218,"requested-shed-level"},
3204 {219,"shed-duration"},
3205 {220,"shed-level-descriptions"},
3206 {221,"shed-levels"},
3207 {222,"state-description"},
3208 /* enumeration values 223-225 are unassigned */
3209 {226,"door-alarm-state"},
3210 {227,"door-extended-pulse-time"},
3211 {228,"door-members"},
3212 {229,"door-open-too-long-time"},
3213 {230,"door-pulse-time"},
3214 {231,"door-status"},
3215 {232,"door-unlock-delay-time"},
3216 {233,"lock-status"},
3217 {234,"masked-alarm-values"},
3218 {235,"secured-status"},
3219 /* enumeration values 236-243 are unassigned */
3220 {244,"absentee-limit"}, /* added with addenda 135-2008j */
3221 {245,"access-alarm-events"},
3222 {246,"access-doors"},
3223 {247,"access-event"},
3224 {248,"access-event-authentication-factor"},
3225 {249,"access-event-credential"},
3226 {250,"access-event-time"},
3227 {251,"access-transaction-events"},
3228 {252,"accompaniment"},
3229 {253,"accompaniment-time"},
3230 {254,"activation-time"},
3231 {255,"active-authentication-policy"},
3232 {256,"assigned-access-rights"},
3233 {257,"authentication-factors"},
3234 {258,"authentication-policy-list"},
3235 {259,"authentication-policy-names"},
3236 {260,"authentication-status"},
3237 {261,"authorization-mode"},
3239 {263,"credential-disable"},
3240 {264,"credential-status"},
3241 {265,"credentials"},
3242 {266,"credentials-in-zone"},
3243 {267,"days-remaining"},
3244 {268,"entry-points"},
3245 {269,"exit-points"},
3246 {270,"expiry-time"},
3247 {271,"extended-time-enable"},
3248 {272,"failed-attempt-events"},
3249 {273,"failed-attempts"},
3250 {274,"failed-attempts-time"},
3251 {275,"last-access-event"},
3252 {276,"last-access-point"},
3253 {277,"last-credential-added"},
3254 {278,"last-credential-added-time"},
3255 {279,"last-credential-removed"},
3256 {280,"last-credential-removed-time"},
3257 {281,"last-use-time"},
3259 {283,"lockout-relinquish-time"},
3260 {284,"master-exemption"},
3261 {285,"max-failed-attempts"},
3263 {287,"muster-point"},
3264 {288,"negative-access-rules"},
3265 {289,"number-of-authentication-policies"},
3266 {290,"occupancy-count"},
3267 {291,"occupancy-count-adjust"},
3268 {292,"occupancy-count-enable"},
3269 {293,"occupancy-exemption"},
3270 {294,"occupancy-lower-limit"},
3271 {295,"occupancy-lower-limit-enforced"},
3272 {296,"occupancy-state"},
3273 {297,"occupancy-upper-limit"},
3274 {298,"occupancy-upper-limit-enforced"},
3275 {299,"passback-exemption"},
3276 {300,"passback-mode"},
3277 {301,"passback-timeout"},
3278 {302,"positive-access-rules"},
3279 {303,"reason-for-disable"},
3280 {304,"supported-formats"},
3281 {305,"supported-format-classes"},
3282 {306,"threat-authority"},
3283 {307,"threat-level"},
3285 {309,"transaction-notification-class"},
3286 {310,"user-external-identifier"},
3287 {311,"user-information-reference"},
3288 /* enumeration values 312-316 are unassigned */
3291 {319,"uses-remaining"},
3294 {322,"access-event-tag"},
3295 {323,"global-identifier"},
3296 /* enumeration values 324-325 reserved for future addenda */
3297 {326,"verification-time"},
3298 {327,"base-device-security-policy"},
3299 {328,"distribution-key-revision"},
3300 {329,"do-not-hide"},
3302 {331,"last-key-server"},
3303 {332,"network-access-security-policies"},
3304 {333,"packet-reorder-time"},
3305 {334,"security-pdu-timeout"},
3306 {335,"security-time-window"},
3307 {336,"supported-security-algorithms"},
3308 {337,"update-key-set-timeout"},
3309 {338,"backup-and-restore-state"},
3310 {339,"backup-preparation-time"},
3311 {340,"restore-completion-time"},
3312 {341,"restore-preparation-time"},
3313 {342,"bit-mask"}, /* addenda 135-2008w */
3316 {345,"group-members"},
3317 {346,"group-member-names"},
3318 {347,"member-status-flags"},
3319 {348,"requested-update-interval"},
3320 {349,"covu-period"},
3321 {350,"covu-recipients"},
3322 {351,"event-message-texts"},
3324 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3325 Enumerated values 512-4194303 may be used by others subject to
3326 the procedures and constraints described in Clause 23. */
3329 static const value_string
3330 BACnetBinaryPV [] = {
3338 #define IBM_MS_DBCS 1
3339 #define JIS_C_6226 2
3340 #define ISO_10646_UCS4 3
3341 #define ISO_10646_UCS2 4
3342 #define ISO_18859_1 5
3343 static const value_string
3344 BACnetCharacterSet [] = {
3345 {ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3346 {IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3347 {JIS_C_6226, "JIS C 6226"},
3348 {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3349 {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3350 {ISO_18859_1, "ISO 18859-1"},
3354 static const value_string
3355 BACnetStatusFlags [] = {
3359 {3,"out-of-service"},
3363 static const value_string
3364 BACnetMessagePriority [] = {
3370 static const value_string
3371 BACnetAcknowledgementFilter [] = {
3378 static const value_string
3379 BACnetResultFlags [] = {
3386 static const value_string
3387 BACnetRelationSpecifier [] = {
3392 {4,"less-than-or-equal"},
3393 {5,"greater-than-or-equal"},
3397 static const value_string
3398 BACnetSelectionLogic [] = {
3405 static const value_string
3406 BACnetEventStateFilter [] = {
3415 static const value_string
3416 BACnetEventTransitionBits [] = {
3423 static const value_string
3424 BACnetSegmentation [] = {
3425 {0,"segmented-both"},
3426 {1,"segmented-transmit"},
3427 {2,"segmented-receive"},
3428 {3,"no-segmentation"},
3432 static const value_string
3433 BACnetSilencedState [] = {
3435 {1,"audible-silenced"},
3436 {2,"visible-silenced"},
3441 static const value_string
3442 BACnetDeviceStatus [] = {
3444 {1,"operational-read-only"},
3445 {2,"download-required"},
3446 {3,"download-in-progress"},
3447 {4,"non-operational"},
3448 {5,"backup-in-progress"},
3452 static const value_string
3453 BACnetEnableDisable [] = {
3456 {2,"disable-initiation"},
3460 static const value_string
3478 static const value_string
3480 {1,"days numbered 1-7" },
3481 {2,"days numbered 8-14" },
3482 {3,"days numbered 15-21" },
3483 {4,"days numbered 22-28" },
3484 {5,"days numbered 29-31" },
3485 {6,"last 7 days of this month" },
3486 {255,"any week of this month" },
3490 /* note: notification class object recipient-list uses
3491 different day-of-week enum */
3492 static const value_string
3501 {255,"any day of week" },
3505 static const value_string
3506 BACnetErrorClass [] = {
3514 {7,"communication" },
3516 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3517 Enumerated values64-65535 may be used by others subject to
3518 the procedures and constraints described in Clause 23. */
3521 static const value_string
3522 BACnetVTClass [] = {
3523 {0,"default-terminal" },
3533 static const value_string
3534 BACnetEventType [] = {
3535 {0,"change-of-bitstring" },
3536 {1,"change-of-state" },
3537 {2,"change-of-value" },
3538 {3,"command-failure" },
3539 {4,"floating-limit" },
3540 {5,"out-of-range" },
3541 {6,"complex-event-type" },
3542 {7,"buffer-ready" },
3543 {8,"change-of-life-safety" },
3545 {10,"buffer-ready" },
3546 {11,"unsigned-range" },
3547 {14,"double-out-of-range"}, /* added with addenda 135-2008w */
3548 {15,"signed-out-of-range"},
3549 {16,"unsigned-out-of-range"},
3550 {17,"change-of-characterstring"},
3551 {18,"change-of-status-flags"},
3553 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3554 Enumerated values 64-65535 may be used by others subject to
3555 the procedures and constraints described in Clause 23.
3556 It is expected that these enumerated values will correspond
3557 to the use of the complex-event-type CHOICE [6] of the
3558 BACnetNotificationParameters production. */
3561 static const value_string
3562 BACnetEventState [] = {
3568 {5,"life-safety-alarm" },
3570 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3571 Enumerated values 64-65535 may be used by others subject to
3572 the procedures and constraints described in Clause 23. */
3575 static const value_string
3576 BACnetLogStatus [] = {
3577 {0,"log-disabled" },
3578 {1,"buffer-purged" },
3579 {2,"log-interrupted"},
3583 static const value_string
3584 BACnetMaintenance [] = {
3586 {1,"periodic-test" },
3587 {2,"need-service-operational" },
3588 {3,"need-service-inoperative" },
3592 static const value_string
3593 BACnetNotifyType [] = {
3596 {2,"ack-notification" },
3600 static const value_string
3601 BACnetServicesSupported [] = {
3602 {0,"acknowledgeAlarm"},
3603 {1,"confirmedCOVNotification"},
3604 {2,"confirmedEventNotification"},
3605 {3,"getAlarmSummary"},
3606 {4,"getEnrollmentSummary"},
3608 {6,"atomicReadFile"},
3609 {7,"atomicWriteFile"},
3610 {8,"addListElement"},
3611 {9,"removeListElement"},
3612 {10,"createObject"},
3613 {11,"deleteObject"},
3614 {12,"readProperty"},
3615 {13,"readPropertyConditional"},
3616 {14,"readPropertyMultiple"},
3617 {15,"writeProperty"},
3618 {16,"writePropertyMultiple"},
3619 {17,"deviceCommunicationControl"},
3620 {18,"confirmedPrivateTransfer"},
3621 {19,"confirmedTextMessage"},
3622 {20,"reinitializeDevice"},
3626 {24,"authenticate"},
3630 {28,"unconfirmedCOVNotification"},
3631 {29,"unconfirmedEventNotification"},
3632 {30,"unconfirmedPrivateTransfer"},
3633 {31,"unconfirmedTextMessage"},
3634 {32,"timeSynchronization"},
3638 {36,"utcTimeSynchronization"},
3639 {37,"lifeSafetyOperation"},
3640 {38,"subscribeCOVProperty"},
3641 {39,"getEventInformation"},
3645 static const value_string
3646 BACnetPropertyStates [] = {
3647 {0,"boolean-value"},
3651 {4,"program-change"},
3652 {5,"program-state"},
3653 {6,"reason-for-halt"},
3656 {9,"system-status"},
3658 {11,"unsigned-value"},
3659 {12,"life-safety-mode"},
3660 {13,"life-safety-state"},
3661 {14,"restart-reason"},
3662 {15,"door-alarm-state"},
3664 {17,"door-secured-status"},
3667 {20,"file-access-method"},
3669 {22,"life-safety-operation"},
3673 {26,"security-level"},
3675 {28,"silenced-state"},
3676 /* context tag 29 reserved for future addenda */
3678 {30,"access-event"},
3679 {31,"zone-occupancy-state"},
3680 {32,"access-credential-disable-reason"},
3681 {33,"access-credential-disable"},
3682 {34,"authentication-status"},
3684 {36,"backup-state"},
3686 /* Tag values 0-63 are reserved for definition by ASHRAE.
3687 Tag values of 64-254 may be used by others to accommodate
3688 vendor specific properties that have discrete or enumerated values,
3689 subject to the constraints described in Clause 23. */
3692 static const value_string
3693 BACnetProgramError [] = {
3700 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3701 Enumerated values 64-65535 may be used by others subject to
3702 the procedures and constraints described in Clause 23. */
3705 static const value_string
3706 BACnetProgramRequest [] = {
3716 static const value_string
3717 BACnetProgramState [] = {
3727 static const value_string
3728 BACnetReinitializedStateOfDevice [] = {
3739 static const value_string
3740 BACnetPolarity [] = {
3746 static const value_string
3747 BACnetTagNames[] = {
3748 { 5, "Extended Value" },
3749 { 6, "Opening Tag" },
3750 { 7, "Closing Tag" },
3754 static const value_string
3755 BACnetReadRangeOptions[] = {
3756 { 3, "range byPosition" },
3757 { 4, "range byTime" },
3758 { 5, "range timeRange" },
3759 { 6, "range bySequenceNumber" },
3760 { 7, "range byTime" },
3764 /* Present_Value for Load Control Object */
3765 static const value_string
3766 BACnetShedState[] = {
3767 { 0, "shed-inactive" },
3768 { 1, "shed-request-pending" },
3769 { 2, "shed-compliant" },
3770 { 3, "shed-non-compliant" },
3774 static const value_string
3775 BACnetNodeType [] = {
3780 { 4, "organizational" },
3784 { 8, "collection" },
3786 { 10, "functional" },
3791 static const value_string
3792 BACnetLoggingType [] = {
3799 static const value_string
3800 BACnetDoorStatus [] = {
3807 static const value_string
3808 BACnetLockStatus [] = {
3816 static const value_string
3817 BACnetDoorSecuredStatus [] = {
3824 static const value_string
3825 BACnetDoorAlarmState [] = {
3828 { 2, "door-open-too-long" },
3829 { 3, "forced-open" },
3831 { 5, "door-fault" },
3833 { 7, "free-access" },
3834 { 8, "egress-open" },
3838 static const value_string
3839 BACnetAccumulatorStatus [] = {
3848 static const value_string
3849 BACnetVendorIdentifiers [] = {
3852 { 2, "The Trane Company" },
3853 { 3, "McQuay International" },
3855 { 5, "Johnson Controls, Inc." },
3856 { 6, "American Auto-Matrix" },
3857 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3858 { 8, "Delta Controls" },
3859 { 9, "Siemens Building Technologies, Inc." },
3860 { 10, "Tour Andover Controls Corporation" },
3862 { 12, "Orion Analysis Corporation" },
3863 { 13, "Teletrol Systems Inc." },
3864 { 14, "Cimetrics Technology" },
3865 { 15, "Cornell University" },
3866 { 16, "United Technologies Carrier" },
3867 { 17, "Honeywell Inc." },
3868 { 18, "Alerton / Honeywell" },
3870 { 20, "Hewlett-Packard Company" },
3871 { 21, "Dorsette's Inc." },
3872 { 22, "Cerberus AG" },
3873 { 23, "York Controls Group" },
3874 { 24, "Automated Logic Corporation" },
3875 { 25, "CSI Control Systems International" },
3876 { 26, "Phoenix Controls Corporation" },
3877 { 27, "Innovex Technologies, Inc." },
3878 { 28, "KMC Controls, Inc." },
3879 { 29, "Xn Technologies, Inc." },
3880 { 30, "Hyundai Information Technology Co., Ltd." },
3881 { 31, "Tokimec Inc." },
3883 { 33, "North Communications Limited" },
3885 { 35, "Reliable Controls Corporation" },
3886 { 36, "Tridium Inc." },
3887 { 37, "Sierra Monitor Corp." },
3888 { 38, "Silicon Energy" },
3889 { 39, "Kieback & Peter GmbH & Co KG" },
3890 { 40, "Anacon Systems, Inc." },
3891 { 41, "Systems Controls & Instruments, LLC" },
3892 { 42, "Lithonia Lighting" },
3893 { 43, "Micropower Manufacturing" },
3894 { 44, "Matrix Controls" },
3895 { 45, "METALAIRE" },
3896 { 46, "ESS Engineering" },
3897 { 47, "Sphere Systems Pty Ltd." },
3898 { 48, "Walker Technologies Corporation" },
3899 { 49, "H I Solutions, Inc." },
3901 { 51, "SAMSON AG" },
3902 { 52, "Badger Meter Inc." },
3903 { 53, "DAIKIN Industries Ltd." },
3904 { 54, "NARA Controls Inc." },
3905 { 55, "Mammoth Inc." },
3906 { 56, "Liebert Corporation" },
3907 { 57, "SEMCO Incorporated" },
3908 { 58, "Air Monitor Corporation" },
3909 { 59, "TRIATEK, Inc." },
3911 { 61, "Multistack" },
3912 { 62, "TSI Incorporated" },
3913 { 63, "Weather-Rite, Inc." },
3914 { 64, "Dunham-Bush" },
3915 { 65, "Reliance Electric" },
3917 { 67, "Regulator Australia PTY Ltd." },
3918 { 68, "Touch-Plate Lighting Controls" },
3919 { 69, "Amann GmbH" },
3920 { 70, "RLE Technologies" },
3921 { 71, "Cardkey Systems" },
3922 { 72, "SECOM Co., Ltd." },
3923 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3924 { 74, "KNX Association cvba" },
3925 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3926 { 76, "Nohmi Bosai, Ltd." },
3927 { 77, "Carel S.p.A." },
3928 { 78, "AirSense Technology, Inc." },
3929 { 79, "Hochiki Corporation" },
3930 { 80, "Fr. Sauter AG" },
3931 { 81, "Matsushita Electric Works, Ltd." },
3932 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3933 { 83, "Mitsubishi Heavy Industries, Ltd." },
3934 { 84, "ITT Bell & Gossett" },
3935 { 85, "Yamatake Building Systems Co., Ltd." },
3936 { 86, "The Watt Stopper, Inc." },
3937 { 87, "Aichi Tokei Denki Co., Ltd." },
3938 { 88, "Activation Technologies, LLC" },
3939 { 89, "Saia-Burgess Controls, Ltd." },
3940 { 90, "Hitachi, Ltd." },
3941 { 91, "Novar Corp./Trend Control Systems Ltd." },
3942 { 92, "Mitsubishi Electric Lighting Corporation" },
3943 { 93, "Argus Control Systems, Ltd." },
3944 { 94, "Kyuki Corporation" },
3945 { 95, "Richards-Zeta Building Intelligence, Inc." },
3946 { 96, "Scientech R&D, Inc." },
3947 { 97, "VCI Controls, Inc." },
3948 { 98, "Toshiba Corporation" },
3949 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3950 { 100, "Custom Mechanical Equipment, LLC" },
3951 { 101, "ClimateMaster" },
3952 { 102, "ICP Panel-Tec, Inc." },
3953 { 103, "D-Tek Controls" },
3954 { 104, "NEC Engineering, Ltd." },
3955 { 105, "PRIVA BV" },
3956 { 106, "Meidensha Corporation" },
3957 { 107, "JCI Systems Integration Services" },
3958 { 108, "Freedom Corporation" },
3959 { 109, "Neuberger Gebaudeautomation GmbH" },
3960 { 110, "Sitronix" },
3961 { 111, "Leviton Manufacturing" },
3962 { 112, "Fujitsu Limited" },
3963 { 113, "Emerson Network Power" },
3964 { 114, "S. A. Armstrong, Ltd." },
3965 { 115, "Visonet AG" },
3966 { 116, "M&M Systems, Inc." },
3967 { 117, "Custom Software Engineering" },
3968 { 118, "Nittan Company, Limited" },
3969 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3970 { 120, "Pacom Systems Pty., Ltd." },
3971 { 121, "Unico, Inc." },
3972 { 122, "Ebtron, Inc." },
3973 { 123, "Scada Engine" },
3974 { 124, "AC Technology Corporation" },
3975 { 125, "Eagle Technology" },
3976 { 126, "Data Aire, Inc." },
3977 { 127, "ABB, Inc." },
3978 { 128, "Transbit Sp. z o. o." },
3979 { 129, "Toshiba Carrier Corporation" },
3980 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
3981 { 131, "Tokai Soft" },
3983 { 133, "Veris Industries" },
3984 { 134, "Centaurus Prime" },
3985 { 135, "Sand Network Systems" },
3986 { 136, "Regulvar, Inc." },
3987 { 137, "Fastek International, Ltd." },
3988 { 138, "PowerCold Comfort Air Solutions, Inc." },
3989 { 139, "I Controls" },
3990 { 140, "Viconics Electronics, Inc." },
3991 { 141, "Yaskawa Electric America, Inc." },
3992 { 142, "Plueth Regelsysteme" },
3993 { 143, "Digitale Mess- und Steuersysteme AG" },
3994 { 144, "Fujitsu General Limited" },
3995 { 145, "Project Engineering S.r.l." },
3996 { 146, "Sanyo Electric Co., Ltd." },
3997 { 147, "Integrated Information Systems, Inc." },
3998 { 148, "Temco Controls, Ltd." },
3999 { 149, "Airtek Technologies, Inc." },
4000 { 150, "Advantech Corporation" },
4001 { 151, "Titan Products, Ltd." },
4002 { 152, "Regel Partners" },
4003 { 153, "National Environmental Product" },
4004 { 154, "Unitec Corporation" },
4005 { 155, "Kanden Engineering Company" },
4006 { 156, "Messner Gebaudetechnik GmbH" },
4007 { 157, "Integrated.CH" },
4008 { 158, "EH Price Limited" },
4009 { 159, "SE-Elektronic GmbH" },
4010 { 160, "Rockwell Automation" },
4011 { 161, "Enflex Corp." },
4012 { 162, "ASI Controls" },
4013 { 163, "SysMik GmbH Dresden" },
4014 { 164, "HSC Regelungstechnik GmbH" },
4015 { 165, "Smart Temp Australia Pty. Ltd." },
4016 { 166, "PCI Lighting Control Systems" },
4017 { 167, "Duksan Mecasys Co., Ltd." },
4018 { 168, "Fuji IT Co., Ltd." },
4019 { 169, "Vacon Plc" },
4020 { 170, "Leader Controls" },
4021 { 171, "Cylon Controls, Ltd." },
4023 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
4024 { 174, "Building Control Integrators" },
4025 { 175, "ITG Worldwide (M) Sdn Bhd" },
4026 { 176, "Lutron Electronics Co., Inc." },
4027 { 177, "Cooper-Atkins Corporation" },
4028 { 178, "LOYTEC Electronics GmbH" },
4030 { 180, "Mega Controls Limited" },
4031 { 181, "Micro Control Systems, Inc." },
4032 { 182, "Kiyon, Inc." },
4033 { 183, "Dust Networks" },
4034 { 184, "Advanced Building Automation Systems" },
4035 { 185, "Hermos AG" },
4038 { 188, "Lynxspring" },
4039 { 189, "Schneider Toshiba Inverter Europe" },
4040 { 190, "Danfoss Drives A/S" },
4041 { 191, "Eaton Corporation" },
4042 { 192, "Matyca S.A." },
4043 { 193, "Botech AB" },
4044 { 194, "Noveo, Inc." },
4046 { 196, "Yokogawa Electric Corporation" },
4047 { 197, "GFR Gesellschaft fur Regelungstechnik" },
4048 { 198, "Exact Logic" },
4049 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
4050 { 200, "Kandenko Co., Ltd." },
4051 { 201, "DTF, Daten-Technik Fries" },
4052 { 202, "Klimasoft, Ltd." },
4053 { 203, "Toshiba Schneider Inverter Corporation" },
4054 { 204, "Control Applications, Ltd." },
4055 { 205, "KDT Systems Co., Ltd." },
4056 { 206, "Onicon Incorporated" },
4057 { 207, "Automation Displays, Inc." },
4058 { 208, "Control Solutions, Inc." },
4059 { 209, "Remsdaq Limited" },
4060 { 210, "NTT Facilities, Inc." },
4061 { 211, "VIPA GmbH" },
4062 { 212, "TSC21 Association of Japan" },
4063 { 213, "BBP Energie Ltee" },
4064 { 214, "HRW Limited" },
4065 { 215, "Lighting Control & Design, Inc." },
4066 { 216, "Mercy Electronic and Electrical Industries" },
4067 { 217, "Samsung SDS Co., Ltd" },
4068 { 218, "Impact Facility Solutions, Inc." },
4069 { 219, "Aircuity" },
4070 { 220, "Control Techniques, Ltd." },
4071 { 221, "Evolve Control Systems, LLC" },
4072 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
4073 { 223, "Cerus Industrial" },
4074 { 224, "Chloride Power Protection Company" },
4075 { 225, "Computrols, Inc." },
4076 { 226, "Phoenix Contact GmbH & Co. KG" },
4077 { 227, "Grundfos Management A/S" },
4078 { 228, "Ridder Drive Systems" },
4079 { 229, "Soft Device SDN BHD" },
4080 { 230, "Integrated Control Technology Limited" },
4081 { 231, "AIRxpert Systems, Inc." },
4082 { 232, "Microtrol Limited" },
4083 { 233, "Red Lion Controls" },
4084 { 234, "Digital Electronics Corporation" },
4085 { 235, "Ennovatis GmbH" },
4086 { 236, "Serotonin Software Technologies, Inc." },
4087 { 237, "LS Industrial Systems Co., Ltd." },
4088 { 238, "Square D Company" },
4089 { 239, "S Squared Innovations, Inc." },
4090 { 240, "Aricent Ltd." },
4091 { 241, "EtherMetrics, LLC" },
4092 { 242, "Industrial Control Communications, Inc." },
4093 { 243, "Paragon Controls, Inc." },
4094 { 244, "A. O. Smith Corporation" },
4095 { 245, "Contemporary Control Systems, Inc." },
4096 { 246, "Intesis Software SL" },
4097 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
4098 { 248, "Heat-Timer Corporation" },
4099 { 249, "Ingrasys Technology, Inc." },
4100 { 250, "Costerm Building Automation" },
4102 { 252, "Embedia Technologies Corp." },
4103 { 253, "Technilog" },
4104 { 254, "HR Controls Ltd. & Co. KG" },
4105 { 255, "Lennox International, Inc." },
4106 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
4107 { 257, "Thermomax, Ltd." },
4108 { 258, "ELCON Electronic Control, Ltd." },
4109 { 259, "Larmia Control AB" },
4110 { 260, "BACnet Stack at SourceForge" },
4111 { 261, "G4S Security Services A/S" },
4112 { 262, "Sitek S.p.A." },
4113 { 263, "Cristal Controles" },
4114 { 264, "Regin AB" },
4115 { 265, "Dimension Software, Inc. " },
4116 { 266, "SynapSense Corporation" },
4117 { 267, "Beijing Nantree Electronic Co., Ltd." },
4118 { 268, "Camus Hydronics Ltd." },
4119 { 269, "Kawasaki Heavy Industries, Ltd. " },
4120 { 270, "Critical Environment Technologies" },
4121 { 271, "ILSHIN IBS Co., Ltd." },
4122 { 272, "ELESTA Energy Control AG" },
4123 { 273, "KROPMAN Installatietechniek" },
4124 { 274, "Baldor Electric Company" },
4125 { 275, "INGA mbH" },
4126 { 276, "GE Consumer & Industrial" },
4127 { 277, "Functional Devices, Inc." },
4129 { 279, "M-System Co., Ltd." },
4130 { 280, "Yokota Co., Ltd." },
4131 { 281, "Hitranse Technology Co., LTD" },
4132 { 282, "Federspiel Controls" },
4133 { 283, "Kele, Inc." },
4134 { 284, "Opera Electronics, Inc." },
4136 { 286, "Embedded Science Labs, LLC" },
4137 { 287, "Parker Hannifin Corporation" },
4138 { 288, "MaCaPS International Limited" },
4139 { 289, "Link4 Corporation" },
4140 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
4141 { 291, "Pribusin, Inc." },
4142 { 292, "Advantage Controls" },
4143 { 293, "Critical Room Control" },
4145 { 295, "Tongdy Control Technology Co., Ltd." },
4146 { 296, "ISSARO Integrierte Systemtechnik" },
4147 { 297, "Pro-Dev Industries" },
4148 { 298, "DRI-STEEM" },
4149 { 299, "Creative Electronic GmbH" },
4150 { 300, "Swegon AB" },
4151 { 301, "Jan Brachacek" },
4152 { 302, "Hitachi Appliances, Inc." },
4153 { 303, "Real Time Automation, Inc." },
4154 { 304, "ITEC Hankyu-Hanshin Co." },
4155 { 305, "Cyrus E&M Engineering Co., Ltd." },
4156 { 306, "Racine Federated, Inc." },
4157 { 307, "Verari Systems, Inc." },
4158 { 308, "Elesta GmbH Building Automation" },
4159 { 309, "Securiton" },
4160 { 310, "OSlsoft, Inc." },
4161 { 311, "Hanazeder Electronic GmbH" },
4162 { 312, "Honeywell Security Deutschland, Novar GmbH" },
4163 { 313, "Siemens Energy & Automation, Inc." },
4164 { 314, "ETM Professional Control GmbH" },
4165 { 315, "Meitav-tec, Ltd." },
4166 { 316, "Janitza Electronics GmbH" },
4167 { 317, "MKS Nordhausen" },
4168 { 318, "De Gier Drive Systems B.V." },
4169 { 319, "Cypress Envirosystems" },
4170 { 320, "SMARTron s.r.o." },
4171 { 321, "Verari Systems, Inc." },
4172 { 322, "K-W Electronic Service, Inc." },
4173 { 323, "ALFA-SMART Energy Management" },
4174 { 324, "Telkonet, Inc." },
4175 { 325, "Securiton GmbH" },
4176 { 326, "Cemtrex, Inc." },
4177 { 327, "Performance Technologies, Inc." },
4178 { 328, "Xtralis (Aust) Pty Ltd" },
4179 { 329, "TROX GmbH" },
4180 { 330, "Beijing Hysine Technology Co., Ltd" },
4181 { 331, "RCK Controls, Inc." },
4183 { 333, "Novar/Honeywell" },
4184 { 334, "The S4 Group, Inc." },
4185 { 335, "Schneider Electric" },
4186 { 336, "LHA Systems" },
4187 { 337, "GHM engineering Group, Inc." },
4188 { 338, "Cllimalux S.A." },
4189 { 339, "VAISALA Oyj" },
4190 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
4191 { 342, "POWERPEG NSI Limited" },
4192 { 343, "BACnet Interoperability Testing Services, Inc." },
4193 { 344, "Teco a.s." },
4194 { 345, "Plexus Technology Limited"},
4195 { 346, "Energy Focus, Inc."},
4196 { 347, "Powersmiths International Corp."},
4197 { 348, "Nichibei Co., Ltd."},
4198 { 349, "HKC Technology Ltd."},
4199 { 350, "Ovation Networks, Inc."},
4200 { 351, "Setra Systems"},
4201 { 352, "AVG Automation"},
4203 { 354, "Byte Sphere"},
4204 { 355, "Generiton Co., Ltd."},
4205 { 356, "Holter Regelarmaturen GmbH & Co. KG"},
4206 { 357, "Bedford Instruments, LLC"},
4207 { 358, "Standair Inc."},
4208 { 359, "WEG Automation - R&D"},
4209 { 360, "Prolon Control Systems ApS"},
4210 { 361, "Inneasoft"},
4211 { 362, "ConneXSoft GmbH"},
4212 { 363, "CEAG Notlichtsysteme GmbH"},
4213 { 364, "Distech Controls Inc."},
4214 { 365, "Industrial Technology Research Institute"},
4215 { 366, "ICONICS, Inc."},
4216 { 367, "IQ Controls s.c."},
4217 { 368, "OJ Electronics A/S"},
4218 { 369, "Rolbit Ltd."},
4219 { 370, "Synapsys Solutions Ltd."},
4220 { 371, "ACME Engineering Prod. Ltd."},
4221 { 372, "Zener Electric Pty, Ltd."},
4222 { 373, "Selectronix, Inc."},
4223 { 374, "Gorbet & Banerjee, LLC."},
4225 { 376, "Stephen H. Dawson Computer Service"},
4226 { 377, "Accutrol, LLC"},
4227 { 378, "Schneider Elektronik GmbH"},
4228 { 379, "Alpha-Inno Tec GmbH"},
4229 { 380, "ADMMicro, Inc."},
4230 { 381, "Greystone Energy Systems, Inc."},
4231 { 382, "CAP Technologie"},
4232 { 383, "KeRo Systems"},
4233 { 384, "Domat Control System s.r.o."},
4234 { 385, "Efektronics Pty. Ltd."},
4235 { 386, "Hekatron Vertriebs GmbH"},
4236 { 387, "Securiton AG"},
4237 { 388, "Carlo Gavazzi Controls SpA"},
4238 { 389, "Chipkin Automation Systems"},
4239 { 390, "Savant Systems, LLC"},
4240 { 391, "Simmtronic Lighting Controls"},
4241 { 392, "Abelko Innovation AB"},
4242 { 393, "Seresco Technologies Inc."},
4243 { 394, "IT Watchdogs"},
4244 { 395, "Automation Assist Japan Corp."},
4245 { 396, "Thermokon Sensortechnik GmbH"},
4246 { 397, "EGauge Systems, LLC"},
4247 { 398, "Quantum Automation (ASIA) PTE, Ltd."},
4248 { 399, "Toshiba Lighting & Technology Corp."},
4249 { 400, "SPIN Engenharia de Automaca Ltda."},
4250 { 401, "Logistics Systems & Software Services India PVT. Ltd."},
4251 { 402, "Delta Controls Integration Products"},
4252 { 403, "Focus Media"},
4253 { 404, "LUMEnergi Inc."},
4254 { 405, "Kara Systems"},
4255 { 406, "RF Code, Inc."},
4256 { 407, "Fatek Automation Corp."},
4257 { 408, "JANDA Software Company, LLC"},
4258 { 409, "Open System Solutions Limited"},
4259 { 410, "Intelec Systems PTY Ltd."},
4260 { 411, "Ecolodgix, LLC"},
4261 { 412, "Douglas Lighting Controls"},
4262 { 413, "iSAtech GmbH intelligente Sensoren Aktoren technologie"},
4264 { 415, "Beckhoff Automation GmbH"},
4265 { 416, "IPAS GmbH"},
4266 { 417, "KE2 Therm Solutions"},
4267 { 418, "Base2Products"},
4268 { 419, "DTL Controls, LLC"},
4269 { 420, "INNCOM International, Inc."},
4270 { 421, "BTR Netcom GmbH"},
4271 { 422, "Greentrol Automation, Inc"},
4272 { 423, "BELIMO Automation AG"},
4273 { 424, "Samsung Heavy Industries Co, Ltd"},
4274 { 425, "Triacta Power Technologies, Inc."},
4275 { 426, "Globestar Systems"},
4276 { 427, "MLB Advanced Media, LP"},
4277 { 428, "SWG Stuckmann Wirtschaftliche Gebaudesysteme GmbH"},
4278 { 429, "SensorSwitch"},
4279 { 430, "Multitek Power Limited"},
4280 { 431, "Aquametro AG"},
4281 { 432, "LG Electronics Inc."},
4282 { 433, "Electronic Theatre Controls, Inc."},
4283 { 434, "Mitsubishi Electric Corporation Nagoya Works"},
4284 { 435, "Delta Electronics, Inc."},
4285 { 436, "Elma Kurtalj, Ltd."},
4286 { 437, "ADT Fire and Security Sp. A.o.o."},
4287 { 438, "Nedap Security Management"},
4288 { 439, "ESC Automation Inc."},
4289 { 440, "DSP4YOU Ltd."},
4290 { 441, "GE Sensing and Inspection Technologies"},
4291 { 442, "Embedded Systems SIA"},
4292 { 443, "BEFEGA GmbH"},
4293 { 444, "Baseline Inc."},
4294 { 445, "M2M Systems Integrators"},
4296 { 447, "Clarkson Controls Limited"},
4297 { 448, "Rogerwell Control System Limited"},
4298 { 449, "SCL Elements"},
4299 { 450, "Hitachi Ltd."},
4300 { 451, "Newron System SA"},
4301 { 452, "BEVECO Gebouwautomatisering BV"},
4302 { 453, "Streamside Solutions"},
4303 { 454, "Yellowstone Soft"},
4304 { 455, "Oztech Intelligent Systems Pty Ltd."},
4305 { 456, "Novelan GmbH"},
4306 { 457, "Flexim Americas Corporation"},
4307 { 458, "ICP DAS Co., Ltd."},
4308 { 459, "CARMA Industries Inc."},
4309 { 460, "Log-One Ltd."},
4310 { 461, "TECO Electric & Machinery Co., Ltd."},
4311 { 462, "ConnectEx, Inc."},
4312 { 463, "Turbo DDC Sudwest"},
4313 { 464, "Quatrosense Environmental Ltd."},
4314 { 465, "Fifth Light Technology Ltd."},
4315 { 466, "Scientific Solutions, Ltd."},
4316 { 467, "Controller Area Network Solutions (M) Sdn Bhd"},
4317 { 468, "RESOL - Elektronische Regelungen GmbH"},
4318 { 469, "RPBUS LLC"},
4319 { 470, "BRS Sistemas Eletronicos"},
4320 { 471, "WindowMaster A/S"},
4321 { 472, "Sunlux Technologies Ltd."},
4322 { 473, "Measurlogic"},
4323 { 474, "Frimat GmbH"},
4324 { 475, "Spirax Sarco"},
4326 { 477, "Raypak Inc"},
4327 { 478, "Air Monitor Corporation"},
4328 { 479, "Regler Och Webbteknik Sverige (ROWS)"},
4329 { 480, "Intelligent Lighting Controls Inc."},
4330 { 481, "Sanyo Electric Industry Co., Ltd"},
4331 { 482, "E-Mon Energy Monitoring Products"},
4332 { 483, "Digital Control Systems"},
4333 { 484, "ATI Airtest Technologies, Inc."},
4335 { 486, "HMS Industrial Networks AB"},
4336 { 487, "Shenzhen Universal Intellisys Co Ltd"},
4337 { 488, "EK Intellisys Sdn Bhd"},
4339 { 490, "Firecom, Inc."},
4340 { 491, "ESA Elektroschaltanlagen Grimma GmbH"},
4341 { 492, "Kumahira Co Ltd"},
4343 { 494, "SABO Elektronik GmbH"},
4344 { 495, "Equip'Trans"},
4345 { 496, "TCS Basys Controls"},
4346 { 497, "FlowCon International A/S"},
4347 { 498, "ThyssenKrupp Elevator Americas"},
4348 { 499, "Abatement Technologies"},
4349 { 500, "Continental Control Systems, LLC"},
4350 { 501, "WISAG Automatisierungstechnik GmbH & Co KG"},
4352 { 503, "EAP-Electric GmbH"},
4353 { 504, "Hardmeier"},
4354 { 505, "Mircom Group of Companies"},
4355 { 506, "Quest Controls"},
4356 { 507, "Mestek, Inc"},
4357 { 508, "Pulse Energy"},
4358 { 509, "Tachikawa Corporation"},
4359 { 510, "University of Nebraska-Lincoln"},
4360 { 511, "Redwood Systems"},
4361 { 512, "PASStec Industrie-Elektronik GmbH"},
4362 { 513, "NgEK, Inc."},
4363 { 514, "FAW Electronics Ltd"},
4364 { 515, "Jireh Energy Tech Co., Ltd."},
4365 { 516, "Enlighted Inc."},
4366 { 517, "El-Piast Sp. Z o.o"},
4367 { 518, "NetxAutomation Software GmbH"},
4368 { 519, "Invertek Drives"},
4369 { 520, "Deutschmann Automation GmbH & Co. KG"},
4370 { 521, "EMU Electronic AG"},
4371 { 522, "Phaedrus Limited"},
4372 { 523, "Sigmatek GmbH & Co KG"},
4373 { 524, "Marlin Controls"},
4374 { 525, "Circutor, SA"},
4375 { 526, "UTC Fire & Security"},
4376 { 527, "DENT Instruments, Inc."},
4377 { 528, "FHP Manufacturing Company - Bosch Group"},
4378 { 529, "GE Intelligent Platforms"},
4379 { 530, "Inner Range Pty Ltd"},
4380 { 531, "GLAS Energy Technology"},
4381 { 532, "MSR-Electronic-GmbH"},
4385 static int proto_bacapp = -1;
4386 static int hf_bacapp_type = -1;
4387 static int hf_bacapp_pduflags = -1;
4388 static int hf_bacapp_SEG = -1;
4389 static int hf_bacapp_MOR = -1;
4390 static int hf_bacapp_SA = -1;
4391 static int hf_bacapp_response_segments = -1;
4392 static int hf_bacapp_max_adpu_size = -1;
4393 static int hf_bacapp_invoke_id = -1;
4394 static int hf_bacapp_objectType = -1;
4395 static int hf_bacapp_instanceNumber = -1;
4396 static int hf_bacapp_sequence_number = -1;
4397 static int hf_bacapp_window_size = -1;
4398 static int hf_bacapp_service = -1;
4399 static int hf_bacapp_NAK = -1;
4400 static int hf_bacapp_SRV = -1;
4401 static int hf_Device_Instance_Range_Low_Limit = -1;
4402 static int hf_Device_Instance_Range_High_Limit = -1;
4403 static int hf_BACnetRejectReason = -1;
4404 static int hf_BACnetAbortReason = -1;
4405 static int hf_BACnetApplicationTagNumber = -1;
4406 static int hf_BACnetContextTagNumber = -1;
4407 static int hf_BACnetExtendedTagNumber = -1;
4408 static int hf_BACnetNamedTag = -1;
4409 static int hf_BACnetTagClass = -1;
4410 static int hf_BACnetCharacterSet = -1;
4411 static int hf_bacapp_tag_lvt = -1;
4412 static int hf_bacapp_tag_ProcessId = -1;
4413 static int hf_bacapp_uservice = -1;
4414 static int hf_BACnetPropertyIdentifier = -1;
4415 static int hf_BACnetVendorIdentifier = -1;
4416 static int hf_BACnetRestartReason = -1;
4417 static int hf_bacapp_tag_IPV4 = -1;
4418 static int hf_bacapp_tag_IPV6 = -1;
4419 static int hf_bacapp_tag_PORT = -1;
4420 /* some more variables for segmented messages */
4421 static int hf_msg_fragments = -1;
4422 static int hf_msg_fragment = -1;
4423 static int hf_msg_fragment_overlap = -1;
4424 static int hf_msg_fragment_overlap_conflicts = -1;
4425 static int hf_msg_fragment_multiple_tails = -1;
4426 static int hf_msg_fragment_too_long_fragment = -1;
4427 static int hf_msg_fragment_error = -1;
4428 static int hf_msg_fragment_count = -1;
4429 static int hf_msg_reassembled_in = -1;
4430 static int hf_msg_reassembled_length = -1;
4432 static gint ett_msg_fragment = -1;
4433 static gint ett_msg_fragments = -1;
4435 static gint ett_bacapp = -1;
4436 static gint ett_bacapp_control = -1;
4437 static gint ett_bacapp_tag = -1;
4438 static gint ett_bacapp_list = -1;
4439 static gint ett_bacapp_value = -1;
4441 static dissector_handle_t data_handle;
4442 static gint32 propertyIdentifier = -1;
4443 static gint32 propertyArrayIndex = -1;
4444 static guint32 object_type = 4096;
4446 static guint8 bacapp_flags = 0;
4447 static guint8 bacapp_seq = 0;
4449 /* Defined to allow vendor identifier registration of private transfer dissectors */
4450 static dissector_table_t bacapp_dissector_table;
4453 /* Stat: BACnet Packets sorted by IP */
4454 bacapp_info_value_t bacinfo;
4456 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
4457 static const gchar* st_str_packets_by_ip_dst = "By Destination";
4458 static const gchar* st_str_packets_by_ip_src = "By Source";
4459 static int st_node_packets_by_ip = -1;
4460 static int st_node_packets_by_ip_dst = -1;
4461 static int st_node_packets_by_ip_src = -1;
4464 bacapp_packet_stats_tree_init(stats_tree* st)
4466 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4467 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4468 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4472 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4474 int packets_for_this_dst;
4475 int packets_for_this_src;
4476 int service_for_this_dst;
4477 int service_for_this_src;
4478 int src_for_this_dst;
4479 int dst_for_this_src;
4480 int objectid_for_this_dst;
4481 int objectid_for_this_src;
4482 int instanceid_for_this_dst;
4483 int instanceid_for_this_src;
4486 const bacapp_info_value_t *binfo = p;
4488 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4489 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4491 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4492 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4493 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4494 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4495 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4496 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4497 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4498 if (binfo->service_type) {
4499 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4500 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4501 if (binfo->object_ident) {
4502 instanceid_for_this_dst=tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4503 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4504 instanceid_for_this_src=tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4505 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4512 /* Stat: BACnet Packets sorted by Service */
4513 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4514 static int st_node_packets_by_service = -1;
4517 bacapp_service_stats_tree_init(stats_tree* st)
4519 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4523 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4531 const bacapp_info_value_t *binfo = p;
4533 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4534 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4536 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4537 if (binfo->service_type) {
4538 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4539 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4540 dst = tick_stat_node(st, dststr, src, TRUE);
4541 if (binfo->object_ident) {
4542 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4543 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4550 /* Stat: BACnet Packets sorted by Object Type */
4551 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
4552 static int st_node_packets_by_objectid = -1;
4555 bacapp_objectid_stats_tree_init(stats_tree* st)
4557 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
4561 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4569 const bacapp_info_value_t *binfo = p;
4571 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4572 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4574 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
4575 if (binfo->object_ident) {
4576 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
4577 src = tick_stat_node(st, srcstr, objectid, TRUE);
4578 dst = tick_stat_node(st, dststr, src, TRUE);
4579 if (binfo->service_type) {
4580 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4581 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
4588 /* Stat: BACnet Packets sorted by Instance No */
4589 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
4590 static int st_node_packets_by_instanceid = -1;
4593 bacapp_instanceid_stats_tree_init(stats_tree* st)
4595 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
4599 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4607 const bacapp_info_value_t *binfo = p;
4609 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4610 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4612 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
4613 if (binfo->object_ident) {
4614 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
4615 src = tick_stat_node(st, srcstr, instanceid, TRUE);
4616 dst = tick_stat_node(st, dststr, src, TRUE);
4617 if (binfo->service_type) {
4618 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4619 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
4626 /* register all BACnet Ststistic trees */
4628 register_bacapp_stat_trees(void)
4630 stats_tree_register("bacapp","bacapp_ip","BACnet/Packets sorted by IP", 0,
4631 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
4632 stats_tree_register("bacapp","bacapp_service","BACnet/Packets sorted by Service", 0,
4633 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
4634 stats_tree_register("bacapp","bacapp_objectid","BACnet/Packets sorted by Object Type", 0,
4635 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
4636 stats_tree_register("bacapp","bacapp_instanceid","BACnet/Packets sorted by Instance ID", 0,
4637 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
4640 /* 'data' must be ep_ allocated */
4642 updateBacnetInfoValue(gint whichval, gchar *data)
4644 if (whichval == BACINFO_SERVICE) {
4645 bacinfo.service_type = data;
4648 if (whichval == BACINFO_INVOKEID) {
4649 bacinfo.invoke_id = data;
4652 if (whichval == BACINFO_OBJECTID) {
4653 bacinfo.object_ident = data;
4656 if (whichval == BACINFO_INSTANCEID) {
4657 bacinfo.instance_ident = data;
4663 static const fragment_items msg_frag_items = {
4664 /* Fragment subtrees */
4667 /* Fragment fields */
4670 &hf_msg_fragment_overlap,
4671 &hf_msg_fragment_overlap_conflicts,
4672 &hf_msg_fragment_multiple_tails,
4673 &hf_msg_fragment_too_long_fragment,
4674 &hf_msg_fragment_error,
4675 &hf_msg_fragment_count,
4676 /* Reassembled in field */
4677 &hf_msg_reassembled_in,
4678 /* Reassembled length field */
4679 &hf_msg_reassembled_length,
4684 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
4685 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
4688 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
4690 fGetMaxAPDUSize(guint8 idx)
4692 /* only 16 values are defined, so use & 0x0f */
4693 /* check the size of the Array, deliver either the entry
4694 or the first entry if idx is outside of the array (bug 3736 comment#7) */
4696 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
4697 return MaxAPDUSize[0];
4699 return MaxAPDUSize[idx & 0x0f];
4704 /* Used when there are ranges of reserved and proprietary enumerations */
4706 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
4707 const char *fmt, const char *split_fmt)
4709 if (val < split_val)
4710 return val_to_str(val, vs, fmt);
4712 return val_to_str(val, vs, split_fmt);
4715 /* from clause 20.2.1.3.2 Constructed Data */
4716 /* returns true if the extended value is used */
4718 tag_is_extended_value(guint8 tag)
4720 return (tag & 0x07) == 5;
4724 tag_is_opening(guint8 tag)
4726 return (tag & 0x07) == 6;
4730 tag_is_closing(guint8 tag)
4732 return (tag & 0x07) == 7;
4735 /* from clause 20.2.1.1 Class
4736 class bit shall be one for context specific tags */
4737 /* returns true if the tag is context specific */
4739 tag_is_context_specific(guint8 tag)
4741 return (tag & 0x08) != 0;
4745 tag_is_extended_tag_number(guint8 tag)
4747 return ((tag & 0xF0) == 0xF0);
4751 object_id_type(guint32 object_identifier)
4753 return ((object_identifier >> 22) & 0x3FF);
4757 object_id_instance(guint32 object_identifier)
4759 return (object_identifier & 0x3FFFFF);
4763 fTagNo (tvbuff_t *tvb, guint offset)
4765 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
4769 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
4771 gboolean valid = TRUE;
4775 *val = tvb_get_guint8(tvb, offset);
4778 *val = tvb_get_ntohs(tvb, offset);
4781 *val = tvb_get_ntoh24(tvb, offset);
4784 *val = tvb_get_ntohl(tvb, offset);
4795 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4797 gboolean valid = FALSE;
4801 if (lvt && (lvt <= 8)) {
4803 data = tvb_get_guint8(tvb, offset);
4804 for (i = 0; i < lvt; i++) {
4805 data = tvb_get_guint8(tvb, offset+i);
4806 value = (value << 8) + data;
4814 /* BACnet Signed Value uses 2's complement notation, but with a twist:
4815 All signed integers shall be encoded in the smallest number of octets
4816 possible. That is, the first octet of any multi-octet encoded value
4817 shall not be X'00' if the most significant bit (bit 7) of the second
4818 octet is 0, and the first octet shall not be X'FF' if the most
4819 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4821 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4823 gboolean valid = FALSE;
4828 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4829 if (lvt && (lvt <= 7)) {
4831 data = tvb_get_guint8(tvb, offset);
4832 if ((data & 0x80) != 0)
4833 value = (-1 << 8) | data;
4836 for (i = 1; i < lvt; i++) {
4837 data = tvb_get_guint8(tvb, offset+i);
4838 value = (value << 8) + data;
4847 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
4848 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4853 guint lvt_len = 1; /* used for tree display of lvt */
4854 guint lvt_offset; /* used for tree display of lvt */
4856 proto_tree *subtree;
4858 lvt_offset = offset;
4859 tag = tvb_get_guint8(tvb, offset);
4862 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4863 /* can mean open/close tag or length of 6/7 after the length is */
4864 /* computed below - store whole tag info, not just context bit. */
4865 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4867 if (tag_is_extended_tag_number(tag)) {
4868 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4870 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4871 lvt_offset += tag_len;
4872 value = tvb_get_guint8(tvb, lvt_offset);
4874 if (value == 254) { /* length is encoded with 16 Bits */
4875 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4878 } else if (value == 255) { /* length is encoded with 32 Bits */
4879 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4887 if (tag_is_opening(tag))
4888 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4889 else if (tag_is_closing(tag))
4890 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4891 else if (tag_is_context_specific(tag)) {
4892 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4893 "Context Tag: %u, Length/Value/Type: %u",
4896 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4897 "Application Tag: %s, Length/Value/Type: %u",
4899 BACnetApplicationTagNumber,
4900 ASHRAE_Reserved_Fmt),
4903 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4904 /* details if needed */
4905 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
4906 if (tag_is_extended_tag_number(tag)) {
4907 proto_tree_add_uint_format(subtree,
4908 hf_BACnetContextTagNumber,
4909 tvb, offset, 1, tag,
4910 "Extended Tag Number");
4911 proto_tree_add_item(subtree,
4912 hf_BACnetExtendedTagNumber,
4913 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4915 if (tag_is_context_specific(tag))
4916 proto_tree_add_item(subtree,
4917 hf_BACnetContextTagNumber,
4918 tvb, offset, 1, ENC_BIG_ENDIAN);
4920 proto_tree_add_item(subtree,
4921 hf_BACnetApplicationTagNumber,
4922 tvb, offset, 1, ENC_BIG_ENDIAN);
4924 if (tag_is_closing(tag) || tag_is_opening(tag))
4925 proto_tree_add_item(subtree,
4927 tvb, offset, 1, ENC_BIG_ENDIAN);
4928 else if (tag_is_extended_value(tag)) {
4929 proto_tree_add_item(subtree,
4931 tvb, offset, 1, ENC_BIG_ENDIAN);
4932 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4933 tvb, lvt_offset, lvt_len, *lvt);
4935 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4936 tvb, lvt_offset, lvt_len, *lvt);
4943 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
4946 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
4950 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4952 guint8 tag_no, tag_info;
4955 proto_tree *subtree;
4957 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4958 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4959 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4965 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4967 guint8 tag_no, tag_info;
4970 proto_tree *subtree;
4973 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4974 if (tag_info && lvt == 1) {
4975 lvt = tvb_get_guint8(tvb, offset+1);
4979 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
4980 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
4981 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4982 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4984 return offset + bool_len;
4988 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4991 guint8 tag_no, tag_info;
4995 proto_tree *subtree;
4997 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4998 /* only support up to an 8 byte (64-bit) integer */
4999 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
5000 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5001 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
5003 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5004 "%s - %u octets (Unsigned)", label, lvt);
5005 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5006 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5008 return offset+tag_len+lvt;
5012 fDevice_Instance (tvbuff_t *tvb, proto_tree *tree, guint offset, int hf)
5014 guint8 tag_no, tag_info;
5018 proto_tree *subtree;
5020 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5021 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, lvt, ENC_BIG_ENDIAN);
5022 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5023 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5025 return offset+tag_len+lvt;
5028 /* set split_val to zero when not needed */
5030 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5031 const value_string *vs, guint32 split_val)
5034 guint8 tag_no, tag_info;
5038 proto_tree *subtree;
5040 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5041 /* only support up to a 4 byte (32-bit) enumeration */
5042 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
5044 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5045 "%s %s", label, val_to_split_str(val, split_val, vs,
5046 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
5048 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5049 "%s %u", label, val);
5051 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5052 "%s - %u octets (enumeration)", label, lvt);
5054 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5055 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5057 return offset+tag_len+lvt;
5061 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5062 const value_string *vs)
5064 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
5068 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5071 guint8 tag_no, tag_info;
5075 proto_tree *subtree;
5077 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5078 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
5079 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5080 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
5082 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5083 "%s - %u octets (Signed)", label, lvt);
5084 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5085 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5087 return offset+tag_len+lvt;
5091 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5093 guint8 tag_no, tag_info;
5098 proto_tree *subtree;
5100 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5101 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
5102 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
5103 "%s%f (Real)", label, f_val);
5104 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5105 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5107 return offset+tag_len+4;
5111 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5113 guint8 tag_no, tag_info;
5118 proto_tree *subtree;
5120 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5121 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
5122 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
5123 "%s%f (Double)", label, d_val);
5124 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5125 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5127 return offset+tag_len+8;
5131 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
5133 guint32 val = 0, lvt;
5134 guint8 tag_no, tag_info;
5136 proto_tree *subtree;
5139 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5140 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5141 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
5142 tvb, offset, lvt+tag_len, val);
5144 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5145 "Process Identifier - %u octets (Signed)", lvt);
5146 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5147 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5148 offset += tag_len + lvt;
5154 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5156 guint32 val = 0, lvt;
5157 guint8 tag_no, tag_info;
5159 proto_tree *subtree;
5162 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5163 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5164 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5165 "%s (hh.mm.ss): %d.%02d.%02d%s",
5167 (val / 3600), ((val % 3600) / 60), (val % 60),
5168 val == 0 ? " (indefinite)" : "");
5170 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5171 "%s - %u octets (Signed)", label, lvt);
5172 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5173 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5175 return offset+tag_len+lvt;
5179 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
5181 guint32 month, weekOfMonth, dayOfWeek;
5182 guint8 tag_no, tag_info;
5186 proto_tree *subtree;
5188 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5189 month = tvb_get_guint8(tvb, offset+tag_len);
5190 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
5191 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
5192 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
5193 val_to_str(month, months, "month (%d) not found"),
5194 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
5195 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
5196 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5197 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5199 return offset+tag_len+lvt;
5203 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5205 guint32 year, month, day, weekday;
5206 guint8 tag_no, tag_info;
5210 proto_tree *subtree;
5212 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5213 year = tvb_get_guint8(tvb, offset+tag_len);
5214 month = tvb_get_guint8(tvb, offset+tag_len+1);
5215 day = tvb_get_guint8(tvb, offset+tag_len+2);
5216 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
5217 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
5218 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5221 else if (year != 255) {
5223 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5224 "%s%s %d, %d, (Day of Week = %s)",
5225 label, val_to_str(month,
5227 "month (%d) not found"),
5228 day, year, val_to_str(weekday,
5232 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5233 "%s%s %d, any year, (Day of Week = %s)",
5234 label, val_to_str(month, months, "month (%d) not found"),
5235 day, val_to_str(weekday, day_of_week, "(%d) not found"));
5237 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5238 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5240 return offset+tag_len+lvt;
5244 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5246 guint32 hour, minute, second, msec, lvt;
5247 guint8 tag_no, tag_info;
5250 proto_tree *subtree;
5252 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5253 hour = tvb_get_guint8(tvb, offset+tag_len);
5254 minute = tvb_get_guint8(tvb, offset+tag_len+1);
5255 second = tvb_get_guint8(tvb, offset+tag_len+2);
5256 msec = tvb_get_guint8(tvb, offset+tag_len+3);
5257 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
5258 ti = proto_tree_add_text(tree, tvb, offset,
5259 lvt+tag_len, "%sany", label);
5261 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5262 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
5264 hour > 12 ? hour - 12 : hour,
5265 minute, second, msec,
5266 hour >= 12 ? "P.M." : "A.M.",
5267 hour, minute, second, msec);
5268 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5269 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5271 return offset+tag_len+lvt;
5275 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5277 proto_tree *subtree = tree;
5280 if (label != NULL) {
5281 tt = proto_tree_add_text (subtree, tvb, offset, 10, "%s", label);
5282 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5284 offset = fDate (tvb,subtree,offset,"Date: ");
5285 return fTime (tvb,subtree,offset,"Time: ");
5289 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5291 guint lastoffset = 0;
5292 guint8 tag_no, tag_info;
5295 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5296 lastoffset = offset;
5297 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5298 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
5301 offset = fTime (tvb,tree,offset,"Time: ");
5302 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
5304 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
5310 fCalendarEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
5312 guint8 tag_no, tag_info;
5315 switch (fTagNo(tvb, offset)) {
5317 offset = fDate (tvb, tree, offset, "Date: ");
5319 case 1: /* dateRange */
5320 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5321 offset = fDateRange (tvb, tree, offset);
5322 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5324 case 2: /* BACnetWeekNDay */
5325 offset = fWeekNDay (tvb, tree, offset);
5335 fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
5338 proto_tree* subtree = tree;
5341 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5342 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
5344 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5346 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
5347 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
5348 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
5354 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5356 guint8 tag_no = 0, tag_info = 0;
5359 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
5360 switch (fTagNo(tvb, offset)) {
5362 offset = fTime (tvb, tree, offset, label?label:"time: ");
5364 case 1: /* sequenceNumber */
5365 offset = fUnsignedTag (tvb, tree, offset,
5366 label?label:"sequence number: ");
5368 case 2: /* dateTime */
5369 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5370 offset = fDateTime (tvb, tree, offset, label?label:"date time: ");
5371 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5383 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5385 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5386 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
5391 static const value_string
5392 BACnetDaysOfWeek [] = {
5404 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5406 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5407 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
5408 "valid Days: ", BACnetDaysOfWeek);
5409 offset = fTime (tvb,tree,offset,"from time: ");
5410 offset = fTime (tvb,tree,offset,"to time: ");
5411 offset = fRecipient (tvb,pinfo,tree,offset);
5412 offset = fProcessId (tvb,tree,offset);
5413 offset = fApplicationTypes (tvb,pinfo,tree,offset,
5414 "issue confirmed notifications: ");
5415 offset = fBitStringTagVS (tvb,tree,offset,
5416 "transitions: ", BACnetEventTransitionBits);
5423 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5426 guint start = offset;
5427 guint8 tag_no, tag_info;
5428 proto_tree* subtree = tree;
5431 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5434 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5435 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
5440 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5442 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5448 fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5451 guint start = offset;
5452 guint8 tag_no, tag_info;
5453 proto_tree* subtree = tree;
5456 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5458 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
5461 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
5463 guint32 ip = tvb_get_ipv4(tvb, offset);
5464 guint16 port = tvb_get_ntohs(tvb, offset+4);
5466 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
5467 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
5470 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
5471 struct e_in6_addr addr;
5472 guint16 port = tvb_get_ntohs(tvb, offset+16);
5473 tvb_get_ipv6(tvb, offset, &addr);
5475 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
5476 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
5478 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
5479 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5480 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
5487 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5489 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5495 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
5497 guint8 tag_no, tag_info;
5501 offset = fUnsignedTag (tvb, tree, offset, "network-number");
5502 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5504 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5507 offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
5513 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
5515 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
5516 return fAddress (tvb,tree,offset);
5520 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5522 guint8 tag_no, tag_info;
5526 proto_tree *subtree;
5529 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5530 object_id = tvb_get_ntohl(tvb,offset+tag_length);
5531 object_type = object_id_type(object_id);
5532 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
5533 "ObjectIdentifier: %s, %u",
5534 val_to_split_str(object_type,
5537 ASHRAE_Reserved_Fmt,
5538 Vendor_Proprietary_Fmt),
5539 object_id_instance(object_id));
5540 if (col_get_writable(pinfo->cinfo))
5541 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5542 val_to_split_str(object_type,
5545 ASHRAE_Reserved_Fmt,
5546 Vendor_Proprietary_Fmt),
5547 object_id_instance(object_id));
5549 /* update BACnet Statistics */
5550 updateBacnetInfoValue(BACINFO_OBJECTID,
5551 ep_strdup(val_to_split_str(object_type, 128,
5552 BACnetObjectType, ASHRAE_Reserved_Fmt,
5553 Vendor_Proprietary_Fmt)));
5554 updateBacnetInfoValue(BACINFO_INSTANCEID, ep_strdup_printf("Instance ID: %u",
5555 object_id_instance(object_id)));
5557 /* here are the details of how we arrived at the above text */
5558 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5559 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5560 offset += tag_length;
5561 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
5562 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
5569 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5571 guint8 tag_no, tag_info;
5574 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5576 if (tag_no == 0) { /* device */
5577 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5579 else { /* address */
5580 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5581 offset = fAddress (tvb, tree, offset);
5582 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5589 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5591 guint lastoffset = 0;
5592 guint8 tag_no, tag_info;
5594 proto_tree* orgtree = tree;
5596 proto_tree* subtree;
5598 /* beginning of new item - indent and label */
5599 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
5600 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5602 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5603 lastoffset = offset;
5605 switch (fTagNo(tvb, offset)) {
5606 case 0: /* recipient */
5607 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5608 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5609 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5610 offset = fRecipient (tvb, pinfo, subtree, offset);
5611 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5613 case 1: /* processId */
5614 offset = fProcessId (tvb, tree, offset);
5615 lastoffset = offset;
5620 if (offset == lastoffset) break; /* nothing happened, exit loop */
5626 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5628 guint lastoffset = 0;
5629 guint8 tag_no, tag_info;
5631 proto_tree* subtree;
5633 proto_tree* orgtree = tree;
5636 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5637 lastoffset = offset;
5638 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5639 if (tag_is_closing(tag_info) ) {
5644 case 0: /* recipient */
5645 /* beginning of new item in list */
5646 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
5647 itemno = itemno + 1;
5648 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5650 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5651 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5652 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5653 offset = fRecipientProcess (tvb, pinfo, subtree, offset);
5654 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5655 subtree = tree; /* done with this level - return to previous tree */
5657 case 1: /* MonitoredPropertyReference */
5658 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
5659 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5660 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5661 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
5662 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5665 case 2: /* IssueConfirmedNotifications - boolean */
5666 offset = fBooleanTag (tvb, tree, offset, "Issue Confirmed Notifications: ");
5668 case 3: /* TimeRemaining */
5669 offset = fUnsignedTag (tvb, tree, offset, "Time Remaining: ");
5671 case 4: /* COVIncrement */
5672 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5677 if (offset == lastoffset) break; /* nothing happened, exit loop */
5683 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5685 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5686 return fAddress (tvb, tree, offset);
5690 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
5692 guint lastoffset = 0, len;
5693 guint8 tag_no, tag_info;
5695 proto_tree *subtree = tree;
5697 /* set the optional global properties to indicate not-used */
5698 propertyArrayIndex = -1;
5699 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5700 lastoffset = offset;
5701 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5702 if (tag_is_closing(tag_info) ) {
5703 if (tag_no == tag_match) {
5712 case 0: /* deviceIdentifier */
5713 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5715 case 1: /* objectIdentifier */
5716 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5718 case 2: /* propertyIdentifier */
5719 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
5721 case 3: /* propertyArrayIndex */
5722 offset = fPropertyArrayIndex (tvb, subtree, offset);
5724 case 4: /* propertyValue */
5725 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
5727 case 5: /* priority */
5728 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
5730 case 6: /* postDelay */
5731 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
5733 case 7: /* quitOnFailure */
5734 offset = fBooleanTag(tvb, subtree, offset,
5735 "Quit On Failure: ");
5737 case 8: /* writeSuccessful */
5738 offset = fBooleanTag(tvb, subtree, offset,
5739 "Write Successful: ");
5744 if (offset == lastoffset) break; /* nothing happened, exit loop */
5749 /* BACnetActionList ::= SEQUENCE{
5750 action [0] SEQUENCE OF BACnetActionCommand
5754 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5756 guint lastoffset = 0, len;
5757 guint8 tag_no, tag_info;
5759 proto_tree *subtree = tree;
5762 while (tvb_reported_length_remaining(tvb, offset)) {
5763 lastoffset = offset;
5764 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5765 if (tag_is_closing(tag_info)) {
5767 if ( tag_no != 0 ) /* don't eat the closing property tag, just return */
5772 if (tag_is_opening(tag_info)) {
5773 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
5774 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5775 offset += fTagHeaderTree (tvb, subtree, offset,
5776 &tag_no, &tag_info, &lvt);
5779 case 0: /* BACnetActionCommand */
5780 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
5785 if (offset == lastoffset) break; /* nothing happened, exit loop */
5791 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5793 guint8 tag_no, tag_info;
5797 proto_tree *subtree;
5798 const gchar *label = "Property Identifier";
5800 propertyIdentifier = 0; /* global Variable */
5801 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5802 /* can we decode this value? */
5803 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
5804 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5805 "%s: %s (%u)", label,
5806 val_to_split_str(propertyIdentifier, 512,
5807 BACnetPropertyIdentifier,
5808 ASHRAE_Reserved_Fmt,
5809 Vendor_Proprietary_Fmt), propertyIdentifier);
5810 if (col_get_writable(pinfo->cinfo))
5811 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
5812 val_to_split_str(propertyIdentifier, 512,
5813 BACnetPropertyIdentifier,
5814 ASHRAE_Reserved_Fmt,
5815 Vendor_Proprietary_Fmt));
5817 /* property identifiers cannot be larger than 22-bits */
5820 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5821 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5822 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
5823 offset+tag_len, lvt, ENC_BIG_ENDIAN);
5825 return offset+tag_len+lvt;
5829 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
5831 guint8 tag_no, tag_info;
5835 proto_tree *subtree;
5837 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5838 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
5839 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5840 "property Array Index (Unsigned) %u", propertyArrayIndex);
5842 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5843 "property Array Index - %u octets (Unsigned)", lvt);
5844 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5845 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5847 return offset+tag_len+lvt;
5851 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5853 guint8 tag_no, tag_info, character_set;
5855 gsize inbytesleft, outbytesleft = 512;
5856 guint offs, extra = 1;
5859 guint8 bf_arr[512], *out = &bf_arr[0];
5861 proto_tree *subtree;
5862 guint start = offset;
5864 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5866 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5868 character_set = tvb_get_guint8(tvb, offset+offs);
5869 /* Account for code page if DBCS */
5870 if (character_set == 1) {
5873 offset += (offs+extra);
5877 inbytesleft = l = MIN(lvt, 255);
5879 * XXX - are we guaranteed that these encoding
5880 * names correspond, on *all* platforms with
5881 * iconv(), to the encodings we want?
5882 * If not (and perhaps even if so), we should
5883 * perhaps have our own iconv() implementation,
5884 * with a different name, so that we control the
5885 * encodings it supports and the names of those
5888 * We should also handle that in the general
5889 * string handling code, rather than making it
5890 * specific to the BACAPP dissector, as many
5891 * other dissectors need to handle various
5892 * character encodings.
5894 str_val = tvb_get_ephemeral_string(tvb, offset, l);
5895 /** this decoding may be not correct for multi-byte characters, Lka */
5896 switch (character_set) {
5898 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UTF-8");
5903 coding = "IBM MS DBCS";
5907 coding = "JIS C 6226";
5909 case ISO_10646_UCS4:
5910 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5911 coding = "ISO 10646 UCS-4";
5913 case ISO_10646_UCS2:
5914 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5915 coding = "ISO 10646 UCS-2";
5918 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5919 coding = "ISO 8859-1";
5926 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s '%s'", label, coding, out);
5931 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5933 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
5934 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
5936 if (character_set == 1) {
5937 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5939 /* XXX - put the string value here */
5945 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5946 const value_string *src)
5948 guint8 tag_no, tag_info, tmp;
5949 gint j, unused, skip;
5950 guint start = offset;
5952 guint32 lvt, i, numberOfBytes;
5954 proto_tree* subtree = tree;
5957 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5958 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
5960 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
5961 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
5965 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5967 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5968 proto_tree_add_text(subtree, tvb, offset, 1,
5972 for (i = 0; i < numberOfBytes; i++) {
5973 tmp = tvb_get_guint8(tvb, (offset)+i+1);
5974 if (i == numberOfBytes-1) { skip = unused; }
5975 for (j = 0; j < 8-skip; j++) {
5977 if (tmp & (1 << (7 - j)))
5978 proto_tree_add_text(subtree, tvb,
5981 val_to_str((guint) (i*8 +j),
5983 ASHRAE_Reserved_Fmt));
5985 proto_tree_add_text(subtree, tvb,
5988 val_to_str((guint) (i*8 +j),
5990 ASHRAE_Reserved_Fmt));
5992 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
5998 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
5999 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
6008 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
6010 return fBitStringTagVS (tvb, tree, offset, label, NULL);
6013 /* handles generic application types, as well as enumerated and enumerations
6014 with reserved and proprietarty ranges (split) */
6016 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6017 const gchar *label, const value_string *src, guint32 split_val)
6019 guint8 tag_no, tag_info;
6023 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6025 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6026 if (!tag_is_context_specific(tag_info)) {
6028 case 0: /** NULL 20.2.2 */
6029 offset = fNullTag(tvb, tree, offset, label);
6031 case 1: /** BOOLEAN 20.2.3 */
6032 offset = fBooleanTag(tvb, tree, offset, label);
6034 case 2: /** Unsigned Integer 20.2.4 */
6035 offset = fUnsignedTag(tvb, tree, offset, label);
6037 case 3: /** Signed Integer 20.2.5 */
6038 offset = fSignedTag(tvb, tree, offset, label);
6040 case 4: /** Real 20.2.6 */
6041 offset = fRealTag(tvb, tree, offset, label);
6043 case 5: /** Double 20.2.7 */
6044 offset = fDoubleTag(tvb, tree, offset, label);
6046 case 6: /** Octet String 20.2.8 */
6047 offset = fOctetString (tvb, tree, offset, label, lvt);
6049 case 7: /** Character String 20.2.9 */
6050 offset = fCharacterString (tvb,tree,offset,label);
6052 case 8: /** Bit String 20.2.10 */
6053 offset = fBitStringTagVS (tvb, tree, offset, label, src);
6055 case 9: /** Enumerated 20.2.11 */
6056 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
6058 case 10: /** Date 20.2.12 */
6059 offset = fDate (tvb, tree, offset, label);
6061 case 11: /** Time 20.2.13 */
6062 offset = fTime (tvb, tree, offset, label);
6064 case 12: /** BACnetObjectIdentifier 20.2.14 */
6065 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6067 case 13: /* reserved for ASHRAE */
6070 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
6071 offset+=lvt+tag_len;
6083 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
6085 guint lastoffset = 0;
6087 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6088 lastoffset = offset;
6090 switch (fTagNo(tvb,offset)) {
6091 case 0: /* percent */
6092 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
6095 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
6097 case 2: /* amount */
6098 offset = fRealTag(tvb, tree, offset, "shed amount: ");
6103 if (offset == lastoffset) break; /* nothing happened, exit loop */
6109 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6110 const gchar *label, const value_string *vs)
6112 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
6116 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6119 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
6123 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
6125 guint8 tag_no, tag_info;
6129 proto_tree *subtree;
6133 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
6134 /* cap the the suggested length in case of bad data */
6135 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
6136 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
6139 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
6140 "Context Value (as %u DATA octets)", lvt);
6142 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6143 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6145 return offset + tag_len + lvt;
6148 BACnetPrescale ::= SEQUENCE {
6149 multiplier [0] Unsigned,
6150 moduloDivide [1] Unsigned
6154 fPrescale (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6156 guint8 tag_no, tag_info;
6158 guint lastoffset = 0;
6160 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6161 lastoffset = offset;
6162 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6163 if (tag_is_closing(tag_info) ) {
6167 case 0: /* multiplier */
6168 offset = fUnsignedTag (tvb,tree,offset,"Multiplier: ");
6170 case 1: /* moduloDivide */
6171 offset = fUnsignedTag (tvb,tree,offset,"Modulo Divide: ");
6176 if (offset == lastoffset) break; /* nothing happened, exit loop */
6182 BACnetScale ::= CHOICE {
6183 floatScale [0] REAL,
6184 integerScale [1] INTEGER
6188 fScale (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6190 guint8 tag_no, tag_info;
6192 guint lastoffset = 0;
6194 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6195 lastoffset = offset;
6196 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6197 if (tag_is_closing(tag_info) ) {
6201 case 0: /* floatScale */
6202 offset = fRealTag (tvb,tree,offset,"Float Scale: ");
6204 case 1: /* integerScale */
6205 offset = fSignedTag (tvb,tree,offset,"Integer Scale: ");
6210 if (offset == lastoffset) break; /* nothing happened, exit loop */
6215 BACnetAccumulatorRecord ::= SEQUENCE {
6216 timestamp [0] BACnetDateTime,
6217 presentValue [1] Unsigned,
6218 accumulatedValue [2] Unsigned,
6219 accumulatortStatus [3] ENUMERATED {
6229 fLoggingRecord (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6231 guint8 tag_no, tag_info;
6233 guint lastoffset = 0;
6235 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6236 lastoffset = offset;
6237 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6238 if (tag_is_closing(tag_info) ) {
6242 case 0: /* timestamp */
6243 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6244 offset = fDateTime (tvb, tree, offset, "Timestamp: ");
6245 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6247 case 1: /* presentValue */
6248 offset = fUnsignedTag (tvb,tree,offset,"Present Value: ");
6250 case 2: /* accumulatedValue */
6251 offset = fUnsignedTag (tvb,tree,offset,"Accumulated Value: ");
6253 case 3: /* accumulatorStatus */
6254 offset = fEnumeratedTag (tvb, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus);
6258 if (offset == lastoffset) break; /* nothing happened, exit loop */
6264 SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState
6267 fSequenceOfEnums (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, const value_string *vs)
6269 guint8 tag_no, tag_info;
6271 guint lastoffset = 0;
6273 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6274 lastoffset = offset;
6275 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6276 if (tag_is_closing(tag_info) ) {
6279 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs);
6280 if ( offset == lastoffset ) break;
6286 SEQ OF BACnetDeviceObjectReference (accessed as an array)
6290 fDoorMembers (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6292 guint8 tag_no, tag_info;
6294 guint lastoffset = 0;
6296 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6297 lastoffset = offset;
6298 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6299 if (tag_is_closing(tag_info) ) {
6302 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6303 if (offset == lastoffset) break;
6309 SEQ OF ReadAccessSpecification
6312 fListOfGroupMembers (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6314 guint8 tag_no, tag_info;
6316 guint lastoffset = 0;
6318 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6319 lastoffset = offset;
6320 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6321 if (tag_is_closing(tag_info) ) {
6324 offset = fReadAccessSpecification(tvb, pinfo, tree, offset);
6325 if ( offset == lastoffset ) break;
6331 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6333 guint8 tag_no, tag_info;
6335 guint lastoffset = 0, depth = 0;
6337 guint32 save_object_type = object_type;
6339 if (propertyIdentifier >= 0) {
6340 g_snprintf (ar, sizeof(ar), "%s: ",
6341 val_to_split_str(propertyIdentifier, 512,
6342 BACnetPropertyIdentifier,
6343 ASHRAE_Reserved_Fmt,
6344 Vendor_Proprietary_Fmt));
6346 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
6348 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6349 lastoffset = offset;
6350 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6351 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
6352 if (depth <= 0) return offset;
6355 /* Application Tags */
6356 switch (propertyIdentifier) {
6357 case 2: /* action */
6358 /* loop object is application tagged,
6359 command object is context tagged */
6360 if (tag_is_context_specific(tag_info)) {
6361 /* BACnetActionList */
6362 offset = fActionList (tvb, pinfo, tree,offset);
6365 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6369 case 30: /* BACnetAddressBinding */
6370 offset = fAddressBinding (tvb,pinfo,tree,offset);
6372 case 54: /* list of object property reference */
6373 offset = fLOPR (tvb, pinfo, tree,offset);
6375 case 55: /* list-of-session-keys */
6376 fSessionKey (tvb, tree, offset);
6378 case 79: /* object-type */
6379 case 96: /* protocol-object-types-supported */
6380 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
6381 BACnetObjectType, 128);
6383 case 97: /* Protocol-Services-Supported */
6384 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6385 BACnetServicesSupported);
6387 case 102: /* recipient-list */
6388 offset = fDestination (tvb, pinfo, tree, offset);
6390 case 107: /* segmentation-supported */
6391 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6392 BACnetSegmentation);
6394 case 111: /* Status-Flags */
6395 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6398 case 112: /* System-Status */
6399 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6400 BACnetDeviceStatus);
6402 case 117: /* units */
6403 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6404 BACnetEngineeringUnits);
6406 case 87: /* priority-array -- accessed as a BACnetARRAY */
6407 if (propertyArrayIndex == 0) {
6408 /* BACnetARRAY index 0 refers to the length
6409 of the array, not the elements of the array */
6410 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6412 offset = fPriorityArray (tvb, pinfo, tree, offset);
6415 case 38: /* exception-schedule */
6416 if (object_type < 128) {
6417 if (propertyArrayIndex == 0) {
6418 /* BACnetARRAY index 0 refers to the length
6419 of the array, not the elements of the array */
6420 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6422 offset = fSpecialEvent (tvb,pinfo,tree,offset);
6426 case 19: /* controlled-variable-reference */
6427 case 60: /* manipulated-variable-reference */
6428 case 109: /* Setpoint-Reference */
6429 case 132: /* log-device-object-property */
6430 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6432 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
6433 if (object_type < 128) {
6434 if (propertyArrayIndex == 0) {
6435 /* BACnetARRAY index 0 refers to the length
6436 of the array, not the elements of the array */
6437 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6439 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
6443 case 127: /* client COV increment */
6444 offset = fClientCOV (tvb, pinfo, tree, offset);
6446 case 131: /* log-buffer */
6447 if ( object_type == 25 )
6448 offset = fEventLogRecord(tvb, pinfo, tree, offset);
6449 else if ( object_type == 27 )
6450 offset = fLogMultipleRecord (tvb, pinfo, tree, offset);
6452 offset = fLogRecord (tvb, pinfo, tree, offset);
6454 case 159: /* member-of */
6455 case 165: /* zone-members */
6456 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6458 case 196: /* last-restart-reason */
6459 offset = fRestartReason (tvb, pinfo, tree, offset);
6461 case 212: /* actual-shed-level */
6462 case 214: /* expected-shed-level */
6463 case 218: /* requested-shed-level */
6464 offset = fShedLevel (tvb, tree, offset);
6466 case 152: /* active-cov-subscriptions */
6467 offset = fCOVSubscription (tvb, pinfo, tree, offset);
6469 case 23: /* date-list */
6470 offset = fCalendarEntry(tvb, tree, offset);
6472 case 116: /* time-sychronization-recipients */
6473 offset = fRecipient(tvb, pinfo, tree, offset);
6475 case 83: /* event-parameters */
6476 offset = fEventParameter(tvb, pinfo, tree, offset);
6478 case 211: /* subordinate-list */
6479 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6481 case 130: /* event-time-stamp */
6482 offset = fEventTimeStamps(tvb, pinfo, tree, offset);
6484 case 197: /* logging-type */
6485 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType);
6487 case 36: /* event-state */
6488 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64);
6490 case 103: /* reliability */
6491 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability);
6493 case 72: /* notify-type */
6494 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNotifyType);
6496 case 208: /* node-type */
6497 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType);
6499 case 231: /* door-status */
6500 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus);
6502 case 233: /* lock-status */
6503 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus);
6505 case 235: /* secured-status */
6506 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus);
6508 case 158: /* maintenance-required */
6509 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance);
6511 case 92: /* program-state */
6512 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState);
6514 case 90: /* program-change */
6515 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest);
6517 case 100: /* reason-for-halt */
6518 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError);
6520 case 160: /* mode */
6521 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode);
6523 case 163: /* silenced */
6524 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState);
6526 case 161: /* operation-expected */
6527 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation);
6529 case 164: /* tracking-value */
6530 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState);
6532 case 41: /* file-access-method */
6533 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod);
6535 case 185: /* prescale */
6536 offset = fPrescale(tvb, pinfo, tree, offset);
6538 case 187: /* scale */
6539 offset = fScale(tvb, pinfo, tree, offset);
6541 case 184: /* logging-record */
6542 offset = fLoggingRecord(tvb, pinfo, tree, offset);
6544 case 228: /* door-members */
6545 offset = fDoorMembers(tvb, pinfo, tree, offset);
6547 case 181: /* input-reference */
6548 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6550 case 78: /* object-property-reference */
6551 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6553 case 234: /* masked-alarm-values */
6554 offset = fSequenceOfEnums(tvb, pinfo, tree, offset, "masked-alarm-value: ", BACnetDoorAlarmState);
6556 case 53: /* list-of-group-members */
6557 save_object_type = object_type;
6558 offset = fListOfGroupMembers(tvb, pinfo, tree, offset);
6559 object_type = save_object_type;
6561 case 85: /* present-value */
6562 if ( object_type == 11 ) /* group object handling of present-value */
6564 offset = fReadAccessResult(tvb, pinfo, tree, offset);
6567 /* intentially fall through here so don't reorder this case statement */
6570 if (tag_is_opening(tag_info)) {
6572 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6573 } else if (tag_is_closing(tag_info)) {
6575 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6577 offset = fContextTaggedValue(tvb, tree, offset, ar);
6580 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6584 if (offset == lastoffset) break; /* nothing happened, exit loop */
6591 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
6596 if (tag_is_opening(tag_info)) {
6597 offset += fTagHeaderTree(tvb, tree, offset,
6598 &tag_no, &tag_info, &lvt);
6599 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6600 if (tvb_length_remaining(tvb, offset) > 0) {
6601 offset += fTagHeaderTree(tvb, tree, offset,
6602 &tag_no, &tag_info, &lvt);
6605 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
6606 "expected Opening Tag!"); \
6607 offset = tvb_length(tvb);
6615 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
6617 guint lastoffset = offset;
6618 guint8 tag_no, tag_info;
6621 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
6622 if (offset > lastoffset) {
6623 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6624 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
6625 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
6632 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6634 guint lastoffset = 0;
6635 guint8 tag_no, tag_info;
6638 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6639 lastoffset = offset;
6640 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
6641 if (offset > lastoffset) {
6642 /* detect optional priority
6643 by looking to see if the next tag is context tag number 3 */
6644 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6645 if (tag_is_context_specific(tag_info) && (tag_no == 3))
6646 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
6648 if (offset == lastoffset) break; /* nothing happened, exit loop */
6654 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6656 guint lastoffset = 0, len;
6657 guint8 tag_no, tag_info;
6659 proto_tree *subtree = tree;
6662 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6663 lastoffset = offset;
6664 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6665 if (tag_is_closing(tag_info)) {
6672 case 0: /* ProcessId */
6673 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
6675 case 1: /* monitored ObjectId */
6676 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6678 case 2: /* issueConfirmedNotifications */
6679 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
6681 case 3: /* life time */
6682 offset = fTimeSpan (tvb,tree,offset,"life time");
6684 case 4: /* monitoredPropertyIdentifier */
6685 if (tag_is_opening(tag_info)) {
6686 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
6688 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6690 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6691 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
6696 case 5: /* covIncrement */
6697 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
6702 if (offset == lastoffset) break; /* nothing happened, exit loop */
6708 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6710 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
6714 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6716 guint lastoffset = 0;
6718 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6719 lastoffset = offset;
6721 switch (fTagNo(tvb, offset)) {
6722 case 0: /* deviceInstanceLowLimit */
6723 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
6725 case 1: /* deviceInstanceHighLimit */
6726 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
6728 case 2: /* BACnetObjectId */
6729 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6731 case 3: /* messageText */
6732 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
6737 if (offset == lastoffset) break; /* nothing happened, exit loop */
6744 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
6746 guint lastoffset = 0;
6747 guint8 tag_no, tag_info;
6750 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6751 if (tag_is_opening(tag_info) && tag_no == 0) {
6752 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
6753 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6754 lastoffset = offset;
6755 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6756 if (tag_is_closing(tag_info)) {
6757 /* should be closing context tag 0 */
6758 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6762 offset = fTimeValue (tvb, pinfo, subtree, offset);
6763 if (offset == lastoffset) break; /* nothing happened, exit loop */
6765 } else if (tag_no == 0 && lvt == 0) {
6766 /* not sure null (empty array element) is legal */
6767 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6773 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6775 guint lastoffset = 0;
6776 guint8 tag_no, tag_info;
6778 guint i = 1; /* day of week array index */
6779 proto_tree *subtree = tree;
6782 if (propertyArrayIndex > 0) {
6783 /* BACnetARRAY index 0 refers to the length
6784 of the array, not the elements of the array.
6785 BACnetARRAY index -1 is our internal flag that
6786 the optional index was not used.
6787 BACnetARRAY refers to this as all elements of the array.
6788 If the optional index is specified for a BACnetARRAY,
6789 then that specific array element is referenced. */
6790 i = propertyArrayIndex;
6792 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6793 lastoffset = offset;
6794 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6795 if (tag_is_closing(tag_info)) {
6796 return offset; /* outer encoding will print out closing tag */
6798 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
6799 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6800 offset = fDailySchedule (tvb, pinfo, subtree, offset);
6801 if (offset == lastoffset) break; /* nothing happened, exit loop */
6808 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
6810 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6813 return fDateTime (tvb, tree, offset, "UTC-Time: ");
6817 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
6819 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6822 return fDateTime (tvb, tree, offset, NULL);
6826 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
6828 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6830 offset = fDate (tvb,tree,offset,"Start Date: ");
6831 return fDate (tvb, tree, offset, "End Date: ");
6835 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6838 guint8 tag_no, tag_info;
6842 proto_tree *subtree;
6843 const gchar *label = "Vendor ID";
6845 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6846 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6847 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6848 "%s: %s (%u)", label,
6849 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
6851 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6852 "%s - %u octets (Unsigned)", label, lvt);
6853 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6854 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6856 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
6857 proto_item *expert_item;
6858 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6859 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6860 PROTO_ITEM_SET_GENERATED(expert_item);
6861 return offset+tag_len+lvt;
6864 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
6865 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6867 return offset+tag_len+lvt;
6871 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6874 guint8 tag_no, tag_info;
6878 proto_tree *subtree;
6879 const gchar *label = "Restart Reason";
6881 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6882 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6883 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6884 "%s: %s (%u)", label,
6885 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
6887 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6888 "%s - %u octets (Unsigned)", label, lvt);
6889 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6890 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6893 proto_item *expert_item;
6894 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
6895 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
6896 PROTO_ITEM_SET_GENERATED(expert_item);
6897 return offset+tag_len+lvt;
6900 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
6901 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6903 return offset+tag_len+lvt;
6907 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6909 guint lastoffset = 0;
6911 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6912 lastoffset = offset;
6913 switch (fTagNo(tvb, offset)) {
6915 case 0: /* textMessageSourceDevice */
6916 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6918 case 1: /* messageClass */
6919 switch (fTagNo(tvb, offset)) {
6920 case 0: /* numeric */
6921 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
6923 case 1: /* character */
6924 offset = fCharacterString (tvb, tree, offset, "message Class: ");
6928 case 2: /* messagePriority */
6929 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
6930 BACnetMessagePriority);
6932 case 3: /* message */
6933 offset = fCharacterString (tvb, tree, offset, "message: ");
6938 if (offset == lastoffset) break; /* nothing happened, exit loop */
6944 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6946 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
6950 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6952 guint lastoffset = 0, len;
6953 guint8 tag_no, tag_info;
6955 proto_tree *subtree = tree;
6958 guint vendor_identifier = 0;
6959 guint service_number = 0;
6961 lastoffset = offset;
6962 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6963 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
6964 if (col_get_writable(pinfo->cinfo))
6965 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
6966 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6968 next_tvb = tvb_new_subset_remaining(tvb,offset);
6969 if (dissector_try_uint(bacapp_dissector_table,
6970 vendor_identifier, next_tvb, pinfo, tree)) {
6971 /* we parsed it so skip over length and we are done */
6972 offset += tvb_length(next_tvb);
6976 /* Not handled by vendor dissector */
6978 /* exit loop if nothing happens inside */
6979 while (tvb_reported_length_remaining(tvb, offset)) {
6980 lastoffset = offset;
6981 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6982 if (tag_is_closing(tag_info)) {
6983 if (tag_no == 2) { /* Make sure it's the expected tag */
6988 break; /* End loop if incorrect closing tag */
6993 /* vendorID is now parsed above */
6994 case 1: /* serviceNumber */
6995 fUnsigned32(tvb, offset+len, lvt, &service_number);
6996 if (col_get_writable(pinfo->cinfo))
6997 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
6998 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
7000 case 2: /*serviceParameters */
7001 if (tag_is_opening(tag_info)) {
7002 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
7003 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7004 propertyIdentifier = -1;
7005 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7013 if (offset == lastoffset) break; /* nothing happened, exit loop */
7020 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7022 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7026 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7028 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7032 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
7034 guint lastoffset = 0;
7035 guint8 tag_no, tag_info;
7037 proto_tree *subtree = tree;
7040 if (label != NULL) {
7041 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
7042 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7045 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7046 lastoffset = offset;
7047 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7050 case 0: /* subscriberProcessId */
7051 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
7053 case 1: /* requestingSource */
7054 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
7056 case 2: /* request */
7057 offset = fEnumeratedTagSplit (tvb, tree, offset,
7058 "request: ", BACnetLifeSafetyOperation, 64);
7060 case 3: /* objectId */
7061 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7066 if (offset == lastoffset) break; /* nothing happened, exit loop */
7071 typedef struct _value_string_enum {
7072 const value_string *valstr;
7073 } value_string_enum;
7075 static const value_string_enum
7076 BACnetPropertyStatesEnums[] = {
7081 {BACnetProgramRequest },
7082 {BACnetProgramState },
7083 {BACnetProgramError },
7084 {BACnetReliability },
7085 {BACnetEventState },
7086 {BACnetDeviceStatus },
7087 {BACnetEngineeringUnits },
7089 {BACnetLifeSafetyMode },
7090 {BACnetLifeSafetyState },
7091 {BACnetRestartReason },
7092 {BACnetDoorAlarmState },
7094 {BACnetDoorSecuredStatus },
7095 {BACnetDoorStatus },
7096 { NULL }, /* {BACnetDoorValue }, */
7097 {BACnetFileAccessMethod },
7098 {BACnetLockStatus },
7099 {BACnetLifeSafetyOperation },
7100 {BACnetMaintenance },
7102 {BACnetNotifyType },
7103 { NULL }, /* {BACnetSecurityLevel }, */
7105 {BACnetSilencedState },
7107 { NULL }, /* {BACnetAccessEvent }, */
7108 { NULL }, /* {BACnetZoneOccupancyState }, */
7109 { NULL }, /* {BACnetAccessCredentialDisableReason }, */
7110 { NULL }, /* {BACnetAccessCredentialDisable }, */
7111 { NULL }, /* {BACnetAuthenticationStatus }, */
7113 { NULL }, /* {BACnetBackupState }, */
7115 #define BACnetPropertyStatesEnums_Size 36
7118 fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
7120 guint8 tag_no, tag_info;
7122 const gchar* label = NULL;
7124 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7125 label = ep_strdup_printf( "%s: ", val_to_str_const( tag_no, VALS(BACnetPropertyStates), "unknown-"+tag_no ));
7130 offset = fBooleanTag (tvb, tree, offset, label);
7133 offset = fUnsignedTag(tvb, tree, offset, label);
7136 if ( (tag_no > BACnetPropertyStatesEnums_Size) ||
7137 VALS(BACnetPropertyStatesEnums[tag_no].valstr) == NULL)
7139 offset = fEnumeratedTag(tvb, tree, offset, "Unknown State: ", NULL);
7140 /* don't use Abstract type here because it is context tagged and therefore we don't know app type */
7144 offset = fEnumeratedTagSplit(tvb, tree, offset, label,
7145 VALS(BACnetPropertyStatesEnums[tag_no].valstr), 64);
7154 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
7155 deviceIdentifier [0] BACnetObjectIdentifier,
7156 objectIdentifier [1] BACnetObjectIdentifier,
7157 propertyIdentifier [2] BACnetPropertyIdentifier,
7158 arrayIndex [3] Unsigned OPTIONAL,
7159 value [4] ABSTRACT-SYNTAX.&Type
7163 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7165 guint lastoffset = 0;
7166 guint8 tag_no, tag_info;
7169 while (tvb_reported_length_remaining(tvb, offset)) {
7170 lastoffset = offset;
7171 /* check the tag. A closing tag means we are done */
7172 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7173 if (tag_is_closing(tag_info)) {
7177 case 0: /* deviceIdentifier */
7178 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7180 case 1: /* objectIdentifier */
7181 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7183 case 2: /* propertyIdentifier */
7184 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7186 case 3: /* arrayIndex - OPTIONAL */
7187 offset = fUnsignedTag (tvb, tree, offset,
7191 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7192 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7193 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7198 if (offset == lastoffset) break; /* nothing happened, exit loop */
7204 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7205 objectIdentifier [0] BACnetObjectIdentifier,
7206 propertyIdentifier [1] BACnetPropertyIdentifier,
7207 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7208 -- if omitted with an array then
7209 -- the entire array is referenced
7210 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7214 fObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7216 return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7220 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7221 objectIdentifier [0] BACnetObjectIdentifier,
7222 propertyIdentifier [1] BACnetPropertyIdentifier,
7223 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7224 -- if omitted with an array then
7225 -- the entire array is referenced
7226 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7230 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7232 guint lastoffset = 0;
7233 guint8 tag_no, tag_info;
7236 while (tvb_reported_length_remaining(tvb, offset)) {
7237 lastoffset = offset;
7238 /* check the tag. A closing tag means we are done */
7239 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7240 if (tag_is_closing(tag_info)) {
7244 case 0: /* objectIdentifier */
7245 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7247 case 1: /* propertyIdentifier */
7248 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7250 case 2: /* arrayIndex - OPTIONAL */
7251 offset = fUnsignedTag (tvb, tree, offset,
7254 case 3: /* deviceIdentifier - OPTIONAL */
7255 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7260 if (offset == lastoffset) break; /* nothing happened, exit loop */
7266 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7268 guint lastoffset = offset;
7269 guint8 tag_no, tag_info;
7271 proto_tree *subtree = tree;
7274 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7275 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
7276 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
7277 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7278 /* Opening tag for parameter choice */
7279 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7282 case 0: /* change-of-bitstring */
7283 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7284 lastoffset = offset;
7285 switch (fTagNo(tvb, offset)) {
7287 offset = fBitStringTag (tvb, subtree, offset,
7288 "referenced-bitstring: ");
7291 offset = fBitStringTagVS (tvb, subtree, offset,
7292 "status-flags: ", BACnetStatusFlags);
7293 lastoffset = offset;
7298 if (offset == lastoffset) break; /* nothing happened, exit loop */
7301 case 1: /* change-of-state */
7302 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7303 lastoffset = offset;
7304 switch (fTagNo(tvb, offset)) {
7306 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7307 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7308 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7311 offset = fBitStringTagVS (tvb, subtree, offset,
7312 "status-flags: ", BACnetStatusFlags);
7313 lastoffset = offset;
7318 if (offset == lastoffset) break; /* nothing happened, exit loop */
7321 case 2: /* change-of-value */
7322 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7323 lastoffset = offset;
7324 switch (fTagNo(tvb, offset)) {
7326 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7327 switch (fTagNo(tvb, offset)) {
7329 offset = fBitStringTag (tvb, subtree, offset,
7333 offset = fRealTag (tvb, subtree, offset,
7339 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7342 offset = fBitStringTagVS (tvb, subtree, offset,
7343 "status-flags: ", BACnetStatusFlags);
7344 lastoffset = offset;
7349 if (offset == lastoffset) break; /* nothing happened, exit loop */
7352 case 3: /* command-failure */
7353 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7354 lastoffset = offset;
7355 switch (fTagNo(tvb, offset)) {
7356 case 0: /* "command-value: " */
7357 /* from BACnet Table 13-3,
7358 Standard Object Property Values Returned in Notifications */
7359 propertyIdentifier = 85; /* PRESENT_VALUE */
7360 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7361 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7362 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7365 offset = fBitStringTagVS (tvb, subtree, offset,
7366 "status-flags: ", BACnetStatusFlags);
7368 case 2: /* "feedback-value: " */
7369 propertyIdentifier = 40; /* FEEDBACK_VALUE */
7370 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7371 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7372 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7373 lastoffset = offset;
7378 if (offset == lastoffset) break; /* nothing happened, exit loop */
7381 case 4: /* floating-limit */
7382 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7383 lastoffset = offset;
7384 switch (fTagNo(tvb, offset)) {
7386 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
7389 offset = fBitStringTagVS (tvb, subtree, offset,
7390 "status-flags: ", BACnetStatusFlags);
7393 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
7396 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
7397 lastoffset = offset;
7402 if (offset == lastoffset) break; /* nothing happened, exit loop */
7405 case 5: /* out-of-range */
7406 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7407 lastoffset = offset;
7408 switch (fTagNo(tvb, offset)) {
7410 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
7413 offset = fBitStringTagVS (tvb, subtree, offset,
7414 "status-flags: ", BACnetStatusFlags);
7417 offset = fRealTag (tvb, subtree, offset, "deadband: ");
7420 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
7421 lastoffset = offset;
7426 if (offset == lastoffset) break; /* nothing happened, exit loop */
7430 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7431 lastoffset = offset;
7432 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
7433 if (offset == lastoffset) break; /* nothing happened, exit loop */
7436 case 7: /* buffer-ready */
7437 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7438 lastoffset = offset;
7439 switch (fTagNo(tvb, offset)) {
7441 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
7444 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
7447 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7448 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
7449 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7452 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7453 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
7454 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7455 lastoffset = offset;
7460 if (offset == lastoffset) break; /* nothing happened, exit loop */
7463 case 8: /* change-of-life-safety */
7464 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7465 lastoffset = offset;
7466 switch (fTagNo(tvb, offset)) {
7468 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7469 "new-state: ", BACnetLifeSafetyState, 256);
7472 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7473 "new-mode: ", BACnetLifeSafetyMode, 256);
7476 offset = fBitStringTagVS (tvb, subtree, offset,
7477 "status-flags: ", BACnetStatusFlags);
7480 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7481 "operation-expected: ", BACnetLifeSafetyOperation, 64);
7482 lastoffset = offset;
7487 if (offset == lastoffset) break; /* nothing happened, exit loop */
7490 case 9: /* extended */
7491 while (tvb_reported_length_remaining(tvb, offset)) {
7492 lastoffset = offset;
7493 switch (fTagNo(tvb, offset)) {
7495 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
7498 offset = fUnsignedTag (tvb, subtree, offset,
7499 "extended-event-type: ");
7501 case 2: /* parameters */
7502 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7503 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
7504 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
7505 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7506 lastoffset = offset;
7511 if (offset == lastoffset) break; /* nothing happened, exit loop */
7514 case 10: /* buffer ready */
7515 while (tvb_reported_length_remaining(tvb, offset)) {
7516 lastoffset = offset;
7517 switch (fTagNo(tvb, offset)) {
7518 case 0: /* buffer-property */
7519 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7520 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7521 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7524 offset = fUnsignedTag (tvb, subtree, offset,
7525 "previous-notification: ");
7528 offset = fUnsignedTag (tvb, subtree, offset,
7529 "current-notification: ");
7530 lastoffset = offset;
7535 if (offset == lastoffset) break; /* nothing happened, exit loop */
7538 case 11: /* unsigned range */
7539 while (tvb_reported_length_remaining(tvb, offset)) {
7540 lastoffset = offset;
7541 switch (fTagNo(tvb, offset)) {
7543 offset = fUnsignedTag (tvb, subtree, offset,
7544 "exceeding-value: ");
7547 offset = fBitStringTagVS (tvb, subtree, offset,
7548 "status-flags: ", BACnetStatusFlags);
7551 offset = fUnsignedTag (tvb, subtree, offset,
7552 "exceeded-limit: ");
7553 lastoffset = offset;
7558 if (offset == lastoffset) break; /* nothing happened, exit loop */
7561 /* todo: add new parameters here ... */
7563 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7567 /* Closing tag for parameter choice */
7568 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7574 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7576 guint lastoffset = offset;
7577 guint8 tag_no, tag_info;
7579 proto_tree *subtree = tree;
7582 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7583 tt = proto_tree_add_text(subtree, tvb, offset, 0, "event parameters (%d) %s",
7584 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
7585 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7586 /* Opening tag for parameter choice */
7587 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7590 case 0: /* change-of-bitstring */
7591 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7592 lastoffset = offset;
7593 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7594 if (tag_is_closing(tag_info)) {
7599 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7602 offset = fBitStringTag (tvb, subtree, offset, "bitmask: ");
7604 case 2: /* SEQUENCE OF BIT STRING */
7605 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7606 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7607 lastoffset = offset;
7608 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7609 if (tag_is_closing(tag_info)) {
7612 offset = fBitStringTag(tvb, subtree, offset,
7613 "bitstring value: ");
7615 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7622 case 1: /* change-of-state */
7623 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7624 lastoffset = offset;
7625 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7626 if (tag_is_closing(tag_info)) {
7631 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7633 case 1: /* SEQUENCE OF BACnetPropertyStates */
7634 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7635 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7636 lastoffset = offset;
7637 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7638 if (tag_is_closing(tag_info)) {
7641 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7643 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7650 case 2: /* change-of-value */
7651 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7652 lastoffset = offset;
7653 switch (fTagNo(tvb, offset)) {
7655 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7657 case 1: /* don't loop it, it's a CHOICE */
7658 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7659 switch (fTagNo(tvb, offset)) {
7661 offset = fBitStringTag (tvb, subtree, offset, "bitmask: ");
7664 offset = fRealTag (tvb, subtree, offset,
7665 "referenced Property Increment: ");
7670 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7677 case 3: /* command-failure */
7678 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7679 lastoffset = offset;
7680 tag_no = fTagNo(tvb, offset);
7683 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7686 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7687 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7688 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7695 case 4: /* floating-limit */
7696 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7697 lastoffset = offset;
7698 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7699 if (tag_is_closing(tag_info)) {
7704 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7707 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7708 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7709 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7712 offset = fRealTag (tvb, subtree, offset, "low diff limit: ");
7715 offset = fRealTag (tvb, subtree, offset, "high diff limit: ");
7718 offset = fRealTag (tvb, subtree, offset, "deadband: ");
7725 case 5: /* out-of-range */
7726 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7727 lastoffset = offset;
7728 switch (fTagNo(tvb, offset)) {
7730 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7733 offset = fRealTag (tvb, subtree, offset, "low limit: ");
7736 offset = fRealTag (tvb, subtree, offset, "high limit: ");
7739 offset = fRealTag (tvb, subtree, offset, "deadband: ");
7748 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
7752 case 7: /* buffer-ready */
7754 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
7755 lastoffset = offset;
7756 switch (fTagNo(tvb, offset)) {
7758 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
7761 offset = fUnsignedTag (tvb,tree,offset,
7762 "previous notification count: ");
7770 case 8: /* change-of-life-safety */
7771 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7772 lastoffset = offset;
7773 switch (fTagNo(tvb, offset)) {
7775 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7778 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7779 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7780 lastoffset = offset;
7781 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7782 if (tag_is_closing(tag_info)) {
7785 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7786 "life safety alarm value: ", BACnetLifeSafetyState, 256);
7788 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7791 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7792 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7793 lastoffset = offset;
7794 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7795 if (tag_is_closing(tag_info)) {
7798 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7799 "alarm value: ", BACnetLifeSafetyState, 256);
7801 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7804 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7805 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7806 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7813 case 9: /* extended */
7814 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7815 lastoffset = offset;
7816 switch (fTagNo(tvb, offset)) {
7818 offset = fVendorIdentifier (tvb, pinfo, tree, offset);
7821 offset = fUnsignedTag (tvb, tree, offset,
7822 "extended-event-type: ");
7824 case 2: /* parameters */
7825 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7826 offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
7827 offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
7828 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7829 lastoffset = offset;
7834 if (offset == lastoffset) break; /* nothing happened, exit loop */
7837 case 10: /* buffer-ready */
7838 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7839 lastoffset = offset;
7840 switch (fTagNo(tvb, offset)) {
7842 offset = fUnsignedTag (tvb, subtree, offset,
7843 "notification-threshold: ");
7846 offset = fUnsignedTag (tvb, subtree, offset,
7847 "previous-notification-count: ");
7854 case 11: /* unsigned-range */
7855 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7856 lastoffset = offset;
7857 switch (fTagNo(tvb, offset)) {
7859 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
7862 offset = fUnsignedTag (tvb, tree, offset,
7866 offset = fUnsignedTag (tvb, tree, offset,
7874 /* todo: add new event-parameter cases here */
7879 /* Closing tag for parameter choice */
7880 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7885 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7887 guint lastoffset = 0;
7888 guint8 tag_no, tag_info;
7890 proto_tree *subtree = tree;
7893 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7894 lastoffset = offset;
7895 switch (fTagNo(tvb, offset)) {
7896 case 0: /* timestamp */
7897 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7898 offset = fDate (tvb,tree,offset,"Date: ");
7899 offset = fTime (tvb,tree,offset,"Time: ");
7900 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7902 case 1: /* logDatum: don't loop, it's a CHOICE */
7903 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7904 switch (fTagNo(tvb, offset)) {
7905 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
7906 offset = fBitStringTagVS(tvb, tree, offset, "log status:", BACnetLogStatus);
7908 case 1: /* todo: move this to new method fConfirmedEventNotificationRequestTag... */
7909 tt = proto_tree_add_text(tree, tvb, offset, 1, "notification: ");
7910 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7911 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7912 offset = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset);
7913 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7916 offset = fRealTag (tvb, tree, offset, "time-change: ");
7921 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7926 if (offset == lastoffset) break; /* nothing happened, exit loop */
7932 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7934 guint lastoffset = 0;
7935 guint8 tag_no, tag_info;
7938 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7939 lastoffset = offset;
7940 switch (fTagNo(tvb, offset)) {
7941 case 0: /* timestamp */
7942 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7943 offset = fDate (tvb,tree,offset,"Date: ");
7944 offset = fTime (tvb,tree,offset,"Time: ");
7945 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7947 case 1: /* logDatum: don't loop, it's a CHOICE */
7948 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7949 switch (fTagNo(tvb, offset)) {
7950 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
7951 offset = fBitStringTagVS(tvb, tree, offset, "log status:", BACnetLogStatus);
7954 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
7957 offset = fRealTag (tvb, tree, offset, "real value: ");
7960 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
7963 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
7966 offset = fSignedTag (tvb, tree, offset, "signed value: ");
7969 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
7972 offset = fNullTag(tvb, tree, offset, "null value: ");
7975 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7976 offset = fError (tvb, pinfo, tree, offset);
7977 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7980 offset = fRealTag (tvb, tree, offset, "time change: ");
7982 case 10: /* any Value */
7983 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7984 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7985 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7990 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7993 /* Changed this to BitString per BACnet Spec. */
7994 offset = fBitStringTagVS(tvb, tree, offset, "Status Flags:", BACnetStatusFlags);
7999 if (offset == lastoffset) break; /* nothing happened, exit loop */
8005 fLogMultipleRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8007 guint lastoffset = 0;
8008 guint8 tag_no, tag_info;
8011 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8012 lastoffset = offset;
8013 switch (fTagNo(tvb, offset)) {
8014 case 0: /* timestamp */
8015 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8016 offset = fDate (tvb,tree,offset,"Date: ");
8017 offset = fTime (tvb,tree,offset,"Time: ");
8018 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8020 case 1: /* logData: don't loop, it's a CHOICE */
8021 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8022 switch (fTagNo(tvb, offset)) {
8023 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8024 offset = fBitStringTagVS(tvb, tree, offset, "log status:", BACnetLogStatus);
8026 case 1: /* log-data: SEQUENCE OF CHOICE */
8027 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8028 while (tvb_reported_length_remaining(tvb, offset) && (offset != lastoffset)) { /* exit loop if nothing happens inside */
8029 lastoffset = offset;
8030 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8031 if (tag_is_closing(tag_info)) {
8032 lastoffset = offset;
8037 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
8040 offset = fRealTag (tvb, tree, offset, "real value: ");
8043 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
8046 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
8049 offset = fSignedTag (tvb, tree, offset, "signed value: ");
8052 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
8055 offset = fNullTag(tvb, tree, offset, "null value: ");
8058 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8059 offset = fError (tvb, pinfo, tree, offset);
8060 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8062 case 8: /* any Value */
8063 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8064 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
8065 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8071 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8074 offset = fRealTag (tvb, tree, offset, "time-change: ");
8079 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8084 if (offset == lastoffset) break; /* nothing happened, exit loop */
8091 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8093 guint lastoffset = 0;
8094 guint8 tag_no, tag_info;
8097 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8098 lastoffset = offset;
8099 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8100 if (tag_is_closing(tag_info)) {
8101 lastoffset = offset;
8106 case 0: /* ProcessId */
8107 offset = fProcessId (tvb,tree,offset);
8109 case 1: /* initiating ObjectId */
8110 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8112 case 2: /* event ObjectId */
8113 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8115 case 3: /* time stamp */
8116 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8117 offset = fTimeStamp (tvb, tree, offset, NULL);
8118 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8120 case 4: /* notificationClass */
8121 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
8123 case 5: /* Priority */
8124 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
8126 case 6: /* EventType */
8127 offset = fEnumeratedTagSplit (tvb, tree, offset,
8128 "Event Type: ", BACnetEventType, 64);
8130 case 7: /* messageText */
8131 offset = fCharacterString (tvb, tree, offset, "message Text: ");
8133 case 8: /* NotifyType */
8134 offset = fEnumeratedTag (tvb, tree, offset,
8135 "Notify Type: ", BACnetNotifyType);
8137 case 9: /* ackRequired */
8138 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
8140 case 10: /* fromState */
8141 offset = fEnumeratedTagSplit (tvb, tree, offset,
8142 "from State: ", BACnetEventState, 64);
8144 case 11: /* toState */
8145 offset = fEnumeratedTagSplit (tvb, tree, offset,
8146 "to State: ", BACnetEventState, 64);
8148 case 12: /* NotificationParameters */
8149 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8150 offset = fNotificationParameters (tvb, pinfo, tree, offset);
8151 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8156 if (offset == lastoffset) break; /* nothing happened, exit loop */
8162 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8164 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8168 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8170 guint lastoffset = 0, len;
8171 guint8 tag_no, tag_info;
8173 proto_tree *subtree = tree;
8176 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8177 lastoffset = offset;
8178 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8179 if (tag_is_closing(tag_info)) {
8186 case 0: /* ProcessId */
8187 offset = fProcessId (tvb,tree,offset);
8189 case 1: /* initiating DeviceId */
8190 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8192 case 2: /* monitored ObjectId */
8193 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8195 case 3: /* time remaining */
8196 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
8198 case 4: /* List of Values */
8199 if (tag_is_opening(tag_info)) {
8200 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
8201 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8202 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8203 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8211 if (offset == lastoffset) break; /* nothing happened, exit loop */
8217 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8219 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8223 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8225 guint lastoffset = 0;
8226 guint8 tag_no = 0, tag_info = 0;
8229 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8230 lastoffset = offset;
8231 switch (fTagNo(tvb, offset)) {
8232 case 0: /* acknowledgingProcessId */
8233 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
8235 case 1: /* eventObjectId */
8236 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8238 case 2: /* eventStateAcknowledged */
8239 offset = fEnumeratedTagSplit (tvb, tree, offset,
8240 "event State Acknowledged: ", BACnetEventState, 64);
8242 case 3: /* timeStamp */
8243 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8244 offset = fTimeStamp(tvb, tree, offset, NULL);
8245 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8247 case 4: /* acknowledgementSource */
8248 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
8250 case 5: /* timeOfAcknowledgement */
8251 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8252 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
8253 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8258 if (offset == lastoffset) break; /* nothing happened, exit loop */
8264 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8266 guint lastoffset = 0;
8268 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8269 lastoffset = offset;
8270 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8271 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8272 "alarm State: ", BACnetEventState, 64);
8273 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8274 "acknowledged Transitions: ", BACnetEventTransitionBits);
8275 if (offset == lastoffset) break; /* nothing happened, exit loop */
8281 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8283 guint lastoffset = 0;
8284 guint8 tag_no, tag_info;
8287 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8288 lastoffset = offset;
8289 switch (fTagNo(tvb, offset)) {
8290 case 0: /* acknowledgmentFilter */
8291 offset = fEnumeratedTag (tvb, tree, offset,
8292 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
8294 case 1: /* eventObjectId - OPTIONAL */
8295 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8296 offset = fRecipientProcess (tvb, pinfo, tree, offset);
8297 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8299 case 2: /* eventStateFilter */
8300 offset = fEnumeratedTag (tvb, tree, offset,
8301 "event State Filter: ", BACnetEventStateFilter);
8303 case 3: /* eventTypeFilter - OPTIONAL */
8304 offset = fEnumeratedTag (tvb, tree, offset,
8305 "event Type Filter: ", BACnetEventType);
8307 case 4: /* priorityFilter */
8308 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8309 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
8310 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
8311 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8313 case 5: /* notificationClassFilter - OPTIONAL */
8314 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
8319 if (offset == lastoffset) break; /* nothing happened, exit loop */
8325 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8327 guint lastoffset = 0;
8329 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8330 lastoffset = offset;
8331 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8332 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8333 "event Type: ", BACnetEventType, 64);
8334 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8335 "event State: ", BACnetEventState);
8336 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
8337 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
8338 if (offset == lastoffset) break; /* nothing happened, exit loop */
8345 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8347 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8348 if (fTagNo(tvb, offset) == 0) {
8349 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8356 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8358 guint lastoffset = 0;
8359 guint8 tag_no, tag_info;
8361 proto_tree* subtree = tree;
8364 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8365 lastoffset = offset;
8366 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8367 /* we are finished here if we spot a closing tag */
8368 if (tag_is_closing(tag_info)) {
8372 case 0: /* ObjectId */
8373 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8375 case 1: /* eventState */
8376 offset = fEnumeratedTag (tvb, tree, offset,
8377 "event State: ", BACnetEventState);
8379 case 2: /* acknowledgedTransitions */
8380 offset = fBitStringTagVS (tvb, tree, offset,
8381 "acknowledged Transitions: ", BACnetEventTransitionBits);
8383 case 3: /* eventTimeStamps */
8384 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
8386 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8388 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8389 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
8390 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
8391 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
8392 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8394 case 4: /* notifyType */
8395 offset = fEnumeratedTag (tvb, tree, offset,
8396 "Notify Type: ", BACnetNotifyType);
8398 case 5: /* eventEnable */
8399 offset = fBitStringTagVS (tvb, tree, offset,
8400 "event Enable: ", BACnetEventTransitionBits);
8402 case 6: /* eventPriorities */
8403 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
8405 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8407 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8408 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
8409 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
8410 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
8411 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8416 if (offset == lastoffset) break; /* nothing happened, exit loop */
8422 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8424 guint lastoffset = 0;
8425 guint8 tag_no, tag_info;
8428 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8429 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8430 lastoffset = offset;
8431 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8432 /* we are finished here if we spot a closing tag */
8433 if (tag_is_closing(tag_info)) {
8436 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
8437 if (offset == lastoffset) break; /* nothing happened, exit loop */
8443 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8445 guint lastoffset = 0;
8446 guint8 tag_no, tag_info;
8449 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8450 lastoffset = offset;
8451 switch (fTagNo(tvb, offset)) {
8452 case 0: /* listOfEventSummaries */
8453 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8454 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
8455 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8457 case 1: /* moreEvents */
8458 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
8463 if (offset == lastoffset) break; /* nothing happened, exit loop */
8469 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8471 guint lastoffset = 0, len;
8472 guint8 tag_no, tag_info;
8474 proto_tree *subtree = tree;
8477 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8479 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8480 lastoffset = offset;
8481 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8482 if (tag_is_closing(tag_info)) {
8489 case 0: /* ObjectId */
8490 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
8492 case 3: /* listOfElements */
8493 if (tag_is_opening(tag_info)) {
8494 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
8495 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8496 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8497 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8505 if (offset == lastoffset) break; /* nothing happened, exit loop */
8511 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8513 return fObjectIdentifier (tvb, pinfo, tree, offset);
8517 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
8519 guint lastoffset = 0;
8521 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8522 lastoffset = offset;
8524 switch (fTagNo(tvb, offset)) {
8525 case 0: /* timeDuration */
8526 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
8528 case 1: /* enable-disable */
8529 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
8530 BACnetEnableDisable);
8532 case 2: /* password - OPTIONAL */
8533 offset = fCharacterString (tvb, tree, offset, "Password: ");
8538 if (offset == lastoffset) break; /* nothing happened, exit loop */
8544 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
8546 guint lastoffset = 0;
8548 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8549 lastoffset = offset;
8551 switch (fTagNo(tvb, offset)) {
8552 case 0: /* reinitializedStateOfDevice */
8553 offset = fEnumeratedTag (tvb, tree, offset,
8554 "reinitialized State Of Device: ",
8555 BACnetReinitializedStateOfDevice);
8557 case 1: /* password - OPTIONAL */
8558 offset = fCharacterString (tvb, tree, offset, "Password: ");
8563 if (offset == lastoffset) break; /* nothing happened, exit loop */
8569 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8571 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8572 "vtClass: ", BACnetVTClass);
8573 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
8577 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8579 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
8583 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8585 guint lastoffset = 0;
8587 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8588 lastoffset = offset;
8589 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
8590 if (offset == lastoffset) break; /* nothing happened, exit loop */
8596 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8598 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
8599 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
8600 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
8604 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
8606 guint lastoffset = 0;
8608 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8609 lastoffset = offset;
8611 switch (fTagNo(tvb,offset)) {
8612 case 0: /* BOOLEAN */
8613 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
8615 case 1: /* Unsigned OPTIONAL */
8616 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
8621 if (offset == lastoffset) break; /* nothing happened, exit loop */
8627 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
8629 guint lastoffset = 0;
8631 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8632 lastoffset = offset;
8634 switch (fTagNo(tvb,offset)) {
8635 case 0: /* Unsigned32 */
8636 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
8638 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
8639 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
8641 case 2: /* Chararacter String OPTIONAL */
8642 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
8644 case 3: /* Chararacter String OPTIONAL */
8645 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
8647 case 4: /* Boolean OPTIONAL */
8648 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
8653 if (offset == lastoffset) break; /* nothing happened, exit loop */
8659 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8661 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
8665 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8667 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
8668 offset = fAddress (tvb, tree, offset);
8669 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
8670 return fAddress (tvb, tree, offset);
8674 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8676 /* Same as AddListElement request after service choice */
8677 return fAddListElementRequest(tvb, pinfo, tree, offset);
8681 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8683 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8687 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8689 guint lastoffset = 0, len;
8690 guint8 tag_no, tag_info;
8692 proto_tree *subtree = tree;
8694 /* set the optional global properties to indicate not-used */
8695 propertyArrayIndex = -1;
8696 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8697 lastoffset = offset;
8698 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8699 if (tag_is_closing(tag_info)) {
8705 case 0: /* objectIdentifier */
8706 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8708 case 1: /* propertyIdentifier */
8709 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8711 case 2: /* propertyArrayIndex */
8712 offset = fPropertyArrayIndex (tvb, subtree, offset);
8714 case 3: /* propertyValue */
8715 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8720 if (offset == lastoffset) break; /* nothing happened, exit loop */
8726 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8728 guint lastoffset = 0;
8729 guint8 tag_no, tag_info;
8731 proto_tree *subtree = tree;
8733 /* set the optional global properties to indicate not-used */
8734 propertyArrayIndex = -1;
8735 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8736 lastoffset = offset;
8737 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8738 /* quit loop if we spot a closing tag */
8739 if (tag_is_closing(tag_info)) {
8745 case 0: /* objectIdentifier */
8746 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8748 case 1: /* propertyIdentifier */
8749 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8751 case 2: /* propertyArrayIndex */
8752 offset = fPropertyArrayIndex (tvb, subtree, offset);
8754 case 3: /* propertyValue */
8755 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8757 case 4: /* Priority (only used for write) */
8758 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
8763 if (offset == lastoffset) break; /* nothing happened, exit loop */
8769 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8771 guint lastoffset = 0, len;
8772 guint8 tag_no, tag_info;
8775 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8776 lastoffset = offset;
8777 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8778 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
8779 if (tag_is_closing(tag_info)) {
8785 case 0: /* objectIdentifier */
8786 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8788 case 1: /* listOfPropertyValues */
8789 if (tag_is_opening(tag_info)) {
8790 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8791 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8799 if (offset == lastoffset) break; /* nothing happened, exit loop */
8805 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8807 if (offset >= tvb_reported_length(tvb))
8810 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8811 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
8815 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
8817 guint lastoffset = 0;
8818 guint8 tag_no, tag_info;
8821 /* set the optional global properties to indicate not-used */
8822 propertyArrayIndex = -1;
8823 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8824 lastoffset = offset;
8825 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8826 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
8828 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
8831 switch (tag_no-tagoffset) {
8832 case 0: /* PropertyIdentifier */
8833 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
8835 case 1: /* propertyArrayIndex */
8836 offset = fPropertyArrayIndex (tvb, tree, offset);
8837 if (list != 0) break; /* Continue decoding if this may be a list */
8839 lastoffset = offset; /* Set loop end condition */
8842 if (offset == lastoffset) break; /* nothing happened, exit loop */
8848 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
8850 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8851 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
8855 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8857 guint lastoffset = 0;
8859 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8860 lastoffset = offset;
8862 switch (fTagNo(tvb,offset)) {
8863 case 0: /* ObjectIdentifier */
8864 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8866 case 1: /* PropertyIdentifier and propertyArrayIndex */
8867 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
8868 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8870 lastoffset = offset; /* Set loop end condition */
8873 if (offset == lastoffset) break; /* nothing happened, exit loop */
8880 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
8882 guint lastoffset = 0;
8883 guint8 tag_no, tag_info;
8885 proto_tree* subtree = tree;
8888 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8889 lastoffset = offset;
8890 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8891 if (tag_is_closing(tag_info)) {
8892 offset += fTagHeaderTree (tvb, subtree, offset,
8893 &tag_no, &tag_info, &lvt);
8897 case 0: /* ObjectIdentifier */
8898 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8900 case 1: /* PropertyIdentifier */
8901 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8903 case 2: /* propertyArrayIndex */
8904 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
8907 offset = fPropertyValue (tvb, subtree, offset, tag_info);
8909 case 4: /* Priority */
8910 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
8921 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8923 char i = 1, ar[256];
8924 guint lastoffset = 0;
8926 if (propertyArrayIndex > 0) {
8927 /* BACnetARRAY index 0 refers to the length
8928 of the array, not the elements of the array.
8929 BACnetARRAY index -1 is our internal flag that
8930 the optional index was not used.
8931 BACnetARRAY refers to this as all elements of the array.
8932 If the optional index is specified for a BACnetARRAY,
8933 then that specific array element is referenced. */
8934 i = propertyArrayIndex;
8936 while (tvb_reported_length_remaining(tvb, offset)) {
8937 /* exit loop if nothing happens inside */
8938 lastoffset = offset;
8939 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
8940 val_to_split_str(87 , 512,
8941 BACnetPropertyIdentifier,
8942 ASHRAE_Reserved_Fmt,
8943 Vendor_Proprietary_Fmt),
8945 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
8946 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
8947 /* there are only 16 priority array elements */
8951 if (offset == lastoffset) break; /* nothing happened, exit loop */
8958 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8960 guint lastoffset = 0;
8962 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8963 lastoffset = offset;
8965 switch (fTagNo(tvb,offset)) {
8966 case 0: /* deviceIdentifier - OPTIONAL */
8967 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8969 case 1: /* ObjectIdentifier */
8970 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8975 if (offset == lastoffset) break; /* nothing happened, exit loop */
8981 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8983 guint8 tag_no, tag_info;
8985 guint lastoffset = 0, len;
8986 gboolean closing_found = FALSE; /* tracks when we are done decoding the fSpecialEvent entries */
8988 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8989 lastoffset = offset;
8990 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8991 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
8992 if (tag_is_closing(tag_info)) {
8993 /* if we find 2 closing tags in succession we need to exit without incrementing the offset again */
8994 /* This handles the special case where we have a special event entry in an RPM-ACK msg */
8995 if ( closing_found == TRUE )
8998 closing_found = TRUE;
9003 case 0: /* calendarEntry */
9004 if (tag_is_opening(tag_info)) {
9005 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9006 offset = fCalendarEntry (tvb, subtree, offset);
9007 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9010 case 1: /* calendarReference */
9011 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9013 case 2: /* list of BACnetTimeValue */
9014 if (tag_is_opening(tag_info)) {
9015 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9016 offset = fTimeValue (tvb, pinfo, subtree, offset);
9017 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9022 case 3: /* eventPriority */
9023 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
9028 closing_found = FALSE; /* reset our closing tag status, we processed another open tag */
9029 if (offset == lastoffset) break; /* nothing happened, exit loop */
9035 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9037 guint lastoffset = 0, len;
9038 guint8 tag_no, tag_info;
9041 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9042 lastoffset = offset;
9043 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9044 /* maybe a listOfSelectionCriteria if we spot a closing tag */
9045 if (tag_is_closing(tag_info)) {
9050 switch (fTagNo(tvb,offset)) {
9051 case 0: /* propertyIdentifier */
9052 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
9054 case 1: /* propertyArrayIndex */
9055 offset = fPropertyArrayIndex (tvb, tree, offset);
9057 case 2: /* relationSpecifier */
9058 offset = fEnumeratedTag (tvb, tree, offset,
9059 "relation Specifier: ", BACnetRelationSpecifier);
9061 case 3: /* comparisonValue */
9062 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
9063 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
9064 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
9069 if (offset == lastoffset) break; /* nothing happened, exit loop */
9075 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9077 guint lastoffset = 0;
9078 guint8 tag_no, tag_info;
9081 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9082 lastoffset = offset;
9083 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9084 /* quit loop if we spot a closing tag */
9085 if (tag_is_closing(tag_info)) {
9090 case 0: /* selectionLogic */
9091 offset = fEnumeratedTag (tvb, subtree, offset,
9092 "selection Logic: ", BACnetSelectionLogic);
9094 case 1: /* listOfSelectionCriteria */
9095 if (tag_is_opening(tag_info)) {
9096 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9097 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
9098 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9106 if (offset == lastoffset) break; /* nothing happened, exit loop */
9113 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
9115 guint lastoffset = 0;
9116 guint8 tag_no, tag_info;
9119 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9120 lastoffset = offset;
9121 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9123 if (tag_is_opening(tag_info) && tag_no < 2) {
9124 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9126 case 0: /* objectSelectionCriteria */
9127 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
9129 case 1: /* listOfPropertyReferences */
9130 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
9135 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9137 if (offset == lastoffset) break; /* nothing happened, exit loop */
9143 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9145 guint lastoffset = 0;
9146 guint8 tag_no, tag_info;
9149 proto_tree *subtree = tree;
9151 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9152 lastoffset = offset;
9153 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9155 case 0: /* objectIdentifier */
9156 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9158 case 1: /* listOfPropertyReferences */
9159 if (tag_is_opening(tag_info)) {
9160 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
9161 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9162 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9163 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
9164 } else if (tag_is_closing(tag_info)) {
9165 offset += fTagHeaderTree (tvb, subtree, offset,
9166 &tag_no, &tag_info, &lvt);
9169 /* error condition: let caller handle */
9176 if (offset == lastoffset) break; /* nothing happened, exit loop */
9182 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9184 guint lastoffset = 0, len;
9188 proto_tree *subtree = tree;
9191 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9192 lastoffset = offset;
9193 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9194 /* maybe a listOfReadAccessResults if we spot a closing tag here */
9195 if (tag_is_closing(tag_info)) {
9197 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
9202 case 0: /* objectSpecifier */
9203 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9205 case 1: /* list of Results */
9206 if (tag_is_opening(tag_info)) {
9207 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
9208 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9209 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9214 case 2: /* propertyIdentifier */
9215 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
9217 case 5: /* propertyAccessError */
9218 if (tag_is_opening(tag_info)) {
9219 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
9220 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9221 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9222 /* Error Code follows */
9223 offset = fError(tvb, pinfo, subtree, offset);
9231 if (offset == lastoffset) break; /* nothing happened, exit loop */
9238 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9240 /* listOfReadAccessResults */
9241 return fReadAccessResult (tvb, pinfo, tree, offset);
9246 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9248 guint lastoffset = 0;
9249 guint8 tag_no, tag_info;
9252 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9253 lastoffset = offset;
9254 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9257 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9259 case 0: /* objectSpecifier */
9260 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
9261 case 0: /* objectType */
9262 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
9264 case 1: /* objectIdentifier */
9265 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9271 case 1: /* propertyValue */
9272 if (tag_is_opening(tag_info)) {
9273 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
9281 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9283 if (offset == lastoffset) break; /* nothing happened, exit loop */
9289 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9291 return fObjectIdentifier (tvb, pinfo, tree, offset);
9295 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9297 guint8 tag_no, tag_info;
9299 proto_tree *subtree = tree;
9302 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9304 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9305 /* optional range choice */
9306 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9307 if (tag_is_opening(tag_info)) {
9308 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
9309 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9310 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9312 case 3: /* range byPosition */
9313 case 6: /* range bySequenceNumber, 2004 spec */
9314 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
9315 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
9317 case 4: /* range byTime - deprecated in 2004 */
9318 case 7: /* 2004 spec */
9319 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
9320 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
9322 case 5: /* range timeRange - deprecated in 2004 */
9323 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
9324 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
9329 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9336 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9338 guint8 tag_no, tag_info;
9340 proto_tree *subtree = tree;
9343 /* set the optional global properties to indicate not-used */
9344 propertyArrayIndex = -1;
9345 /* objectIdentifier, propertyIdentifier, and
9346 OPTIONAL propertyArrayIndex */
9347 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9348 /* resultFlags => BACnetResultFlags ::= BIT STRING */
9349 offset = fBitStringTagVS (tvb, tree, offset,
9353 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
9355 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9356 if (tag_is_opening(tag_info)) {
9357 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9358 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
9359 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9360 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9361 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
9362 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9364 /* firstSequenceNumber - OPTIONAL */
9365 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9366 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
9373 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9375 guint lastoffset = 0;
9377 guint8 tag_no, tag_info;
9379 proto_tree* subtree = NULL;
9381 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9383 if (tag_is_opening(tag_info)) {
9384 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
9385 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9386 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9387 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
9388 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
9391 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
9392 /* exit loop if nothing happens inside */
9393 lastoffset = offset;
9394 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
9398 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
9399 /* More Flag is not set, so we can look for closing tag in this segment */
9400 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9401 if (tag_is_closing(tag_info)) {
9402 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9410 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9412 guint8 tag_no, tag_info;
9414 proto_tree *subtree = tree;
9417 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9419 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9421 if (tag_is_opening(tag_info)) {
9422 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
9423 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9424 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9425 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
9426 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
9427 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9433 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9436 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
9437 offset = fAccessMethod(tvb, pinfo, tree, offset);
9443 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
9445 guint tag_no = fTagNo(tvb, offset);
9446 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
9450 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9452 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
9453 offset = fAccessMethod(tvb,pinfo, tree, offset);
9459 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9461 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9462 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
9466 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9468 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9469 return fReadAccessResult (tvb,pinfo,tree,offset);
9473 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9475 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9478 switch (service_choice) {
9479 case 0: /* acknowledgeAlarm */
9480 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
9482 case 1: /* confirmedCOVNotification */
9483 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
9485 case 2: /* confirmedEventNotification */
9486 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
9488 case 3: /* confirmedGetAlarmSummary conveys no parameters */
9490 case 4: /* getEnrollmentSummaryRequest */
9491 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
9493 case 5: /* subscribeCOVRequest */
9494 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
9496 case 6: /* atomicReadFile-Request */
9497 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
9499 case 7: /* atomicWriteFile-Request */
9500 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
9502 case 8: /* AddListElement-Request */
9503 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
9505 case 9: /* removeListElement-Request */
9506 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
9508 case 10: /* createObjectRequest */
9509 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
9511 case 11: /* deleteObject */
9512 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
9515 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
9518 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
9521 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
9524 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
9527 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
9530 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
9533 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
9536 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
9539 offset = fReinitializeDeviceRequest(tvb, tree, offset);
9542 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
9545 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
9548 offset = fVtDataRequest (tvb, pinfo, tree, offset);
9551 offset = fAuthenticateRequest (tvb, tree, offset);
9554 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
9557 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
9560 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
9563 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
9566 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
9575 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9577 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9580 switch (service_choice) {
9581 case 3: /* confirmedEventNotificationAck */
9582 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
9584 case 4: /* getEnrollmentSummaryAck */
9585 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
9587 case 6: /* atomicReadFile */
9588 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
9590 case 7: /* atomicReadFileAck */
9591 offset = fAtomicWriteFileAck (tvb, tree, offset);
9593 case 10: /* createObject */
9594 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
9597 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
9600 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
9603 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
9606 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
9609 offset = fVtOpenAck (tvb, pinfo, tree, offset);
9612 offset = fVtDataAck (tvb, tree, offset);
9615 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
9618 offset = fReadRangeAck (tvb, pinfo, tree, offset);
9621 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
9630 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9632 /* BACnetObjectIdentifier */
9633 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
9635 /* MaxAPDULengthAccepted */
9636 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
9638 /* segmentationSupported */
9639 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
9640 "Segmentation Supported: ", BACnetSegmentation);
9643 return fVendorIdentifier (tvb, pinfo, tree, offset);
9647 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9649 /* BACnetDeviceIdentifier */
9650 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
9652 /* BACnetObjectIdentifier */
9653 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
9656 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
9661 fWhoIsRequest (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
9663 guint lastoffset = 0;
9667 guint8 tag_no, tag_info;
9670 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9671 lastoffset = offset;
9673 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9677 /* DeviceInstanceRangeLowLimit Optional */
9678 fUnsigned32(tvb, offset+tag_len, lvt, &val);
9679 if (col_get_writable(pinfo->cinfo))
9680 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
9681 offset = fDevice_Instance (tvb, tree, offset,
9682 hf_Device_Instance_Range_Low_Limit);
9685 /* DeviceInstanceRangeHighLimit Optional but
9686 required if DeviceInstanceRangeLowLimit is there */
9687 fUnsigned32(tvb, offset+tag_len, lvt, &val);
9688 if (col_get_writable(pinfo->cinfo))
9689 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
9690 offset = fDevice_Instance (tvb, tree, offset,
9691 hf_Device_Instance_Range_High_Limit);
9696 if (offset == lastoffset) break; /* nothing happened, exit loop */
9702 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9704 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9707 switch (service_choice) {
9708 case 0: /* I-Am-Request */
9709 offset = fIAmRequest (tvb, pinfo, tree, offset);
9711 case 1: /* i-Have Request */
9712 offset = fIHaveRequest (tvb, pinfo, tree, offset);
9714 case 2: /* unconfirmedCOVNotification */
9715 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
9717 case 3: /* unconfirmedEventNotification */
9718 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
9720 case 4: /* unconfirmedPrivateTransfer */
9721 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
9723 case 5: /* unconfirmedTextMessage */
9724 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
9726 case 6: /* timeSynchronization */
9727 offset = fTimeSynchronizationRequest (tvb, tree, offset);
9729 case 7: /* who-Has */
9730 offset = fWhoHas (tvb, pinfo, tree, offset);
9732 case 8: /* who-Is */
9733 offset = fWhoIsRequest (tvb, pinfo, tree, offset);
9735 case 9: /* utcTimeSynchronization */
9736 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
9745 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
9746 gint *svc, proto_item **tt)
9749 proto_tree *bacapp_tree_control;
9754 tmp = (gint) tvb_get_guint8(tvb, offset);
9755 bacapp_flags = tmp & 0x0f;
9760 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
9761 if (bacapp_flags & 0x08)
9762 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
9764 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9765 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
9766 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
9768 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
9769 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
9770 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
9771 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
9772 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
9773 offset, 1, ENC_BIG_ENDIAN);
9774 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
9775 offset, 1, ENC_BIG_ENDIAN);
9778 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
9779 if (bacapp_flags & 0x08) {
9780 bacapp_seq = tvb_get_guint8(tvb, offset);
9781 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
9782 offset++, 1, ENC_BIG_ENDIAN);
9783 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
9784 offset++, 1, ENC_BIG_ENDIAN);
9786 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
9787 offset++, 1, ENC_BIG_ENDIAN);
9792 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
9793 { /* BACnet-Confirmed-Request */
9794 /* ASHRAE 135-2001 20.1.2 */
9796 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
9800 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9801 { /* BACnet-Confirmed-Request */
9802 /* ASHRAE 135-2001 20.1.2 */
9806 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
9807 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
9811 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9812 { /* BACnet-Unconfirmed-Request-PDU */
9813 /* ASHRAE 135-2001 20.1.3 */
9817 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9819 tmp = tvb_get_guint8(tvb, offset);
9820 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
9821 offset++, 1, ENC_BIG_ENDIAN);
9822 /* Service Request follows... Variable Encoding 20.2ff */
9823 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
9827 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9828 { /* BACnet-Simple-Ack-PDU */
9829 /* ASHRAE 135-2001 20.1.4 */
9831 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9833 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
9834 offset++, 1, ENC_BIG_ENDIAN);
9835 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
9836 offset++, 1, ENC_BIG_ENDIAN);
9842 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
9843 { /* BACnet-Complex-Ack-PDU */
9844 /* ASHRAE 135-2001 20.1.5 */
9846 /* Service ACK follows... */
9847 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
9851 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9852 { /* BACnet-Complex-Ack-PDU */
9853 /* ASHRAE 135-2001 20.1.5 */
9857 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
9858 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
9862 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9863 { /* BACnet-SegmentAck-PDU */
9864 /* ASHRAE 135-2001 20.1.6 */
9867 proto_tree *bacapp_tree_control;
9869 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9870 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9872 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
9873 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
9874 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9875 offset++, 1, ENC_BIG_ENDIAN);
9876 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
9877 offset++, 1, ENC_BIG_ENDIAN);
9878 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
9879 offset++, 1, ENC_BIG_ENDIAN);
9884 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9886 guint8 tag_info = 0;
9887 guint8 parsed_tag = 0;
9889 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
9890 offset = fError(tvb, pinfo, tree, offset);
9891 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
9895 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9897 guint lastoffset = 0;
9898 guint8 tag_no = 0, tag_info = 0;
9900 proto_tree *subtree = tree;
9903 guint vendor_identifier = 0;
9904 guint service_number = 0;
9907 while (tvb_reported_length_remaining(tvb, offset)) {
9908 /* exit loop if nothing happens inside */
9909 lastoffset = offset;
9910 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9912 case 0: /* errorType */
9913 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
9915 case 1: /* vendorID */
9916 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
9917 if (col_get_writable(pinfo->cinfo))
9918 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
9919 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
9921 case 2: /* serviceNumber */
9922 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
9923 if (col_get_writable(pinfo->cinfo))
9924 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
9925 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
9927 case 3: /* errorParameters */
9928 if (tag_is_opening(tag_info)) {
9929 tt = proto_tree_add_text(subtree, tvb, offset, 1,
9930 "error Parameters");
9931 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9932 propertyIdentifier = -1;
9933 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9934 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
9935 } else if (tag_is_closing(tag_info)) {
9936 offset += fTagHeaderTree (tvb, subtree, offset,
9937 &tag_no, &tag_info, &lvt);
9940 /* error condition: let caller handle */
9947 if (offset == lastoffset) break; /* nothing happened, exit loop */
9953 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9955 guint lastoffset = 0;
9957 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9958 lastoffset = offset;
9959 switch (fTagNo(tvb, offset)) {
9960 case 0: /* errorType */
9961 offset = fContextTaggedError(tvb, pinfo, tree, offset);
9963 case 1: /* firstFailedElementNumber */
9964 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
9969 if (offset == lastoffset) break; /* nothing happened, exit loop */
9975 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9977 /* Identical to CreateObjectError */
9978 return fCreateObjectError(tvb, pinfo, tree, offset);
9982 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9984 guint8 tag_no = 0, tag_info = 0;
9987 if (fTagNo(tvb, offset) == 0) {
9989 offset = fContextTaggedError(tvb, pinfo, tree,offset);
9990 if (fTagNo(tvb, offset) == 1) {
9991 /* listOfVTSessionIdentifiers [OPTIONAL] */
9992 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
9993 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
9994 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
9997 /* should report bad packet if initial tag wasn't 0 */
10002 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10004 guint lastoffset = 0;
10005 guint8 tag_no = 0, tag_info = 0;
10008 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10009 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
10010 lastoffset = offset;
10011 switch (fTagNo(tvb, offset)) {
10012 case 0: /* errorType */
10013 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10015 case 1: /* firstFailedWriteAttempt */
10016 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
10017 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
10018 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
10023 if (offset == lastoffset) break; /* nothing happened, exit loop */
10029 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10031 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
10032 "error Class: ", BACnetErrorClass, 64);
10033 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
10034 "error Code: ", BACnetErrorCode, 256);
10038 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
10041 case 8: /* no break here !!!! */
10043 offset = fChangeListError (tvb, pinfo, tree, offset);
10046 offset = fCreateObjectError (tvb, pinfo, tree, offset);
10049 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
10052 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
10055 offset = fVTCloseError (tvb, pinfo, tree, offset);
10058 return fError (tvb, pinfo, tree, offset);
10064 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10065 { /* BACnet-Error-PDU */
10066 /* ASHRAE 135-2001 20.1.7 */
10069 proto_tree *bacapp_tree_control;
10072 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10073 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10075 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10076 offset++, 1, ENC_BIG_ENDIAN);
10077 tmp = tvb_get_guint8(tvb, offset);
10078 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
10079 offset++, 1, ENC_BIG_ENDIAN);
10080 /* Error Handling follows... */
10081 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
10085 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10086 { /* BACnet-Reject-PDU */
10087 /* ASHRAE 135-2001 20.1.8 */
10090 proto_tree *bacapp_tree_control;
10092 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10093 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10095 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10096 offset++, 1, ENC_BIG_ENDIAN);
10097 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
10098 offset++, 1, ENC_BIG_ENDIAN);
10103 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10104 { /* BACnet-Abort-PDU */
10105 /* ASHRAE 135-2001 20.1.9 */
10108 proto_tree *bacapp_tree_control;
10110 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10111 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10113 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10114 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10115 offset++, 1, ENC_BIG_ENDIAN);
10116 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
10117 offset++, 1, ENC_BIG_ENDIAN);
10122 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10124 guint8 flag, bacapp_type;
10127 flag = (gint) tvb_get_guint8(tvb, 0);
10128 bacapp_type = (flag >> 4) & 0x0f;
10134 /* ASHRAE 135-2001 20.1.1 */
10135 switch (bacapp_type) {
10136 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
10137 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
10139 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
10140 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
10142 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
10143 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
10145 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
10146 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
10148 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
10149 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
10151 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
10152 offset = fErrorPDU(tvb, pinfo, tree, offset);
10154 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
10155 offset = fRejectPDU(tvb, pinfo, tree, offset);
10157 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
10158 offset = fAbortPDU(tvb, pinfo, tree, offset);
10165 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10167 guint8 flag, bacapp_type;
10168 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
10169 tvbuff_t* new_tvb = NULL;
10171 guint8 bacapp_seqno = 0;
10172 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
10173 guint8 bacapp_invoke_id = 0;
10175 proto_tree *bacapp_tree = NULL;
10178 proto_item *tt = 0;
10181 /* Strings for BACnet Statistics */
10182 const gchar errstr[]="ERROR: ";
10183 const gchar rejstr[]="REJECTED: ";
10184 const gchar abortstr[]="ABORTED: ";
10185 const gchar sackstr[]=" (SimpleAck)";
10186 const gchar cackstr[]=" (ComplexAck)";
10187 const gchar uconfsreqstr[]=" (Unconfirmed Service Request)";
10188 const gchar confsreqstr[]=" (Confirmed Service Request)";
10190 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
10191 col_clear (pinfo->cinfo, COL_INFO);
10193 flag = tvb_get_guint8(tvb, 0);
10194 bacapp_type = (flag >> 4) & 0x0f;
10196 /* show some descriptive text in the INFO column */
10197 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
10198 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
10200 bacinfo.service_type = NULL;
10201 bacinfo.invoke_id = NULL;
10202 bacinfo.instance_ident = NULL;
10203 bacinfo.object_ident = NULL;
10205 switch (bacapp_type)
10207 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10208 /* segmented messages have 2 additional bytes */
10209 if (flag & BACAPP_SEGMENTED_REQUEST) {
10212 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
10213 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10214 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
10215 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
10216 bacapp_service = tvb_get_guint8(tvb, offset + 5);
10219 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10220 bacapp_service = tvb_get_guint8(tvb, offset + 3);
10222 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
10223 val_to_str(bacapp_service,
10224 BACnetConfirmedServiceChoice,
10225 bacapp_unknown_service_str),bacapp_invoke_id);
10227 updateBacnetInfoValue(BACINFO_INVOKEID,
10228 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10230 updateBacnetInfoValue(BACINFO_SERVICE,
10231 ep_strconcat(val_to_str(bacapp_service,
10232 BACnetConfirmedServiceChoice,
10233 bacapp_unknown_service_str),
10234 confsreqstr, NULL));
10236 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
10237 bacapp_service = tvb_get_guint8(tvb, offset + 1);
10238 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
10239 val_to_str(bacapp_service,
10240 BACnetUnconfirmedServiceChoice,
10241 bacapp_unknown_service_str));
10243 updateBacnetInfoValue(BACINFO_SERVICE,
10244 ep_strconcat(val_to_str(bacapp_service,
10245 BACnetUnconfirmedServiceChoice,
10246 bacapp_unknown_service_str),
10247 uconfsreqstr, NULL));
10249 case BACAPP_TYPE_SIMPLE_ACK:
10250 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10251 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10252 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10253 val_to_str(bacapp_service,
10254 BACnetConfirmedServiceChoice,
10255 bacapp_unknown_service_str), bacapp_invoke_id);
10257 updateBacnetInfoValue(BACINFO_INVOKEID,
10258 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10260 updateBacnetInfoValue(BACINFO_SERVICE,
10261 ep_strconcat(val_to_str(bacapp_service,
10262 BACnetConfirmedServiceChoice,
10263 bacapp_unknown_service_str),
10266 case BACAPP_TYPE_COMPLEX_ACK:
10267 /* segmented messages have 2 additional bytes */
10268 if (flag & BACAPP_SEGMENTED_REQUEST) {
10271 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
10272 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10273 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
10274 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
10275 bacapp_service = tvb_get_guint8(tvb, offset + 4);
10278 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10279 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10281 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10282 val_to_str(bacapp_service,
10283 BACnetConfirmedServiceChoice,
10284 bacapp_unknown_service_str), bacapp_invoke_id);
10286 updateBacnetInfoValue(BACINFO_INVOKEID,
10287 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10289 updateBacnetInfoValue(BACINFO_SERVICE,
10290 ep_strconcat(val_to_str(bacapp_service,
10291 BACnetConfirmedServiceChoice,
10292 bacapp_unknown_service_str),
10295 case BACAPP_TYPE_SEGMENT_ACK:
10296 /* nothing more to add */
10298 case BACAPP_TYPE_ERROR:
10299 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10300 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10301 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10302 val_to_str(bacapp_service,
10303 BACnetConfirmedServiceChoice,
10304 bacapp_unknown_service_str), bacapp_invoke_id);
10306 updateBacnetInfoValue(BACINFO_INVOKEID,
10307 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10309 updateBacnetInfoValue(BACINFO_SERVICE,
10310 ep_strconcat(errstr,
10311 val_to_str(bacapp_service,
10312 BACnetConfirmedServiceChoice,
10313 bacapp_unknown_service_str),
10316 case BACAPP_TYPE_REJECT:
10317 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10318 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10319 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10320 val_to_split_str(bacapp_reason,
10322 BACnetRejectReason,
10323 ASHRAE_Reserved_Fmt,
10324 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10326 updateBacnetInfoValue(BACINFO_INVOKEID,
10327 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10329 updateBacnetInfoValue(BACINFO_SERVICE,
10330 ep_strconcat(rejstr,
10331 val_to_split_str(bacapp_reason, 64,
10332 BACnetRejectReason,
10333 ASHRAE_Reserved_Fmt,
10334 Vendor_Proprietary_Fmt),
10337 case BACAPP_TYPE_ABORT:
10338 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10339 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10340 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10341 val_to_split_str(bacapp_reason,
10344 ASHRAE_Reserved_Fmt,
10345 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10347 updateBacnetInfoValue(BACINFO_INVOKEID,
10348 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10350 updateBacnetInfoValue(BACINFO_SERVICE,
10351 ep_strconcat(abortstr,
10352 val_to_split_str(bacapp_reason,
10355 ASHRAE_Reserved_Fmt,
10356 Vendor_Proprietary_Fmt),
10361 /* nothing more to add */
10365 save_fragmented = pinfo->fragmented;
10367 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA);
10368 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
10371 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
10373 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
10374 /* not resetting the offset so the remaining can be done */
10376 if (fragment) { /* fragmented */
10377 fragment_data *frag_msg = NULL;
10380 pinfo->fragmented = TRUE;
10382 frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
10383 bacapp_invoke_id, /* ID for fragments belonging together */
10384 msg_fragment_table, /* list of message fragments */
10385 msg_reassembled_table, /* list of reassembled messages */
10386 bacapp_seqno, /* fragment sequence number */
10387 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
10388 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
10389 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
10390 "Reassembled BACapp", frag_msg, &msg_frag_items,
10393 if (new_tvb) { /* Reassembled */
10394 col_append_str(pinfo->cinfo, COL_INFO,
10395 " (Message Reassembled)");
10396 } else { /* Not last packet of reassembled Short Message */
10397 col_append_fstr(pinfo->cinfo, COL_INFO,
10398 " (Message fragment %u)", bacapp_seqno);
10400 if (new_tvb) { /* take it all */
10401 switch (bacapp_type)
10403 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10404 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10406 case BACAPP_TYPE_COMPLEX_ACK:
10407 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10417 pinfo->fragmented = save_fragmented;
10420 tap_queue_packet(bacapp_tap,pinfo,&bacinfo);
10424 bacapp_init_routine(void)
10426 fragment_table_init(&msg_fragment_table);
10427 reassembled_table_init(&msg_reassembled_table);
10431 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
10436 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
10437 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
10438 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
10441 g_iconv_close (icd);
10445 uni_to_string(in,*inbytesleft,out);
10446 out[*inbytesleft] = '\0';
10447 *outbytesleft -= *inbytesleft;
10454 uni_to_string(char * data, gsize str_length, char *dest_buf)
10458 gsize length_remaining = 0;
10460 length_remaining = str_length;
10461 dest_buf[0] = '\0';
10462 if(str_length == 0) {
10465 for ( i = 0; i < (gint) str_length; i++ ) {
10467 if (c_char<0x20 || c_char>0x7e) {
10468 if (c_char != 0x00) {
10470 dest_buf[i] = c_char & 0xff;
10476 dest_buf[i] = c_char & 0xff;
10478 length_remaining--;
10480 if(length_remaining==0) {
10481 dest_buf[i+1] = '\0';
10488 dest_buf[i] = '\0';
10493 proto_register_bacapp(void)
10495 static hf_register_info hf[] = {
10497 { "APDU Type", "bacapp.type",
10498 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
10500 { &hf_bacapp_pduflags,
10501 { "PDU Flags", "bacapp.pduflags",
10502 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
10505 { "Segmented Request", "bacapp.segmented_request",
10506 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
10509 { "More Segments", "bacapp.more_segments",
10510 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
10513 { "SA", "bacapp.SA",
10514 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
10516 { &hf_bacapp_max_adpu_size,
10517 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
10518 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
10520 { &hf_bacapp_response_segments,
10521 { "Max Response Segments accepted", "bacapp.response_segments",
10522 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
10524 { &hf_bacapp_objectType,
10525 { "Object Type", "bacapp.objectType",
10526 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
10528 { &hf_bacapp_instanceNumber,
10529 { "Instance Number", "bacapp.instance_number",
10530 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
10532 { &hf_BACnetPropertyIdentifier,
10533 { "Property Identifier", "bacapp.property_identifier",
10534 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
10536 { &hf_BACnetVendorIdentifier,
10537 { "Vendor Identifier", "bacapp.vendor_identifier",
10538 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
10540 { &hf_BACnetRestartReason,
10541 { "Restart Reason", "bacapp.restart_reason",
10542 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
10544 { &hf_bacapp_invoke_id,
10545 { "Invoke ID", "bacapp.invoke_id",
10546 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10548 { &hf_bacapp_sequence_number,
10549 { "Sequence Number", "bacapp.sequence_number",
10550 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10552 { &hf_bacapp_window_size,
10553 { "Proposed Window Size", "bacapp.window_size",
10554 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10556 { &hf_bacapp_service,
10557 { "Service Choice", "bacapp.confirmed_service",
10558 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
10560 { &hf_bacapp_uservice,
10561 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
10562 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
10565 { "NAK", "bacapp.NAK",
10566 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
10569 { "SRV", "bacapp.SRV",
10570 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
10572 { &hf_Device_Instance_Range_Low_Limit,
10573 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
10574 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
10576 { &hf_Device_Instance_Range_High_Limit,
10577 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
10578 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
10580 { &hf_BACnetRejectReason,
10581 { "Reject Reason", "bacapp.reject_reason",
10582 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
10584 { &hf_BACnetAbortReason,
10585 { "Abort Reason", "bacapp.abort_reason",
10586 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
10588 { &hf_BACnetApplicationTagNumber,
10589 { "Application Tag Number",
10590 "bacapp.application_tag_number",
10591 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
10594 { &hf_BACnetContextTagNumber,
10595 { "Context Tag Number",
10596 "bacapp.context_tag_number",
10597 FT_UINT8, BASE_DEC, NULL, 0xF0,
10600 { &hf_BACnetExtendedTagNumber,
10601 { "Extended Tag Number",
10602 "bacapp.extended_tag_number",
10603 FT_UINT8, BASE_DEC, NULL, 0,
10606 { &hf_BACnetNamedTag,
10608 "bacapp.named_tag",
10609 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
10612 { &hf_BACnetCharacterSet,
10613 { "String Character Set",
10614 "bacapp.string_character_set",
10615 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet),0,
10618 { &hf_BACnetTagClass,
10619 { "Tag Class", "bacapp.tag_class",
10620 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
10622 { &hf_bacapp_tag_lvt,
10623 { "Length Value Type",
10625 FT_UINT8, BASE_DEC, NULL, 0,
10628 { &hf_bacapp_tag_ProcessId,
10629 { "ProcessIdentifier", "bacapp.processId",
10630 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
10632 { &hf_bacapp_tag_IPV4,
10633 { "IPV4", "bacapp.IPV4",
10634 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
10636 { &hf_bacapp_tag_IPV6,
10637 { "IPV6", "bacapp.IPV6",
10638 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
10640 { &hf_bacapp_tag_PORT,
10641 { "Port", "bacapp.Port",
10642 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
10644 {&hf_msg_fragments,
10645 {"Message fragments", "bacapp.fragments",
10646 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10648 {"Message fragment", "bacapp.fragment",
10649 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10650 {&hf_msg_fragment_overlap,
10651 {"Message fragment overlap", "bacapp.fragment.overlap",
10652 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10653 {&hf_msg_fragment_overlap_conflicts,
10654 {"Message fragment overlapping with conflicting data",
10655 "bacapp.fragment.overlap.conflicts",
10656 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10657 {&hf_msg_fragment_multiple_tails,
10658 {"Message has multiple tail fragments",
10659 "bacapp.fragment.multiple_tails",
10660 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10661 {&hf_msg_fragment_too_long_fragment,
10662 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
10663 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10664 {&hf_msg_fragment_error,
10665 {"Message defragmentation error", "bacapp.fragment.error",
10666 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10667 {&hf_msg_fragment_count,
10668 {"Message fragment count", "bacapp.fragment.count",
10669 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
10670 {&hf_msg_reassembled_in,
10671 {"Reassembled in", "bacapp.reassembled.in",
10672 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10673 {&hf_msg_reassembled_length,
10674 {"Reassembled BACapp length", "bacapp.reassembled.length",
10675 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
10677 static gint *ett[] = {
10679 &ett_bacapp_control,
10688 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
10689 "BACapp", "bacapp");
10691 proto_register_field_array(proto_bacapp, hf, array_length(hf));
10692 proto_register_subtree_array(ett, array_length(ett));
10693 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
10694 register_init_routine (&bacapp_init_routine);
10696 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
10697 "BACapp Vendor Identifier",
10698 FT_UINT8, BASE_HEX);
10700 /* Register BACnet Statistic trees */
10701 register_bacapp_stat_trees();
10702 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
10706 proto_reg_handoff_bacapp(void)
10708 data_handle = find_dissector("data");