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 * BACnetDeviceObjectReference ::= SEQUENCE {
1543 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1544 * objectIdentifier [1] BACnetObjectIdentifier
1550 * @return modified offset
1553 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1556 * BACnetEventParameter ::= CHOICE {
1557 * change-of-bitstring [0] SEQUENCE {
1558 * time-delay [0] Unsigned,
1559 * bitmask [1] BIT STRING,
1560 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1562 * change-of-state [1] SEQUENCE {
1563 * time-delay [0] Unsigned,
1564 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1566 * change-of-value [2] SEQUENCE {
1567 * time-delay [0] Unsigned,
1568 * cov-criteria [1] CHOICE {
1569 * bitmask [0] BIT STRING,
1570 * referenced-property-increment [1] REAL
1573 * command-failure [3] SEQUENCE {
1574 * time-delay [0] Unsigned,
1575 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1577 * floating-limit [4] SEQUENCE {
1578 * time-delay [0] Unsigned,
1579 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1580 * low-diff-limit [2] REAL,
1581 * high-diff-limit [3] REAL,
1584 * out-of-range [5] SEQUENCE {
1585 * time-delay [0] Unsigned,
1586 * low-limit [1] REAL,
1587 * high-limit [2] REAL,
1590 * buffer-ready [7] SEQUENCE {
1591 * notification-threshold [0] Unsigned,
1592 * previous-notification-count [1] Unsigned32
1594 * change-of-life-safety [8] SEQUENCE {
1595 * time-delay [0] Unsigned,
1596 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1597 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1598 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1604 * @return modified offset
1607 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1612 * BACnetLogRecord ::= SEQUENCE {
1613 * timestamp [0] BACnetDateTime,
1614 * logDatum [1] CHOICE {
1615 * log-status [0] BACnetLogStatus,
1616 * boolean-value [1] BOOLEAN,
1617 * real-value [2] REAL,
1618 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1619 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1620 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1621 * bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
1622 * null-value [7] NULL,
1623 * failure [8] Error,
1624 * time-change [9] REAL,
1625 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1627 * statusFlags [2] BACnetStatusFlags OPTIONAL
1633 * @return modified offset
1636 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1640 * BACnetNotificationParameters ::= CHOICE {
1641 * change-of-bitstring [0] SEQUENCE {
1642 * referenced-bitstring [0] BIT STRING,
1643 * status-flags [1] BACnetStatusFlags
1645 * change-of-state [1] SEQUENCE {
1646 * new-state [0] BACnetPropertyStatus,
1647 * status-flags [1] BACnetStatusFlags
1649 * change-of-value [2] SEQUENCE {
1650 * new-value [0] CHOICE {
1651 * changed-bits [0] BIT STRING,
1652 * changed-value [1] REAL
1654 * status-flags [1] BACnetStatusFlags
1656 * command-failure [3] SEQUENCE {
1657 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1658 * status-flags [1] BACnetStatusFlags
1659 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1661 * floating-limit [4] SEQUENCE {
1662 * reference-value [0] REAL,
1663 * status-flags [1] BACnetStatusFlags
1664 * setpoint-value [2] REAL,
1665 * error-limit [3] REAL
1667 * out-of-range [5] SEQUENCE {
1668 * exceeding-value [0] REAL,
1669 * status-flags [1] BACnetStatusFlags
1670 * deadband [2] REAL,
1671 * exceeded-limit [0] REAL
1673 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1674 * buffer-ready [7] SEQUENCE {
1675 * buffer-device [0] BACnetObjectIdentifier,
1676 * buffer-object [1] BACnetObjectIdentifier
1677 * previous-notification [2] BACnetDateTime,
1678 * current-notification [3] BACnetDateTime
1680 * change-of-life-safety [8] SEQUENCE {
1681 * new-state [0] BACnetLifeSafetyState,
1682 * new-mode [1] BACnetLifeSafetyState
1683 * status-flags [2] BACnetStatusFlags,
1684 * operation-expected [3] BACnetLifeSafetyOperation
1691 * @return modified offset
1694 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1697 * BACnetObjectPropertyReference ::= SEQUENCE {
1698 * objectIdentifier [0] BACnetObjectIdentifier,
1699 * propertyIdentifier [1] BACnetPropertyIdentifier,
1700 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1706 * @return modified offset
1709 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1713 * BACnetObjectPropertyValue ::= SEQUENCE {
1714 * objectIdentifier [0] BACnetObjectIdentifier,
1715 * propertyIdentifier [1] BACnetPropertyIdentifier,
1716 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1717 * -- if omitted with an array the entire array is referenced
1718 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1719 * priority [4] Unsigned (1..16) OPTIONAL
1724 * @return modified offset
1727 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
1731 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1736 * @return modified offset
1739 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1742 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1745 * BACnetPropertyReference ::= SEQUENCE {
1746 * propertyIdentifier [0] BACnetPropertyIdentifier,
1747 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1753 * @return modified offset
1756 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1759 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1762 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1765 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1768 * BACnetPropertyValue ::= SEQUENCE {
1769 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1770 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1771 * -- if omitted with an array the entire array is referenced
1772 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1773 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1779 * @return modified offset
1782 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1785 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1788 * BACnet Application PDUs chapter 21
1789 * BACnetRecipient::= CHOICE {
1790 * device [0] BACnetObjectIdentifier
1791 * address [1] BACnetAddress
1797 * @return modified offset
1800 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1803 * BACnet Application PDUs chapter 21
1804 * BACnetRecipientProcess::= SEQUENCE {
1805 * recipient [0] BACnetRecipient
1806 * processID [1] Unsigned32
1812 * @return modified offset
1815 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1818 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1822 * BACnetSessionKey ::= SEQUENCE {
1823 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1824 * peerAddress BACnetAddress
1829 * @return modified offset
1830 * @todo check if checksum is displayed correctly
1833 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1837 * BACnetSpecialEvent ::= SEQUENCE {
1839 * calendarEntry [0] BACnetCalendarEntry,
1840 * calendarRefernce [1] BACnetObjectIdentifier
1842 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1843 * eventPriority [3] Unsigned (1..16)
1849 * @return modified offset
1852 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1855 * BACnetTimeStamp ::= CHOICE {
1857 * sequenceNumber [1] Unsigned (0..65535),
1858 * dateTime [2] BACnetDateTime
1864 * @return modified offset
1867 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1870 * BACnetTimeValue ::= SEQUENCE {
1872 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1878 * @return modified offset
1881 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1885 * BACnetVTSession ::= SEQUENCE {
1886 * local-vtSessionID Unsigned8,
1887 * remote-vtSessionID Unsigned8,
1888 * remote-vtAddress BACnetAddress
1893 * @return modified offset
1896 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1900 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1901 * -- first octet month (1..12) January = 1, X'FF' = any month
1902 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1903 * -- 2 = days numbered 8-14
1904 * -- 3 = days numbered 15-21
1905 * -- 4 = days numbered 22-28
1906 * -- 5 = days numbered 29-31
1907 * -- 6 = last 7 days of this month
1908 * -- X'FF' = any week of this month
1909 * -- third octet dayOfWeek (1..7) where 1 = Monday
1911 * -- X'FF' = any day of week
1915 * @return modified offset
1918 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
1921 * ReadAccessResult ::= SEQUENCE {
1922 * objectIdentifier [0] BACnetObjectIdentifier,
1923 * listOfResults [1] SEQUENCE OF SEQUENCE {
1924 * propertyIdentifier [2] BACnetPropertyIdentifier,
1925 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1926 * readResult CHOICE {
1927 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1928 * propertyAccessError [5] Error
1936 * @return modified offset
1939 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1942 * ReadAccessSpecification ::= SEQUENCE {
1943 * objectIdentifier [0] BACnetObjectIdentifier,
1944 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
1950 * @return modified offset
1953 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1956 * WriteAccessSpecification ::= SEQUENCE {
1957 * objectIdentifier [0] BACnetObjectIdentifier,
1958 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
1964 * @return modified offset
1967 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1970 /********************************************************* Helper functions *******************************************/
1973 * extracts the tag number from the tag header.
1974 * @param tvb "TestyVirtualBuffer"
1975 * @param offset in actual tvb
1976 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
1979 fTagNo (tvbuff_t *tvb, guint offset);
1982 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
1983 * @param tvb = "TestyVirtualBuffer"
1984 * @param offset = offset in actual tvb
1985 * @return tag_no BACnet 20.2.1.2 Tag Number
1986 * @return class_tag BACnet 20.2.1.1 Class
1987 * @return lvt BACnet 20.2.1.3 Length/Value/Type
1988 * @return offs = length of this header
1992 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
1996 * adds processID with max 32Bit unsigned Integer Value to tree
2000 * @return modified offset
2003 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
2006 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2010 * @return modified offset
2013 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2016 * BACnet Application PDUs chapter 21
2017 * BACnetPropertyIdentifier::= ENUMERATED {
2018 * @see bacapp_property_identifier
2024 * @param tt returnvalue of this item
2025 * @return modified offset
2028 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2031 * BACnet Application PDUs chapter 21
2032 * BACnetPropertyArrayIndex::= ENUMERATED {
2033 * @see bacapp_property_array_index
2038 * @param tt returnvalue of this item
2039 * @return modified offset
2042 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
2045 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2046 * objectIdentifier [0] BACnetObjectIdentifier,
2047 * eventState [1] BACnetEventState,
2048 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2049 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2050 * notifyType [4] BACnetNotifyType,
2051 * eventEnable [5] BACnetEventTransitionBits,
2052 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2058 * @return modified offset
2061 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2064 * SelectionCriteria ::= SEQUENCE {
2065 * propertyIdentifier [0] BACnetPropertyIdentifier,
2066 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2067 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2068 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2074 * @return modified offset
2077 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2080 * objectSelectionCriteria ::= SEQUENCE {
2081 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2082 * listOfSelectionCriteria [1] SelectionCriteria
2088 * @return modified offset
2091 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2094 * BACnet-Error ::= SEQUENCE {
2095 * error-class ENUMERATED {},
2096 * error-code ENUMERATED {}
2103 * @return modified offset
2106 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2109 * Generic handler for context tagged values. Mostly for handling
2110 * vendor-defined properties and services.
2114 * @return modified offset
2115 * @todo beautify this ugly construct
2118 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2121 * realizes some ABSTRACT-SYNTAX.&Type
2126 * @return modified offset
2127 * @todo beautify this ugly construct
2130 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2134 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2135 const value_string *src);
2141 proto_register_bacapp(void);
2144 * proto_reg_handoff_bacapp
2147 proto_reg_handoff_bacapp(void);
2150 * converts XXX coded strings to UTF-8
2151 * else 'in' is copied to 'out'
2152 * @param in -- pointer to string
2153 * @param inbytesleft
2154 * @param out -- pointer to string
2155 * @param outbytesleft
2157 * @return count of modified characters of returned string, -1 for errors
2160 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2163 uni_to_string(char * data, gsize str_length, char *dest_buf);
2165 /* <<<< formerly bacapp.h */
2167 /* some hashes for segmented messages */
2168 static GHashTable *msg_fragment_table = NULL;
2169 static GHashTable *msg_reassembled_table = NULL;
2171 /* some necessary forward function prototypes */
2173 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2174 const gchar *label, const value_string *vs);
2176 static const char *bacapp_unknown_service_str = "unknown service";
2177 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2178 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2180 static const value_string
2181 BACnetTypeName[] = {
2182 {0, "Confirmed-REQ"},
2183 {1, "Unconfirmed-REQ"},
2193 static const true_false_string segments_follow = {
2194 "Segmented Request",
2195 "Unsegmented Request"
2198 static const true_false_string more_follow = {
2199 "More Segments Follow",
2200 "No More Segments Follow"
2203 static const true_false_string segmented_accept = {
2204 "Segmented Response accepted",
2205 "Segmented Response not accepted"
2208 static const true_false_string
2210 "Context Specific Tag",
2214 static const value_string
2215 BACnetMaxSegmentsAccepted [] = {
2223 {7,"Greater than 64 segments"},
2227 static const value_string
2228 BACnetMaxAPDULengthAccepted [] = {
2229 {0,"Up to MinimumMessageSize (50 octets)"},
2230 {1,"Up to 128 octets"},
2231 {2,"Up to 206 octets (fits in a LonTalk frame)"},
2232 {3,"Up to 480 octets (fits in an ARCNET frame)"},
2233 {4,"Up to 1024 octets"},
2234 {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2235 {6,"reserved by ASHRAE"},
2236 {7,"reserved by ASHRAE"},
2237 {8,"reserved by ASHRAE"},
2238 {9,"reserved by ASHRAE"},
2239 {10,"reserved by ASHRAE"},
2240 {11,"reserved by ASHRAE"},
2241 {12,"reserved by ASHRAE"},
2242 {13,"reserved by ASHRAE"},
2243 {14,"reserved by ASHRAE"},
2244 {15,"reserved by ASHRAE"},
2248 static const value_string
2249 BACnetRejectReason [] = {
2251 {1,"buffer-overflow"},
2252 {2,"inconsistent-parameters"},
2253 {3,"invalid-parameter-data-type"},
2255 {5,"missing-required-parameter"},
2256 {6,"parameter-out-of-range"},
2257 {7,"too-many-arguments"},
2258 {8,"undefined-enumeration"},
2259 {9,"unrecognized-service"},
2263 static const value_string
2264 BACnetRestartReason [] = {
2268 {3,"detected-power-lost"},
2269 {4,"detected-powered-off"},
2270 {5,"hardware-watchdog"},
2271 {6,"software-watchdog"},
2276 static const value_string
2277 BACnetApplicationTagNumber [] = {
2280 {2,"Unsigned Integer"},
2281 {3,"Signed Integer (2's complement notation)"},
2282 {4,"Real (ANSI/IEE-754 floating point)"},
2283 {5,"Double (ANSI/IEE-754 double precision floating point)"},
2285 {7,"Character String"},
2290 {12,"BACnetObjectIdentifier"},
2291 {13,"reserved by ASHRAE"},
2292 {14,"reserved by ASHRAE"},
2293 {15,"reserved by ASHRAE"},
2297 static const value_string
2304 static const value_string
2305 BACnetFileAccessMethod [] = {
2306 {0,"record-access"},
2307 {1,"stream-access"},
2311 /* For some reason, BACnet defines the choice parameter
2312 in the file read and write services backwards from the
2313 BACnetFileAccessMethod enumeration.
2315 static const value_string
2316 BACnetFileAccessOption [] = {
2317 {0,"stream access"},
2318 {1,"record access"},
2322 static const value_string
2323 BACnetFileStartOption [] = {
2324 {0, "File Start Position: "},
2325 {1, "File Start Record: "},
2329 static const value_string
2330 BACnetFileRequestCount [] = {
2331 {0, "Requested Octet Count: "},
2332 {1, "Requested Record Count: "},
2336 static const value_string
2337 BACnetFileWriteInfo [] = {
2339 {1, "Record Count: "},
2343 static const value_string
2344 BACnetAbortReason [] = {
2346 {1,"buffer-overflow"},
2347 {2,"invalid-apdu-in-this-state"},
2348 {3,"preempted-by-higher-priority-task"},
2349 {4,"segmentation-not-supported"},
2353 static const value_string
2354 BACnetLifeSafetyMode [] = {
2365 {10,"disconnected"},
2368 {13,"atomic-release-disabled"},
2371 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2372 Enumerated values 256-65535 may be used by others subject to
2373 procedures and constraints described in Clause 23. */
2376 static const value_string
2377 BACnetLifeSafetyOperation [] = {
2380 {2,"silence-audible"},
2381 {3,"silence-visual"},
2386 {8,"unsilence-audible"},
2387 {9,"unsilence-visual"},
2389 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2390 Enumerated values 64-65535 may be used by others subject to
2391 procedures and constraints described in Clause 23. */
2394 static const value_string
2395 BACnetLimitEnable [] = {
2396 {0,"lowLimitEnable"},
2397 {1,"highLimitEnable"},
2401 static const value_string
2402 BACnetLifeSafetyState [] = {
2407 {4,"fault-pre-alarm"},
2415 {12,"test-fault-alarm"},
2418 {15,"tamper-alarm"},
2420 {17,"emergency-power"},
2424 {21,"general-alarm"},
2426 {23,"test-supervisory"},
2428 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2429 Enumerated values 256-65535 may be used by others subject to
2430 procedures and constraints described in Clause 23. */
2433 static const value_string
2434 BACnetConfirmedServiceChoice [] = {
2435 {0,"acknowledgeAlarm"},
2436 {1,"confirmedCOVNotification"},
2437 {2,"confirmedEventNotification"},
2438 {3,"getAlarmSummary"},
2439 {4,"getEnrollmentSummary"},
2441 {6,"atomicReadFile"},
2442 {7,"atomicWriteFile"},
2443 {8,"addListElement"},
2444 {9,"removeListElement"},
2445 {10,"createObject"},
2446 {11,"deleteObject"},
2447 {12,"readProperty"},
2448 {13,"readPropertyConditional"},
2449 {14,"readPropertyMultiple"},
2450 {15,"writeProperty"},
2451 {16,"writePropertyMultiple"},
2452 {17,"deviceCommunicationControl"},
2453 {18,"confirmedPrivateTransfer"},
2454 {19,"confirmedTextMessage"},
2455 {20,"reinitializeDevice"},
2459 {24,"authenticate"},
2462 {27,"lifeSafetyOperation"},
2463 {28,"subscribeCOVProperty"},
2464 {29,"getEventInformation"},
2465 {30,"reserved by ASHRAE"},
2469 static const value_string
2470 BACnetReliability [] = {
2471 {0,"no-fault-detected"},
2478 {7,"unreliable-other"},
2479 {8,"process-error"},
2480 {9,"multi-state-fault"},
2481 {10,"configuration-error"},
2482 /* enumeration value 11 is reserved for a future addendum */
2483 {12,"communication-failure"},
2484 {13,"member-fault"},
2488 static const value_string
2489 BACnetUnconfirmedServiceChoice [] = {
2492 {2,"unconfirmedCOVNotification"},
2493 {3,"unconfirmedEventNotification"},
2494 {4,"unconfirmedPrivateTransfer"},
2495 {5,"unconfirmedTextMessage"},
2496 {6,"timeSynchronization"},
2499 {9,"utcTimeSynchonization"},
2503 static const value_string
2504 BACnetUnconfirmedServiceRequest [] = {
2506 {1,"i-Have-Request"},
2507 {2,"unconfirmedCOVNotification-Request"},
2508 {3,"unconfirmedEventNotification-Request"},
2509 {4,"unconfirmedPrivateTransfer-Request"},
2510 {5,"unconfirmedTextMessage-Request"},
2511 {6,"timeSynchronization-Request"},
2512 {7,"who-Has-Request"},
2513 {8,"who-Is-Request"},
2514 {9,"utcTimeSynchonization-Request"},
2518 static const value_string
2519 BACnetObjectType [] = {
2521 {1,"analog-output"},
2524 {4,"binary-output"},
2529 {9,"event-enrollment"},
2533 {13,"multi-state-input"},
2534 {14,"multi-state-output"},
2535 {15,"notification-class"},
2539 {19,"multi-state-value"},
2541 {21,"life-safety-point"},
2542 {22,"life-safety-zone"},
2544 {24,"pulse-converter"},
2546 {26,"global-group"},
2547 {27,"trend-log-multiple"},
2548 {28,"load-control"},
2549 {29,"structured-view"},
2550 {30,"access-door"}, /* 30-37 added with addanda 135-2008j */
2551 /* value 31 is unassigned */
2552 {32,"access-credential"},
2553 {33,"access-point"},
2554 {34,"access-rights"},
2557 {37,"credential-data-input"},
2558 {38,"network-security"},
2559 {39,"bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2560 {40,"characterstring-value"},
2561 {41,"date-pattern-value"},
2563 {43,"datetime-pattern-value"},
2564 {44,"datetime-value"},
2565 {45,"integer-value"},
2566 {46,"large-analog-value"},
2567 {47,"octetstring-value"},
2568 {48,"positive-integer-value"},
2569 {49,"time-pattern-value"},
2572 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2573 Enumerated values 128-1023 may be used by others subject to
2574 the procedures and constraints described in Clause 23. */
2577 static const value_string
2578 BACnetEngineeringUnits [] = {
2588 {9,"Kilovolt Amperes"},
2589 {10,"Megavolt Amperes"},
2590 {11,"Volt Amperes Reactive"},
2591 {12,"Kilovolt Amperes Reactive"},
2592 {13,"Megavolt Amperes Reactive"},
2593 {14,"Degrees Phase"},
2594 {15,"Power Factor"},
2598 {19,"Kilowatt Hours"},
2602 {23,"Joules Per Kg Dry Air"},
2603 {24,"BTUs Per Pound Dry Air"},
2604 {25,"Cycles Per Hour"},
2605 {26,"Cycles Per Minute"},
2607 {28,"Grams Of Water Per Kilogram Dry Air"},
2608 {29,"Relative Humidity"},
2613 {34,"Watts Per Sq Foot"},
2614 {35,"Watts Per Sq meter"},
2617 {38,"Foot Candles"},
2621 {42,"Kgs per Second"},
2622 {43,"Kgs Per Minute"},
2623 {44,"Kgs Per Hour"},
2624 {45,"Pounds Mass Per Minute"},
2625 {46,"Pounds Mass Per Hour"},
2629 {50,"BTUs Per Hour"},
2631 {52,"Tons Refrigeration"},
2635 {56,"Pounds Force Per Square Inch"},
2636 {57,"Centimeters Of Water"},
2637 {58,"Inches Of Water"},
2638 {59,"Millimeters Of Mercury"},
2639 {60,"Centimeters Of Mercury"},
2640 {61,"Inches Of Mercury"},
2641 {62,"Degrees Celsius"},
2642 {63,"Degrees Kelvin"},
2643 {64,"Degrees Fahrenheit"},
2644 {65,"Degree Days Celsius"},
2645 {66,"Degree Days Fahrenheit"},
2653 {74,"Meters Per Second"},
2654 {75,"Kilometers Per Hour"},
2655 {76,"Feed Per Second"},
2656 {77,"Feet Per Minute"},
2657 {78,"Miles Per Hour"},
2659 {80,"Cubic Meters"},
2660 {81,"Imperial Gallons"},
2663 {84,"Cubic Feet Per Minute"},
2664 {85,"Cubic Meters Per Second"},
2665 {86,"Imperial Gallons Per Minute"},
2666 {87,"Liters Per Second"},
2667 {88,"Liters Per Minute"},
2668 {89,"US Gallons Per Minute"},
2669 {90,"Degrees Angular"},
2670 {91,"Degrees Celsius Per Hour"},
2671 {92,"Degrees Celsius Per Minute"},
2672 {93,"Degrees Fahrenheit Per Hour"},
2673 {94,"Degrees Fahrenheit Per Minute"},
2675 {96,"Parts Per Million"},
2676 {97,"Parts Per Billion"},
2678 {99,"Pecent Per Second"},
2681 {102,"Psi Per Degree Fahrenheit"},
2683 {104,"Revolutions Per Min"},
2695 {116,"Sq Centimeters"},
2696 {117,"BTUs Per Pound"},
2697 {118,"Centimeters"},
2698 {119,"Pounds Mass Per Second"},
2699 {120,"Delta Degrees Fahrenheit"},
2700 {121,"Delta Degrees Kelvin"},
2704 {125,"Kilojoules Per Kg"},
2706 {127,"Joules Per Degree Kelvin"},
2707 {128,"Joules Per Kg Degree Kelvin"},
2712 {133,"Hectopascals"},
2714 {135,"Cubic Meters Per Hour"},
2715 {136,"Liters Per Hour"},
2716 {137,"KWatt Hours Per Square Meter"},
2717 {138,"KWatt Hours Per Square Foot"},
2718 {139,"Megajoules Per Square Meter"},
2719 {140,"Megajoules Per Square Foot"},
2720 {141,"Watts Per Sq Meter Degree Kelvin"},
2721 {142,"Cubic Feet Per Second"},
2722 {143,"Percent Obstruction Per Foot"},
2723 {144,"Percent Obstruction Per Meter"},
2725 {146,"megawatt-hours"},
2728 {149,"kilojoules-per-kilogram-dry-air"},
2729 {150,"megajoules-per-kilogram-dry-air"},
2730 {151,"kilojoules-per-degree-Kelvin"},
2731 {152,"megajoules-per-degree-Kelvin"},
2733 {154,"grams-per-second"},
2734 {155,"grams-per-minute"},
2735 {156,"tons-per-hour"},
2736 {157,"kilo-btus-per-hour"},
2737 {158,"hundredths-seconds"},
2738 {159,"milliseconds"},
2739 {160,"newton-meters"},
2740 {161,"millimeters-per-second"},
2741 {162,"millimeters-per-minute"},
2742 {163,"meters-per-minute"},
2743 {164,"meters-per-hour"},
2744 {165,"cubic-meters-per-minute"},
2745 {166,"meters-per-second-per-second"},
2746 {167,"amperes-per-meter"},
2747 {168,"amperes-per-square-meter"},
2748 {169,"ampere-square-meters"},
2753 {174,"siemens-per-meter"},
2755 {176,"volts-per-degree-Kelvin"},
2756 {177,"volts-per-meter"},
2759 {180,"candelas-per-square-meter"},
2760 {181,"degrees-Kelvin-per-hour"},
2761 {182,"degrees-Kelvin-per-minute"},
2762 {183,"joule-seconds"},
2763 {184,"radians-per-second"},
2764 {185,"square-meters-per-Newton"},
2765 {186,"kilograms-per-cubic-meter"},
2766 {187,"newton-seconds"},
2767 {188,"newtons-per-meter"},
2768 {189,"watts-per-meter-per-degree-Kelvin"},
2769 {190,"micro-siemens"},
2770 {191,"cubic-feet-per-hour"},
2771 {192,"us-gallons-per-hour"},
2773 {194,"micrometers"},
2776 {197,"milliliters"},
2777 {198,"milliliters-per-second"},
2779 {200,"decibels-millivolt"},
2780 {201,"decibels-volt"},
2781 {202,"millisiemens"},
2782 {203,"watt-hours-reactive"},
2783 {204,"kilowatt-hours-reactive"},
2784 {205,"megawatt-hours-reactive"},
2785 {206,"millimeters-of-water"},
2787 {208,"grams-per-gram"},
2788 {209,"kilograms-per-kilogram"},
2789 {210,"grams-per-kilogram"},
2790 {211,"milligrams-per-gram"},
2791 {212,"milligrams-per-kilogram"},
2792 {213,"grams-per-milliliter"},
2793 {214,"grams-per-liter"},
2794 {215,"milligrams-per-liter"},
2795 {216,"micrograms-per-liter"},
2796 {217,"grams-per-cubic-meter"},
2797 {218,"milligrams-per-cubic-meter"},
2798 {219,"micrograms-per-cubic-meter"},
2799 {220,"nanograms-per-cubic-meter"},
2800 {221,"grams-per-cubic-centimeter"},
2802 {223,"kilobecquerels"},
2803 {224,"megabecquerels"},
2808 {229,"millisieverts"},
2809 {230,"microsieverts"},
2810 {231,"microsieverts-per-hour"},
2812 {233,"nephelometric-turbidity-unit"},
2814 {235,"grams-per-square-meter"},
2815 {236,"minutes-per-degree-kelvin"},
2817 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2818 Enumerated values 256-65535 may be used by others subject to
2819 the procedures and constraints described in Clause 23. */
2822 static const value_string
2823 BACnetErrorCode [] = {
2825 {1,"authentication-failed"},
2826 {2,"configuration-in-progress"},
2828 {4,"dynamic-creation-not-supported"},
2829 {5,"file-access-denied"},
2830 {6,"incompatible-security-levels"},
2831 {7,"inconsistent-parameters"},
2832 {8,"inconsistent-selection-criterion"},
2833 {9,"invalid-data-type"},
2834 {10,"invalid-file-access-method"},
2835 {11,"invalid-file-start-position"},
2836 {12,"invalid-operator-name"},
2837 {13,"invalid-parameter-data-type"},
2838 {14,"invalid-time-stamp"},
2839 {15,"key-generation-error"},
2840 {16,"missing-required-parameter"},
2841 {17,"no-objects-of-specified-type"},
2842 {18,"no-space-for-object"},
2843 {19,"no-space-to-add-list-element"},
2844 {20,"no-space-to-write-property"},
2845 {21,"no-vt-sessions-available"},
2846 {22,"property-is-not-a-list"},
2847 {23,"object-deletion-not-permitted"},
2848 {24,"object-identifier-already-exists"},
2849 {25,"operational-problem"},
2850 {26,"password-failure"},
2851 {27,"read-access-denied"},
2852 {28,"security-not-supported"},
2853 {29,"service-request-denied"},
2855 {31,"unknown-object"},
2856 {32,"unknown-property"},
2857 {33,"removed enumeration"},
2858 {34,"unknown-vt-class"},
2859 {35,"unknown-vt-session"},
2860 {36,"unsupported-object-type"},
2861 {37,"value-out-of-range"},
2862 {38,"vt-session-already-closed"},
2863 {39,"vt-session-termination-failure"},
2864 {40,"write-access-denied"},
2865 {41,"character-set-not-supported"},
2866 {42,"invalid-array-index"},
2867 {43,"cov-subscription-failed"},
2868 {44,"not-cov-property"},
2869 {45,"optional-functionality-not-supported"},
2870 {46,"invalid-configuration-data"},
2871 {47,"datatype-not-supported"},
2872 {48,"duplicate-name"},
2873 {49,"duplicate-object-id"},
2874 {50,"property-is-not-an-array"},
2875 {73,"invalid-event-state"},
2876 {74,"no-alarm-configured"},
2877 {75,"log-buffer-full"},
2878 {76,"logged-value-purged"},
2879 {77,"no-property-specified"},
2880 {78,"not-configured-for-triggered-logging"},
2881 {79,"unknown-subscription"},
2882 {80,"parameter-out-of-range"},
2883 {81,"list-element-not-found"},
2885 {83,"communication-disabled"},
2887 {85,"access-denied"},
2888 {86,"bad-destination-address"},
2889 {87,"bad-destination-device-id"},
2890 {88,"bad-signature"},
2891 {89,"bad-source-address"},
2892 {90,"bad-timestamp"},
2893 {91,"cannot-use-key"},
2894 {92,"cannot-verify-message-id"},
2895 {93,"correct-key-revision"},
2896 {94,"destination-device-id-required"},
2897 {95,"duplicate-message"},
2898 {96,"encryption-not-configured"},
2899 {97,"encryption-required"},
2900 {98,"incorrect-key"},
2901 {99,"invalid-key-data"},
2902 {100,"key-update-in-progress"},
2903 {101,"malformed-message"},
2904 {102,"not-key-server"},
2905 {103,"security-not-configured"},
2906 {104,"source-security-required"},
2907 {105,"too-many-keys"},
2908 {106,"unknown-authentication-type"},
2909 {107,"unknown-key"},
2910 {108,"unknown-key-revision"},
2911 {109,"unknown-source-message"},
2912 {110,"not-router-to-dnet"},
2913 {111,"router-busy"},
2914 {112,"unknown-network-message"},
2915 {113,"message-too-long"},
2916 {114,"security-error"},
2917 {115,"addressing-error"},
2918 {116,"write-bdt-failed"},
2919 {117,"read-bdt-failed"},
2920 {118,"register-foreign-device-failed"},
2921 {119,"read-fdt-failed"},
2922 {120,"delete-fdt-entry-failed"},
2923 {121,"distribute-broadcast-failed"},
2924 {122,"unknown-file-size"},
2925 {123,"abort-apdu-too-long"},
2926 {124,"abort-application-exceeded-reply-time"},
2927 {125,"abort-out-of-resources"},
2928 {126,"abort-tsm-timeout"},
2929 {127,"abort-window-size-out-of-range"},
2931 {129,"inconsistent-configuration"},
2932 {130,"inconsistent-object-type"},
2933 {131,"internal-error"},
2934 {132,"not-configured"},
2935 {133,"out-of-memory"},
2936 {134,"value-too-long"},
2937 {135,"abort-insufficient-security"},
2938 {136,"abort-security-error"},
2940 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2941 Enumerated values 256-65535 may be used by others subject to the
2942 procedures and constraints described in Clause 23. */
2945 static const value_string
2946 BACnetPropertyIdentifier [] = {
2947 {0,"acked-transition"},
2952 {5,"active-vt-session"},
2956 {9,"all-write-successful"},
2957 {10,"apdu-segment-timeout"},
2958 {11,"apdu-timeout"},
2959 {12,"application-software-version"},
2962 {15,"change-of-state-count"},
2963 {16,"change-of-state-time"},
2964 {17,"notification-class"},
2965 {18,"the property in this place was deleted"},
2966 {19,"controlled-variable-reference"},
2967 {20,"controlled-variable-units"},
2968 {21,"controlled-variable-value"},
2969 {22,"cov-increment"},
2971 {24,"daylights-savings-status"},
2973 {26,"derivative-constant"},
2974 {27,"derivative-constant-units"},
2976 {29,"description-of-halt"},
2977 {30,"device-address-binding"},
2979 {32,"effective-period"},
2980 {33,"elapsed-active-time"},
2982 {35,"event-enable"},
2985 {38,"exception-schedule"},
2986 {39,"fault-values"},
2987 {40,"feedback-value"},
2988 {41,"file-access-method"},
2991 {44,"firmware-revision"},
2993 {46,"inactive-text"},
2996 {49,"integral-constant"},
2997 {50,"integral-constant-units"},
2998 {51,"issue-confirmed-notifications"},
2999 {52,"limit-enable"},
3000 {53,"list-of-group-members"},
3001 {54,"list-of-object-property-references"},
3002 {55,"list-of-session-keys"},
3007 {60,"manipulated-variable-reference"},
3008 {61,"maximum-output"},
3009 {62,"max-apdu-length-accepted"},
3010 {63,"max-info-frames"},
3012 {65,"max-pres-value"},
3013 {66,"minimum-off-time"},
3014 {67,"minimum-on-time"},
3015 {68,"minimum-output"},
3016 {69,"min-pres-value"},
3018 {71,"modification-date"},
3020 {73,"number-of-APDU-retries"},
3021 {74,"number-of-states"},
3022 {75,"object-identifier"},
3025 {78,"object-property-reference"},
3028 {81,"out-of-service"},
3029 {82,"output-units"},
3030 {83,"event-parameters"},
3032 {85,"present-value"},
3034 {87,"priority-array"},
3035 {88,"priority-for-writing"},
3036 {89,"process-identifier"},
3037 {90,"program-change"},
3038 {91,"program-location"},
3039 {92,"program-state"},
3040 {93,"proportional-constant"},
3041 {94,"proportional-constant-units"},
3042 {95,"protocol-conformance-class"},
3043 {96,"protocol-object-types-supported"},
3044 {97,"protocol-services-supported"},
3045 {98,"protocol-version"},
3047 {100,"reason-for-halt"},
3049 {102,"recipient-list"},
3050 {103,"reliability"},
3051 {104,"relinquish-default"},
3054 {107,"segmentation-supported"},
3056 {109,"setpoint-reference"},
3058 {111,"status-flags"},
3059 {112,"system-status"},
3061 {114,"time-of-active-time-reset"},
3062 {115,"time-of-state-count-reset"},
3063 {116,"time-synchronization-recipients"},
3065 {118,"update-interval"},
3067 {120,"vendor-identifier"},
3068 {121,"vendor-name"},
3069 {122,"vt-class-supported"},
3070 {123,"weekly-schedule"},
3071 {124,"attempted-samples"},
3072 {125,"average-value"},
3073 {126,"buffer-size"},
3074 {127,"client-cov-increment"},
3075 {128,"cov-resubscription-interval"},
3076 {129,"current-notify-time"},
3077 {130,"event-time-stamp"},
3079 {132,"log-device-object-property"},
3080 {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
3081 {134,"log-interval"},
3082 {135,"maximum-value"},
3083 {136,"minimum-value"},
3084 {137,"notification-threshold"},
3085 {138,"previous-notify-time"},
3086 {139,"protocol-revision"},
3087 {140,"records-since-notification"},
3088 {141,"record-count"},
3091 {144,"stop-when-full"},
3092 {145,"total-record-count"},
3093 {146,"valid-samples"},
3094 {147,"window-interval"},
3095 {148,"window-samples"},
3096 {149,"maximum-value-time-stamp"},
3097 {150,"minimum-value-time-stamp"},
3098 {151,"variance-value"},
3099 {152,"active-cov-subscriptions"},
3100 {153,"backup-failure-timeout"},
3101 {154,"configuration-files"},
3102 {155,"database-revision"},
3103 {156,"direct-reading"},
3104 {157,"last-restore-time"},
3105 {158,"maintenance-required"},
3108 {161,"operation-expected"},
3111 {164,"tracking-value"},
3112 {165,"zone-members"},
3113 {166,"life-safety-alarm-values"},
3114 {167,"max-segments-accepted"},
3115 {168,"profile-name"},
3116 {169,"auto-slave-discovery"},
3117 {170,"manual-slave-address-binding"},
3118 {171,"slave-address-binding"},
3119 {172,"slave-proxy-enable"},
3120 {173,"last-notify-record"}, /* bug 4117 */
3121 {174,"schedule-default"},
3122 {175,"accepted-modes"},
3123 {176,"adjust-value"},
3125 {178,"count-before-change"},
3126 {179,"count-change-time"},
3128 {181,"input-reference"},
3129 {182,"limit-monitoring-interval"},
3130 {183,"logging-device"},
3131 {184,"logging-record"},
3135 {188,"scale-factor"},
3136 {189,"update-time"},
3137 {190,"value-before-change"},
3139 {192,"value-change-time"},
3140 {193,"align-intervals"},
3141 {194,"group-member-names"},
3142 {195,"interval-offset"},
3143 {196,"last-restart-reason"},
3144 {197,"logging-type"},
3145 {198,"member-status-flags"},
3146 {199,"notification-period"},
3147 {200,"previous-notify-record"},
3148 {201,"requested-update-interval"},
3149 {202,"restart-notification-recipients"},
3150 {203,"time-of-device-restart"},
3151 {204,"time-synchronization-interval"},
3153 {206,"UTC-time-synchronization-recipients"},
3154 {207,"node-subtype"},
3156 {209,"structured-object-list"},
3157 {210,"subordinate-annotations"},
3158 {211,"subordinate-list"},
3159 {212,"actual-shed-level"},
3160 {213,"duty-window"},
3161 {214,"expected-shed-level"},
3162 {215,"full-duty-baseline"},
3163 {216,"node-subtype"},
3165 {218,"requested-shed-level"},
3166 {219,"shed-duration"},
3167 {220,"shed-level-descriptions"},
3168 {221,"shed-levels"},
3169 {222,"state-description"},
3170 /* enumeration values 223-225 are unassigned */
3171 {226,"door-alarm-state"},
3172 {227,"door-extended-pulse-time"},
3173 {228,"door-members"},
3174 {229,"door-open-too-long-time"},
3175 {230,"door-pulse-time"},
3176 {231,"door-status"},
3177 {232,"door-unlock-delay-time"},
3178 {233,"lock-status"},
3179 {234,"masked-alarm-values"},
3180 {235,"secured-status"},
3181 /* enumeration values 236-243 are unassigned */
3182 {244,"absentee-limit"}, /* added with addenda 135-2008j */
3183 {245,"access-alarm-events"},
3184 {246,"access-doors"},
3185 {247,"access-event"},
3186 {248,"access-event-authentication-factor"},
3187 {249,"access-event-credential"},
3188 {250,"access-event-time"},
3189 {251,"access-transaction-events"},
3190 {252,"accompaniment"},
3191 {253,"accompaniment-time"},
3192 {254,"activation-time"},
3193 {255,"active-authentication-policy"},
3194 {256,"assigned-access-rights"},
3195 {257,"authentication-factors"},
3196 {258,"authentication-policy-list"},
3197 {259,"authentication-policy-names"},
3198 {260,"authentication-status"},
3199 {261,"authorization-mode"},
3201 {263,"credential-disable"},
3202 {264,"credential-status"},
3203 {265,"credentials"},
3204 {266,"credentials-in-zone"},
3205 {267,"days-remaining"},
3206 {268,"entry-points"},
3207 {269,"exit-points"},
3208 {270,"expiry-time"},
3209 {271,"extended-time-enable"},
3210 {272,"failed-attempt-events"},
3211 {273,"failed-attempts"},
3212 {274,"failed-attempts-time"},
3213 {275,"last-access-event"},
3214 {276,"last-access-point"},
3215 {277,"last-credential-added"},
3216 {278,"last-credential-added-time"},
3217 {279,"last-credential-removed"},
3218 {280,"last-credential-removed-time"},
3219 {281,"last-use-time"},
3221 {283,"lockout-relinquish-time"},
3222 {284,"master-exemption"},
3223 {285,"max-failed-attempts"},
3225 {287,"muster-point"},
3226 {288,"negative-access-rules"},
3227 {289,"number-of-authentication-policies"},
3228 {290,"occupancy-count"},
3229 {291,"occupancy-count-adjust"},
3230 {292,"occupancy-count-enable"},
3231 {293,"occupancy-exemption"},
3232 {294,"occupancy-lower-limit"},
3233 {295,"occupancy-lower-limit-enforced"},
3234 {296,"occupancy-state"},
3235 {297,"occupancy-upper-limit"},
3236 {298,"occupancy-upper-limit-enforced"},
3237 {299,"passback-exemption"},
3238 {300,"passback-mode"},
3239 {301,"passback-timeout"},
3240 {302,"positive-access-rules"},
3241 {303,"reason-for-disable"},
3242 {304,"supported-formats"},
3243 {305,"supported-format-classes"},
3244 {306,"threat-authority"},
3245 {307,"threat-level"},
3247 {309,"transaction-notification-class"},
3248 {310,"user-external-identifier"},
3249 {311,"user-information-reference"},
3250 /* enumeration values 312-316 are unassigned */
3253 {319,"uses-remaining"},
3256 {322,"access-event-tag"},
3257 {323,"global-identifier"},
3258 /* enumeration values 324-325 reserved for future addenda */
3259 {326,"verification-time"},
3260 {327,"base-device-security-policy"},
3261 {328,"distribution-key-revision"},
3262 {329,"do-not-hide"},
3264 {331,"last-key-server"},
3265 {332,"network-access-security-policies"},
3266 {333,"packet-reorder-time"},
3267 {334,"security-pdu-timeout"},
3268 {335,"security-time-window"},
3269 {336,"supported-security-algorithms"},
3270 {337,"update-key-set-timeout"},
3271 {338,"backup-and-restore-state"},
3272 {339,"backup-preparation-time"},
3273 {340,"restore-completion-time"},
3274 {341,"restore-preparation-time"},
3275 {342,"bit-mask"}, /* addenda 135-2008w */
3278 {345,"group-members"},
3279 {346,"group-member-names"},
3280 {347,"member-status-flags"},
3281 {348,"requested-update-interval"},
3282 {349,"covu-period"},
3283 {350,"covu-recipients"},
3284 {351,"event-message-texts"},
3286 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3287 Enumerated values 512-4194303 may be used by others subject to
3288 the procedures and constraints described in Clause 23. */
3291 static const value_string
3292 BACnetBinaryPV [] = {
3300 #define IBM_MS_DBCS 1
3301 #define JIS_C_6226 2
3302 #define ISO_10646_UCS4 3
3303 #define ISO_10646_UCS2 4
3304 #define ISO_18859_1 5
3305 static const value_string
3306 BACnetCharacterSet [] = {
3307 {ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3308 {IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3309 {JIS_C_6226, "JIS C 6226"},
3310 {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3311 {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3312 {ISO_18859_1, "ISO 18859-1"},
3316 static const value_string
3317 BACnetStatusFlags [] = {
3321 {3,"out-of-service"},
3325 static const value_string
3326 BACnetMessagePriority [] = {
3332 static const value_string
3333 BACnetAcknowledgementFilter [] = {
3340 static const value_string
3341 BACnetResultFlags [] = {
3348 static const value_string
3349 BACnetRelationSpecifier [] = {
3354 {4,"less-than-or-equal"},
3355 {5,"greater-than-or-equal"},
3359 static const value_string
3360 BACnetSelectionLogic [] = {
3367 static const value_string
3368 BACnetEventStateFilter [] = {
3377 static const value_string
3378 BACnetEventTransitionBits [] = {
3385 static const value_string
3386 BACnetSegmentation [] = {
3387 {0,"segmented-both"},
3388 {1,"segmented-transmit"},
3389 {2,"segmented-receive"},
3390 {3,"no-segmentation"},
3394 static const value_string
3395 BACnetSilencedState [] = {
3397 {1,"audible-silenced"},
3398 {2,"visible-silenced"},
3403 static const value_string
3404 BACnetDeviceStatus [] = {
3406 {1,"operational-read-only"},
3407 {2,"download-required"},
3408 {3,"download-in-progress"},
3409 {4,"non-operational"},
3410 {5,"backup-in-progress"},
3414 static const value_string
3415 BACnetEnableDisable [] = {
3418 {2,"disable-initiation"},
3422 static const value_string
3440 static const value_string
3442 {1,"days numbered 1-7" },
3443 {2,"days numbered 8-14" },
3444 {3,"days numbered 15-21" },
3445 {4,"days numbered 22-28" },
3446 {5,"days numbered 29-31" },
3447 {6,"last 7 days of this month" },
3448 {255,"any week of this month" },
3452 /* note: notification class object recipient-list uses
3453 different day-of-week enum */
3454 static const value_string
3463 {255,"any day of week" },
3467 static const value_string
3468 BACnetErrorClass [] = {
3477 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3478 Enumerated values64-65535 may be used by others subject to
3479 the procedures and constraints described in Clause 23. */
3482 static const value_string
3483 BACnetVTClass [] = {
3484 {0,"default-terminal" },
3494 static const value_string
3495 BACnetEventType [] = {
3496 {0,"change-of-bitstring" },
3497 {1,"change-of-state" },
3498 {2,"change-of-value" },
3499 {3,"command-failure" },
3500 {4,"floating-limit" },
3501 {5,"out-of-range" },
3502 {6,"complex-event-type" },
3503 {7,"buffer-ready" },
3504 {8,"change-of-life-safety" },
3506 {10,"buffer-ready" },
3507 {11,"unsigned-range" },
3508 {14,"double-out-of-range"}, /* added with addenda 135-2008w */
3509 {15,"signed-out-of-range"},
3510 {16,"unsigned-out-of-range"},
3511 {17,"change-of-characterstring"},
3512 {18,"change-of-status-flags"},
3514 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3515 Enumerated values 64-65535 may be used by others subject to
3516 the procedures and constraints described in Clause 23.
3517 It is expected that these enumerated values will correspond
3518 to the use of the complex-event-type CHOICE [6] of the
3519 BACnetNotificationParameters production. */
3522 static const value_string
3523 BACnetEventState [] = {
3529 {5,"life-safety-alarm" },
3531 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3532 Enumerated values 64-65535 may be used by others subject to
3533 the procedures and constraints described in Clause 23. */
3536 static const value_string
3537 BACnetLogStatus [] = {
3538 {0,"log-disabled" },
3539 {1,"buffer-purged" },
3540 {2,"log-interrupted"},
3544 static const value_string
3545 BACnetMaintenance [] = {
3547 {1,"periodic-test" },
3548 {2,"need-service-operational" },
3549 {3,"need-service-inoperative" },
3553 static const value_string
3554 BACnetNotifyType [] = {
3557 {2,"ack-notification" },
3561 static const value_string
3562 BACnetServicesSupported [] = {
3563 {0,"acknowledgeAlarm"},
3564 {1,"confirmedCOVNotification"},
3565 {2,"confirmedEventNotification"},
3566 {3,"getAlarmSummary"},
3567 {4,"getEnrollmentSummary"},
3569 {6,"atomicReadFile"},
3570 {7,"atomicWriteFile"},
3571 {8,"addListElement"},
3572 {9,"removeListElement"},
3573 {10,"createObject"},
3574 {11,"deleteObject"},
3575 {12,"readProperty"},
3576 {13,"readPropertyConditional"},
3577 {14,"readPropertyMultiple"},
3578 {15,"writeProperty"},
3579 {16,"writePropertyMultiple"},
3580 {17,"deviceCommunicationControl"},
3581 {18,"confirmedPrivateTransfer"},
3582 {19,"confirmedTextMessage"},
3583 {20,"reinitializeDevice"},
3587 {24,"authenticate"},
3591 {28,"unconfirmedCOVNotification"},
3592 {29,"unconfirmedEventNotification"},
3593 {30,"unconfirmedPrivateTransfer"},
3594 {31,"unconfirmedTextMessage"},
3595 {32,"timeSynchronization"},
3599 {36,"utcTimeSynchronization"},
3600 {37,"lifeSafetyOperation"},
3601 {38,"subscribeCOVProperty"},
3602 {39,"getEventInformation"},
3606 static const value_string
3607 BACnetPropertyStates [] = {
3608 {0,"boolean-value"},
3612 {4,"program-change"},
3613 {5,"program-state"},
3614 {6,"reason-for-halt"},
3617 {9,"system-status"},
3619 {11,"unsigned-value"},
3620 {12,"life-safety-mode"},
3621 {13,"life-safety-state"},
3622 {14,"restart-reason"},
3623 {15,"door-alarm-state"},
3625 {17,"door-secured-status"},
3628 {20,"file-access-method"},
3630 {22,"life-safety-operation"},
3634 {26,"security-level"},
3636 {28,"silenced-state"},
3637 /* context tag 29 reserved for future addenda */
3638 {30,"access-event"},
3639 {31,"zone-occupancy-state"},
3640 {32,"access-credential-disable-reason"},
3641 {33,"access-credential-disable"},
3642 {34,"authentication-status"},
3643 {36,"backup-state"},
3645 /* Tag values 0-63 are reserved for definition by ASHRAE.
3646 Tag values of 64-254 may be used by others to accommodate
3647 vendor specific properties that have discrete or enumerated values,
3648 subject to the constraints described in Clause 23. */
3651 static const value_string
3652 BACnetProgramError [] = {
3659 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3660 Enumerated values 64-65535 may be used by others subject to
3661 the procedures and constraints described in Clause 23. */
3664 static const value_string
3665 BACnetProgramRequest [] = {
3675 static const value_string
3676 BACnetProgramState [] = {
3686 static const value_string
3687 BACnetReinitializedStateOfDevice [] = {
3698 static const value_string
3699 BACnetPolarity [] = {
3705 static const value_string
3706 BACnetTagNames[] = {
3707 { 5, "Extended Value" },
3708 { 6, "Opening Tag" },
3709 { 7, "Closing Tag" },
3713 static const value_string
3714 BACnetReadRangeOptions[] = {
3715 { 3, "range byPosition" },
3716 { 4, "range byTime" },
3717 { 5, "range timeRange" },
3718 { 6, "range bySequenceNumber" },
3719 { 7, "range byTime" },
3723 /* Present_Value for Load Control Object */
3724 static const value_string
3725 BACnetShedState[] = {
3726 { 0, "shed-inactive" },
3727 { 1, "shed-request-pending" },
3728 { 2, "shed-compliant" },
3729 { 3, "shed-non-compliant" },
3733 static const value_string
3734 BACnetVendorIdentifiers [] = {
3737 { 2, "The Trane Company" },
3738 { 3, "McQuay International" },
3740 { 5, "Johnson Controls, Inc." },
3741 { 6, "American Auto-Matrix" },
3742 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3743 { 8, "Delta Controls" },
3744 { 9, "Siemens Building Technologies, Inc." },
3745 { 10, "Tour Andover Controls Corporation" },
3747 { 12, "Orion Analysis Corporation" },
3748 { 13, "Teletrol Systems Inc." },
3749 { 14, "Cimetrics Technology" },
3750 { 15, "Cornell University" },
3751 { 16, "United Technologies Carrier" },
3752 { 17, "Honeywell Inc." },
3753 { 18, "Alerton / Honeywell" },
3755 { 20, "Hewlett-Packard Company" },
3756 { 21, "Dorsette's Inc." },
3757 { 22, "Cerberus AG" },
3758 { 23, "York Controls Group" },
3759 { 24, "Automated Logic Corporation" },
3760 { 25, "CSI Control Systems International" },
3761 { 26, "Phoenix Controls Corporation" },
3762 { 27, "Innovex Technologies, Inc." },
3763 { 28, "KMC Controls, Inc." },
3764 { 29, "Xn Technologies, Inc." },
3765 { 30, "Hyundai Information Technology Co., Ltd." },
3766 { 31, "Tokimec Inc." },
3768 { 33, "North Communications Limited" },
3770 { 35, "Reliable Controls Corporation" },
3771 { 36, "Tridium Inc." },
3772 { 37, "Sierra Monitor Corp." },
3773 { 38, "Silicon Energy" },
3774 { 39, "Kieback & Peter GmbH & Co KG" },
3775 { 40, "Anacon Systems, Inc." },
3776 { 41, "Systems Controls & Instruments, LLC" },
3777 { 42, "Lithonia Lighting" },
3778 { 43, "Micropower Manufacturing" },
3779 { 44, "Matrix Controls" },
3780 { 45, "METALAIRE" },
3781 { 46, "ESS Engineering" },
3782 { 47, "Sphere Systems Pty Ltd." },
3783 { 48, "Walker Technologies Corporation" },
3784 { 49, "H I Solutions, Inc." },
3786 { 51, "SAMSON AG" },
3787 { 52, "Badger Meter Inc." },
3788 { 53, "DAIKIN Industries Ltd." },
3789 { 54, "NARA Controls Inc." },
3790 { 55, "Mammoth Inc." },
3791 { 56, "Liebert Corporation" },
3792 { 57, "SEMCO Incorporated" },
3793 { 58, "Air Monitor Corporation" },
3794 { 59, "TRIATEK, Inc." },
3796 { 61, "Multistack" },
3797 { 62, "TSI Incorporated" },
3798 { 63, "Weather-Rite, Inc." },
3799 { 64, "Dunham-Bush" },
3800 { 65, "Reliance Electric" },
3802 { 67, "Regulator Australia PTY Ltd." },
3803 { 68, "Touch-Plate Lighting Controls" },
3804 { 69, "Amann GmbH" },
3805 { 70, "RLE Technologies" },
3806 { 71, "Cardkey Systems" },
3807 { 72, "SECOM Co., Ltd." },
3808 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3809 { 74, "KNX Association cvba" },
3810 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3811 { 76, "Nohmi Bosai, Ltd." },
3812 { 77, "Carel S.p.A." },
3813 { 78, "AirSense Technology, Inc." },
3814 { 79, "Hochiki Corporation" },
3815 { 80, "Fr. Sauter AG" },
3816 { 81, "Matsushita Electric Works, Ltd." },
3817 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3818 { 83, "Mitsubishi Heavy Industries, Ltd." },
3819 { 84, "ITT Bell & Gossett" },
3820 { 85, "Yamatake Building Systems Co., Ltd." },
3821 { 86, "The Watt Stopper, Inc." },
3822 { 87, "Aichi Tokei Denki Co., Ltd." },
3823 { 88, "Activation Technologies, LLC" },
3824 { 89, "Saia-Burgess Controls, Ltd." },
3825 { 90, "Hitachi, Ltd." },
3826 { 91, "Novar Corp./Trend Control Systems Ltd." },
3827 { 92, "Mitsubishi Electric Lighting Corporation" },
3828 { 93, "Argus Control Systems, Ltd." },
3829 { 94, "Kyuki Corporation" },
3830 { 95, "Richards-Zeta Building Intelligence, Inc." },
3831 { 96, "Scientech R&D, Inc." },
3832 { 97, "VCI Controls, Inc." },
3833 { 98, "Toshiba Corporation" },
3834 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3835 { 100, "Custom Mechanical Equipment, LLC" },
3836 { 101, "ClimateMaster" },
3837 { 102, "ICP Panel-Tec, Inc." },
3838 { 103, "D-Tek Controls" },
3839 { 104, "NEC Engineering, Ltd." },
3840 { 105, "PRIVA BV" },
3841 { 106, "Meidensha Corporation" },
3842 { 107, "JCI Systems Integration Services" },
3843 { 108, "Freedom Corporation" },
3844 { 109, "Neuberger Gebaudeautomation GmbH" },
3845 { 110, "Sitronix" },
3846 { 111, "Leviton Manufacturing" },
3847 { 112, "Fujitsu Limited" },
3848 { 113, "Emerson Network Power" },
3849 { 114, "S. A. Armstrong, Ltd." },
3850 { 115, "Visonet AG" },
3851 { 116, "M&M Systems, Inc." },
3852 { 117, "Custom Software Engineering" },
3853 { 118, "Nittan Company, Limited" },
3854 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3855 { 120, "Pacom Systems Pty., Ltd." },
3856 { 121, "Unico, Inc." },
3857 { 122, "Ebtron, Inc." },
3858 { 123, "Scada Engine" },
3859 { 124, "AC Technology Corporation" },
3860 { 125, "Eagle Technology" },
3861 { 126, "Data Aire, Inc." },
3862 { 127, "ABB, Inc." },
3863 { 128, "Transbit Sp. z o. o." },
3864 { 129, "Toshiba Carrier Corporation" },
3865 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
3866 { 131, "Tokai Soft" },
3868 { 133, "Veris Industries" },
3869 { 134, "Centaurus Prime" },
3870 { 135, "Sand Network Systems" },
3871 { 136, "Regulvar, Inc." },
3872 { 137, "Fastek International, Ltd." },
3873 { 138, "PowerCold Comfort Air Solutions, Inc." },
3874 { 139, "I Controls" },
3875 { 140, "Viconics Electronics, Inc." },
3876 { 141, "Yaskawa Electric America, Inc." },
3877 { 142, "Plueth Regelsysteme" },
3878 { 143, "Digitale Mess- und Steuersysteme AG" },
3879 { 144, "Fujitsu General Limited" },
3880 { 145, "Project Engineering S.r.l." },
3881 { 146, "Sanyo Electric Co., Ltd." },
3882 { 147, "Integrated Information Systems, Inc." },
3883 { 148, "Temco Controls, Ltd." },
3884 { 149, "Airtek Technologies, Inc." },
3885 { 150, "Advantech Corporation" },
3886 { 151, "Titan Products, Ltd." },
3887 { 152, "Regel Partners" },
3888 { 153, "National Environmental Product" },
3889 { 154, "Unitec Corporation" },
3890 { 155, "Kanden Engineering Company" },
3891 { 156, "Messner Gebaudetechnik GmbH" },
3892 { 157, "Integrated.CH" },
3893 { 158, "EH Price Limited" },
3894 { 159, "SE-Elektronic GmbH" },
3895 { 160, "Rockwell Automation" },
3896 { 161, "Enflex Corp." },
3897 { 162, "ASI Controls" },
3898 { 163, "SysMik GmbH Dresden" },
3899 { 164, "HSC Regelungstechnik GmbH" },
3900 { 165, "Smart Temp Australia Pty. Ltd." },
3901 { 166, "PCI Lighting Control Systems" },
3902 { 167, "Duksan Mecasys Co., Ltd." },
3903 { 168, "Fuji IT Co., Ltd." },
3904 { 169, "Vacon Plc" },
3905 { 170, "Leader Controls" },
3906 { 171, "Cylon Controls, Ltd." },
3908 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
3909 { 174, "Building Control Integrators" },
3910 { 175, "ITG Worldwide (M) Sdn Bhd" },
3911 { 176, "Lutron Electronics Co., Inc." },
3912 { 177, "Cooper-Atkins Corporation" },
3913 { 178, "LOYTEC Electronics GmbH" },
3915 { 180, "Mega Controls Limited" },
3916 { 181, "Micro Control Systems, Inc." },
3917 { 182, "Kiyon, Inc." },
3918 { 183, "Dust Networks" },
3919 { 184, "Advanced Building Automation Systems" },
3920 { 185, "Hermos AG" },
3923 { 188, "Lynxspring" },
3924 { 189, "Schneider Toshiba Inverter Europe" },
3925 { 190, "Danfoss Drives A/S" },
3926 { 191, "Eaton Corporation" },
3927 { 192, "Matyca S.A." },
3928 { 193, "Botech AB" },
3929 { 194, "Noveo, Inc." },
3931 { 196, "Yokogawa Electric Corporation" },
3932 { 197, "GFR Gesellschaft fur Regelungstechnik" },
3933 { 198, "Exact Logic" },
3934 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
3935 { 200, "Kandenko Co., Ltd." },
3936 { 201, "DTF, Daten-Technik Fries" },
3937 { 202, "Klimasoft, Ltd." },
3938 { 203, "Toshiba Schneider Inverter Corporation" },
3939 { 204, "Control Applications, Ltd." },
3940 { 205, "KDT Systems Co., Ltd." },
3941 { 206, "Onicon Incorporated" },
3942 { 207, "Automation Displays, Inc." },
3943 { 208, "Control Solutions, Inc." },
3944 { 209, "Remsdaq Limited" },
3945 { 210, "NTT Facilities, Inc." },
3946 { 211, "VIPA GmbH" },
3947 { 212, "TSC21 Association of Japan" },
3948 { 213, "BBP Energie Ltee" },
3949 { 214, "HRW Limited" },
3950 { 215, "Lighting Control & Design, Inc." },
3951 { 216, "Mercy Electronic and Electrical Industries" },
3952 { 217, "Samsung SDS Co., Ltd" },
3953 { 218, "Impact Facility Solutions, Inc." },
3954 { 219, "Aircuity" },
3955 { 220, "Control Techniques, Ltd." },
3956 { 221, "Evolve Control Systems, LLC" },
3957 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
3958 { 223, "Cerus Industrial" },
3959 { 224, "Chloride Power Protection Company" },
3960 { 225, "Computrols, Inc." },
3961 { 226, "Phoenix Contact GmbH & Co. KG" },
3962 { 227, "Grundfos Management A/S" },
3963 { 228, "Ridder Drive Systems" },
3964 { 229, "Soft Device SDN BHD" },
3965 { 230, "Integrated Control Technology Limited" },
3966 { 231, "AIRxpert Systems, Inc." },
3967 { 232, "Microtrol Limited" },
3968 { 233, "Red Lion Controls" },
3969 { 234, "Digital Electronics Corporation" },
3970 { 235, "Ennovatis GmbH" },
3971 { 236, "Serotonin Software Technologies, Inc." },
3972 { 237, "LS Industrial Systems Co., Ltd." },
3973 { 238, "Square D Company" },
3974 { 239, "S Squared Innovations, Inc." },
3975 { 240, "Aricent Ltd." },
3976 { 241, "EtherMetrics, LLC" },
3977 { 242, "Industrial Control Communications, Inc." },
3978 { 243, "Paragon Controls, Inc." },
3979 { 244, "A. O. Smith Corporation" },
3980 { 245, "Contemporary Control Systems, Inc." },
3981 { 246, "Intesis Software SL" },
3982 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
3983 { 248, "Heat-Timer Corporation" },
3984 { 249, "Ingrasys Technology, Inc." },
3985 { 250, "Costerm Building Automation" },
3987 { 252, "Embedia Technologies Corp." },
3988 { 253, "Technilog" },
3989 { 254, "HR Controls Ltd. & Co. KG" },
3990 { 255, "Lennox International, Inc." },
3991 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
3992 { 257, "Thermomax, Ltd." },
3993 { 258, "ELCON Electronic Control, Ltd." },
3994 { 259, "Larmia Control AB" },
3995 { 260, "BACnet Stack at SourceForge" },
3996 { 261, "G4S Security Services A/S" },
3997 { 262, "Sitek S.p.A." },
3998 { 263, "Cristal Controles" },
3999 { 264, "Regin AB" },
4000 { 265, "Dimension Software, Inc. " },
4001 { 266, "SynapSense Corporation" },
4002 { 267, "Beijing Nantree Electronic Co., Ltd." },
4003 { 268, "Camus Hydronics Ltd." },
4004 { 269, "Kawasaki Heavy Industries, Ltd. " },
4005 { 270, "Critical Environment Technologies" },
4006 { 271, "ILSHIN IBS Co., Ltd." },
4007 { 272, "ELESTA Energy Control AG" },
4008 { 273, "KROPMAN Installatietechniek" },
4009 { 274, "Baldor Electric Company" },
4010 { 275, "INGA mbH" },
4011 { 276, "GE Consumer & Industrial" },
4012 { 277, "Functional Devices, Inc." },
4014 { 279, "M-System Co., Ltd." },
4015 { 280, "Yokota Co., Ltd." },
4016 { 281, "Hitranse Technology Co., LTD" },
4017 { 282, "Federspiel Controls" },
4018 { 283, "Kele, Inc." },
4019 { 284, "Opera Electronics, Inc." },
4021 { 286, "Embedded Science Labs, LLC" },
4022 { 287, "Parker Hannifin Corporation" },
4023 { 288, "MaCaPS International Limited" },
4024 { 289, "Link4 Corporation" },
4025 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
4026 { 291, "Pribusin, Inc." },
4027 { 292, "Advantage Controls" },
4028 { 293, "Critical Room Control" },
4030 { 295, "Tongdy Control Technology Co., Ltd." },
4031 { 296, "ISSARO Integrierte Systemtechnik" },
4032 { 297, "Pro-Dev Industries" },
4033 { 298, "DRI-STEEM" },
4034 { 299, "Creative Electronic GmbH" },
4035 { 300, "Swegon AB" },
4036 { 301, "Jan Brachacek" },
4037 { 302, "Hitachi Appliances, Inc." },
4038 { 303, "Real Time Automation, Inc." },
4039 { 304, "ITEC Hankyu-Hanshin Co." },
4040 { 305, "Cyrus E&M Engineering Co., Ltd." },
4041 { 306, "Racine Federated, Inc." },
4042 { 307, "Verari Systems, Inc." },
4043 { 308, "Elesta GmbH Building Automation" },
4044 { 309, "Securiton" },
4045 { 310, "OSlsoft, Inc." },
4046 { 311, "Hanazeder Electronic GmbH" },
4047 { 312, "Honeywell Security Deutschland, Novar GmbH" },
4048 { 313, "Siemens Energy & Automation, Inc." },
4049 { 314, "ETM Professional Control GmbH" },
4050 { 315, "Meitav-tec, Ltd." },
4051 { 316, "Janitza Electronics GmbH" },
4052 { 317, "MKS Nordhausen" },
4053 { 318, "De Gier Drive Systems B.V." },
4054 { 319, "Cypress Envirosystems" },
4055 { 320, "SMARTron s.r.o." },
4056 { 321, "Verari Systems, Inc." },
4057 { 322, "K-W Electronic Service, Inc." },
4058 { 323, "ALFA-SMART Energy Management" },
4059 { 324, "Telkonet, Inc." },
4060 { 325, "Securiton GmbH" },
4061 { 326, "Cemtrex, Inc." },
4062 { 327, "Performance Technologies, Inc." },
4063 { 328, "Xtralis (Aust) Pty Ltd" },
4064 { 329, "TROX GmbH" },
4065 { 330, "Beijing Hysine Technology Co., Ltd" },
4066 { 331, "RCK Controls, Inc." },
4068 { 333, "Novar/Honeywell" },
4069 { 334, "The S4 Group, Inc." },
4070 { 335, "Schneider Electric" },
4071 { 336, "LHA Systems" },
4072 { 337, "GHM engineering Group, Inc." },
4073 { 338, "Cllimalux S.A." },
4074 { 339, "VAISALA Oyj" },
4075 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
4076 { 342, "POWERPEG NSI Limited" },
4077 { 343, "BACnet Interoperability Testing Services, Inc." },
4078 { 344, "Teco a.s." },
4079 { 345, "Plexus Technology Limited"},
4080 { 346, "Energy Focus, Inc."},
4081 { 347, "Powersmiths International Corp."},
4082 { 348, "Nichibei Co., Ltd."},
4083 { 349, "HKC Technology Ltd."},
4084 { 350, "Ovation Networks, Inc."},
4085 { 351, "Setra Systems"},
4086 { 352, "AVG Automation"},
4088 { 354, "Byte Sphere"},
4089 { 355, "Generiton Co., Ltd."},
4090 { 356, "Holter Regelarmaturen GmbH & Co. KG"},
4091 { 357, "Bedford Instruments, LLC"},
4092 { 358, "Standair Inc."},
4093 { 359, "WEG Automation - R&D"},
4094 { 360, "Prolon Control Systems ApS"},
4095 { 361, "Inneasoft"},
4096 { 362, "ConneXSoft GmbH"},
4097 { 363, "CEAG Notlichtsysteme GmbH"},
4098 { 364, "Distech Controls Inc."},
4099 { 365, "Industrial Technology Research Institute"},
4100 { 366, "ICONICS, Inc."},
4101 { 367, "IQ Controls s.c."},
4102 { 368, "OJ Electronics A/S"},
4103 { 369, "Rolbit Ltd."},
4104 { 370, "Synapsys Solutions Ltd."},
4105 { 371, "ACME Engineering Prod. Ltd."},
4106 { 372, "Zener Electric Pty, Ltd."},
4107 { 373, "Selectronix, Inc."},
4108 { 374, "Gorbet & Banerjee, LLC."},
4110 { 376, "Stephen H. Dawson Computer Service"},
4111 { 377, "Accutrol, LLC"},
4112 { 378, "Schneider Elektronik GmbH"},
4113 { 379, "Alpha-Inno Tec GmbH"},
4114 { 380, "ADMMicro, Inc."},
4115 { 381, "Greystone Energy Systems, Inc."},
4116 { 382, "CAP Technologie"},
4117 { 383, "KeRo Systems"},
4118 { 384, "Domat Control System s.r.o."},
4119 { 385, "Efektronics Pty. Ltd."},
4120 { 386, "Hekatron Vertriebs GmbH"},
4121 { 387, "Securiton AG"},
4122 { 388, "Carlo Gavazzi Controls SpA"},
4123 { 389, "Chipkin Automation Systems"},
4124 { 390, "Savant Systems, LLC"},
4125 { 391, "Simmtronic Lighting Controls"},
4126 { 392, "Abelko Innovation AB"},
4127 { 393, "Seresco Technologies Inc."},
4128 { 394, "IT Watchdogs"},
4129 { 395, "Automation Assist Japan Corp."},
4130 { 396, "Thermokon Sensortechnik GmbH"},
4131 { 397, "EGauge Systems, LLC"},
4132 { 398, "Quantum Automation (ASIA) PTE, Ltd."},
4133 { 399, "Toshiba Lighting & Technology Corp."},
4134 { 400, "SPIN Engenharia de Automaca Ltda."},
4135 { 401, "Logistics Systems & Software Services India PVT. Ltd."},
4136 { 402, "Delta Controls Integration Products"},
4137 { 403, "Focus Media"},
4138 { 404, "LUMEnergi Inc."},
4139 { 405, "Kara Systems"},
4140 { 406, "RF Code, Inc."},
4141 { 407, "Fatek Automation Corp."},
4142 { 408, "JANDA Software Company, LLC"},
4143 { 409, "Open System Solutions Limited"},
4144 { 410, "Intelec Systems PTY Ltd."},
4145 { 411, "Ecolodgix, LLC"},
4146 { 412, "Douglas Lighting Controls"},
4147 { 413, "iSAtech GmbH intelligente Sensoren Aktoren technologie"},
4149 { 415, "Beckhoff Automation GmbH"},
4150 { 416, "IPAS GmbH"},
4151 { 417, "KE2 Therm Solutions"},
4152 { 418, "Base2Products"},
4153 { 419, "DTL Controls, LLC"},
4154 { 420, "INNCOM International, Inc."},
4155 { 421, "BTR Netcom GmbH"},
4156 { 422, "Greentrol Automation, Inc"},
4157 { 423, "BELIMO Automation AG"},
4158 { 424, "Samsung Heavy Industries Co, Ltd"},
4159 { 425, "Triacta Power Technologies, Inc."},
4160 { 426, "Globestar Systems"},
4161 { 427, "MLB Advanced Media, LP"},
4162 { 428, "SWG Stuckmann Wirtschaftliche Gebaudesysteme GmbH"},
4163 { 429, "SensorSwitch"},
4164 { 430, "Multitek Power Limited"},
4165 { 431, "Aquametro AG"},
4166 { 432, "LG Electronics Inc."},
4167 { 433, "Electronic Theatre Controls, Inc."},
4168 { 434, "Mitsubishi Electric Corporation Nagoya Works"},
4169 { 435, "Delta Electronics, Inc."},
4170 { 436, "Elma Kurtalj, Ltd."},
4171 { 437, "ADT Fire and Security Sp. A.o.o."},
4172 { 438, "Nedap Security Management"},
4173 { 439, "ESC Automation Inc."},
4174 { 440, "DSP4YOU Ltd."},
4175 { 441, "GE Sensing and Inspection Technologies"},
4176 { 442, "Embedded Systems SIA"},
4177 { 443, "BEFEGA GmbH"},
4178 { 444, "Baseline Inc."},
4179 { 445, "M2M Systems Integrators"},
4181 { 447, "Clarkson Controls Limited"},
4182 { 448, "Rogerwell Control System Limited"},
4183 { 449, "SCL Elements"},
4184 { 450, "Hitachi Ltd."},
4185 { 451, "Newron System SA"},
4186 { 452, "BEVECO Gebouwautomatisering BV"},
4187 { 453, "Streamside Solutions"},
4188 { 454, "Yellowstone Soft"},
4189 { 455, "Oztech Intelligent Systems Pty Ltd."},
4190 { 456, "Novelan GmbH"},
4191 { 457, "Flexim Americas Corporation"},
4192 { 458, "ICP DAS Co., Ltd."},
4193 { 459, "CARMA Industries Inc."},
4194 { 460, "Log-One Ltd."},
4195 { 461, "TECO Electric & Machinery Co., Ltd."},
4196 { 462, "ConnectEx, Inc."},
4197 { 463, "Turbo DDC Sudwest"},
4198 { 464, "Quatrosense Environmental Ltd."},
4199 { 465, "Fifth Light Technology Ltd."},
4200 { 466, "Scientific Solutions, Ltd."},
4201 { 467, "Controller Area Network Solutions (M) Sdn Bhd"},
4202 { 468, "RESOL - Elektronische Regelungen GmbH"},
4203 { 469, "RPBUS LLC"},
4204 { 470, "BRS Sistemas Eletronicos"},
4205 { 471, "WindowMaster A/S"},
4206 { 472, "Sunlux Technologies Ltd."},
4207 { 473, "Measurlogic"},
4208 { 474, "Frimat GmbH"},
4209 { 475, "Spirax Sarco"},
4211 { 477, "Raypak Inc"},
4212 { 478, "Air Monitor Corporation"},
4213 { 479, "Regler Och Webbteknik Sverige (ROWS)"},
4214 { 480, "Intelligent Lighting Controls Inc."},
4215 { 481, "Sanyo Electric Industry Co., Ltd"},
4216 { 482, "E-Mon Energy Monitoring Products"},
4217 { 483, "Digital Control Systems"},
4218 { 484, "ATI Airtest Technologies, Inc."},
4220 { 486, "HMS Industrial Networks AB"},
4221 { 487, "Shenzhen Universal Intellisys Co Ltd"},
4222 { 488, "EK Intellisys Sdn Bhd"},
4224 { 490, "Firecom, Inc."},
4225 { 491, "ESA Elektroschaltanlagen Grimma GmbH"},
4226 { 492, "Kumahira Co Ltd"},
4228 { 494, "SABO Elektronik GmbH"},
4229 { 495, "Equip'Trans"},
4230 { 496, "TCS Basys Controls"},
4231 { 497, "FlowCon International A/S"},
4232 { 498, "ThyssenKrupp Elevator Americas"},
4233 { 499, "Abatement Technologies"},
4234 { 500, "Continental Control Systems, LLC"},
4235 { 501, "WISAG Automatisierungstechnik GmbH & Co KG"},
4237 { 503, "EAP-Electric GmbH"},
4238 { 504, "Hardmeier"},
4239 { 505, "Mircom Group of Companies"},
4240 { 506, "Quest Controls"},
4241 { 507, "Mestek, Inc"},
4242 { 508, "Pulse Energy"},
4243 { 509, "Tachikawa Corporation"},
4244 { 510, "University of Nebraska-Lincoln"},
4245 { 511, "Redwood Systems"},
4246 { 512, "PASStec Industrie-Elektronik GmbH"},
4247 { 513, "NgEK, Inc."},
4248 { 514, "FAW Electronics Ltd"},
4249 { 515, "Jireh Energy Tech Co., Ltd."},
4250 { 516, "Enlighted Inc."},
4251 { 517, "El-Piast Sp. Z o.o"},
4252 { 518, "NetxAutomation Software GmbH"},
4253 { 519, "Invertek Drives"},
4254 { 520, "Deutschmann Automation GmbH & Co. KG"},
4255 { 521, "EMU Electronic AG"},
4256 { 522, "Phaedrus Limited"},
4257 { 523, "Sigmatek GmbH & Co KG"},
4258 { 524, "Marlin Controls"},
4259 { 525, "Circutor, SA"},
4260 { 526, "UTC Fire & Security"},
4261 { 527, "DENT Instruments, Inc."},
4262 { 528, "FHP Manufacturing Company - Bosch Group"},
4263 { 529, "GE Intelligent Platforms"},
4264 { 530, "Inner Range Pty Ltd"},
4265 { 531, "GLAS Energy Technology"},
4266 { 532, "MSR-Electronic-GmbH"},
4270 static int proto_bacapp = -1;
4271 static int hf_bacapp_type = -1;
4272 static int hf_bacapp_pduflags = -1;
4273 static int hf_bacapp_SEG = -1;
4274 static int hf_bacapp_MOR = -1;
4275 static int hf_bacapp_SA = -1;
4276 static int hf_bacapp_response_segments = -1;
4277 static int hf_bacapp_max_adpu_size = -1;
4278 static int hf_bacapp_invoke_id = -1;
4279 static int hf_bacapp_objectType = -1;
4280 static int hf_bacapp_instanceNumber = -1;
4281 static int hf_bacapp_sequence_number = -1;
4282 static int hf_bacapp_window_size = -1;
4283 static int hf_bacapp_service = -1;
4284 static int hf_bacapp_NAK = -1;
4285 static int hf_bacapp_SRV = -1;
4286 static int hf_Device_Instance_Range_Low_Limit = -1;
4287 static int hf_Device_Instance_Range_High_Limit = -1;
4288 static int hf_BACnetRejectReason = -1;
4289 static int hf_BACnetAbortReason = -1;
4290 static int hf_BACnetApplicationTagNumber = -1;
4291 static int hf_BACnetContextTagNumber = -1;
4292 static int hf_BACnetExtendedTagNumber = -1;
4293 static int hf_BACnetNamedTag = -1;
4294 static int hf_BACnetTagClass = -1;
4295 static int hf_BACnetCharacterSet = -1;
4296 static int hf_bacapp_tag_lvt = -1;
4297 static int hf_bacapp_tag_ProcessId = -1;
4298 static int hf_bacapp_uservice = -1;
4299 static int hf_BACnetPropertyIdentifier = -1;
4300 static int hf_BACnetVendorIdentifier = -1;
4301 static int hf_BACnetRestartReason = -1;
4302 static int hf_bacapp_tag_IPV4 = -1;
4303 static int hf_bacapp_tag_IPV6 = -1;
4304 static int hf_bacapp_tag_PORT = -1;
4305 /* some more variables for segmented messages */
4306 static int hf_msg_fragments = -1;
4307 static int hf_msg_fragment = -1;
4308 static int hf_msg_fragment_overlap = -1;
4309 static int hf_msg_fragment_overlap_conflicts = -1;
4310 static int hf_msg_fragment_multiple_tails = -1;
4311 static int hf_msg_fragment_too_long_fragment = -1;
4312 static int hf_msg_fragment_error = -1;
4313 static int hf_msg_fragment_count = -1;
4314 static int hf_msg_reassembled_in = -1;
4315 static int hf_msg_reassembled_length = -1;
4317 static gint ett_msg_fragment = -1;
4318 static gint ett_msg_fragments = -1;
4320 static gint ett_bacapp = -1;
4321 static gint ett_bacapp_control = -1;
4322 static gint ett_bacapp_tag = -1;
4323 static gint ett_bacapp_list = -1;
4324 static gint ett_bacapp_value = -1;
4326 static dissector_handle_t data_handle;
4327 static gint32 propertyIdentifier = -1;
4328 static gint32 propertyArrayIndex = -1;
4329 static guint32 object_type = 4096;
4331 static guint8 bacapp_flags = 0;
4332 static guint8 bacapp_seq = 0;
4334 /* Defined to allow vendor identifier registration of private transfer dissectors */
4335 static dissector_table_t bacapp_dissector_table;
4338 /* Stat: BACnet Packets sorted by IP */
4339 bacapp_info_value_t bacinfo;
4341 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
4342 static const gchar* st_str_packets_by_ip_dst = "By Destination";
4343 static const gchar* st_str_packets_by_ip_src = "By Source";
4344 static int st_node_packets_by_ip = -1;
4345 static int st_node_packets_by_ip_dst = -1;
4346 static int st_node_packets_by_ip_src = -1;
4349 bacapp_packet_stats_tree_init(stats_tree* st)
4351 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4352 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4353 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4357 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4359 int packets_for_this_dst;
4360 int packets_for_this_src;
4361 int service_for_this_dst;
4362 int service_for_this_src;
4363 int src_for_this_dst;
4364 int dst_for_this_src;
4365 int objectid_for_this_dst;
4366 int objectid_for_this_src;
4367 int instanceid_for_this_dst;
4368 int instanceid_for_this_src;
4371 const bacapp_info_value_t *binfo = p;
4373 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4374 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4376 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4377 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4378 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4379 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4380 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4381 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4382 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4383 if (binfo->service_type) {
4384 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4385 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4386 if (binfo->object_ident) {
4387 instanceid_for_this_dst=tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4388 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4389 instanceid_for_this_src=tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4390 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4397 /* Stat: BACnet Packets sorted by Service */
4398 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4399 static int st_node_packets_by_service = -1;
4402 bacapp_service_stats_tree_init(stats_tree* st)
4404 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4408 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4416 const bacapp_info_value_t *binfo = p;
4418 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4419 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4421 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4422 if (binfo->service_type) {
4423 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4424 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4425 dst = tick_stat_node(st, dststr, src, TRUE);
4426 if (binfo->object_ident) {
4427 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4428 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4435 /* Stat: BACnet Packets sorted by Object Type */
4436 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
4437 static int st_node_packets_by_objectid = -1;
4440 bacapp_objectid_stats_tree_init(stats_tree* st)
4442 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
4446 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4454 const bacapp_info_value_t *binfo = p;
4456 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4457 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4459 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
4460 if (binfo->object_ident) {
4461 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
4462 src = tick_stat_node(st, srcstr, objectid, TRUE);
4463 dst = tick_stat_node(st, dststr, src, TRUE);
4464 if (binfo->service_type) {
4465 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4466 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
4473 /* Stat: BACnet Packets sorted by Instance No */
4474 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
4475 static int st_node_packets_by_instanceid = -1;
4478 bacapp_instanceid_stats_tree_init(stats_tree* st)
4480 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
4484 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4492 const bacapp_info_value_t *binfo = p;
4494 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4495 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4497 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
4498 if (binfo->object_ident) {
4499 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
4500 src = tick_stat_node(st, srcstr, instanceid, TRUE);
4501 dst = tick_stat_node(st, dststr, src, TRUE);
4502 if (binfo->service_type) {
4503 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4504 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
4511 /* register all BACnet Ststistic trees */
4513 register_bacapp_stat_trees(void)
4515 stats_tree_register("bacapp","bacapp_ip","BACnet/Packets sorted by IP", 0,
4516 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
4517 stats_tree_register("bacapp","bacapp_service","BACnet/Packets sorted by Service", 0,
4518 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
4519 stats_tree_register("bacapp","bacapp_objectid","BACnet/Packets sorted by Object Type", 0,
4520 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
4521 stats_tree_register("bacapp","bacapp_instanceid","BACnet/Packets sorted by Instance ID", 0,
4522 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
4525 /* 'data' must be ep_ allocated */
4527 updateBacnetInfoValue(gint whichval, gchar *data)
4529 if (whichval == BACINFO_SERVICE) {
4530 bacinfo.service_type = data;
4533 if (whichval == BACINFO_INVOKEID) {
4534 bacinfo.invoke_id = data;
4537 if (whichval == BACINFO_OBJECTID) {
4538 bacinfo.object_ident = data;
4541 if (whichval == BACINFO_INSTANCEID) {
4542 bacinfo.instance_ident = data;
4548 static const fragment_items msg_frag_items = {
4549 /* Fragment subtrees */
4552 /* Fragment fields */
4555 &hf_msg_fragment_overlap,
4556 &hf_msg_fragment_overlap_conflicts,
4557 &hf_msg_fragment_multiple_tails,
4558 &hf_msg_fragment_too_long_fragment,
4559 &hf_msg_fragment_error,
4560 &hf_msg_fragment_count,
4561 /* Reassembled in field */
4562 &hf_msg_reassembled_in,
4563 /* Reassembled length field */
4564 &hf_msg_reassembled_length,
4569 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
4570 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
4573 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
4575 fGetMaxAPDUSize(guint8 idx)
4577 /* only 16 values are defined, so use & 0x0f */
4578 /* check the size of the Array, deliver either the entry
4579 or the first entry if idx is outside of the array (bug 3736 comment#7) */
4581 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
4582 return MaxAPDUSize[0];
4584 return MaxAPDUSize[idx & 0x0f];
4589 /* Used when there are ranges of reserved and proprietary enumerations */
4591 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
4592 const char *fmt, const char *split_fmt)
4594 if (val < split_val)
4595 return val_to_str(val, vs, fmt);
4597 return val_to_str(val, vs, split_fmt);
4600 /* from clause 20.2.1.3.2 Constructed Data */
4601 /* returns true if the extended value is used */
4603 tag_is_extended_value(guint8 tag)
4605 return (tag & 0x07) == 5;
4609 tag_is_opening(guint8 tag)
4611 return (tag & 0x07) == 6;
4615 tag_is_closing(guint8 tag)
4617 return (tag & 0x07) == 7;
4620 /* from clause 20.2.1.1 Class
4621 class bit shall be one for context specific tags */
4622 /* returns true if the tag is context specific */
4624 tag_is_context_specific(guint8 tag)
4626 return (tag & 0x08) != 0;
4630 tag_is_extended_tag_number(guint8 tag)
4632 return ((tag & 0xF0) == 0xF0);
4636 object_id_type(guint32 object_identifier)
4638 return ((object_identifier >> 22) & 0x3FF);
4642 object_id_instance(guint32 object_identifier)
4644 return (object_identifier & 0x3FFFFF);
4648 fTagNo (tvbuff_t *tvb, guint offset)
4650 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
4654 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
4656 gboolean valid = TRUE;
4660 *val = tvb_get_guint8(tvb, offset);
4663 *val = tvb_get_ntohs(tvb, offset);
4666 *val = tvb_get_ntoh24(tvb, offset);
4669 *val = tvb_get_ntohl(tvb, offset);
4680 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4682 gboolean valid = FALSE;
4686 if (lvt && (lvt <= 8)) {
4688 data = tvb_get_guint8(tvb, offset);
4689 for (i = 0; i < lvt; i++) {
4690 data = tvb_get_guint8(tvb, offset+i);
4691 value = (value << 8) + data;
4699 /* BACnet Signed Value uses 2's complement notation, but with a twist:
4700 All signed integers shall be encoded in the smallest number of octets
4701 possible. That is, the first octet of any multi-octet encoded value
4702 shall not be X'00' if the most significant bit (bit 7) of the second
4703 octet is 0, and the first octet shall not be X'FF' if the most
4704 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4706 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4708 gboolean valid = FALSE;
4713 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4714 if (lvt && (lvt <= 7)) {
4716 data = tvb_get_guint8(tvb, offset);
4717 if ((data & 0x80) != 0)
4718 value = (-1 << 8) | data;
4721 for (i = 1; i < lvt; i++) {
4722 data = tvb_get_guint8(tvb, offset+i);
4723 value = (value << 8) + data;
4732 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
4733 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4738 guint lvt_len = 1; /* used for tree display of lvt */
4739 guint lvt_offset; /* used for tree display of lvt */
4741 proto_tree *subtree;
4743 lvt_offset = offset;
4744 tag = tvb_get_guint8(tvb, offset);
4747 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4748 /* can mean open/close tag or length of 6/7 after the length is */
4749 /* computed below - store whole tag info, not just context bit. */
4750 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4752 if (tag_is_extended_tag_number(tag)) {
4753 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4755 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4756 lvt_offset += tag_len;
4757 value = tvb_get_guint8(tvb, lvt_offset);
4759 if (value == 254) { /* length is encoded with 16 Bits */
4760 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4763 } else if (value == 255) { /* length is encoded with 32 Bits */
4764 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4772 if (tag_is_opening(tag))
4773 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4774 else if (tag_is_closing(tag))
4775 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4776 else if (tag_is_context_specific(tag)) {
4777 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4778 "Context Tag: %u, Length/Value/Type: %u",
4781 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4782 "Application Tag: %s, Length/Value/Type: %u",
4784 BACnetApplicationTagNumber,
4785 ASHRAE_Reserved_Fmt),
4788 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4789 /* details if needed */
4790 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, FALSE);
4791 if (tag_is_extended_tag_number(tag)) {
4792 proto_tree_add_uint_format(subtree,
4793 hf_BACnetContextTagNumber,
4794 tvb, offset, 1, tag,
4795 "Extended Tag Number");
4796 proto_tree_add_item(subtree,
4797 hf_BACnetExtendedTagNumber,
4798 tvb, offset + 1, 1, FALSE);
4800 if (tag_is_context_specific(tag))
4801 proto_tree_add_item(subtree,
4802 hf_BACnetContextTagNumber,
4803 tvb, offset, 1, FALSE);
4805 proto_tree_add_item(subtree,
4806 hf_BACnetApplicationTagNumber,
4807 tvb, offset, 1, FALSE);
4809 if (tag_is_closing(tag) || tag_is_opening(tag))
4810 proto_tree_add_item(subtree,
4812 tvb, offset, 1, FALSE);
4813 else if (tag_is_extended_value(tag)) {
4814 proto_tree_add_item(subtree,
4816 tvb, offset, 1, FALSE);
4817 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4818 tvb, lvt_offset, lvt_len, *lvt);
4820 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4821 tvb, lvt_offset, lvt_len, *lvt);
4828 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
4831 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
4835 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4837 guint8 tag_no, tag_info;
4840 proto_tree *subtree;
4842 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4843 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4844 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4850 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4852 guint8 tag_no, tag_info;
4855 proto_tree *subtree;
4858 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4859 if (tag_info && lvt == 1) {
4860 lvt = tvb_get_guint8(tvb, offset+1);
4864 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
4865 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
4866 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4867 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4869 return offset + bool_len;
4873 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4876 guint8 tag_no, tag_info;
4880 proto_tree *subtree;
4882 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4883 /* only support up to an 8 byte (64-bit) integer */
4884 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
4885 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4886 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
4888 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4889 "%s - %u octets (Unsigned)", label, lvt);
4890 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4891 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4893 return offset+tag_len+lvt;
4897 fDevice_Instance (tvbuff_t *tvb, proto_tree *tree, guint offset, int hf)
4899 guint8 tag_no, tag_info;
4903 proto_tree *subtree;
4905 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4906 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, lvt, ENC_BIG_ENDIAN);
4907 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4908 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4910 return offset+tag_len+lvt;
4913 /* set split_val to zero when not needed */
4915 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4916 const value_string *vs, guint32 split_val)
4919 guint8 tag_no, tag_info;
4923 proto_tree *subtree;
4925 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4926 /* only support up to a 4 byte (32-bit) enumeration */
4927 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
4929 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4930 "%s %s", label, val_to_split_str(val, split_val, vs,
4931 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
4933 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4934 "%s %u", label, val);
4936 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4937 "%s - %u octets (enumeration)", label, lvt);
4939 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4940 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4942 return offset+tag_len+lvt;
4946 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4947 const value_string *vs)
4949 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
4953 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4956 guint8 tag_no, tag_info;
4960 proto_tree *subtree;
4962 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4963 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
4964 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4965 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
4967 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4968 "%s - %u octets (Signed)", label, lvt);
4969 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4970 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4972 return offset+tag_len+lvt;
4976 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4978 guint8 tag_no, tag_info;
4983 proto_tree *subtree;
4985 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4986 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
4987 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
4988 "%s%f (Real)", label, f_val);
4989 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4990 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4992 return offset+tag_len+4;
4996 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4998 guint8 tag_no, tag_info;
5003 proto_tree *subtree;
5005 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5006 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
5007 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
5008 "%s%f (Double)", label, d_val);
5009 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5010 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5012 return offset+tag_len+8;
5016 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
5018 guint32 val = 0, lvt;
5019 guint8 tag_no, tag_info;
5021 proto_tree *subtree;
5024 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5025 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5026 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
5027 tvb, offset, lvt+tag_len, val);
5029 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5030 "Process Identifier - %u octets (Signed)", lvt);
5031 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5032 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5033 offset += tag_len + lvt;
5039 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5041 guint32 val = 0, lvt;
5042 guint8 tag_no, tag_info;
5044 proto_tree *subtree;
5047 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5048 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5049 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5050 "%s (hh.mm.ss): %d.%02d.%02d%s",
5052 (val / 3600), ((val % 3600) / 60), (val % 60),
5053 val == 0 ? " (indefinite)" : "");
5055 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5056 "%s - %u octets (Signed)", label, lvt);
5057 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5058 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5060 return offset+tag_len+lvt;
5064 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
5066 guint32 month, weekOfMonth, dayOfWeek;
5067 guint8 tag_no, tag_info;
5071 proto_tree *subtree;
5073 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5074 month = tvb_get_guint8(tvb, offset+tag_len);
5075 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
5076 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
5077 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
5078 val_to_str(month, months, "month (%d) not found"),
5079 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
5080 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
5081 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5082 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5084 return offset+tag_len+lvt;
5088 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5090 guint32 year, month, day, weekday;
5091 guint8 tag_no, tag_info;
5095 proto_tree *subtree;
5097 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5098 year = tvb_get_guint8(tvb, offset+tag_len);
5099 month = tvb_get_guint8(tvb, offset+tag_len+1);
5100 day = tvb_get_guint8(tvb, offset+tag_len+2);
5101 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
5102 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
5103 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5106 else if (year != 255) {
5108 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5109 "%s%s %d, %d, (Day of Week = %s)",
5110 label, val_to_str(month,
5112 "month (%d) not found"),
5113 day, year, val_to_str(weekday,
5117 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5118 "%s%s %d, any year, (Day of Week = %s)",
5119 label, val_to_str(month, months, "month (%d) not found"),
5120 day, val_to_str(weekday, day_of_week, "(%d) not found"));
5122 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5123 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5125 return offset+tag_len+lvt;
5129 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5131 guint32 hour, minute, second, msec, lvt;
5132 guint8 tag_no, tag_info;
5135 proto_tree *subtree;
5137 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5138 hour = tvb_get_guint8(tvb, offset+tag_len);
5139 minute = tvb_get_guint8(tvb, offset+tag_len+1);
5140 second = tvb_get_guint8(tvb, offset+tag_len+2);
5141 msec = tvb_get_guint8(tvb, offset+tag_len+3);
5142 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
5143 ti = proto_tree_add_text(tree, tvb, offset,
5144 lvt+tag_len, "%sany", label);
5146 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5147 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
5149 hour > 12 ? hour - 12 : hour,
5150 minute, second, msec,
5151 hour >= 12 ? "P.M." : "A.M.",
5152 hour, minute, second, msec);
5153 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5154 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5156 return offset+tag_len+lvt;
5160 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5162 proto_tree *subtree = tree;
5165 if (label != NULL) {
5166 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
5167 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5169 offset = fDate (tvb,subtree,offset,"Date: ");
5170 return fTime (tvb,subtree,offset,"Time: ");
5174 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5176 guint lastoffset = 0;
5177 guint8 tag_no, tag_info;
5180 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5181 lastoffset = offset;
5182 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5183 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
5186 offset = fTime (tvb,tree,offset,"Time: ");
5187 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
5189 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
5195 fCalendarEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
5197 guint8 tag_no, tag_info;
5200 switch (fTagNo(tvb, offset)) {
5202 offset = fDate (tvb, tree, offset, "Date: ");
5204 case 1: /* dateRange */
5205 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5206 offset = fDateRange (tvb, tree, offset);
5207 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5209 case 2: /* BACnetWeekNDay */
5210 offset = fWeekNDay (tvb, tree, offset);
5220 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5222 guint8 tag_no = 0, tag_info = 0;
5225 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
5226 switch (fTagNo(tvb, offset)) {
5228 offset = fTime (tvb, tree, offset, label?label:"timestamp: ");
5230 case 1: /* sequenceNumber */
5231 offset = fUnsignedTag (tvb, tree, offset,
5232 label?label:"sequence Number: ");
5234 case 2: /* dateTime */
5235 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5236 offset = fDateTime (tvb, tree, offset, label?label:"timestamp: ");
5237 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5249 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5251 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5252 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
5257 static const value_string
5258 BACnetDaysOfWeek [] = {
5270 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5272 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5273 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
5274 "valid Days: ", BACnetDaysOfWeek);
5275 offset = fTime (tvb,tree,offset,"from time: ");
5276 offset = fTime (tvb,tree,offset,"to time: ");
5277 offset = fRecipient (tvb,pinfo,tree,offset);
5278 offset = fProcessId (tvb,tree,offset);
5279 offset = fApplicationTypes (tvb,pinfo,tree,offset,
5280 "issue confirmed notifications: ");
5281 offset = fBitStringTagVS (tvb,tree,offset,
5282 "transitions: ", BACnetEventTransitionBits);
5289 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5292 guint start = offset;
5293 guint8 tag_no, tag_info;
5294 proto_tree* subtree = tree;
5297 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5300 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5301 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
5306 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5308 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5314 fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5317 guint start = offset;
5318 guint8 tag_no, tag_info;
5319 proto_tree* subtree = tree;
5322 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5324 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
5327 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
5329 guint32 ip = tvb_get_ipv4(tvb, offset);
5330 guint16 port = tvb_get_ntohs(tvb, offset+4);
5332 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
5333 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
5336 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
5337 struct e_in6_addr addr;
5338 guint16 port = tvb_get_ntohs(tvb, offset+16);
5339 tvb_get_ipv6(tvb, offset, &addr);
5341 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
5342 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
5344 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
5345 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5346 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
5353 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5355 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5361 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
5363 guint8 tag_no, tag_info;
5367 offset = fUnsignedTag (tvb, tree, offset, "network-number");
5368 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5370 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5373 offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
5379 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
5381 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
5382 return fAddress (tvb,tree,offset);
5386 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5388 guint8 tag_no, tag_info;
5392 proto_tree *subtree;
5395 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5396 object_id = tvb_get_ntohl(tvb,offset+tag_length);
5397 object_type = object_id_type(object_id);
5398 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
5399 "ObjectIdentifier: %s, %u",
5400 val_to_split_str(object_type,
5403 ASHRAE_Reserved_Fmt,
5404 Vendor_Proprietary_Fmt),
5405 object_id_instance(object_id));
5406 if (col_get_writable(pinfo->cinfo))
5407 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5408 val_to_split_str(object_type,
5411 ASHRAE_Reserved_Fmt,
5412 Vendor_Proprietary_Fmt),
5413 object_id_instance(object_id));
5415 /* update BACnet Statistics */
5416 updateBacnetInfoValue(BACINFO_OBJECTID,
5417 ep_strdup(val_to_split_str(object_type, 128,
5418 BACnetObjectType, ASHRAE_Reserved_Fmt,
5419 Vendor_Proprietary_Fmt)));
5420 updateBacnetInfoValue(BACINFO_INSTANCEID, ep_strdup_printf("Instance ID: %u",
5421 object_id_instance(object_id)));
5423 /* here are the details of how we arrived at the above text */
5424 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5425 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5426 offset += tag_length;
5427 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, FALSE);
5428 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, FALSE);
5435 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5437 guint8 tag_no, tag_info;
5440 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5442 if (tag_no == 0) { /* device */
5443 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5445 else { /* address */
5446 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5447 offset = fAddress (tvb, tree, offset);
5448 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5455 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5457 guint lastoffset = 0;
5458 guint8 tag_no, tag_info;
5460 proto_tree* orgtree = tree;
5462 proto_tree* subtree;
5464 /* beginning of new item - indent and label */
5465 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
5466 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5468 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5469 lastoffset = offset;
5471 switch (fTagNo(tvb, offset)) {
5472 case 0: /* recipient */
5473 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5474 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5475 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5476 offset = fRecipient (tvb, pinfo, subtree, offset);
5477 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5479 case 1: /* processId */
5480 offset = fProcessId (tvb, tree, offset);
5481 lastoffset = offset;
5486 if (offset == lastoffset) break; /* nothing happened, exit loop */
5492 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5494 guint lastoffset = 0;
5495 guint8 tag_no, tag_info;
5497 proto_tree* subtree;
5499 proto_tree* orgtree = tree;
5502 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5503 lastoffset = offset;
5504 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5505 if (tag_is_closing(tag_info) ) {
5510 case 0: /* recipient */
5511 /* beginning of new item in list */
5512 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
5513 itemno = itemno + 1;
5514 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5516 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5517 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5518 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5519 offset = fRecipientProcess (tvb, pinfo, subtree, offset);
5520 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5521 subtree = tree; /* done with this level - return to previous tree */
5523 case 1: /* MonitoredPropertyReference */
5524 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
5525 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5526 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5527 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
5528 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5531 case 2: /* IssueConfirmedNotifications - boolean */
5532 offset = fBooleanTag (tvb, tree, offset, "Issue Confirmed Notifications: ");
5534 case 3: /* TimeRemaining */
5535 offset = fUnsignedTag (tvb, tree, offset, "Time Remaining: ");
5537 case 4: /* COVIncrement */
5538 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5543 if (offset == lastoffset) break; /* nothing happened, exit loop */
5549 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5551 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5552 return fAddress (tvb, tree, offset);
5556 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
5558 guint lastoffset = 0, len;
5559 guint8 tag_no, tag_info;
5561 proto_tree *subtree = tree;
5563 /* set the optional global properties to indicate not-used */
5564 propertyArrayIndex = -1;
5565 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5566 lastoffset = offset;
5567 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5568 if (tag_is_closing(tag_info) ) {
5569 if (tag_no == tag_match) {
5578 case 0: /* deviceIdentifier */
5579 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5581 case 1: /* objectIdentifier */
5582 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5584 case 2: /* propertyIdentifier */
5585 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
5587 case 3: /* propertyArrayIndex */
5588 offset = fPropertyArrayIndex (tvb, subtree, offset);
5590 case 4: /* propertyValue */
5591 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
5593 case 5: /* priority */
5594 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
5596 case 6: /* postDelay */
5597 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
5599 case 7: /* quitOnFailure */
5600 offset = fBooleanTag(tvb, subtree, offset,
5601 "Quit On Failure: ");
5603 case 8: /* writeSuccessful */
5604 offset = fBooleanTag(tvb, subtree, offset,
5605 "Write Successful: ");
5610 if (offset == lastoffset) break; /* nothing happened, exit loop */
5615 /* BACnetActionList ::= SEQUENCE{
5616 action [0] SEQUENCE OF BACnetActionCommand
5620 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5622 guint lastoffset = 0, len;
5623 guint8 tag_no, tag_info;
5625 proto_tree *subtree = tree;
5628 while (tvb_reported_length_remaining(tvb, offset)) {
5629 lastoffset = offset;
5630 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5631 if (tag_is_closing(tag_info)) {
5636 if (tag_is_opening(tag_info)) {
5637 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
5638 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5639 offset += fTagHeaderTree (tvb, subtree, offset,
5640 &tag_no, &tag_info, &lvt);
5643 case 0: /* BACnetActionCommand */
5644 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
5649 if (offset == lastoffset) break; /* nothing happened, exit loop */
5655 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5657 guint8 tag_no, tag_info;
5661 proto_tree *subtree;
5662 const gchar *label = "Property Identifier";
5664 propertyIdentifier = 0; /* global Variable */
5665 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5666 /* can we decode this value? */
5667 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
5668 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5669 "%s: %s (%u)", label,
5670 val_to_split_str(propertyIdentifier, 512,
5671 BACnetPropertyIdentifier,
5672 ASHRAE_Reserved_Fmt,
5673 Vendor_Proprietary_Fmt), propertyIdentifier);
5674 if (col_get_writable(pinfo->cinfo))
5675 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
5676 val_to_split_str(propertyIdentifier, 512,
5677 BACnetPropertyIdentifier,
5678 ASHRAE_Reserved_Fmt,
5679 Vendor_Proprietary_Fmt));
5681 /* property identifiers cannot be larger than 22-bits */
5684 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5685 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5686 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
5687 offset+tag_len, lvt, FALSE);
5689 return offset+tag_len+lvt;
5693 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
5695 guint8 tag_no, tag_info;
5699 proto_tree *subtree;
5701 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5702 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
5703 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5704 "property Array Index (Unsigned) %u", propertyArrayIndex);
5706 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5707 "property Array Index - %u octets (Unsigned)", lvt);
5708 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5709 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5711 return offset+tag_len+lvt;
5715 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5717 guint8 tag_no, tag_info, character_set;
5719 gsize inbytesleft, outbytesleft = 512;
5720 guint offs, extra = 1;
5723 guint8 bf_arr[512], *out = &bf_arr[0];
5725 proto_tree *subtree;
5726 guint start = offset;
5728 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5730 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5732 character_set = tvb_get_guint8(tvb, offset+offs);
5733 /* Account for code page if DBCS */
5734 if (character_set == 1) {
5737 offset += (offs+extra);
5741 inbytesleft = l = MIN(lvt, 255);
5743 * XXX - are we guaranteed that these encoding
5744 * names correspond, on *all* platforms with
5745 * iconv(), to the encodings we want?
5746 * If not (and perhaps even if so), we should
5747 * perhaps have our own iconv() implementation,
5748 * with a different name, so that we control the
5749 * encodings it supports and the names of those
5752 * We should also handle that in the general
5753 * string handling code, rather than making it
5754 * specific to the BACAPP dissector, as many
5755 * other dissectors need to handle various
5756 * character encodings.
5758 str_val = tvb_get_ephemeral_string(tvb, offset, l);
5759 /** this decoding may be not correct for multi-byte characters, Lka */
5760 switch (character_set) {
5762 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UTF-8");
5767 coding = "IBM MS DBCS";
5771 coding = "JIS C 6226";
5773 case ISO_10646_UCS4:
5774 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5775 coding = "ISO 10646 UCS-4";
5777 case ISO_10646_UCS2:
5778 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5779 coding = "ISO 10646 UCS-2";
5782 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5783 coding = "ISO 8859-1";
5790 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s '%s'", label, coding, out);
5795 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5797 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
5798 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, FALSE);
5800 if (character_set == 1) {
5801 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5803 /* XXX - put the string value here */
5809 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5810 const value_string *src)
5812 guint8 tag_no, tag_info, tmp;
5813 gint j, unused, skip;
5814 guint start = offset;
5816 guint32 lvt, i, numberOfBytes;
5818 proto_tree* subtree = tree;
5821 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5822 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
5824 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
5825 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
5829 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5831 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5832 proto_tree_add_text(subtree, tvb, offset, 1,
5836 for (i = 0; i < numberOfBytes; i++) {
5837 tmp = tvb_get_guint8(tvb, (offset)+i+1);
5838 if (i == numberOfBytes-1) { skip = unused; }
5839 for (j = 0; j < 8-skip; j++) {
5841 if (tmp & (1 << (7 - j)))
5842 proto_tree_add_text(subtree, tvb,
5845 val_to_str((guint) (i*8 +j),
5847 ASHRAE_Reserved_Fmt));
5849 proto_tree_add_text(subtree, tvb,
5852 val_to_str((guint) (i*8 +j),
5854 ASHRAE_Reserved_Fmt));
5856 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
5862 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
5863 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
5872 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5874 return fBitStringTagVS (tvb, tree, offset, label, NULL);
5877 /* handles generic application types, as well as enumerated and enumerations
5878 with reserved and proprietarty ranges (split) */
5880 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5881 const gchar *label, const value_string *src, guint32 split_val)
5883 guint8 tag_no, tag_info;
5887 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5889 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5890 if (!tag_is_context_specific(tag_info)) {
5892 case 0: /** NULL 20.2.2 */
5893 offset = fNullTag(tvb, tree, offset, label);
5895 case 1: /** BOOLEAN 20.2.3 */
5896 offset = fBooleanTag(tvb, tree, offset, label);
5898 case 2: /** Unsigned Integer 20.2.4 */
5899 offset = fUnsignedTag(tvb, tree, offset, label);
5901 case 3: /** Signed Integer 20.2.5 */
5902 offset = fSignedTag(tvb, tree, offset, label);
5904 case 4: /** Real 20.2.6 */
5905 offset = fRealTag(tvb, tree, offset, label);
5907 case 5: /** Double 20.2.7 */
5908 offset = fDoubleTag(tvb, tree, offset, label);
5910 case 6: /** Octet String 20.2.8 */
5911 offset = fOctetString (tvb, tree, offset, label, lvt);
5913 case 7: /** Character String 20.2.9 */
5914 offset = fCharacterString (tvb,tree,offset,label);
5916 case 8: /** Bit String 20.2.10 */
5917 offset = fBitStringTagVS (tvb, tree, offset, label, src);
5919 case 9: /** Enumerated 20.2.11 */
5920 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
5922 case 10: /** Date 20.2.12 */
5923 offset = fDate (tvb, tree, offset, label);
5925 case 11: /** Time 20.2.13 */
5926 offset = fTime (tvb, tree, offset, label);
5928 case 12: /** BACnetObjectIdentifier 20.2.14 */
5929 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5931 case 13: /* reserved for ASHRAE */
5934 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
5935 offset+=lvt+tag_len;
5947 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
5949 guint lastoffset = 0;
5951 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5952 lastoffset = offset;
5954 switch (fTagNo(tvb,offset)) {
5955 case 0: /* percent */
5956 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
5959 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
5961 case 2: /* amount */
5962 offset = fRealTag(tvb, tree, offset, "shed amount: ");
5967 if (offset == lastoffset) break; /* nothing happened, exit loop */
5973 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5974 const gchar *label, const value_string *vs)
5976 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
5980 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5983 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
5987 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5989 guint8 tag_no, tag_info;
5993 proto_tree *subtree;
5997 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5998 /* cap the the suggested length in case of bad data */
5999 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
6000 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
6003 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
6004 "Context Value (as %u DATA octets)", lvt);
6006 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6007 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6009 return offset + tag_len + lvt;
6013 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6015 guint8 tag_no, tag_info;
6017 guint lastoffset = 0, depth = 0;
6020 if (propertyIdentifier >= 0) {
6021 g_snprintf (ar, sizeof(ar), "%s: ",
6022 val_to_split_str(propertyIdentifier, 512,
6023 BACnetPropertyIdentifier,
6024 ASHRAE_Reserved_Fmt,
6025 Vendor_Proprietary_Fmt));
6027 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
6029 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6030 lastoffset = offset;
6031 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6032 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
6033 if (depth <= 0) return offset;
6036 /* Application Tags */
6037 switch (propertyIdentifier) {
6038 case 2: /* action */
6039 /* loop object is application tagged,
6040 command object is context tagged */
6041 if (tag_is_context_specific(tag_info)) {
6042 /* BACnetActionList */
6043 offset = fActionList (tvb, pinfo, tree,offset);
6046 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6050 case 30: /* BACnetAddressBinding */
6051 offset = fAddressBinding (tvb,pinfo,tree,offset);
6053 case 54: /* list of object property reference */
6054 offset = fLOPR (tvb, pinfo, tree,offset);
6056 case 55: /* list-of-session-keys */
6057 fSessionKey (tvb, tree, offset);
6059 case 79: /* object-type */
6060 case 96: /* protocol-object-types-supported */
6061 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
6062 BACnetObjectType, 128);
6064 case 97: /* Protocol-Services-Supported */
6065 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6066 BACnetServicesSupported);
6068 case 102: /* recipient-list */
6069 offset = fDestination (tvb, pinfo, tree, offset);
6071 case 107: /* segmentation-supported */
6072 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6073 BACnetSegmentation);
6075 case 111: /* Status-Flags */
6076 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6079 case 112: /* System-Status */
6080 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6081 BACnetDeviceStatus);
6083 case 117: /* units */
6084 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6085 BACnetEngineeringUnits);
6087 case 87: /* priority-array -- accessed as a BACnetARRAY */
6088 if (propertyArrayIndex == 0) {
6089 /* BACnetARRAY index 0 refers to the length
6090 of the array, not the elements of the array */
6091 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6093 offset = fPriorityArray (tvb, pinfo, tree, offset);
6096 case 38: /* exception-schedule */
6097 if (object_type < 128) {
6098 if (propertyArrayIndex == 0) {
6099 /* BACnetARRAY index 0 refers to the length
6100 of the array, not the elements of the array */
6101 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6103 offset = fSpecialEvent (tvb,pinfo,tree,offset);
6107 case 19: /* controlled-variable-reference */
6108 case 60: /* manipulated-variable-reference */
6109 case 109: /* Setpoint-Reference */
6110 case 132: /* log-device-object-property */
6111 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6113 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
6114 if (object_type < 128) {
6115 if (propertyArrayIndex == 0) {
6116 /* BACnetARRAY index 0 refers to the length
6117 of the array, not the elements of the array */
6118 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6120 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
6124 case 127: /* client COV increment */
6125 offset = fClientCOV (tvb, pinfo, tree, offset);
6127 case 131: /* log-buffer */
6128 offset = fLogRecord (tvb, pinfo, tree, offset);
6130 case 159: /* member-of */
6131 case 165: /* zone-members */
6132 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6134 case 196: /* last-restart-reason */
6135 offset = fRestartReason (tvb, pinfo, tree, offset);
6137 case 212: /* actual-shed-level */
6138 case 214: /* expected-shed-level */
6139 case 218: /* requested-shed-level */
6140 offset = fShedLevel (tvb, tree, offset);
6142 case 152: /* active-cov-subscriptions */
6143 offset = fCOVSubscription (tvb, pinfo, tree, offset);
6145 case 23: /* date-list */
6146 offset = fCalendarEntry(tvb, tree, offset);
6148 case 116: /* time-sychronization-recipients */
6149 offset = fRecipient(tvb, pinfo, tree, offset);
6151 case 83: /* event-parameters */
6152 offset = fEventParameter(tvb, pinfo, tree, offset);
6156 if (tag_is_opening(tag_info)) {
6158 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6159 } else if (tag_is_closing(tag_info)) {
6161 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6163 offset = fContextTaggedValue(tvb, tree, offset, ar);
6166 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6170 if (offset == lastoffset) break; /* nothing happened, exit loop */
6177 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
6182 if (tag_is_opening(tag_info)) {
6183 offset += fTagHeaderTree(tvb, tree, offset,
6184 &tag_no, &tag_info, &lvt);
6185 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6186 if (tvb_length_remaining(tvb, offset) > 0) {
6187 offset += fTagHeaderTree(tvb, tree, offset,
6188 &tag_no, &tag_info, &lvt);
6191 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
6192 "expected Opening Tag!"); \
6193 offset = tvb_length(tvb);
6201 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
6203 guint lastoffset = offset;
6204 guint8 tag_no, tag_info;
6207 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
6208 if (offset > lastoffset) {
6209 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6210 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
6211 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
6218 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6220 guint lastoffset = 0;
6221 guint8 tag_no, tag_info;
6224 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6225 lastoffset = offset;
6226 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
6227 if (offset > lastoffset) {
6228 /* detect optional priority
6229 by looking to see if the next tag is context tag number 3 */
6230 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6231 if (tag_is_context_specific(tag_info) && (tag_no == 3))
6232 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
6234 if (offset == lastoffset) break; /* nothing happened, exit loop */
6240 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6242 guint lastoffset = 0, len;
6243 guint8 tag_no, tag_info;
6245 proto_tree *subtree = tree;
6248 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6249 lastoffset = offset;
6250 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6251 if (tag_is_closing(tag_info)) {
6258 case 0: /* ProcessId */
6259 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
6261 case 1: /* monitored ObjectId */
6262 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6264 case 2: /* issueConfirmedNotifications */
6265 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
6267 case 3: /* life time */
6268 offset = fTimeSpan (tvb,tree,offset,"life time");
6270 case 4: /* monitoredPropertyIdentifier */
6271 if (tag_is_opening(tag_info)) {
6272 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
6274 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6276 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6277 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
6282 case 5: /* covIncrement */
6283 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
6288 if (offset == lastoffset) break; /* nothing happened, exit loop */
6294 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6296 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
6300 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6302 guint lastoffset = 0;
6304 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6305 lastoffset = offset;
6307 switch (fTagNo(tvb, offset)) {
6308 case 0: /* deviceInstanceLowLimit */
6309 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
6311 case 1: /* deviceInstanceHighLimit */
6312 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
6314 case 2: /* BACnetObjectId */
6315 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6317 case 3: /* messageText */
6318 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
6323 if (offset == lastoffset) break; /* nothing happened, exit loop */
6330 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
6332 guint lastoffset = 0;
6333 guint8 tag_no, tag_info;
6336 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6337 if (tag_is_opening(tag_info) && tag_no == 0) {
6338 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
6339 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6340 lastoffset = offset;
6341 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6342 if (tag_is_closing(tag_info)) {
6343 /* should be closing context tag 0 */
6344 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6348 offset = fTimeValue (tvb, pinfo, subtree, offset);
6349 if (offset == lastoffset) break; /* nothing happened, exit loop */
6351 } else if (tag_no == 0 && lvt == 0) {
6352 /* not sure null (empty array element) is legal */
6353 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6359 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6361 guint lastoffset = 0;
6362 guint8 tag_no, tag_info;
6364 guint i = 1; /* day of week array index */
6365 proto_tree *subtree = tree;
6368 if (propertyArrayIndex > 0) {
6369 /* BACnetARRAY index 0 refers to the length
6370 of the array, not the elements of the array.
6371 BACnetARRAY index -1 is our internal flag that
6372 the optional index was not used.
6373 BACnetARRAY refers to this as all elements of the array.
6374 If the optional index is specified for a BACnetARRAY,
6375 then that specific array element is referenced. */
6376 i = propertyArrayIndex;
6378 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6379 lastoffset = offset;
6380 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6381 if (tag_is_closing(tag_info)) {
6382 return offset; /* outer encoding will print out closing tag */
6384 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
6385 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6386 offset = fDailySchedule (tvb, pinfo, subtree, offset);
6387 if (offset == lastoffset) break; /* nothing happened, exit loop */
6394 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
6396 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6399 return fDateTime (tvb, tree, offset, "UTC-Time: ");
6403 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
6405 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6408 return fDateTime (tvb, tree, offset, NULL);
6412 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
6414 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6416 offset = fDate (tvb,tree,offset,"Start Date: ");
6417 return fDate (tvb, tree, offset, "End Date: ");
6421 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6424 guint8 tag_no, tag_info;
6428 proto_tree *subtree;
6429 const gchar *label = "Vendor ID";
6431 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6432 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6433 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6434 "%s: %s (%u)", label,
6435 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
6437 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6438 "%s - %u octets (Unsigned)", label, lvt);
6439 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6440 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6442 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
6443 proto_item *expert_item;
6444 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6445 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6446 PROTO_ITEM_SET_GENERATED(expert_item);
6447 return offset+tag_len+lvt;
6450 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
6451 offset+tag_len, lvt, FALSE);
6453 return offset+tag_len+lvt;
6457 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6460 guint8 tag_no, tag_info;
6464 proto_tree *subtree;
6465 const gchar *label = "Restart Reason";
6467 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6468 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6469 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6470 "%s: %s (%u)", label,
6471 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
6473 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6474 "%s - %u octets (Unsigned)", label, lvt);
6475 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6476 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6479 proto_item *expert_item;
6480 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
6481 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
6482 PROTO_ITEM_SET_GENERATED(expert_item);
6483 return offset+tag_len+lvt;
6486 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
6487 offset+tag_len, lvt, FALSE);
6489 return offset+tag_len+lvt;
6493 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6495 guint lastoffset = 0;
6497 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6498 lastoffset = offset;
6499 switch (fTagNo(tvb, offset)) {
6501 case 0: /* textMessageSourceDevice */
6502 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6504 case 1: /* messageClass */
6505 switch (fTagNo(tvb, offset)) {
6506 case 0: /* numeric */
6507 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
6509 case 1: /* character */
6510 offset = fCharacterString (tvb, tree, offset, "message Class: ");
6514 case 2: /* messagePriority */
6515 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
6516 BACnetMessagePriority);
6518 case 3: /* message */
6519 offset = fCharacterString (tvb, tree, offset, "message: ");
6524 if (offset == lastoffset) break; /* nothing happened, exit loop */
6530 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6532 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
6536 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6538 guint lastoffset = 0, len;
6539 guint8 tag_no, tag_info;
6541 proto_tree *subtree = tree;
6544 guint vendor_identifier = 0;
6545 guint service_number = 0;
6547 lastoffset = offset;
6548 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6549 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
6550 if (col_get_writable(pinfo->cinfo))
6551 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
6552 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6554 next_tvb = tvb_new_subset_remaining(tvb,offset);
6555 if (dissector_try_uint(bacapp_dissector_table,
6556 vendor_identifier, next_tvb, pinfo, tree)) {
6557 /* we parsed it so skip over length and we are done */
6558 offset += tvb_length(next_tvb);
6562 /* Not handled by vendor dissector */
6564 /* exit loop if nothing happens inside */
6565 while (tvb_reported_length_remaining(tvb, offset)) {
6566 lastoffset = offset;
6567 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6568 if (tag_is_closing(tag_info)) {
6569 if (tag_no == 2) { /* Make sure it's the expected tag */
6574 break; /* End loop if incorrect closing tag */
6579 /* vendorID is now parsed above */
6580 case 1: /* serviceNumber */
6581 fUnsigned32(tvb, offset+len, lvt, &service_number);
6582 if (col_get_writable(pinfo->cinfo))
6583 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
6584 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
6586 case 2: /*serviceParameters */
6587 if (tag_is_opening(tag_info)) {
6588 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
6589 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6590 propertyIdentifier = -1;
6591 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6599 if (offset == lastoffset) break; /* nothing happened, exit loop */
6606 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6608 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
6612 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6614 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
6618 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6620 guint lastoffset = 0;
6621 guint8 tag_no, tag_info;
6623 proto_tree *subtree = tree;
6626 if (label != NULL) {
6627 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
6628 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6631 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6632 lastoffset = offset;
6633 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6636 case 0: /* subscriberProcessId */
6637 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
6639 case 1: /* requestingSource */
6640 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
6642 case 2: /* request */
6643 offset = fEnumeratedTagSplit (tvb, tree, offset,
6644 "request: ", BACnetLifeSafetyOperation, 64);
6646 case 3: /* objectId */
6647 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6652 if (offset == lastoffset) break; /* nothing happened, exit loop */
6658 fBACnetPropertyStates(tvbuff_t *tvb, proto_tree *tree, guint offset)
6660 switch (fTagNo(tvb, offset))
6663 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6666 offset = fEnumeratedTagSplit (tvb, tree, offset,
6667 "binary-value: ", BACnetBinaryPV, 2);
6670 offset = fEnumeratedTagSplit (tvb, tree, offset,
6671 "event-type: ", BACnetEventType, 12);
6674 offset = fEnumeratedTagSplit (tvb, tree, offset,
6675 "polarity: ", BACnetPolarity, 2);
6678 offset = fEnumeratedTagSplit (tvb, tree, offset,
6679 "program-change: ", BACnetProgramRequest, 5);
6682 offset = fEnumeratedTagSplit (tvb, tree, offset,
6683 "program-state: ", BACnetProgramState, 5);
6686 offset = fEnumeratedTagSplit (tvb, tree, offset,
6687 "reason-for-halt: ", BACnetProgramError, 5);
6690 offset = fEnumeratedTagSplit (tvb, tree, offset,
6691 "reliability: ", BACnetReliability, 10);
6694 offset = fEnumeratedTagSplit (tvb, tree, offset,
6695 "state: ", BACnetEventState, 64);
6698 offset = fEnumeratedTagSplit (tvb, tree, offset,
6699 "system-status: ", BACnetDeviceStatus, 64);
6702 offset = fEnumeratedTagSplit (tvb, tree, offset,
6703 "units: ", BACnetEngineeringUnits, 2);
6706 offset = fUnsignedTag(tvb, tree, offset, "unsigned-value: ");
6709 offset = fEnumeratedTagSplit (tvb, tree, offset,
6710 "life-safety-mode: ", BACnetLifeSafetyMode, 64);
6713 offset = fEnumeratedTagSplit (tvb, tree, offset,
6714 "life-safety-state: ", BACnetLifeSafetyState, 64);
6724 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
6725 deviceIdentifier [0] BACnetObjectIdentifier,
6726 objectIdentifier [1] BACnetObjectIdentifier,
6727 propertyIdentifier [2] BACnetPropertyIdentifier,
6728 arrayIndex [3] Unsigned OPTIONAL,
6729 value [4] ABSTRACT-SYNTAX.&Type
6733 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6735 guint lastoffset = 0;
6736 guint8 tag_no, tag_info;
6739 while (tvb_reported_length_remaining(tvb, offset)) {
6740 lastoffset = offset;
6741 /* check the tag. A closing tag means we are done */
6742 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6743 if (tag_is_closing(tag_info)) {
6747 case 0: /* deviceIdentifier */
6748 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6750 case 1: /* objectIdentifier */
6751 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6753 case 2: /* propertyIdentifier */
6754 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6756 case 3: /* arrayIndex - OPTIONAL */
6757 offset = fUnsignedTag (tvb, tree, offset,
6761 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6762 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6763 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6768 if (offset == lastoffset) break; /* nothing happened, exit loop */
6775 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
6776 objectIdentifier [0] BACnetObjectIdentifier,
6777 propertyIdentifier [1] BACnetPropertyIdentifier,
6778 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
6779 -- if omitted with an array then
6780 -- the entire array is referenced
6781 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
6785 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6787 guint lastoffset = 0;
6788 guint8 tag_no, tag_info;
6791 while (tvb_reported_length_remaining(tvb, offset)) {
6792 lastoffset = offset;
6793 /* check the tag. A closing tag means we are done */
6794 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6795 if (tag_is_closing(tag_info)) {
6799 case 0: /* objectIdentifier */
6800 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6802 case 1: /* propertyIdentifier */
6803 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6805 case 2: /* arrayIndex - OPTIONAL */
6806 offset = fUnsignedTag (tvb, tree, offset,
6809 case 3: /* deviceIdentifier - OPTIONAL */
6810 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6815 if (offset == lastoffset) break; /* nothing happened, exit loop */
6821 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6823 guint lastoffset = offset;
6824 guint8 tag_no, tag_info;
6826 proto_tree *subtree = tree;
6829 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6830 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
6831 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
6832 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6833 /* Opening tag for parameter choice */
6834 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6837 case 0: /* change-of-bitstring */
6838 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6839 lastoffset = offset;
6840 switch (fTagNo(tvb, offset)) {
6842 offset = fBitStringTag (tvb, subtree, offset,
6843 "referenced-bitstring: ");
6846 offset = fBitStringTagVS (tvb, subtree, offset,
6847 "status-flags: ", BACnetStatusFlags);
6848 lastoffset = offset;
6853 if (offset == lastoffset) break; /* nothing happened, exit loop */
6856 case 1: /* change-of-state */
6857 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6858 lastoffset = offset;
6859 switch (fTagNo(tvb, offset)) {
6861 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6862 offset = fBACnetPropertyStates(tvb, subtree, offset);
6863 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6866 offset = fBitStringTagVS (tvb, subtree, offset,
6867 "status-flags: ", BACnetStatusFlags);
6868 lastoffset = offset;
6873 if (offset == lastoffset) break; /* nothing happened, exit loop */
6876 case 2: /* change-of-value */
6877 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6878 lastoffset = offset;
6879 switch (fTagNo(tvb, offset)) {
6881 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6882 switch (fTagNo(tvb, offset)) {
6884 offset = fBitStringTag (tvb, subtree, offset,
6888 offset = fRealTag (tvb, subtree, offset,
6894 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6897 offset = fBitStringTagVS (tvb, subtree, offset,
6898 "status-flags: ", BACnetStatusFlags);
6899 lastoffset = offset;
6904 if (offset == lastoffset) break; /* nothing happened, exit loop */
6907 case 3: /* command-failure */
6908 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6909 lastoffset = offset;
6910 switch (fTagNo(tvb, offset)) {
6911 case 0: /* "command-value: " */
6912 /* from BACnet Table 13-3,
6913 Standard Object Property Values Returned in Notifications */
6914 propertyIdentifier = 85; /* PRESENT_VALUE */
6915 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6916 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6917 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6920 offset = fBitStringTagVS (tvb, subtree, offset,
6921 "status-flags: ", BACnetStatusFlags);
6923 case 2: /* "feedback-value: " */
6924 propertyIdentifier = 40; /* FEEDBACK_VALUE */
6925 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6926 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6927 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6928 lastoffset = offset;
6933 if (offset == lastoffset) break; /* nothing happened, exit loop */
6936 case 4: /* floating-limit */
6937 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6938 lastoffset = offset;
6939 switch (fTagNo(tvb, offset)) {
6941 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
6944 offset = fBitStringTagVS (tvb, subtree, offset,
6945 "status-flags: ", BACnetStatusFlags);
6948 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
6951 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
6952 lastoffset = offset;
6957 if (offset == lastoffset) break; /* nothing happened, exit loop */
6960 case 5: /* out-of-range */
6961 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6962 lastoffset = offset;
6963 switch (fTagNo(tvb, offset)) {
6965 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
6968 offset = fBitStringTagVS (tvb, subtree, offset,
6969 "status-flags: ", BACnetStatusFlags);
6972 offset = fRealTag (tvb, subtree, offset, "deadband: ");
6975 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
6976 lastoffset = offset;
6981 if (offset == lastoffset) break; /* nothing happened, exit loop */
6985 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6986 lastoffset = offset;
6987 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
6988 if (offset == lastoffset) break; /* nothing happened, exit loop */
6991 case 7: /* buffer-ready */
6992 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6993 lastoffset = offset;
6994 switch (fTagNo(tvb, offset)) {
6996 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
6999 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
7002 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7003 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
7004 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7007 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7008 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
7009 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7010 lastoffset = offset;
7015 if (offset == lastoffset) break; /* nothing happened, exit loop */
7018 case 8: /* change-of-life-safety */
7019 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7020 lastoffset = offset;
7021 switch (fTagNo(tvb, offset)) {
7023 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7024 "new-state: ", BACnetLifeSafetyState, 256);
7027 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7028 "new-mode: ", BACnetLifeSafetyMode, 256);
7031 offset = fBitStringTagVS (tvb, subtree, offset,
7032 "status-flags: ", BACnetStatusFlags);
7035 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7036 "operation-expected: ", BACnetLifeSafetyOperation, 64);
7037 lastoffset = offset;
7042 if (offset == lastoffset) break; /* nothing happened, exit loop */
7045 case 9: /* extended */
7046 while (tvb_reported_length_remaining(tvb, offset)) {
7047 lastoffset = offset;
7048 switch (fTagNo(tvb, offset)) {
7050 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
7053 offset = fUnsignedTag (tvb, subtree, offset,
7054 "extended-event-type: ");
7056 case 2: /* parameters */
7057 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7058 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
7059 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
7060 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7061 lastoffset = offset;
7066 if (offset == lastoffset) break; /* nothing happened, exit loop */
7069 case 10: /* buffer ready */
7070 while (tvb_reported_length_remaining(tvb, offset)) {
7071 lastoffset = offset;
7072 switch (fTagNo(tvb, offset)) {
7073 case 0: /* buffer-property */
7074 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7075 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7076 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7079 offset = fUnsignedTag (tvb, subtree, offset,
7080 "previous-notification: ");
7083 offset = fUnsignedTag (tvb, subtree, offset,
7084 "current-notification: ");
7085 lastoffset = offset;
7090 if (offset == lastoffset) break; /* nothing happened, exit loop */
7093 case 11: /* unsigned range */
7094 while (tvb_reported_length_remaining(tvb, offset)) {
7095 lastoffset = offset;
7096 switch (fTagNo(tvb, offset)) {
7098 offset = fUnsignedTag (tvb, subtree, offset,
7099 "exceeding-value: ");
7102 offset = fBitStringTagVS (tvb, subtree, offset,
7103 "status-flags: ", BACnetStatusFlags);
7106 offset = fUnsignedTag (tvb, subtree, offset,
7107 "exceeded-limit: ");
7108 lastoffset = offset;
7113 if (offset == lastoffset) break; /* nothing happened, exit loop */
7120 /* Closing tag for parameter choice */
7121 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7127 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7129 guint lastoffset = offset;
7130 guint8 tag_no, tag_info;
7132 proto_tree *subtree = tree;
7135 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7136 tt = proto_tree_add_text(subtree, tvb, offset, 0, "event parameters (%d) %s",
7137 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
7138 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7139 /* Opening tag for parameter choice */
7140 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7143 case 0: /* change-of-bitstring */
7144 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7145 lastoffset = offset;
7146 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7147 if (tag_is_closing(tag_info)) {
7152 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7155 offset = fBitStringTag (tvb, subtree, offset, "bitmask: ");
7157 case 2: /* SEQUENCE OF BIT STRING */
7158 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7159 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7160 lastoffset = offset;
7161 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7162 if (tag_is_closing(tag_info)) {
7165 offset = fBitStringTag(tvb, subtree, offset,
7166 "bitstring value: ");
7168 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7175 case 1: /* change-of-state */
7176 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7177 lastoffset = offset;
7178 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7179 if (tag_is_closing(tag_info)) {
7184 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7186 case 1: /* SEQUENCE OF BACnetPropertyStates */
7187 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7188 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7189 lastoffset = offset;
7190 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7191 if (tag_is_closing(tag_info)) {
7194 offset = fBACnetPropertyStates(tvb, subtree, offset);
7196 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7203 case 2: /* change-of-value */
7204 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7205 lastoffset = offset;
7206 switch (fTagNo(tvb, offset)) {
7208 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7210 case 1: /* don't loop it, it's a CHOICE */
7211 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7212 switch (fTagNo(tvb, offset)) {
7214 offset = fBitStringTag (tvb, subtree, offset, "bitmask: ");
7217 offset = fRealTag (tvb, subtree, offset,
7218 "referenced Property Increment: ");
7223 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7230 case 3: /* command-failure */
7231 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7232 lastoffset = offset;
7233 tag_no = fTagNo(tvb, offset);
7236 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7239 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7240 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7241 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7248 case 4: /* floating-limit */
7249 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7250 lastoffset = offset;
7251 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7252 if (tag_is_closing(tag_info)) {
7257 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7260 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7261 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7262 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7265 offset = fRealTag (tvb, subtree, offset, "low diff limit: ");
7268 offset = fRealTag (tvb, subtree, offset, "high diff limit: ");
7271 offset = fRealTag (tvb, subtree, offset, "deadband: ");
7278 case 5: /* out-of-range */
7279 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7280 lastoffset = offset;
7281 switch (fTagNo(tvb, offset)) {
7283 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7286 offset = fRealTag (tvb, subtree, offset, "low limit: ");
7289 offset = fRealTag (tvb, subtree, offset, "high limit: ");
7292 offset = fRealTag (tvb, subtree, offset, "deadband: ");
7301 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
7305 case 7: /* buffer-ready */
7307 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
7308 lastoffset = offset;
7309 switch (fTagNo(tvb, offset)) {
7311 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
7314 offset = fUnsignedTag (tvb,tree,offset,
7315 "previous notification count: ");
7323 case 8: /* change-of-life-safety */
7324 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7325 lastoffset = offset;
7326 switch (fTagNo(tvb, offset)) {
7328 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7331 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7332 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7333 lastoffset = offset;
7334 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7335 if (tag_is_closing(tag_info)) {
7338 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7339 "life safety alarm value: ", BACnetLifeSafetyState, 256);
7341 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7344 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7345 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7346 lastoffset = offset;
7347 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7348 if (tag_is_closing(tag_info)) {
7351 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7352 "alarm value: ", BACnetLifeSafetyState, 256);
7354 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7357 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7358 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7359 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7366 case 9: /* extended */
7367 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7368 lastoffset = offset;
7369 switch (fTagNo(tvb, offset)) {
7371 offset = fVendorIdentifier (tvb, pinfo, tree, offset);
7374 offset = fUnsignedTag (tvb, tree, offset,
7375 "extended-event-type: ");
7377 case 2: /* parameters */
7378 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7379 offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
7380 offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
7381 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7382 lastoffset = offset;
7387 if (offset == lastoffset) break; /* nothing happened, exit loop */
7390 case 10: /* buffer-ready */
7391 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7392 lastoffset = offset;
7393 switch (fTagNo(tvb, offset)) {
7395 offset = fUnsignedTag (tvb, subtree, offset,
7396 "notification-threshold: ");
7399 offset = fUnsignedTag (tvb, subtree, offset,
7400 "previous-notification-count: ");
7407 case 11: /* unsigned-range */
7408 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7409 lastoffset = offset;
7410 switch (fTagNo(tvb, offset)) {
7412 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
7415 offset = fUnsignedTag (tvb, tree, offset,
7419 offset = fUnsignedTag (tvb, tree, offset,
7431 /* Closing tag for parameter choice */
7432 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7437 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7439 guint lastoffset = 0;
7440 guint8 tag_no, tag_info;
7443 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7444 lastoffset = offset;
7445 switch (fTagNo(tvb, offset)) {
7446 case 0: /* timestamp */
7447 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7448 offset = fDate (tvb,tree,offset,"Date: ");
7449 offset = fTime (tvb,tree,offset,"Time: ");
7450 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7452 case 1: /* logDatum: don't loop, it's a CHOICE */
7453 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7454 switch (fTagNo(tvb, offset)) {
7455 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
7456 offset = fBitStringTagVS(tvb, tree, offset, "log status:", BACnetLogStatus);
7459 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
7462 offset = fRealTag (tvb, tree, offset, "real value: ");
7465 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
7468 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
7471 offset = fSignedTag (tvb, tree, offset, "signed value: ");
7474 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
7477 offset = fNullTag(tvb, tree, offset, "null value: ");
7480 offset = fError (tvb, pinfo, tree, offset);
7483 offset = fRealTag (tvb, tree, offset, "time change: ");
7485 case 10: /* any Value */
7486 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7487 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7488 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7493 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7496 /* Changed this to BitString per BACnet Spec. */
7497 offset = fBitStringTagVS(tvb, tree, offset, "Status Flags:", BACnetStatusFlags);
7502 if (offset == lastoffset) break; /* nothing happened, exit loop */
7509 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7511 guint lastoffset = 0;
7512 guint8 tag_no, tag_info;
7515 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7516 lastoffset = offset;
7518 switch (fTagNo(tvb,offset)) {
7519 case 0: /* ProcessId */
7520 offset = fProcessId (tvb,tree,offset);
7522 case 1: /* initiating ObjectId */
7523 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7525 case 2: /* event ObjectId */
7526 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7528 case 3: /* time stamp */
7529 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7530 offset = fTimeStamp (tvb, tree, offset, NULL);
7531 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7533 case 4: /* notificationClass */
7534 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
7536 case 5: /* Priority */
7537 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
7539 case 6: /* EventType */
7540 offset = fEnumeratedTagSplit (tvb, tree, offset,
7541 "Event Type: ", BACnetEventType, 64);
7543 case 7: /* messageText */
7544 offset = fCharacterString (tvb, tree, offset, "message Text: ");
7546 case 8: /* NotifyType */
7547 offset = fEnumeratedTag (tvb, tree, offset,
7548 "Notify Type: ", BACnetNotifyType);
7550 case 9: /* ackRequired */
7551 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
7553 case 10: /* fromState */
7554 offset = fEnumeratedTagSplit (tvb, tree, offset,
7555 "from State: ", BACnetEventState, 64);
7557 case 11: /* toState */
7558 offset = fEnumeratedTagSplit (tvb, tree, offset,
7559 "to State: ", BACnetEventState, 64);
7561 case 12: /* NotificationParameters */
7562 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7563 offset = fNotificationParameters (tvb, pinfo, tree, offset);
7564 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7569 if (offset == lastoffset) break; /* nothing happened, exit loop */
7575 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7577 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
7581 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7583 guint lastoffset = 0, len;
7584 guint8 tag_no, tag_info;
7586 proto_tree *subtree = tree;
7589 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7590 lastoffset = offset;
7591 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7592 if (tag_is_closing(tag_info)) {
7599 case 0: /* ProcessId */
7600 offset = fProcessId (tvb,tree,offset);
7602 case 1: /* initiating DeviceId */
7603 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7605 case 2: /* monitored ObjectId */
7606 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7608 case 3: /* time remaining */
7609 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
7611 case 4: /* List of Values */
7612 if (tag_is_opening(tag_info)) {
7613 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
7614 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7615 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7616 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7624 if (offset == lastoffset) break; /* nothing happened, exit loop */
7630 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7632 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
7636 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7638 guint lastoffset = 0;
7639 guint8 tag_no = 0, tag_info = 0;
7642 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7643 lastoffset = offset;
7644 switch (fTagNo(tvb, offset)) {
7645 case 0: /* acknowledgingProcessId */
7646 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
7648 case 1: /* eventObjectId */
7649 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7651 case 2: /* eventStateAcknowledged */
7652 offset = fEnumeratedTagSplit (tvb, tree, offset,
7653 "event State Acknowledged: ", BACnetEventState, 64);
7655 case 3: /* timeStamp */
7656 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7657 offset = fTimeStamp(tvb, tree, offset, NULL);
7658 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7660 case 4: /* acknowledgementSource */
7661 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
7663 case 5: /* timeOfAcknowledgement */
7664 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7665 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
7666 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7671 if (offset == lastoffset) break; /* nothing happened, exit loop */
7677 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7679 guint lastoffset = 0;
7681 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7682 lastoffset = offset;
7683 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
7684 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
7685 "alarm State: ", BACnetEventState, 64);
7686 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7687 "acknowledged Transitions: ", BACnetEventTransitionBits);
7688 if (offset == lastoffset) break; /* nothing happened, exit loop */
7694 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7696 guint lastoffset = 0;
7697 guint8 tag_no, tag_info;
7700 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7701 lastoffset = offset;
7702 switch (fTagNo(tvb, offset)) {
7703 case 0: /* acknowledgmentFilter */
7704 offset = fEnumeratedTag (tvb, tree, offset,
7705 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
7707 case 1: /* eventObjectId - OPTIONAL */
7708 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7709 offset = fRecipientProcess (tvb, pinfo, tree, offset);
7710 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7712 case 2: /* eventStateFilter */
7713 offset = fEnumeratedTag (tvb, tree, offset,
7714 "event State Filter: ", BACnetEventStateFilter);
7716 case 3: /* eventTypeFilter - OPTIONAL */
7717 offset = fEnumeratedTag (tvb, tree, offset,
7718 "event Type Filter: ", BACnetEventType);
7720 case 4: /* priorityFilter */
7721 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7722 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
7723 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
7724 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7726 case 5: /* notificationClassFilter - OPTIONAL */
7727 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
7732 if (offset == lastoffset) break; /* nothing happened, exit loop */
7738 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7740 guint lastoffset = 0;
7742 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7743 lastoffset = offset;
7744 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
7745 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
7746 "event Type: ", BACnetEventType, 64);
7747 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7748 "event State: ", BACnetEventState);
7749 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
7750 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
7751 if (offset == lastoffset) break; /* nothing happened, exit loop */
7758 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7760 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7761 if (fTagNo(tvb, offset) == 0) {
7762 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7769 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7771 guint lastoffset = 0;
7772 guint8 tag_no, tag_info;
7774 proto_tree* subtree = tree;
7777 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7778 lastoffset = offset;
7779 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7780 /* we are finished here if we spot a closing tag */
7781 if (tag_is_closing(tag_info)) {
7785 case 0: /* ObjectId */
7786 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7788 case 1: /* eventState */
7789 offset = fEnumeratedTag (tvb, tree, offset,
7790 "event State: ", BACnetEventState);
7792 case 2: /* acknowledgedTransitions */
7793 offset = fBitStringTagVS (tvb, tree, offset,
7794 "acknowledged Transitions: ", BACnetEventTransitionBits);
7796 case 3: /* eventTimeStamps */
7797 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
7799 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7801 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7802 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
7803 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
7804 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
7805 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7807 case 4: /* notifyType */
7808 offset = fEnumeratedTag (tvb, tree, offset,
7809 "Notify Type: ", BACnetNotifyType);
7811 case 5: /* eventEnable */
7812 offset = fBitStringTagVS (tvb, tree, offset,
7813 "event Enable: ", BACnetEventTransitionBits);
7815 case 6: /* eventPriorities */
7816 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
7818 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7820 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7821 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
7822 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
7823 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
7824 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7829 if (offset == lastoffset) break; /* nothing happened, exit loop */
7835 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7837 guint lastoffset = 0;
7838 guint8 tag_no, tag_info;
7841 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7842 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7843 lastoffset = offset;
7844 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7845 /* we are finished here if we spot a closing tag */
7846 if (tag_is_closing(tag_info)) {
7849 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7850 if (offset == lastoffset) break; /* nothing happened, exit loop */
7856 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7858 guint lastoffset = 0;
7859 guint8 tag_no, tag_info;
7862 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7863 lastoffset = offset;
7864 switch (fTagNo(tvb, offset)) {
7865 case 0: /* listOfEventSummaries */
7866 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7867 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
7868 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7870 case 1: /* moreEvents */
7871 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
7876 if (offset == lastoffset) break; /* nothing happened, exit loop */
7882 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7884 guint lastoffset = 0, len;
7885 guint8 tag_no, tag_info;
7887 proto_tree *subtree = tree;
7890 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7892 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7893 lastoffset = offset;
7894 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7895 if (tag_is_closing(tag_info)) {
7902 case 0: /* ObjectId */
7903 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
7905 case 3: /* listOfElements */
7906 if (tag_is_opening(tag_info)) {
7907 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
7908 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7909 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7910 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7918 if (offset == lastoffset) break; /* nothing happened, exit loop */
7924 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7926 return fObjectIdentifier (tvb, pinfo, tree, offset);
7930 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7932 guint lastoffset = 0;
7934 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7935 lastoffset = offset;
7937 switch (fTagNo(tvb, offset)) {
7938 case 0: /* timeDuration */
7939 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
7941 case 1: /* enable-disable */
7942 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
7943 BACnetEnableDisable);
7945 case 2: /* password - OPTIONAL */
7946 offset = fCharacterString (tvb, tree, offset, "Password: ");
7951 if (offset == lastoffset) break; /* nothing happened, exit loop */
7957 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7959 guint lastoffset = 0;
7961 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7962 lastoffset = offset;
7964 switch (fTagNo(tvb, offset)) {
7965 case 0: /* reinitializedStateOfDevice */
7966 offset = fEnumeratedTag (tvb, tree, offset,
7967 "reinitialized State Of Device: ",
7968 BACnetReinitializedStateOfDevice);
7970 case 1: /* password - OPTIONAL */
7971 offset = fCharacterString (tvb, tree, offset, "Password: ");
7976 if (offset == lastoffset) break; /* nothing happened, exit loop */
7982 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7984 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7985 "vtClass: ", BACnetVTClass);
7986 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
7990 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7992 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7996 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7998 guint lastoffset = 0;
8000 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8001 lastoffset = offset;
8002 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
8003 if (offset == lastoffset) break; /* nothing happened, exit loop */
8009 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8011 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
8012 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
8013 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
8017 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
8019 guint lastoffset = 0;
8021 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8022 lastoffset = offset;
8024 switch (fTagNo(tvb,offset)) {
8025 case 0: /* BOOLEAN */
8026 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
8028 case 1: /* Unsigned OPTIONAL */
8029 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
8034 if (offset == lastoffset) break; /* nothing happened, exit loop */
8040 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
8042 guint lastoffset = 0;
8044 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8045 lastoffset = offset;
8047 switch (fTagNo(tvb,offset)) {
8048 case 0: /* Unsigned32 */
8049 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
8051 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
8052 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
8054 case 2: /* Chararacter String OPTIONAL */
8055 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
8057 case 3: /* Chararacter String OPTIONAL */
8058 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
8060 case 4: /* Boolean OPTIONAL */
8061 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
8066 if (offset == lastoffset) break; /* nothing happened, exit loop */
8072 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8074 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
8078 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8080 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
8081 offset = fAddress (tvb, tree, offset);
8082 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
8083 return fAddress (tvb, tree, offset);
8087 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8089 /* Same as AddListElement request after service choice */
8090 return fAddListElementRequest(tvb, pinfo, tree, offset);
8094 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8096 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8100 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8102 guint lastoffset = 0, len;
8103 guint8 tag_no, tag_info;
8105 proto_tree *subtree = tree;
8107 /* set the optional global properties to indicate not-used */
8108 propertyArrayIndex = -1;
8109 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8110 lastoffset = offset;
8111 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8112 if (tag_is_closing(tag_info)) {
8118 case 0: /* objectIdentifier */
8119 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8121 case 1: /* propertyIdentifier */
8122 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8124 case 2: /* propertyArrayIndex */
8125 offset = fPropertyArrayIndex (tvb, subtree, offset);
8127 case 3: /* propertyValue */
8128 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8133 if (offset == lastoffset) break; /* nothing happened, exit loop */
8139 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8141 guint lastoffset = 0;
8142 guint8 tag_no, tag_info;
8144 proto_tree *subtree = tree;
8146 /* set the optional global properties to indicate not-used */
8147 propertyArrayIndex = -1;
8148 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8149 lastoffset = offset;
8150 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8151 /* quit loop if we spot a closing tag */
8152 if (tag_is_closing(tag_info)) {
8158 case 0: /* objectIdentifier */
8159 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8161 case 1: /* propertyIdentifier */
8162 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8164 case 2: /* propertyArrayIndex */
8165 offset = fPropertyArrayIndex (tvb, subtree, offset);
8167 case 3: /* propertyValue */
8168 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8170 case 4: /* Priority (only used for write) */
8171 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
8176 if (offset == lastoffset) break; /* nothing happened, exit loop */
8182 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8184 guint lastoffset = 0, len;
8185 guint8 tag_no, tag_info;
8188 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8189 lastoffset = offset;
8190 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8191 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
8192 if (tag_is_closing(tag_info)) {
8198 case 0: /* objectIdentifier */
8199 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8201 case 1: /* listOfPropertyValues */
8202 if (tag_is_opening(tag_info)) {
8203 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8204 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8212 if (offset == lastoffset) break; /* nothing happened, exit loop */
8218 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8220 if (offset >= tvb_reported_length(tvb))
8223 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8224 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
8228 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
8230 guint lastoffset = 0;
8231 guint8 tag_no, tag_info;
8234 /* set the optional global properties to indicate not-used */
8235 propertyArrayIndex = -1;
8236 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8237 lastoffset = offset;
8238 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8239 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
8241 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
8244 switch (tag_no-tagoffset) {
8245 case 0: /* PropertyIdentifier */
8246 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
8248 case 1: /* propertyArrayIndex */
8249 offset = fPropertyArrayIndex (tvb, tree, offset);
8250 if (list != 0) break; /* Continue decoding if this may be a list */
8252 lastoffset = offset; /* Set loop end condition */
8255 if (offset == lastoffset) break; /* nothing happened, exit loop */
8261 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
8263 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8264 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
8268 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8270 guint lastoffset = 0;
8272 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8273 lastoffset = offset;
8275 switch (fTagNo(tvb,offset)) {
8276 case 0: /* ObjectIdentifier */
8277 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8279 case 1: /* PropertyIdentifier and propertyArrayIndex */
8280 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
8281 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8283 lastoffset = offset; /* Set loop end condition */
8286 if (offset == lastoffset) break; /* nothing happened, exit loop */
8293 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
8295 guint lastoffset = 0;
8296 guint8 tag_no, tag_info;
8298 proto_tree* subtree = tree;
8301 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8302 lastoffset = offset;
8303 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8304 if (tag_is_closing(tag_info)) {
8305 offset += fTagHeaderTree (tvb, subtree, offset,
8306 &tag_no, &tag_info, &lvt);
8310 case 0: /* ObjectIdentifier */
8311 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8313 case 1: /* PropertyIdentifier */
8314 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8316 case 2: /* propertyArrayIndex */
8317 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
8320 offset = fPropertyValue (tvb, subtree, offset, tag_info);
8322 case 4: /* Priority */
8323 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
8334 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8336 char i = 1, ar[256];
8337 guint lastoffset = 0;
8339 if (propertyArrayIndex > 0) {
8340 /* BACnetARRAY index 0 refers to the length
8341 of the array, not the elements of the array.
8342 BACnetARRAY index -1 is our internal flag that
8343 the optional index was not used.
8344 BACnetARRAY refers to this as all elements of the array.
8345 If the optional index is specified for a BACnetARRAY,
8346 then that specific array element is referenced. */
8347 i = propertyArrayIndex;
8349 while (tvb_reported_length_remaining(tvb, offset)) {
8350 /* exit loop if nothing happens inside */
8351 lastoffset = offset;
8352 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
8353 val_to_split_str(87 , 512,
8354 BACnetPropertyIdentifier,
8355 ASHRAE_Reserved_Fmt,
8356 Vendor_Proprietary_Fmt),
8358 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
8359 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
8360 /* there are only 16 priority array elements */
8364 if (offset == lastoffset) break; /* nothing happened, exit loop */
8371 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8373 guint lastoffset = 0;
8375 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8376 lastoffset = offset;
8378 switch (fTagNo(tvb,offset)) {
8379 case 0: /* deviceIdentifier - OPTIONAL */
8380 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8382 case 1: /* ObjectIdentifier */
8383 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8388 if (offset == lastoffset) break; /* nothing happened, exit loop */
8394 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8396 guint8 tag_no, tag_info;
8398 guint lastoffset = 0, len;
8399 gboolean closing_found = FALSE; /* tracks when we are done decoding the fSpecialEvent entries */
8401 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8402 lastoffset = offset;
8403 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8404 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
8405 if (tag_is_closing(tag_info)) {
8406 /* if we find 2 closing tags in succession we need to exit without incrementing the offset again */
8407 /* This handles the special case where we have a special event entry in an RPM-ACK msg */
8408 if ( closing_found == TRUE )
8411 closing_found = TRUE;
8416 case 0: /* calendarEntry */
8417 if (tag_is_opening(tag_info)) {
8418 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8419 offset = fCalendarEntry (tvb, subtree, offset);
8420 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8423 case 1: /* calendarReference */
8424 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8426 case 2: /* list of BACnetTimeValue */
8427 if (tag_is_opening(tag_info)) {
8428 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8429 offset = fTimeValue (tvb, pinfo, subtree, offset);
8430 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8435 case 3: /* eventPriority */
8436 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
8441 closing_found = FALSE; /* reset our closing tag status, we processed another open tag */
8442 if (offset == lastoffset) break; /* nothing happened, exit loop */
8448 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8450 guint lastoffset = 0, len;
8451 guint8 tag_no, tag_info;
8454 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8455 lastoffset = offset;
8456 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8457 /* maybe a listOfSelectionCriteria if we spot a closing tag */
8458 if (tag_is_closing(tag_info)) {
8463 switch (fTagNo(tvb,offset)) {
8464 case 0: /* propertyIdentifier */
8465 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
8467 case 1: /* propertyArrayIndex */
8468 offset = fPropertyArrayIndex (tvb, tree, offset);
8470 case 2: /* relationSpecifier */
8471 offset = fEnumeratedTag (tvb, tree, offset,
8472 "relation Specifier: ", BACnetRelationSpecifier);
8474 case 3: /* comparisonValue */
8475 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8476 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
8477 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8482 if (offset == lastoffset) break; /* nothing happened, exit loop */
8488 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8490 guint lastoffset = 0;
8491 guint8 tag_no, tag_info;
8494 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8495 lastoffset = offset;
8496 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8497 /* quit loop if we spot a closing tag */
8498 if (tag_is_closing(tag_info)) {
8503 case 0: /* selectionLogic */
8504 offset = fEnumeratedTag (tvb, subtree, offset,
8505 "selection Logic: ", BACnetSelectionLogic);
8507 case 1: /* listOfSelectionCriteria */
8508 if (tag_is_opening(tag_info)) {
8509 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8510 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
8511 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8519 if (offset == lastoffset) break; /* nothing happened, exit loop */
8526 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
8528 guint lastoffset = 0;
8529 guint8 tag_no, tag_info;
8532 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8533 lastoffset = offset;
8534 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8536 if (tag_is_opening(tag_info) && tag_no < 2) {
8537 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8539 case 0: /* objectSelectionCriteria */
8540 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
8542 case 1: /* listOfPropertyReferences */
8543 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
8548 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8550 if (offset == lastoffset) break; /* nothing happened, exit loop */
8556 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8558 guint lastoffset = 0;
8559 guint8 tag_no, tag_info;
8562 proto_tree *subtree = tree;
8564 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8565 lastoffset = offset;
8566 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8568 case 0: /* objectIdentifier */
8569 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8571 case 1: /* listOfPropertyReferences */
8572 if (tag_is_opening(tag_info)) {
8573 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
8574 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8575 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8576 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
8577 } else if (tag_is_closing(tag_info)) {
8578 offset += fTagHeaderTree (tvb, subtree, offset,
8579 &tag_no, &tag_info, &lvt);
8582 /* error condition: let caller handle */
8589 if (offset == lastoffset) break; /* nothing happened, exit loop */
8595 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8597 guint lastoffset = 0, len;
8601 proto_tree *subtree = tree;
8604 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8605 lastoffset = offset;
8606 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8607 /* maybe a listOfReadAccessResults if we spot a closing tag here */
8608 if (tag_is_closing(tag_info)) {
8610 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
8615 case 0: /* objectSpecifier */
8616 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8618 case 1: /* list of Results */
8619 if (tag_is_opening(tag_info)) {
8620 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
8621 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8622 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8627 case 2: /* propertyIdentifier */
8628 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
8630 case 5: /* propertyAccessError */
8631 if (tag_is_opening(tag_info)) {
8632 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
8633 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8634 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8635 /* Error Code follows */
8636 offset = fError(tvb, pinfo, subtree, offset);
8644 if (offset == lastoffset) break; /* nothing happened, exit loop */
8651 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8653 /* listOfReadAccessResults */
8654 return fReadAccessResult (tvb, pinfo, tree, offset);
8659 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8661 guint lastoffset = 0;
8662 guint8 tag_no, tag_info;
8665 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8666 lastoffset = offset;
8667 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8670 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8672 case 0: /* objectSpecifier */
8673 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
8674 case 0: /* objectType */
8675 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
8677 case 1: /* objectIdentifier */
8678 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8684 case 1: /* propertyValue */
8685 if (tag_is_opening(tag_info)) {
8686 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8694 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8696 if (offset == lastoffset) break; /* nothing happened, exit loop */
8702 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8704 return fObjectIdentifier (tvb, pinfo, tree, offset);
8708 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8710 guint8 tag_no, tag_info;
8712 proto_tree *subtree = tree;
8715 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
8717 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8718 /* optional range choice */
8719 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8720 if (tag_is_opening(tag_info)) {
8721 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
8722 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8723 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8725 case 3: /* range byPosition */
8726 case 6: /* range bySequenceNumber, 2004 spec */
8727 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
8728 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
8730 case 4: /* range byTime - deprecated in 2004 */
8731 case 7: /* 2004 spec */
8732 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
8733 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
8735 case 5: /* range timeRange - deprecated in 2004 */
8736 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
8737 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
8742 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8749 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8751 guint8 tag_no, tag_info;
8753 proto_tree *subtree = tree;
8756 /* set the optional global properties to indicate not-used */
8757 propertyArrayIndex = -1;
8758 /* objectIdentifier, propertyIdentifier, and
8759 OPTIONAL propertyArrayIndex */
8760 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
8761 /* resultFlags => BACnetResultFlags ::= BIT STRING */
8762 offset = fBitStringTagVS (tvb, tree, offset,
8766 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
8768 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8769 if (tag_is_opening(tag_info)) {
8770 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8771 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
8772 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8773 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8774 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8775 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8777 /* firstSequenceNumber - OPTIONAL */
8778 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8779 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
8786 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8788 guint lastoffset = 0;
8790 guint8 tag_no, tag_info;
8792 proto_tree* subtree = NULL;
8794 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8796 if (tag_is_opening(tag_info)) {
8797 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
8798 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8799 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8800 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
8801 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
8804 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
8805 /* exit loop if nothing happens inside */
8806 lastoffset = offset;
8807 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
8811 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
8812 /* More Flag is not set, so we can look for closing tag in this segment */
8813 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8814 if (tag_is_closing(tag_info)) {
8815 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8823 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8825 guint8 tag_no, tag_info;
8827 proto_tree *subtree = tree;
8830 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8832 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8834 if (tag_is_opening(tag_info)) {
8835 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
8836 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8837 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8838 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
8839 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
8840 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8846 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8849 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
8850 offset = fAccessMethod(tvb, pinfo, tree, offset);
8856 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
8858 guint tag_no = fTagNo(tvb, offset);
8859 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
8863 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8865 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
8866 offset = fAccessMethod(tvb,pinfo, tree, offset);
8872 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8874 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8875 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
8879 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8881 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8882 return fReadAccessResult (tvb,pinfo,tree,offset);
8886 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8888 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8891 switch (service_choice) {
8892 case 0: /* acknowledgeAlarm */
8893 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
8895 case 1: /* confirmedCOVNotification */
8896 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8898 case 2: /* confirmedEventNotification */
8899 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8901 case 3: /* confirmedGetAlarmSummary conveys no parameters */
8903 case 4: /* getEnrollmentSummaryRequest */
8904 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
8906 case 5: /* subscribeCOVRequest */
8907 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
8909 case 6: /* atomicReadFile-Request */
8910 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
8912 case 7: /* atomicWriteFile-Request */
8913 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
8915 case 8: /* AddListElement-Request */
8916 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
8918 case 9: /* removeListElement-Request */
8919 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
8921 case 10: /* createObjectRequest */
8922 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
8924 case 11: /* deleteObject */
8925 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
8928 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
8931 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
8934 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
8937 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
8940 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
8943 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
8946 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8949 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8952 offset = fReinitializeDeviceRequest(tvb, tree, offset);
8955 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
8958 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8961 offset = fVtDataRequest (tvb, pinfo, tree, offset);
8964 offset = fAuthenticateRequest (tvb, tree, offset);
8967 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
8970 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
8973 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
8976 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
8979 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
8988 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8990 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8993 switch (service_choice) {
8994 case 3: /* confirmedEventNotificationAck */
8995 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
8997 case 4: /* getEnrollmentSummaryAck */
8998 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
9000 case 6: /* atomicReadFile */
9001 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
9003 case 7: /* atomicReadFileAck */
9004 offset = fAtomicWriteFileAck (tvb, tree, offset);
9006 case 10: /* createObject */
9007 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
9010 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
9013 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
9016 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
9019 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
9022 offset = fVtOpenAck (tvb, pinfo, tree, offset);
9025 offset = fVtDataAck (tvb, tree, offset);
9028 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
9031 offset = fReadRangeAck (tvb, pinfo, tree, offset);
9034 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
9043 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9045 /* BACnetObjectIdentifier */
9046 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
9048 /* MaxAPDULengthAccepted */
9049 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
9051 /* segmentationSupported */
9052 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
9053 "Segmentation Supported: ", BACnetSegmentation);
9056 return fVendorIdentifier (tvb, pinfo, tree, offset);
9060 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9062 /* BACnetDeviceIdentifier */
9063 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
9065 /* BACnetObjectIdentifier */
9066 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
9069 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
9074 fWhoIsRequest (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
9076 guint lastoffset = 0;
9080 guint8 tag_no, tag_info;
9083 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9084 lastoffset = offset;
9086 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9090 /* DeviceInstanceRangeLowLimit Optional */
9091 fUnsigned32(tvb, offset+tag_len, lvt, &val);
9092 if (col_get_writable(pinfo->cinfo))
9093 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
9094 offset = fDevice_Instance (tvb, tree, offset,
9095 hf_Device_Instance_Range_Low_Limit);
9098 /* DeviceInstanceRangeHighLimit Optional but
9099 required if DeviceInstanceRangeLowLimit is there */
9100 fUnsigned32(tvb, offset+tag_len, lvt, &val);
9101 if (col_get_writable(pinfo->cinfo))
9102 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
9103 offset = fDevice_Instance (tvb, tree, offset,
9104 hf_Device_Instance_Range_High_Limit);
9109 if (offset == lastoffset) break; /* nothing happened, exit loop */
9115 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9117 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9120 switch (service_choice) {
9121 case 0: /* I-Am-Request */
9122 offset = fIAmRequest (tvb, pinfo, tree, offset);
9124 case 1: /* i-Have Request */
9125 offset = fIHaveRequest (tvb, pinfo, tree, offset);
9127 case 2: /* unconfirmedCOVNotification */
9128 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
9130 case 3: /* unconfirmedEventNotification */
9131 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
9133 case 4: /* unconfirmedPrivateTransfer */
9134 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
9136 case 5: /* unconfirmedTextMessage */
9137 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
9139 case 6: /* timeSynchronization */
9140 offset = fTimeSynchronizationRequest (tvb, tree, offset);
9142 case 7: /* who-Has */
9143 offset = fWhoHas (tvb, pinfo, tree, offset);
9145 case 8: /* who-Is */
9146 offset = fWhoIsRequest (tvb, pinfo, tree, offset);
9148 case 9: /* utcTimeSynchronization */
9149 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
9158 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
9159 gint *svc, proto_item **tt)
9162 proto_tree *bacapp_tree_control;
9167 tmp = (gint) tvb_get_guint8(tvb, offset);
9168 bacapp_flags = tmp & 0x0f;
9173 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
9174 if (bacapp_flags & 0x08)
9175 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
9177 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9178 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
9179 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
9181 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
9182 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
9183 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
9184 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
9185 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
9186 offset, 1, ENC_BIG_ENDIAN);
9187 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
9188 offset, 1, ENC_BIG_ENDIAN);
9191 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
9192 if (bacapp_flags & 0x08) {
9193 bacapp_seq = tvb_get_guint8(tvb, offset);
9194 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
9195 offset++, 1, ENC_BIG_ENDIAN);
9196 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
9197 offset++, 1, ENC_BIG_ENDIAN);
9199 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
9200 offset++, 1, ENC_BIG_ENDIAN);
9205 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
9206 { /* BACnet-Confirmed-Request */
9207 /* ASHRAE 135-2001 20.1.2 */
9209 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
9213 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9214 { /* BACnet-Confirmed-Request */
9215 /* ASHRAE 135-2001 20.1.2 */
9219 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
9220 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
9224 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9225 { /* BACnet-Unconfirmed-Request-PDU */
9226 /* ASHRAE 135-2001 20.1.3 */
9230 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9232 tmp = tvb_get_guint8(tvb, offset);
9233 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
9234 offset++, 1, ENC_BIG_ENDIAN);
9235 /* Service Request follows... Variable Encoding 20.2ff */
9236 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
9240 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9241 { /* BACnet-Simple-Ack-PDU */
9242 /* ASHRAE 135-2001 20.1.4 */
9244 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9246 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
9247 offset++, 1, ENC_BIG_ENDIAN);
9248 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
9249 offset++, 1, ENC_BIG_ENDIAN);
9255 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
9256 { /* BACnet-Complex-Ack-PDU */
9257 /* ASHRAE 135-2001 20.1.5 */
9259 /* Service ACK follows... */
9260 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
9264 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9265 { /* BACnet-Complex-Ack-PDU */
9266 /* ASHRAE 135-2001 20.1.5 */
9270 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
9271 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
9275 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9276 { /* BACnet-SegmentAck-PDU */
9277 /* ASHRAE 135-2001 20.1.6 */
9280 proto_tree *bacapp_tree_control;
9282 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9283 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9285 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
9286 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
9287 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9288 offset++, 1, ENC_BIG_ENDIAN);
9289 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
9290 offset++, 1, ENC_BIG_ENDIAN);
9291 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
9292 offset++, 1, ENC_BIG_ENDIAN);
9297 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9299 guint8 tag_info = 0;
9300 guint8 parsed_tag = 0;
9302 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
9303 offset = fError(tvb, pinfo, tree, offset);
9304 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
9308 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9310 guint lastoffset = 0;
9311 guint8 tag_no = 0, tag_info = 0;
9313 proto_tree *subtree = tree;
9316 guint vendor_identifier = 0;
9317 guint service_number = 0;
9320 while (tvb_reported_length_remaining(tvb, offset)) {
9321 /* exit loop if nothing happens inside */
9322 lastoffset = offset;
9323 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9325 case 0: /* errorType */
9326 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
9328 case 1: /* vendorID */
9329 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
9330 if (col_get_writable(pinfo->cinfo))
9331 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
9332 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
9334 case 2: /* serviceNumber */
9335 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
9336 if (col_get_writable(pinfo->cinfo))
9337 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
9338 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
9340 case 3: /* errorParameters */
9341 if (tag_is_opening(tag_info)) {
9342 tt = proto_tree_add_text(subtree, tvb, offset, 1,
9343 "error Parameters");
9344 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9345 propertyIdentifier = -1;
9346 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9347 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
9348 } else if (tag_is_closing(tag_info)) {
9349 offset += fTagHeaderTree (tvb, subtree, offset,
9350 &tag_no, &tag_info, &lvt);
9353 /* error condition: let caller handle */
9360 if (offset == lastoffset) break; /* nothing happened, exit loop */
9366 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9368 guint lastoffset = 0;
9370 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9371 lastoffset = offset;
9372 switch (fTagNo(tvb, offset)) {
9373 case 0: /* errorType */
9374 offset = fContextTaggedError(tvb, pinfo, tree, offset);
9376 case 1: /* firstFailedElementNumber */
9377 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
9382 if (offset == lastoffset) break; /* nothing happened, exit loop */
9388 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9390 /* Identical to CreateObjectError */
9391 return fCreateObjectError(tvb, pinfo, tree, offset);
9395 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9397 guint8 tag_no = 0, tag_info = 0;
9400 if (fTagNo(tvb, offset) == 0) {
9402 offset = fContextTaggedError(tvb, pinfo, tree,offset);
9403 if (fTagNo(tvb, offset) == 1) {
9404 /* listOfVTSessionIdentifiers [OPTIONAL] */
9405 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
9406 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
9407 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
9410 /* should report bad packet if initial tag wasn't 0 */
9415 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9417 guint lastoffset = 0;
9418 guint8 tag_no = 0, tag_info = 0;
9421 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9422 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
9423 lastoffset = offset;
9424 switch (fTagNo(tvb, offset)) {
9425 case 0: /* errorType */
9426 offset = fContextTaggedError(tvb, pinfo, tree, offset);
9428 case 1: /* firstFailedWriteAttempt */
9429 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
9430 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
9431 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
9436 if (offset == lastoffset) break; /* nothing happened, exit loop */
9442 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9444 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
9445 "error Class: ", BACnetErrorClass, 64);
9446 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
9447 "error Code: ", BACnetErrorCode, 256);
9451 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
9454 case 8: /* no break here !!!! */
9456 offset = fChangeListError (tvb, pinfo, tree, offset);
9459 offset = fCreateObjectError (tvb, pinfo, tree, offset);
9462 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
9465 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
9468 offset = fVTCloseError (tvb, pinfo, tree, offset);
9471 return fError (tvb, pinfo, tree, offset);
9477 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9478 { /* BACnet-Error-PDU */
9479 /* ASHRAE 135-2001 20.1.7 */
9482 proto_tree *bacapp_tree_control;
9485 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9486 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9488 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9489 offset++, 1, ENC_BIG_ENDIAN);
9490 tmp = tvb_get_guint8(tvb, offset);
9491 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
9492 offset++, 1, ENC_BIG_ENDIAN);
9493 /* Error Handling follows... */
9494 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
9498 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9499 { /* BACnet-Reject-PDU */
9500 /* ASHRAE 135-2001 20.1.8 */
9503 proto_tree *bacapp_tree_control;
9505 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9506 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9508 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9509 offset++, 1, ENC_BIG_ENDIAN);
9510 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
9511 offset++, 1, ENC_BIG_ENDIAN);
9516 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9517 { /* BACnet-Abort-PDU */
9518 /* ASHRAE 135-2001 20.1.9 */
9521 proto_tree *bacapp_tree_control;
9523 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9524 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9526 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
9527 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9528 offset++, 1, ENC_BIG_ENDIAN);
9529 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
9530 offset++, 1, ENC_BIG_ENDIAN);
9535 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
9537 guint8 flag, bacapp_type;
9540 flag = (gint) tvb_get_guint8(tvb, 0);
9541 bacapp_type = (flag >> 4) & 0x0f;
9547 /* ASHRAE 135-2001 20.1.1 */
9548 switch (bacapp_type) {
9549 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
9550 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
9552 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
9553 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
9555 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
9556 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
9558 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
9559 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
9561 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
9562 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
9564 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
9565 offset = fErrorPDU(tvb, pinfo, tree, offset);
9567 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
9568 offset = fRejectPDU(tvb, pinfo, tree, offset);
9570 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
9571 offset = fAbortPDU(tvb, pinfo, tree, offset);
9578 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
9580 guint8 flag, bacapp_type;
9581 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
9582 tvbuff_t* new_tvb = NULL;
9584 guint8 bacapp_seqno = 0;
9585 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
9586 guint8 bacapp_invoke_id = 0;
9588 proto_tree *bacapp_tree = NULL;
9594 /* Strings for BACnet Statistics */
9595 const gchar errstr[]="ERROR: ";
9596 const gchar rejstr[]="REJECTED: ";
9597 const gchar abortstr[]="ABORTED: ";
9598 const gchar sackstr[]=" (SimpleAck)";
9599 const gchar cackstr[]=" (ComplexAck)";
9600 const gchar uconfsreqstr[]=" (Unconfirmed Service Request)";
9601 const gchar confsreqstr[]=" (Confirmed Service Request)";
9603 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
9604 col_clear (pinfo->cinfo, COL_INFO);
9606 flag = tvb_get_guint8(tvb, 0);
9607 bacapp_type = (flag >> 4) & 0x0f;
9609 /* show some descriptive text in the INFO column */
9610 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
9611 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
9613 bacinfo.service_type = NULL;
9614 bacinfo.invoke_id = NULL;
9615 bacinfo.instance_ident = NULL;
9616 bacinfo.object_ident = NULL;
9618 switch (bacapp_type)
9620 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
9621 /* segmented messages have 2 additional bytes */
9622 if (flag & BACAPP_SEGMENTED_REQUEST) {
9625 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
9626 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
9627 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
9628 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
9629 bacapp_service = tvb_get_guint8(tvb, offset + 5);
9632 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
9633 bacapp_service = tvb_get_guint8(tvb, offset + 3);
9635 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
9636 val_to_str(bacapp_service,
9637 BACnetConfirmedServiceChoice,
9638 bacapp_unknown_service_str),bacapp_invoke_id);
9640 updateBacnetInfoValue(BACINFO_INVOKEID,
9641 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9643 updateBacnetInfoValue(BACINFO_SERVICE,
9644 ep_strconcat(val_to_str(bacapp_service,
9645 BACnetConfirmedServiceChoice,
9646 bacapp_unknown_service_str),
9647 confsreqstr, NULL));
9649 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
9650 bacapp_service = tvb_get_guint8(tvb, offset + 1);
9651 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
9652 val_to_str(bacapp_service,
9653 BACnetUnconfirmedServiceChoice,
9654 bacapp_unknown_service_str));
9656 updateBacnetInfoValue(BACINFO_SERVICE,
9657 ep_strconcat(val_to_str(bacapp_service,
9658 BACnetUnconfirmedServiceChoice,
9659 bacapp_unknown_service_str),
9660 uconfsreqstr, NULL));
9662 case BACAPP_TYPE_SIMPLE_ACK:
9663 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9664 bacapp_service = tvb_get_guint8(tvb, offset + 2);
9665 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9666 val_to_str(bacapp_service,
9667 BACnetConfirmedServiceChoice,
9668 bacapp_unknown_service_str), bacapp_invoke_id);
9670 updateBacnetInfoValue(BACINFO_INVOKEID,
9671 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9673 updateBacnetInfoValue(BACINFO_SERVICE,
9674 ep_strconcat(val_to_str(bacapp_service,
9675 BACnetConfirmedServiceChoice,
9676 bacapp_unknown_service_str),
9679 case BACAPP_TYPE_COMPLEX_ACK:
9680 /* segmented messages have 2 additional bytes */
9681 if (flag & BACAPP_SEGMENTED_REQUEST) {
9684 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
9685 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9686 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
9687 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
9688 bacapp_service = tvb_get_guint8(tvb, offset + 4);
9691 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9692 bacapp_service = tvb_get_guint8(tvb, offset + 2);
9694 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9695 val_to_str(bacapp_service,
9696 BACnetConfirmedServiceChoice,
9697 bacapp_unknown_service_str), bacapp_invoke_id);
9699 updateBacnetInfoValue(BACINFO_INVOKEID,
9700 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9702 updateBacnetInfoValue(BACINFO_SERVICE,
9703 ep_strconcat(val_to_str(bacapp_service,
9704 BACnetConfirmedServiceChoice,
9705 bacapp_unknown_service_str),
9708 case BACAPP_TYPE_SEGMENT_ACK:
9709 /* nothing more to add */
9711 case BACAPP_TYPE_ERROR:
9712 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9713 bacapp_service = tvb_get_guint8(tvb, offset + 2);
9714 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9715 val_to_str(bacapp_service,
9716 BACnetConfirmedServiceChoice,
9717 bacapp_unknown_service_str), bacapp_invoke_id);
9719 updateBacnetInfoValue(BACINFO_INVOKEID,
9720 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9722 updateBacnetInfoValue(BACINFO_SERVICE,
9723 ep_strconcat(errstr,
9724 val_to_str(bacapp_service,
9725 BACnetConfirmedServiceChoice,
9726 bacapp_unknown_service_str),
9729 case BACAPP_TYPE_REJECT:
9730 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9731 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
9732 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9733 val_to_split_str(bacapp_reason,
9736 ASHRAE_Reserved_Fmt,
9737 Vendor_Proprietary_Fmt), bacapp_invoke_id);
9739 updateBacnetInfoValue(BACINFO_INVOKEID,
9740 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9742 updateBacnetInfoValue(BACINFO_SERVICE,
9743 ep_strconcat(rejstr,
9744 val_to_split_str(bacapp_reason, 64,
9746 ASHRAE_Reserved_Fmt,
9747 Vendor_Proprietary_Fmt),
9750 case BACAPP_TYPE_ABORT:
9751 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9752 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
9753 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9754 val_to_split_str(bacapp_reason,
9757 ASHRAE_Reserved_Fmt,
9758 Vendor_Proprietary_Fmt), bacapp_invoke_id);
9760 updateBacnetInfoValue(BACINFO_INVOKEID,
9761 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
9763 updateBacnetInfoValue(BACINFO_SERVICE,
9764 ep_strconcat(abortstr,
9765 val_to_split_str(bacapp_reason,
9768 ASHRAE_Reserved_Fmt,
9769 Vendor_Proprietary_Fmt),
9774 /* nothing more to add */
9778 save_fragmented = pinfo->fragmented;
9780 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, FALSE);
9781 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
9784 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
9786 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
9787 /* not resetting the offset so the remaining can be done */
9789 if (fragment) { /* fragmented */
9790 fragment_data *frag_msg = NULL;
9793 pinfo->fragmented = TRUE;
9795 frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
9796 bacapp_invoke_id, /* ID for fragments belonging together */
9797 msg_fragment_table, /* list of message fragments */
9798 msg_reassembled_table, /* list of reassembled messages */
9799 bacapp_seqno, /* fragment sequence number */
9800 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
9801 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
9802 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
9803 "Reassembled BACapp", frag_msg, &msg_frag_items,
9806 if (new_tvb) { /* Reassembled */
9807 col_append_str(pinfo->cinfo, COL_INFO,
9808 " (Message Reassembled)");
9809 } else { /* Not last packet of reassembled Short Message */
9810 col_append_fstr(pinfo->cinfo, COL_INFO,
9811 " (Message fragment %u)", bacapp_seqno);
9813 if (new_tvb) { /* take it all */
9814 switch (bacapp_type)
9816 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
9817 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
9819 case BACAPP_TYPE_COMPLEX_ACK:
9820 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
9830 pinfo->fragmented = save_fragmented;
9833 tap_queue_packet(bacapp_tap,pinfo,&bacinfo);
9837 bacapp_init_routine(void)
9839 fragment_table_init(&msg_fragment_table);
9840 reassembled_table_init(&msg_reassembled_table);
9844 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
9849 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
9850 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
9851 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
9854 g_iconv_close (icd);
9858 uni_to_string(in,*inbytesleft,out);
9859 out[*inbytesleft] = '\0';
9860 *outbytesleft -= *inbytesleft;
9867 uni_to_string(char * data, gsize str_length, char *dest_buf)
9871 gsize length_remaining = 0;
9873 length_remaining = str_length;
9875 if(str_length == 0) {
9878 for ( i = 0; i < (gint) str_length; i++ ) {
9880 if (c_char<0x20 || c_char>0x7e) {
9881 if (c_char != 0x00) {
9883 dest_buf[i] = c_char & 0xff;
9889 dest_buf[i] = c_char & 0xff;
9893 if(length_remaining==0) {
9894 dest_buf[i+1] = '\0';
9906 proto_register_bacapp(void)
9908 static hf_register_info hf[] = {
9910 { "APDU Type", "bacapp.type",
9911 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
9913 { &hf_bacapp_pduflags,
9914 { "PDU Flags", "bacapp.pduflags",
9915 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
9918 { "Segmented Request", "bacapp.segmented_request",
9919 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
9922 { "More Segments", "bacapp.more_segments",
9923 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
9926 { "SA", "bacapp.SA",
9927 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
9929 { &hf_bacapp_max_adpu_size,
9930 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
9931 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
9933 { &hf_bacapp_response_segments,
9934 { "Max Response Segments accepted", "bacapp.response_segments",
9935 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
9937 { &hf_bacapp_objectType,
9938 { "Object Type", "bacapp.objectType",
9939 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
9941 { &hf_bacapp_instanceNumber,
9942 { "Instance Number", "bacapp.instance_number",
9943 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
9945 { &hf_BACnetPropertyIdentifier,
9946 { "Property Identifier", "bacapp.property_identifier",
9947 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
9949 { &hf_BACnetVendorIdentifier,
9950 { "Vendor Identifier", "bacapp.vendor_identifier",
9951 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
9953 { &hf_BACnetRestartReason,
9954 { "Restart Reason", "bacapp.restart_reason",
9955 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
9957 { &hf_bacapp_invoke_id,
9958 { "Invoke ID", "bacapp.invoke_id",
9959 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9961 { &hf_bacapp_sequence_number,
9962 { "Sequence Number", "bacapp.sequence_number",
9963 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9965 { &hf_bacapp_window_size,
9966 { "Proposed Window Size", "bacapp.window_size",
9967 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9969 { &hf_bacapp_service,
9970 { "Service Choice", "bacapp.confirmed_service",
9971 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
9973 { &hf_bacapp_uservice,
9974 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
9975 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
9978 { "NAK", "bacapp.NAK",
9979 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
9982 { "SRV", "bacapp.SRV",
9983 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
9985 { &hf_Device_Instance_Range_Low_Limit,
9986 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
9987 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
9989 { &hf_Device_Instance_Range_High_Limit,
9990 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
9991 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
9993 { &hf_BACnetRejectReason,
9994 { "Reject Reason", "bacapp.reject_reason",
9995 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
9997 { &hf_BACnetAbortReason,
9998 { "Abort Reason", "bacapp.abort_reason",
9999 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
10001 { &hf_BACnetApplicationTagNumber,
10002 { "Application Tag Number",
10003 "bacapp.application_tag_number",
10004 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
10007 { &hf_BACnetContextTagNumber,
10008 { "Context Tag Number",
10009 "bacapp.context_tag_number",
10010 FT_UINT8, BASE_DEC, NULL, 0xF0,
10013 { &hf_BACnetExtendedTagNumber,
10014 { "Extended Tag Number",
10015 "bacapp.extended_tag_number",
10016 FT_UINT8, BASE_DEC, NULL, 0,
10019 { &hf_BACnetNamedTag,
10021 "bacapp.named_tag",
10022 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
10025 { &hf_BACnetCharacterSet,
10026 { "String Character Set",
10027 "bacapp.string_character_set",
10028 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet),0,
10031 { &hf_BACnetTagClass,
10032 { "Tag Class", "bacapp.tag_class",
10033 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
10035 { &hf_bacapp_tag_lvt,
10036 { "Length Value Type",
10038 FT_UINT8, BASE_DEC, NULL, 0,
10041 { &hf_bacapp_tag_ProcessId,
10042 { "ProcessIdentifier", "bacapp.processId",
10043 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
10045 { &hf_bacapp_tag_IPV4,
10046 { "IPV4", "bacapp.IPV4",
10047 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
10049 { &hf_bacapp_tag_IPV6,
10050 { "IPV6", "bacapp.IPV6",
10051 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
10053 { &hf_bacapp_tag_PORT,
10054 { "Port", "bacapp.Port",
10055 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
10057 {&hf_msg_fragments,
10058 {"Message fragments", "bacapp.fragments",
10059 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10061 {"Message fragment", "bacapp.fragment",
10062 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10063 {&hf_msg_fragment_overlap,
10064 {"Message fragment overlap", "bacapp.fragment.overlap",
10065 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10066 {&hf_msg_fragment_overlap_conflicts,
10067 {"Message fragment overlapping with conflicting data",
10068 "bacapp.fragment.overlap.conflicts",
10069 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10070 {&hf_msg_fragment_multiple_tails,
10071 {"Message has multiple tail fragments",
10072 "bacapp.fragment.multiple_tails",
10073 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10074 {&hf_msg_fragment_too_long_fragment,
10075 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
10076 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10077 {&hf_msg_fragment_error,
10078 {"Message defragmentation error", "bacapp.fragment.error",
10079 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10080 {&hf_msg_fragment_count,
10081 {"Message fragment count", "bacapp.fragment.count",
10082 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
10083 {&hf_msg_reassembled_in,
10084 {"Reassembled in", "bacapp.reassembled.in",
10085 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10086 {&hf_msg_reassembled_length,
10087 {"Reassembled BACapp length", "bacapp.reassembled.length",
10088 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
10090 static gint *ett[] = {
10092 &ett_bacapp_control,
10101 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
10102 "BACapp", "bacapp");
10104 proto_register_field_array(proto_bacapp, hf, array_length(hf));
10105 proto_register_subtree_array(ett, array_length(ett));
10106 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
10107 register_init_routine (&bacapp_init_routine);
10109 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
10110 "BACapp Vendor Identifier",
10111 FT_UINT8, BASE_HEX);
10113 /* Register BACnet Statistic trees */
10114 register_bacapp_stat_trees();
10115 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
10119 proto_reg_handoff_bacapp(void)
10121 data_handle = find_dissector("data");