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 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #include <epan/packet.h>
37 #include <epan/reassemble.h>
38 #include <epan/expert.h>
39 #include <epan/stats_tree.h>
40 #include "packet-bacapp.h"
42 static int bacapp_tap = -1;
44 /* formerly bacapp.h contains definitions and forward declarations */
47 #define FAULT proto_tree_add_text(subtree, tvb, offset, tvb_length(tvb) - offset, "something is going wrong here !!"); \
48 offset = tvb_length(tvb);
51 /* BACnet PDU Types */
52 #define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0
53 #define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1
54 #define BACAPP_TYPE_SIMPLE_ACK 2
55 #define BACAPP_TYPE_COMPLEX_ACK 3
56 #define BACAPP_TYPE_SEGMENT_ACK 4
57 #define BACAPP_TYPE_ERROR 5
58 #define BACAPP_TYPE_REJECT 6
59 #define BACAPP_TYPE_ABORT 7
60 #define MAX_BACAPP_TYPE 8
62 #define BACAPP_SEGMENTED_REQUEST 0x08
63 #define BACAPP_MORE_SEGMENTS 0x04
64 #define BACAPP_SEGMENTED_RESPONSE 0x02
65 #define BACAPP_SEGMENT_NAK 0x02
66 #define BACAPP_SENT_BY 0x01
70 * dissect_bacapp ::= CHOICE {
71 * confirmed-request-PDU [0] BACnet-Confirmed-Request-PDU,
72 * unconfirmed-request-PDU [1] BACnet-Unconfirmed-Request-PDU,
73 * simpleACK-PDU [2] BACnet-SimpleACK-PDU,
74 * complexACK-PDU [3] BACnet-ComplexACK-PDU,
75 * segmentACK-PDU [4] BACnet-SegmentACK-PDU,
76 * error-PDU [5] BACnet-Error-PDU,
77 * reject-PDU [6] BACnet-Reject-PDU,
78 * abort-PDU [7] BACnet-Abort-PDU
85 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
88 * ConfirmedRequest-PDU ::= SEQUENCE {
89 * pdu-type [0] Unsigned (0..15), -- 0 for this PDU Type
90 * segmentedMessage [1] BOOLEAN,
91 * moreFollows [2] BOOLEAN,
92 * segmented-response-accepted [3] BOOLEAN,
93 * reserved [4] Unsigned (0..3), -- must be set zero
94 * max-segments-accepted [5] Unsigned (0..7), -- as per 20.1.2.4
95 * max-APDU-length-accepted [5] Unsigned (0..15), -- as per 20.1.2.5
96 * invokeID [6] Unsigned (0..255),
97 * sequence-number [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
98 * proposed-window-size [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
99 * service-choice [9] BACnetConfirmedServiceChoice,
100 * service-request [10] BACnet-Confirmed-Service-Request OPTIONAL
106 * @return modified offset
109 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
116 * @param ack - indocates whether working on request or ack
117 * @param svc - output variable to return service choice
118 * @param tt - output varable to return service choice item
119 * @return modified offset
122 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 ack,
123 gint *svc, proto_item **tt);
126 * Unconfirmed-Request-PDU ::= SEQUENCE {
127 * pdu-type [0] Unsigned (0..15), -- 1 for this PDU type
128 * reserved [1] Unsigned (0..15), -- must be set zero
129 * service-choice [2] BACnetUnconfirmedServiceChoice,
130 * service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
136 * @return modified offset
139 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
142 * SimpleACK-PDU ::= SEQUENCE {
143 * pdu-type [0] Unsigned (0..15), -- 2 for this PDU type
144 * reserved [1] Unsigned (0..15), -- must be set zero
145 * invokeID [2] Unsigned (0..255),
146 * service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
152 * @return modified offset
155 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
158 * ComplexACK-PDU ::= SEQUENCE {
159 * pdu-type [0] Unsigned (0..15), -- 3 for this PDU Type
160 * segmentedMessage [1] BOOLEAN,
161 * moreFollows [2] BOOLEAN,
162 * reserved [3] Unsigned (0..3), -- must be set zero
163 * invokeID [4] Unsigned (0..255),
164 * sequence-number [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
165 * proposed-window-size [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
166 * service-ACK-choice [7] BACnetConfirmedServiceChoice,
167 * service-ACK [8] BACnet-Confirmed-Service-Request -- Context-specific tags 0..8 are NOT used in header encoding
173 * @return modified offset
176 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
179 * SegmentACK-PDU ::= SEQUENCE {
180 * pdu-type [0] Unsigned (0..15), -- 4 for this PDU Type
181 * reserved [1] Unsigned (0..3), -- must be set zero
182 * negative-ACK [2] BOOLEAN,
183 * server [3] BOOLEAN,
184 * original-invokeID [4] Unsigned (0..255),
185 * sequence-number [5] Unsigned (0..255),
186 * actual-window-size [6] Unsigned (0..127)
192 * @return modified offset
195 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
198 * Error-PDU ::= SEQUENCE {
199 * pdu-type [0] Unsigned (0..15), -- 5 for this PDU Type
200 * reserved [1] Unsigned (0..3), -- must be set zero
201 * original-invokeID [2] Unsigned (0..255),
202 * error-choice [3] BACnetConfirmedServiceChoice,
203 * error [4] BACnet-Error
209 * @return modified offset
212 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
215 * Reject-PDU ::= SEQUENCE {
216 * pdu-type [0] Unsigned (0..15), -- 6 for this PDU Type
217 * reserved [1] Unsigned (0..3), -- must be set zero
218 * original-invokeID [2] Unsigned (0..255),
219 * reject-reason [3] BACnetRejectReason
225 * @return modified offset
228 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
231 * Abort-PDU ::= SEQUENCE {
232 * pdu-type [0] Unsigned (0..15), -- 7 for this PDU Type
233 * reserved [1] Unsigned (0..3), -- must be set zero
234 * server [2] BOOLEAN,
235 * original-invokeID [3] Unsigned (0..255),
236 * abort-reason [4] BACnetAbortReason
242 * @return modified offset
245 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
248 * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree
253 * @return modified offset
256 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
259 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
264 * @return modified offset
267 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
270 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
275 * @param lvt length of String
276 * @return modified offset
279 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
282 * 20.2.12, adds the label with Date Value to tree
287 * @return modified offset
290 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
293 * 20.2.13, adds the label with Time Value to tree
298 * @return modified offset
301 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
304 * 20.2.14, adds Object Identifier to tree
305 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
310 * @return modified offset
313 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
316 * BACnet-Confirmed-Service-Request ::= CHOICE {
322 * @param service_choice
326 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
329 * BACnet-Confirmed-Service-ACK ::= CHOICE {
335 * @param service_choice
339 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
342 * AcknowledgeAlarm-Request ::= SEQUENCE {
343 * acknowledgingProcessIdentifier [0] Unsigned32,
344 * eventObjectIdentifier [1] BACnetObjectIdentifer,
345 * eventStateAcknowledge [2] BACnetEventState,
346 * timeStamp [3] BACnetTimeStamp,
347 * acknowledgementSource [4] Character String,
348 * timeOfAcknowledgement [5] BACnetTimeStamp
354 * @return modified offset
357 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
360 * ConfirmedCOVNotification-Request ::= SEQUENCE {
361 * subscriberProcessIdentifier [0] Unsigned32,
362 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
363 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
364 * timeRemaining [3] unsigned,
365 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
371 * @return modified offset
374 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
377 * ConfirmedEventNotification-Request ::= SEQUENCE {
378 * ProcessIdentifier [0] Unsigned32,
379 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
380 * eventObjectIdentifier [2] BACnetObjectIdentifer,
381 * timeStamp [3] BACnetTimeStamp,
382 * notificationClass [4] unsigned,
383 * priority [5] unsigned8,
384 * eventType [6] BACnetEventType,
385 * messageText [7] CharacterString OPTIONAL,
386 * notifyType [8] BACnetNotifyType,
387 * ackRequired [9] BOOLEAN OPTIONAL,
388 * fromState [10] BACnetEventState OPTIONAL,
389 * toState [11] BACnetEventState,
390 * eventValues [12] BACnetNotificationParameters OPTIONAL
396 * @return modified offset
399 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
402 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
403 * objectIdentifier BACnetObjectIdentifer,
404 * alarmState BACnetEventState,
405 * acknowledgedTransitions BACnetEventTransitionBits
411 * @return modified offset
414 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
417 * GetEnrollmentSummary-Request ::= SEQUENCE {
418 * acknowledgmentFilter [0] ENUMERATED {
423 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
424 * eventStateFilter [2] ENUMERATED {
431 * eventTypeFilter [3] BACnetEventType OPTIONAL,
432 * priorityFilter [4] SEQUENCE {
433 * minPriority [0] Unsigned8,
434 * maxPriority [1] Unsigned8
436 * notificationClassFilter [5] Unsigned OPTIONAL
442 * @return modified offset
445 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
448 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
449 * objectIdentifier BACnetObjectIdentifer,
450 * eventType BACnetEventType,
451 * eventState BACnetEventState,
452 * priority Unsigned8,
453 * notificationClass Unsigned OPTIONAL
459 * @return modified offset
462 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
465 * GetEventInformation-Request ::= SEQUENCE {
466 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
472 * @return modified offset
475 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
478 * GetEventInformation-ACK ::= SEQUENCE {
479 * listOfEventSummaries [0] listOfEventSummaries,
480 * moreEvents [1] BOOLEAN
486 * @return modified offset
489 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
492 * LifeSafetyOperation-Request ::= SEQUENCE {
493 * requestingProcessIdentifier [0] Unsigned32
494 * requestingSource [1] CharacterString
495 * request [2] BACnetLifeSafetyOperation
496 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
502 * @return modified offset
505 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
508 * SubscribeCOV-Request ::= SEQUENCE {
509 * subscriberProcessIdentifier [0] Unsigned32
510 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
511 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
512 * lifetime [3] Unsigned OPTIONAL
520 * @return modified offset
523 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
526 * SubscribeCOVProperty-Request ::= SEQUENCE {
527 * subscriberProcessIdentifier [0] Unsigned32
528 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
529 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
530 * lifetime [3] Unsigned OPTIONAL
531 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
532 * covIncrement [5] Unsigned OPTIONAL
538 * @return modified offset
541 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
544 * AtomicReadFile-Request ::= SEQUENCE {
545 * fileIdentifier BACnetObjectIdentifier,
546 * accessMethod CHOICE {
547 * streamAccess [0] SEQUENCE {
548 * fileStartPosition INTEGER,
549 * requestedOctetCount Unsigned
551 * recordAccess [1] SEQUENCE {
552 * fileStartRecord INTEGER,
553 * requestedRecordCount Unsigned
561 * @return modified offset
564 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
567 * AtomicWriteFile-ACK ::= SEQUENCE {
569 * accessMethod CHOICE {
570 * streamAccess [0] SEQUENCE {
571 * fileStartPosition INTEGER,
572 * fileData OCTET STRING
574 * recordAccess [1] SEQUENCE {
575 * fileStartRecord INTEGER,
576 * returnedRecordCount Unsigned,
577 * fileRecordData SEQUENCE OF OCTET STRING
585 * @return modified offset
588 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
591 * AtomicWriteFile-Request ::= SEQUENCE {
592 * fileIdentifier BACnetObjectIdentifier,
593 * accessMethod CHOICE {
594 * streamAccess [0] SEQUENCE {
595 * fileStartPosition INTEGER,
596 * fileData OCTET STRING
598 * recordAccess [1] SEQUENCE {
599 * fileStartRecord INTEGER,
600 * recordCount Unsigned,
601 * fileRecordData SEQUENCE OF OCTET STRING
609 * @return modified offset
612 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
615 * AtomicWriteFile-ACK ::= SEQUENCE {
616 * fileStartPosition [0] INTEGER,
617 * fileStartRecord [1] INTEGER,
622 * @return modified offset
625 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
628 * AddListElement-Request ::= SEQUENCE {
629 * objectIdentifier [0] BACnetObjectIdentifier,
630 * propertyIdentifier [1] BACnetPropertyIdentifier,
631 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
632 * listOfElements [3] ABSTRACT-SYNTAX.&Type
638 * @return modified offset
641 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
644 * CreateObject-Request ::= SEQUENCE {
645 * objectSpecifier [0] ObjectSpecifier,
646 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
652 * @return modified offset
655 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
658 * CreateObject-Request ::= BACnetObjectIdentifier
663 * @return modified offset
666 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
669 * DeleteObject-Request ::= SEQUENCE {
670 * ObjectIdentifier BACnetObjectIdentifer
676 * @return modified offset
679 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
682 * ReadProperty-Request ::= SEQUENCE {
683 * objectIdentifier [0] BACnetObjectIdentifier,
684 * propertyIdentifier [1] BACnetPropertyIdentifier,
685 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
691 * @return modified offset
694 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
697 * ReadProperty-ACK ::= SEQUENCE {
698 * objectIdentifier [0] BACnetObjectIdentifier,
699 * propertyIdentifier [1] BACnetPropertyIdentifier,
700 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
701 * propertyValue [3] ABSTRACT-SYNTAX.&Type
707 * @return modified offset
710 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
713 * ReadPropertyConditional-Request ::= SEQUENCE {
714 * objectSelectionCriteria [0] objectSelectionCriteria,
715 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
721 * @return modified offset
724 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
727 * ReadPropertyConditional-ACK ::= SEQUENCE {
728 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
734 * @return modified offset
737 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
740 * ReadPropertyMultiple-Request ::= SEQUENCE {
741 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
747 * @return offset modified
750 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
753 * ReadPropertyMultiple-Ack ::= SEQUENCE {
754 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
760 * @return offset modified
763 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
766 * ReadRange-Request ::= SEQUENCE {
767 * objectIdentifier [0] BACnetObjectIdentifier,
768 * propertyIdentifier [1] BACnetPropertyIdentifier,
769 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
771 * byPosition [3] SEQUENCE {
772 * referencedIndex Unsigned,
775 * byTime [4] SEQUENCE {
776 * referenceTime BACnetDateTime,
779 * timeRange [5] SEQUENCE {
780 * beginningTime BACnetDateTime,
781 * endingTime BACnetDateTime
789 * @return modified offset
792 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
795 * ReadRange-ACK ::= SEQUENCE {
796 * objectIdentifier [0] BACnetObjectIdentifier,
797 * propertyIdentifier [1] BACnetPropertyIdentifier,
798 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
799 * resultFlags [3] BACnetResultFlags,
800 * itemCount [4] Unsigned,
801 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
807 * @return modified offset
810 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
813 * RemoveListElement-Request ::= SEQUENCE {
814 * objectIdentifier [0] BACnetObjectIdentifier,
815 * propertyIdentifier [1] BACnetPropertyIdentifier,
816 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
817 * listOfElements [3] ABSTRACT-SYNTAX.&Type
823 * @return modified offset
826 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
829 * WriteProperty-Request ::= SEQUENCE {
830 * objectIdentifier [0] BACnetObjectIdentifier,
831 * propertyIdentifier [1] BACnetPropertyIdentifier,
832 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
833 * propertyValue [3] ABSTRACT-SYNTAX.&Type
834 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
840 * @return modified offset
843 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
846 * WritePropertyMultiple-Request ::= SEQUENCE {
847 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
853 * @return modified offset
856 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
859 * DeviceCommunicationControl-Request ::= SEQUENCE {
860 * timeDuration [0] Unsigned16 OPTIONAL,
861 * enable-disable [1] ENUMERATED {
865 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
870 * @return modified offset
873 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
876 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
877 * vendorID [0] Unsigned,
878 * serviceNumber [1] Unsigned,
879 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
885 * @return modified offset
888 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
891 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
892 * vendorID [0] Unsigned,
893 * serviceNumber [1] Unsigned,
894 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
900 * @return modified offset
903 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
906 * ConfirmedTextMessage-Request ::= SEQUENCE {
907 * textMessageSourceDevice [0] BACnetObjectIdentifier,
908 * messageClass [1] CHOICE {
909 * numeric [0] Unsigned,
910 * character [1] CharacterString
912 * messagePriority [2] ENUMERATED {
916 * message [3] CharacterString
922 * @return modified offset
925 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
928 * ReinitializeDevice-Request ::= SEQUENCE {
929 * reinitializedStateOfDevice [0] ENUMERATED {
938 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
943 * @return modified offset
946 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
949 * VTOpen-Request ::= SEQUENCE {
950 * vtClass BACnetVTClass,
951 * localVTSessionIdentifier Unsigned8
957 * @return modified offset
960 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
963 * VTOpen-ACK ::= SEQUENCE {
964 * remoteVTSessionIdentifier Unsigned8
970 * @return modified offset
973 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
976 * VTClose-Request ::= SEQUENCE {
977 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
983 * @return modified offset
986 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
989 * VTData-Request ::= SEQUENCE {
990 * vtSessionIdentifier Unsigned8,
991 * vtNewData OCTET STRING,
992 * vtDataFlag Unsigned (0..1)
998 * @return modified offset
1001 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1004 * VTData-ACK ::= SEQUENCE {
1005 * allNewDataAccepted [0] BOOLEAN,
1006 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1011 * @return modified offset
1014 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
1017 * Authenticate-Request ::= SEQUENCE {
1018 * pseudoRandomNumber [0] Unsigned32,
1019 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1020 * operatorName [2] CharacterString OPTIONAL,
1021 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1022 * startEncypheredSession [4] BOOLEAN OPTIONAL
1027 * @return modified offset
1030 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1033 * Authenticate-ACK ::= SEQUENCE {
1034 * modifiedRandomNumber Unsigned32,
1040 * @return modified offset
1043 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1046 * RequestKey-Request ::= SEQUENCE {
1047 * requestingDeviceIdentifier BACnetObjectIdentifier,
1048 * requestingDeviceAddress BACnetAddress,
1049 * remoteDeviceIdentifier BACnetObjectIdentifier,
1050 * remoteDeviceAddress BACnetAddress
1056 * @return modified offset
1059 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1062 * Unconfirmed-Service-Request ::= CHOICE {
1068 * @param service_choice
1069 * @return modified offset
1072 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1075 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1076 * subscriberProcessIdentifier [0] Unsigned32,
1077 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1078 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1079 * timeRemaining [3] unsigned,
1080 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1086 * @return modified offset
1089 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1092 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1093 * ProcessIdentifier [0] Unsigned32,
1094 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1095 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1096 * timeStamp [3] BACnetTimeStamp,
1097 * notificationClass [4] unsigned,
1098 * priority [5] unsigned8,
1099 * eventType [6] BACnetEventType,
1100 * messageText [7] CharacterString OPTIONAL,
1101 * notifyType [8] BACnetNotifyType,
1102 * ackRequired [9] BOOLEAN OPTIONAL,
1103 * fromState [10] BACnetEventState OPTIONAL,
1104 * toState [11] BACnetEventState,
1105 * eventValues [12] BACnetNotificationParameters OPTIONAL
1111 * @return modified offset
1114 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1117 * I-Am-Request ::= SEQUENCE {
1118 * aAmDeviceIdentifier BACnetObjectIdentifier,
1119 * maxAPDULengthAccepted Unsigned,
1120 * segmentationSupported BACnetSegmentation,
1127 * @return modified offset
1130 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1134 * I-Have-Request ::= SEQUENCE {
1135 * deviceIdentifier BACnetObjectIdentifier,
1136 * objectIdentifier BACnetObjectIdentifier,
1137 * objectName CharacterString
1143 * @return modified offset
1146 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1149 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1150 * vendorID [0] Unsigned,
1151 * serviceNumber [1] Unsigned,
1152 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1158 * @return modified offset
1161 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1164 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1165 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1166 * messageClass [1] CHOICE {
1167 * numeric [0] Unsigned,
1168 * character [1] CharacterString
1170 * messagePriority [2] ENUMERATED {
1174 * message [3] CharacterString
1180 * @return modified offset
1183 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1186 * TimeSynchronization-Request ::= SEQUENCE {
1192 * @return modified offset
1195 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1198 * UTCTimeSynchronization-Request ::= SEQUENCE {
1204 * @return modified offset
1207 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1210 * Who-Has-Request ::= SEQUENCE {
1212 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1213 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1216 * objectIdentifier [2] BACnetObjectIdentifier,
1217 * objectName [3] CharacterString
1224 * @return modified offset
1227 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1230 * Who-Is-Request ::= SEQUENCE {
1231 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1232 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1237 * @return modified offset
1240 fWhoIsRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1243 * BACnet-Error ::= CHOICE {
1244 * addListElement [8] ChangeList-Error,
1245 * removeListElement [9] ChangeList-Error,
1246 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1247 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1248 * vtClose [22] VTClose-Error,
1249 * readRange [26] ObjectAccessService-Error
1257 * @return modified offset
1260 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1263 * Dissect a BACnetError in a context tag
1269 * @return modified offset
1271 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1274 * ChangeList-Error ::= SEQUENCE {
1275 * errorType [0] Error,
1276 * firstFailedElementNumber [1] Unsigned
1283 * @return modified offset
1286 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1289 * CreateObject-Error ::= SEQUENCE {
1290 * errorType [0] Error,
1291 * firstFailedElementNumber [1] Unsigned
1298 * @return modified offset
1301 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1304 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1305 * errorType [0] Error,
1306 * vendorID [1] Unsigned,
1307 * serviceNumber [2] Unsigned,
1308 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1315 * @return modified offset
1318 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1321 * WritePropertyMultiple-Error ::= SEQUENCE {
1322 * errorType [0] Error,
1323 * firstFailedWriteAttempt [1] Unsigned
1330 * @return modified offset
1333 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1336 * VTClose-Error ::= SEQUENCE {
1337 * errorType [0] Error,
1338 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1345 * @return modified offset
1348 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1351 * BACnet Application Types chapter 20.2.1
1357 * @return modified offset
1360 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1363 * BACnetActionCommand ::= SEQUENCE {
1364 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1365 * objectIdentifier [1] BACnetObjectIdentifier,
1366 * propertyIdentifier [2] BACnetPropertyIdentifier,
1367 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1368 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1369 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1370 * postDelay [6] Unsigned OPTIONAL,
1371 * quitOnFailure [7] BOOLEAN,
1372 * writeSuccessful [8] BOOLEAN
1378 * @param matching tag number
1379 * @return modified offset
1382 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1385 * BACnetActionList ::= SEQUENCE {
1386 * action [0] SEQUENCE of BACnetActionCommand
1392 * @return modified offset
1395 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1397 /** BACnetAddress ::= SEQUENCE {
1398 * network-number Unsigned16, -- A value 0 indicates the local network
1399 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1404 * @return modified offset
1407 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset);
1410 * BACnetAddressBinding ::= SEQUENCE {
1411 * deviceObjectID BACnetObjectIdentifier
1412 * deviceAddress BacnetAddress
1418 * @return modified offset
1421 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1424 * BACnetCalendarEntry ::= CHOICE {
1426 * dateRange [1] BACnetDateRange,
1427 * weekNDay [2] BacnetWeekNday
1432 * @return modified offset
1435 fCalendarEntry (tvbuff_t *tvb, proto_tree *tree, guint offset);
1438 * BACnetClientCOV ::= CHOICE {
1439 * real-increment REAL,
1440 * default-increment NULL
1445 * @return modified offset
1448 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1452 * BACnetDailySchedule ::= SEQUENCE {
1453 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1459 * @return modified offset
1462 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1465 * BACnetWeeklySchedule ::= SEQUENCE {
1466 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1472 * @return modified offset
1475 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1478 * BACnetDateRange ::= SEQUENCE {
1485 * @return modified offset
1488 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset);
1491 * BACnetDateTime ::= SEQUENCE {
1499 * @return modified offset
1502 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1505 * BACnetDestination ::= SEQUENCE {
1506 * validDays BACnetDaysOfWeek,
1509 * recipient BACnetRecipient,
1510 * processIdentifier Unsigned32,
1511 * issueConfirmedNotifications BOOLEAN,
1512 * transitions BACnetEventTransitionBits
1518 * @return modified offset
1521 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1524 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1525 * objectIdentifier [0] BACnetObjectIdentifier,
1526 * propertyIdentifier [1] BACnetPropertyIdentifier,
1527 * propertyArrayIndex [2] Unsigend OPTIONAL,
1528 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1534 * @return modified offset
1537 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1540 * BACnetObjectPropertyReference ::= SEQUENCE {
1541 * objectIdentifier [0] BACnetObjectIdentifier,
1542 * propertyIdentifier [1] BACnetPropertyIdentifier,
1543 * propertyArrayIndex [2] Unsigend OPTIONAL,
1549 * @return modified offset
1552 fObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1555 * BACnetDeviceObjectReference ::= SEQUENCE {
1556 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1557 * objectIdentifier [1] BACnetObjectIdentifier
1563 * @return modified offset
1566 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1569 * BACnetEventParameter ::= CHOICE {
1570 * change-of-bitstring [0] SEQUENCE {
1571 * time-delay [0] Unsigned,
1572 * bitmask [1] BIT STRING,
1573 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1575 * change-of-state [1] SEQUENCE {
1576 * time-delay [0] Unsigned,
1577 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1579 * change-of-value [2] SEQUENCE {
1580 * time-delay [0] Unsigned,
1581 * cov-criteria [1] CHOICE {
1582 * bitmask [0] BIT STRING,
1583 * referenced-property-increment [1] REAL
1586 * command-failure [3] SEQUENCE {
1587 * time-delay [0] Unsigned,
1588 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1590 * floating-limit [4] SEQUENCE {
1591 * time-delay [0] Unsigned,
1592 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1593 * low-diff-limit [2] REAL,
1594 * high-diff-limit [3] REAL,
1597 * out-of-range [5] SEQUENCE {
1598 * time-delay [0] Unsigned,
1599 * low-limit [1] REAL,
1600 * high-limit [2] REAL,
1603 * buffer-ready [7] SEQUENCE {
1604 * notification-threshold [0] Unsigned,
1605 * previous-notification-count [1] Unsigned32
1607 * change-of-life-safety [8] SEQUENCE {
1608 * time-delay [0] Unsigned,
1609 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1610 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1611 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1617 * @return modified offset
1620 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1625 * BACnetLogRecord ::= SEQUENCE {
1626 * timestamp [0] BACnetDateTime,
1627 * logDatum [1] CHOICE {
1628 * log-status [0] BACnetLogStatus,
1629 * boolean-value [1] BOOLEAN,
1630 * real-value [2] REAL,
1631 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1632 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1633 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1634 * bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
1635 * null-value [7] NULL,
1636 * failure [8] Error,
1637 * time-change [9] REAL,
1638 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1640 * statusFlags [2] BACnetStatusFlags OPTIONAL
1646 * @return modified offset
1649 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1652 * BACnetEventLogRecord ::= SEQUENCE {
1653 * timestamp [0] BACnetDateTime,
1654 * logDatum [1] CHOICE {
1655 * log-status [0] BACnetLogStatus,
1656 * notification [1] ConfirmedEventNotification-Request,
1657 * time-change [2] REAL,
1664 * @return modified offset
1667 fEventLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1670 fLogMultipleRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1673 * BACnetNotificationParameters ::= CHOICE {
1674 * change-of-bitstring [0] SEQUENCE {
1675 * referenced-bitstring [0] BIT STRING,
1676 * status-flags [1] BACnetStatusFlags
1678 * change-of-state [1] SEQUENCE {
1679 * new-state [0] BACnetPropertyStatus,
1680 * status-flags [1] BACnetStatusFlags
1682 * change-of-value [2] SEQUENCE {
1683 * new-value [0] CHOICE {
1684 * changed-bits [0] BIT STRING,
1685 * changed-value [1] REAL
1687 * status-flags [1] BACnetStatusFlags
1689 * command-failure [3] SEQUENCE {
1690 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1691 * status-flags [1] BACnetStatusFlags
1692 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1694 * floating-limit [4] SEQUENCE {
1695 * reference-value [0] REAL,
1696 * status-flags [1] BACnetStatusFlags
1697 * setpoint-value [2] REAL,
1698 * error-limit [3] REAL
1700 * out-of-range [5] SEQUENCE {
1701 * exceeding-value [0] REAL,
1702 * status-flags [1] BACnetStatusFlags
1703 * deadband [2] REAL,
1704 * exceeded-limit [0] REAL
1706 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1707 * buffer-ready [7] SEQUENCE {
1708 * buffer-device [0] BACnetObjectIdentifier,
1709 * buffer-object [1] BACnetObjectIdentifier
1710 * previous-notification[2] BACnetDateTime,
1711 * current-notification [3] BACnetDateTime
1713 * change-of-life-safety [8] SEQUENCE {
1714 * new-state [0] BACnetLifeSafetyState,
1715 * new-mode [1] BACnetLifeSafetyState
1716 * status-flags [2] BACnetStatusFlags,
1717 * operation-expected [3] BACnetLifeSafetyOperation
1724 * @return modified offset
1727 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1730 * BACnetObjectPropertyReference ::= SEQUENCE {
1731 * objectIdentifier [0] BACnetObjectIdentifier,
1732 * propertyIdentifier [1] BACnetPropertyIdentifier,
1733 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1739 * @return modified offset
1742 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1746 * BACnetObjectPropertyValue ::= SEQUENCE {
1747 * objectIdentifier [0] BACnetObjectIdentifier,
1748 * propertyIdentifier [1] BACnetPropertyIdentifier,
1749 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1750 * -- if omitted with an array the entire array is referenced
1751 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1752 * priority [4] Unsigned (1..16) OPTIONAL
1757 * @return modified offset
1760 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
1764 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1769 * @return modified offset
1772 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1775 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1778 * BACnetPropertyReference ::= SEQUENCE {
1779 * propertyIdentifier [0] BACnetPropertyIdentifier,
1780 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1786 * @return modified offset
1789 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1792 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1795 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1798 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1801 * BACnetPropertyValue ::= SEQUENCE {
1802 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1803 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1804 * -- if omitted with an array the entire array is referenced
1805 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1806 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1812 * @return modified offset
1815 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1818 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1821 * BACnet Application PDUs chapter 21
1822 * BACnetRecipient::= CHOICE {
1823 * device [0] BACnetObjectIdentifier
1824 * address [1] BACnetAddress
1830 * @return modified offset
1833 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1836 * BACnet Application PDUs chapter 21
1837 * BACnetRecipientProcess::= SEQUENCE {
1838 * recipient [0] BACnetRecipient
1839 * processID [1] Unsigned32
1845 * @return modified offset
1848 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1851 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1855 * BACnetSessionKey ::= SEQUENCE {
1856 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1857 * peerAddress BACnetAddress
1862 * @return modified offset
1863 * @todo check if checksum is displayed correctly
1866 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1870 * BACnetSpecialEvent ::= SEQUENCE {
1872 * calendarEntry [0] BACnetCalendarEntry,
1873 * calendarRefernce [1] BACnetObjectIdentifier
1875 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1876 * eventPriority [3] Unsigned (1..16)
1882 * @return modified offset
1885 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1888 * BACnetTimeStamp ::= CHOICE {
1890 * sequenceNumber [1] Unsigned (0..65535),
1891 * dateTime [2] BACnetDateTime
1897 * @return modified offset
1900 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1903 fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1906 * BACnetTimeValue ::= SEQUENCE {
1908 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1914 * @return modified offset
1917 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1921 * BACnetVTSession ::= SEQUENCE {
1922 * local-vtSessionID Unsigned8,
1923 * remote-vtSessionID Unsigned8,
1924 * remote-vtAddress BACnetAddress
1929 * @return modified offset
1932 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1936 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1937 * -- first octet month (1..12) January = 1, X'FF' = any month
1938 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1939 * -- 2 = days numbered 8-14
1940 * -- 3 = days numbered 15-21
1941 * -- 4 = days numbered 22-28
1942 * -- 5 = days numbered 29-31
1943 * -- 6 = last 7 days of this month
1944 * -- X'FF' = any week of this month
1945 * -- third octet dayOfWeek (1..7) where 1 = Monday
1947 * -- X'FF' = any day of week
1951 * @return modified offset
1954 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
1957 * ReadAccessResult ::= SEQUENCE {
1958 * objectIdentifier [0] BACnetObjectIdentifier,
1959 * listOfResults [1] SEQUENCE OF SEQUENCE {
1960 * propertyIdentifier [2] BACnetPropertyIdentifier,
1961 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1962 * readResult CHOICE {
1963 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1964 * propertyAccessError [5] Error
1972 * @return modified offset
1975 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1978 * ReadAccessSpecification ::= SEQUENCE {
1979 * objectIdentifier [0] BACnetObjectIdentifier,
1980 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
1986 * @return modified offset
1989 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1992 * WriteAccessSpecification ::= SEQUENCE {
1993 * objectIdentifier [0] BACnetObjectIdentifier,
1994 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
2000 * @return modified offset
2003 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2006 /********************************************************* Helper functions *******************************************/
2009 * extracts the tag number from the tag header.
2010 * @param tvb "TestyVirtualBuffer"
2011 * @param offset in actual tvb
2012 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
2015 fTagNo (tvbuff_t *tvb, guint offset);
2018 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
2019 * @param tvb = "TestyVirtualBuffer"
2020 * @param offset = offset in actual tvb
2021 * @return tag_no BACnet 20.2.1.2 Tag Number
2022 * @return class_tag BACnet 20.2.1.1 Class
2023 * @return lvt BACnet 20.2.1.3 Length/Value/Type
2024 * @return offs = length of this header
2028 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
2032 * adds processID with max 32Bit unsigned Integer Value to tree
2036 * @return modified offset
2039 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
2042 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2046 * @return modified offset
2049 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2052 * BACnet Application PDUs chapter 21
2053 * BACnetPropertyIdentifier::= ENUMERATED {
2054 * @see bacapp_property_identifier
2060 * @param tt returnvalue of this item
2061 * @return modified offset
2064 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2067 * BACnet Application PDUs chapter 21
2068 * BACnetPropertyArrayIndex::= ENUMERATED {
2069 * @see bacapp_property_array_index
2074 * @param tt returnvalue of this item
2075 * @return modified offset
2078 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
2081 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2082 * objectIdentifier [0] BACnetObjectIdentifier,
2083 * eventState [1] BACnetEventState,
2084 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2085 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2086 * notifyType [4] BACnetNotifyType,
2087 * eventEnable [5] BACnetEventTransitionBits,
2088 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2094 * @return modified offset
2097 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2100 * SelectionCriteria ::= SEQUENCE {
2101 * propertyIdentifier [0] BACnetPropertyIdentifier,
2102 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2103 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2104 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2110 * @return modified offset
2113 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2116 * objectSelectionCriteria ::= SEQUENCE {
2117 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2118 * listOfSelectionCriteria [1] SelectionCriteria
2124 * @return modified offset
2127 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2130 * BACnet-Error ::= SEQUENCE {
2131 * error-class ENUMERATED {},
2132 * error-code ENUMERATED {}
2139 * @return modified offset
2142 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2145 * Generic handler for context tagged values. Mostly for handling
2146 * vendor-defined properties and services.
2150 * @return modified offset
2151 * @todo beautify this ugly construct
2154 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2157 * realizes some ABSTRACT-SYNTAX.&Type
2162 * @return modified offset
2163 * @todo beautify this ugly construct
2166 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2170 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2171 const value_string *src);
2177 proto_register_bacapp(void);
2180 * proto_reg_handoff_bacapp
2183 proto_reg_handoff_bacapp(void);
2186 * converts XXX coded strings to UTF-8
2187 * else 'in' is copied to 'out'
2188 * @param in -- pointer to string
2189 * @param inbytesleft
2190 * @param out -- pointer to string
2191 * @param outbytesleft
2193 * @return count of modified characters of returned string, -1 for errors
2196 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2199 uni_to_string(char * data, gsize str_length, char *dest_buf);
2201 /* <<<< formerly bacapp.h */
2203 /* some hashes for segmented messages */
2204 static GHashTable *msg_fragment_table = NULL;
2205 static GHashTable *msg_reassembled_table = NULL;
2207 /* some necessary forward function prototypes */
2209 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2210 const gchar *label, const value_string *vs);
2212 static const char *bacapp_unknown_service_str = "unknown service";
2213 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2214 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2216 static const value_string
2217 BACnetTypeName[] = {
2218 { 0, "Confirmed-REQ"},
2219 { 1, "Unconfirmed-REQ"},
2221 { 3, "Complex-ACK"},
2222 { 4, "Segment-ACK"},
2229 static const true_false_string segments_follow = {
2230 "Segmented Request",
2231 "Unsegmented Request"
2234 static const true_false_string more_follow = {
2235 "More Segments Follow",
2236 "No More Segments Follow"
2239 static const true_false_string segmented_accept = {
2240 "Segmented Response accepted",
2241 "Segmented Response not accepted"
2244 static const true_false_string
2246 "Context Specific Tag",
2250 static const value_string
2251 BACnetMaxSegmentsAccepted [] = {
2252 { 0, "Unspecified"},
2256 { 4, "16 segments"},
2257 { 5, "32 segments"},
2258 { 6, "64 segments"},
2259 { 7, "Greater than 64 segments"},
2263 static const value_string
2264 BACnetMaxAPDULengthAccepted [] = {
2265 { 0, "Up to MinimumMessageSize (50 octets)"},
2266 { 1, "Up to 128 octets"},
2267 { 2, "Up to 206 octets (fits in a LonTalk frame)"},
2268 { 3, "Up to 480 octets (fits in an ARCNET frame)"},
2269 { 4, "Up to 1024 octets"},
2270 { 5, "Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2271 { 6, "reserved by ASHRAE"},
2272 { 7, "reserved by ASHRAE"},
2273 { 8, "reserved by ASHRAE"},
2274 { 9, "reserved by ASHRAE"},
2275 { 10, "reserved by ASHRAE"},
2276 { 11, "reserved by ASHRAE"},
2277 { 12, "reserved by ASHRAE"},
2278 { 13, "reserved by ASHRAE"},
2279 { 14, "reserved by ASHRAE"},
2280 { 15, "reserved by ASHRAE"},
2284 static const value_string
2285 BACnetRejectReason [] = {
2287 {1, "buffer-overflow"},
2288 {2, "inconsistent-parameters"},
2289 {3, "invalid-parameter-data-type"},
2291 {5, "missing-required-parameter"},
2292 {6, "parameter-out-of-range"},
2293 {7, "too-many-arguments"},
2294 {8, "undefined-enumeration"},
2295 {9, "unrecognized-service"},
2299 static const value_string
2300 BACnetRestartReason [] = {
2304 { 3, "detected-power-lost"},
2305 { 4, "detected-powered-off"},
2306 { 5, "hardware-watchdog"},
2307 { 6, "software-watchdog"},
2312 static const value_string
2313 BACnetApplicationTagNumber [] = {
2316 { 2, "Unsigned Integer"},
2317 { 3, "Signed Integer (2's complement notation)"},
2318 { 4, "Real (ANSI/IEE-754 floating point)"},
2319 { 5, "Double (ANSI/IEE-754 double precision floating point)"},
2320 { 6, "Octet String"},
2321 { 7, "Character String"},
2326 { 12, "BACnetObjectIdentifier"},
2327 { 13, "reserved by ASHRAE"},
2328 { 14, "reserved by ASHRAE"},
2329 { 15, "reserved by ASHRAE"},
2333 static const value_string
2340 static const value_string
2341 BACnetFileAccessMethod [] = {
2342 { 0, "record-access"},
2343 { 1, "stream-access"},
2347 /* For some reason, BACnet defines the choice parameter
2348 in the file read and write services backwards from the
2349 BACnetFileAccessMethod enumeration.
2351 static const value_string
2352 BACnetFileAccessOption [] = {
2353 { 0, "stream access"},
2354 { 1, "record access"},
2358 static const value_string
2359 BACnetFileStartOption [] = {
2360 { 0, "File Start Position: "},
2361 { 1, "File Start Record: "},
2365 static const value_string
2366 BACnetFileRequestCount [] = {
2367 { 0, "Requested Octet Count: "},
2368 { 1, "Requested Record Count: "},
2372 static const value_string
2373 BACnetFileWriteInfo [] = {
2374 { 0, "File Data: "},
2375 { 1, "Record Count: "},
2379 static const value_string
2380 BACnetAbortReason [] = {
2382 { 1, "buffer-overflow"},
2383 { 2, "invalid-apdu-in-this-state"},
2384 { 3, "preempted-by-higher-priority-task"},
2385 { 4, "segmentation-not-supported"},
2389 static const value_string
2390 BACnetLifeSafetyMode [] = {
2401 { 10, "disconnected"},
2404 { 13, "atomic-release-disabled"},
2407 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2408 Enumerated values 256-65535 may be used by others subject to
2409 procedures and constraints described in Clause 23. */
2412 static const value_string
2413 BACnetLifeSafetyOperation [] = {
2416 { 2, "silence-audible"},
2417 { 3, "silence-visual"},
2419 { 5, "reset-alarm"},
2420 { 6, "reset-fault"},
2422 { 8, "unsilence-audible"},
2423 { 9, "unsilence-visual"},
2425 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2426 Enumerated values 64-65535 may be used by others subject to
2427 procedures and constraints described in Clause 23. */
2430 static const value_string
2431 BACnetLimitEnable [] = {
2432 { 0, "lowLimitEnable"},
2433 { 1, "highLimitEnable"},
2437 static const value_string
2438 BACnetLifeSafetyState [] = {
2443 { 4, "fault-pre-alarm"},
2444 { 5, "fault-alarm"},
2449 { 10, "test-active"},
2450 { 11, "test-fault"},
2451 { 12, "test-fault-alarm"},
2454 { 15, "tamper-alarm"},
2456 { 17, "emergency-power"},
2459 { 20, "local-alarm"},
2460 { 21, "general-alarm"},
2461 { 22, "supervisory"},
2462 { 23, "test-supervisory"},
2464 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2465 Enumerated values 256-65535 may be used by others subject to
2466 procedures and constraints described in Clause 23. */
2469 static const value_string
2470 BACnetConfirmedServiceChoice [] = {
2471 { 0, "acknowledgeAlarm"},
2472 { 1, "confirmedCOVNotification"},
2473 { 2, "confirmedEventNotification"},
2474 { 3, "getAlarmSummary"},
2475 { 4, "getEnrollmentSummary"},
2476 { 5, "subscribeCOV"},
2477 { 6, "atomicReadFile"},
2478 { 7, "atomicWriteFile"},
2479 { 8, "addListElement"},
2480 { 9, "removeListElement"},
2481 { 10, "createObject"},
2482 { 11, "deleteObject"},
2483 { 12, "readProperty"},
2484 { 13, "readPropertyConditional"},
2485 { 14, "readPropertyMultiple"},
2486 { 15, "writeProperty"},
2487 { 16, "writePropertyMultiple"},
2488 { 17, "deviceCommunicationControl"},
2489 { 18, "confirmedPrivateTransfer"},
2490 { 19, "confirmedTextMessage"},
2491 { 20, "reinitializeDevice"},
2495 { 24, "authenticate"},
2496 { 25, "requestKey"},
2498 { 27, "lifeSafetyOperation"},
2499 { 28, "subscribeCOVProperty"},
2500 { 29, "getEventInformation"},
2501 { 30, "reserved by ASHRAE"},
2505 static const value_string
2506 BACnetReliability [] = {
2507 { 0, "no-fault-detected"},
2510 { 3, "under-range"},
2512 { 5, "shorted-loop"},
2514 { 7, "unreliable-other"},
2515 { 8, "process-error"},
2516 { 9, "multi-state-fault"},
2517 { 10, "configuration-error"},
2518 /* enumeration value 11 is reserved for a future addendum */
2519 { 12, "communication-failure"},
2520 { 13, "member-fault"},
2524 static const value_string
2525 BACnetUnconfirmedServiceChoice [] = {
2528 { 2, "unconfirmedCOVNotification"},
2529 { 3, "unconfirmedEventNotification"},
2530 { 4, "unconfirmedPrivateTransfer"},
2531 { 5, "unconfirmedTextMessage"},
2532 { 6, "timeSynchronization"},
2535 { 9, "utcTimeSynchonization"},
2539 static const value_string
2540 BACnetUnconfirmedServiceRequest [] = {
2541 { 0, "i-Am-Request"},
2542 { 1, "i-Have-Request"},
2543 { 2, "unconfirmedCOVNotification-Request"},
2544 { 3, "unconfirmedEventNotification-Request"},
2545 { 4, "unconfirmedPrivateTransfer-Request"},
2546 { 5, "unconfirmedTextMessage-Request"},
2547 { 6, "timeSynchronization-Request"},
2548 { 7, "who-Has-Request"},
2549 { 8, "who-Is-Request"},
2550 { 9, "utcTimeSynchonization-Request"},
2554 static const value_string
2555 BACnetObjectType [] = {
2556 { 0, "analog-input"},
2557 { 1, "analog-output"},
2558 { 2, "analog-value"},
2559 { 3, "binary-input"},
2560 { 4, "binary-output"},
2561 { 5, "binary-value"},
2565 { 9, "event-enrollment"},
2569 { 13, "multi-state-input"},
2570 { 14, "multi-state-output"},
2571 { 15, "notification-class"},
2575 { 19, "multi-state-value"},
2577 { 21, "life-safety-point"},
2578 { 22, "life-safety-zone"},
2579 { 23, "accumulator"},
2580 { 24, "pulse-converter"},
2582 { 26, "global-group"},
2583 { 27, "trend-log-multiple"},
2584 { 28, "load-control"},
2585 { 29, "structured-view"},
2586 { 30, "access-door"}, /* 30-37 added with addanda 135-2008j */
2587 /* value 31 is unassigned */
2588 { 32, "access-credential"},
2589 { 33, "access-point"},
2590 { 34, "access-rights"},
2591 { 35, "access-user"},
2592 { 36, "access-zone"},
2593 { 37, "credential-data-input"},
2594 { 38, "network-security"},
2595 { 39, "bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2596 { 40, "characterstring-value"},
2597 { 41, "date-pattern-value"},
2598 { 42, "date-value"},
2599 { 43, "datetime-pattern-value"},
2600 { 44, "datetime-value"},
2601 { 45, "integer-value"},
2602 { 46, "large-analog-value"},
2603 { 47, "octetstring-value"},
2604 { 48, "positive-integer-value"},
2605 { 49, "time-pattern-value"},
2606 { 50, "time-value"},
2608 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2609 Enumerated values 128-1023 may be used by others subject to
2610 the procedures and constraints described in Clause 23. */
2613 static const value_string
2614 BACnetEngineeringUnits [] = {
2617 { 2, "Milliamperes"},
2623 { 8, "Volt Amperes"},
2624 { 9, "Kilovolt Amperes"},
2625 { 10, "Megavolt Amperes"},
2626 { 11, "Volt Amperes Reactive"},
2627 { 12, "Kilovolt Amperes Reactive"},
2628 { 13, "Megavolt Amperes Reactive"},
2629 { 14, "Degrees Phase"},
2630 { 15, "Power Factor"},
2632 { 17, "Kilojoules"},
2633 { 18, "Watt Hours"},
2634 { 19, "Kilowatt Hours"},
2638 { 23, "Joules Per Kg Dry Air"},
2639 { 24, "BTUs Per Pound Dry Air"},
2640 { 25, "Cycles Per Hour"},
2641 { 26, "Cycles Per Minute"},
2643 { 28, "Grams Of Water Per Kilogram Dry Air"},
2644 { 29, "Relative Humidity"},
2645 { 30, "Millimeters"},
2649 { 34, "Watts Per Sq Foot"},
2650 { 35, "Watts Per Sq meter"},
2653 { 38, "Foot Candles"},
2655 { 40, "Pounds Mass"},
2657 { 42, "Kgs per Second"},
2658 { 43, "Kgs Per Minute"},
2659 { 44, "Kgs Per Hour"},
2660 { 45, "Pounds Mass Per Minute"},
2661 { 46, "Pounds Mass Per Hour"},
2665 { 50, "BTUs Per Hour"},
2666 { 51, "Horsepower"},
2667 { 52, "Tons Refrigeration"},
2669 { 54, "Kilopascals"},
2671 { 56, "Pounds Force Per Square Inch"},
2672 { 57, "Centimeters Of Water"},
2673 { 58, "Inches Of Water"},
2674 { 59, "Millimeters Of Mercury"},
2675 { 60, "Centimeters Of Mercury"},
2676 { 61, "Inches Of Mercury"},
2677 { 62, "Degrees Celsius"},
2678 { 63, "Degrees Kelvin"},
2679 { 64, "Degrees Fahrenheit"},
2680 { 65, "Degree Days Celsius"},
2681 { 66, "Degree Days Fahrenheit"},
2689 { 74, "Meters Per Second"},
2690 { 75, "Kilometers Per Hour"},
2691 { 76, "Feed Per Second"},
2692 { 77, "Feet Per Minute"},
2693 { 78, "Miles Per Hour"},
2694 { 79, "Cubic Feet"},
2695 { 80, "Cubic Meters"},
2696 { 81, "Imperial Gallons"},
2698 { 83, "US Gallons"},
2699 { 84, "Cubic Feet Per Minute"},
2700 { 85, "Cubic Meters Per Second"},
2701 { 86, "Imperial Gallons Per Minute"},
2702 { 87, "Liters Per Second"},
2703 { 88, "Liters Per Minute"},
2704 { 89, "US Gallons Per Minute"},
2705 { 90, "Degrees Angular"},
2706 { 91, "Degrees Celsius Per Hour"},
2707 { 92, "Degrees Celsius Per Minute"},
2708 { 93, "Degrees Fahrenheit Per Hour"},
2709 { 94, "Degrees Fahrenheit Per Minute"},
2711 { 96, "Parts Per Million"},
2712 { 97, "Parts Per Billion"},
2714 { 99, "Pecent Per Second"},
2715 { 100, "Per Minute"},
2716 { 101, "Per Second"},
2717 { 102, "Psi Per Degree Fahrenheit"},
2719 { 104, "Revolutions Per Min"},
2720 { 105, "Currency1"},
2721 { 106, "Currency2"},
2722 { 107, "Currency3"},
2723 { 108, "Currency4"},
2724 { 109, "Currency5"},
2725 { 110, "Currency6"},
2726 { 111, "Currency7"},
2727 { 112, "Currency8"},
2728 { 113, "Currency9"},
2729 { 114, "Currency10"},
2730 { 115, "Sq Inches"},
2731 { 116, "Sq Centimeters"},
2732 { 117, "BTUs Per Pound"},
2733 { 118, "Centimeters"},
2734 { 119, "Pounds Mass Per Second"},
2735 { 120, "Delta Degrees Fahrenheit"},
2736 { 121, "Delta Degrees Kelvin"},
2739 { 124, "Millivolts"},
2740 { 125, "Kilojoules Per Kg"},
2741 { 126, "Megajoules"},
2742 { 127, "Joules Per Degree Kelvin"},
2743 { 128, "Joules Per Kg Degree Kelvin"},
2744 { 129, "Kilohertz"},
2745 { 130, "Megahertz"},
2747 { 132, "Milliwatts"},
2748 { 133, "Hectopascals"},
2749 { 134, "Millibars"},
2750 { 135, "Cubic Meters Per Hour"},
2751 { 136, "Liters Per Hour"},
2752 { 137, "KWatt Hours Per Square Meter"},
2753 { 138, "KWatt Hours Per Square Foot"},
2754 { 139, "Megajoules Per Square Meter"},
2755 { 140, "Megajoules Per Square Foot"},
2756 { 141, "Watts Per Sq Meter Degree Kelvin"},
2757 { 142, "Cubic Feet Per Second"},
2758 { 143, "Percent Obstruction Per Foot"},
2759 { 144, "Percent Obstruction Per Meter"},
2760 { 145, "milliohms"},
2761 { 146, "megawatt-hours"},
2762 { 147, "kilo-btus"},
2763 { 148, "mega-btus"},
2764 { 149, "kilojoules-per-kilogram-dry-air"},
2765 { 150, "megajoules-per-kilogram-dry-air"},
2766 { 151, "kilojoules-per-degree-Kelvin"},
2767 { 152, "megajoules-per-degree-Kelvin"},
2769 { 154, "grams-per-second"},
2770 { 155, "grams-per-minute"},
2771 { 156, "tons-per-hour"},
2772 { 157, "kilo-btus-per-hour"},
2773 { 158, "hundredths-seconds"},
2774 { 159, "milliseconds"},
2775 { 160, "newton-meters"},
2776 { 161, "millimeters-per-second"},
2777 { 162, "millimeters-per-minute"},
2778 { 163, "meters-per-minute"},
2779 { 164, "meters-per-hour"},
2780 { 165, "cubic-meters-per-minute"},
2781 { 166, "meters-per-second-per-second"},
2782 { 167, "amperes-per-meter"},
2783 { 168, "amperes-per-square-meter"},
2784 { 169, "ampere-square-meters"},
2787 { 172, "ohm-meters"},
2789 { 174, "siemens-per-meter"},
2791 { 176, "volts-per-degree-Kelvin"},
2792 { 177, "volts-per-meter"},
2795 { 180, "candelas-per-square-meter"},
2796 { 181, "degrees-Kelvin-per-hour"},
2797 { 182, "degrees-Kelvin-per-minute"},
2798 { 183, "joule-seconds"},
2799 { 184, "radians-per-second"},
2800 { 185, "square-meters-per-Newton"},
2801 { 186, "kilograms-per-cubic-meter"},
2802 { 187, "newton-seconds"},
2803 { 188, "newtons-per-meter"},
2804 { 189, "watts-per-meter-per-degree-Kelvin"},
2805 { 190, "micro-siemens"},
2806 { 191, "cubic-feet-per-hour"},
2807 { 192, "us-gallons-per-hour"},
2808 { 193, "kilometers"},
2809 { 194, "micrometers"},
2811 { 196, "milligrams"},
2812 { 197, "milliliters"},
2813 { 198, "milliliters-per-second"},
2815 { 200, "decibels-millivolt"},
2816 { 201, "decibels-volt"},
2817 { 202, "millisiemens"},
2818 { 203, "watt-hours-reactive"},
2819 { 204, "kilowatt-hours-reactive"},
2820 { 205, "megawatt-hours-reactive"},
2821 { 206, "millimeters-of-water"},
2822 { 207, "per-mille"},
2823 { 208, "grams-per-gram"},
2824 { 209, "kilograms-per-kilogram"},
2825 { 210, "grams-per-kilogram"},
2826 { 211, "milligrams-per-gram"},
2827 { 212, "milligrams-per-kilogram"},
2828 { 213, "grams-per-milliliter"},
2829 { 214, "grams-per-liter"},
2830 { 215, "milligrams-per-liter"},
2831 { 216, "micrograms-per-liter"},
2832 { 217, "grams-per-cubic-meter"},
2833 { 218, "milligrams-per-cubic-meter"},
2834 { 219, "micrograms-per-cubic-meter"},
2835 { 220, "nanograms-per-cubic-meter"},
2836 { 221, "grams-per-cubic-centimeter"},
2837 { 222, "becquerels"},
2838 { 223, "kilobecquerels"},
2839 { 224, "megabecquerels"},
2841 { 226, "milligray"},
2842 { 227, "microgray"},
2844 { 229, "millisieverts"},
2845 { 230, "microsieverts"},
2846 { 231, "microsieverts-per-hour"},
2847 { 232, "decibels-a"},
2848 { 233, "nephelometric-turbidity-unit"},
2850 { 235, "grams-per-square-meter"},
2851 { 236, "minutes-per-degree-kelvin"},
2853 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2854 Enumerated values 256-65535 may be used by others subject to
2855 the procedures and constraints described in Clause 23. */
2858 static const value_string
2859 BACnetErrorCode [] = {
2861 { 1, "authentication-failed"},
2862 { 2, "configuration-in-progress"},
2863 { 3, "device-busy"},
2864 { 4, "dynamic-creation-not-supported"},
2865 { 5, "file-access-denied"},
2866 { 6, "incompatible-security-levels"},
2867 { 7, "inconsistent-parameters"},
2868 { 8, "inconsistent-selection-criterion"},
2869 { 9, "invalid-data-type"},
2870 { 10, "invalid-file-access-method"},
2871 { 11, "invalid-file-start-position"},
2872 { 12, "invalid-operator-name"},
2873 { 13, "invalid-parameter-data-type"},
2874 { 14, "invalid-time-stamp"},
2875 { 15, "key-generation-error"},
2876 { 16, "missing-required-parameter"},
2877 { 17, "no-objects-of-specified-type"},
2878 { 18, "no-space-for-object"},
2879 { 19, "no-space-to-add-list-element"},
2880 { 20, "no-space-to-write-property"},
2881 { 21, "no-vt-sessions-available"},
2882 { 22, "property-is-not-a-list"},
2883 { 23, "object-deletion-not-permitted"},
2884 { 24, "object-identifier-already-exists"},
2885 { 25, "operational-problem"},
2886 { 26, "password-failure"},
2887 { 27, "read-access-denied"},
2888 { 28, "security-not-supported"},
2889 { 29, "service-request-denied"},
2891 { 31, "unknown-object"},
2892 { 32, "unknown-property"},
2893 { 33, "removed enumeration"},
2894 { 34, "unknown-vt-class"},
2895 { 35, "unknown-vt-session"},
2896 { 36, "unsupported-object-type"},
2897 { 37, "value-out-of-range"},
2898 { 38, "vt-session-already-closed"},
2899 { 39, "vt-session-termination-failure"},
2900 { 40, "write-access-denied"},
2901 { 41, "character-set-not-supported"},
2902 { 42, "invalid-array-index"},
2903 { 43, "cov-subscription-failed"},
2904 { 44, "not-cov-property"},
2905 { 45, "optional-functionality-not-supported"},
2906 { 46, "invalid-configuration-data"},
2907 { 47, "datatype-not-supported"},
2908 { 48, "duplicate-name"},
2909 { 49, "duplicate-object-id"},
2910 { 50, "property-is-not-an-array"},
2911 { 73, "invalid-event-state"},
2912 { 74, "no-alarm-configured"},
2913 { 75, "log-buffer-full"},
2914 { 76, "logged-value-purged"},
2915 { 77, "no-property-specified"},
2916 { 78, "not-configured-for-triggered-logging"},
2917 { 79, "unknown-subscription"},
2918 { 80, "parameter-out-of-range"},
2919 { 81, "list-element-not-found"},
2921 { 83, "communication-disabled"},
2923 { 85, "access-denied"},
2924 { 86, "bad-destination-address"},
2925 { 87, "bad-destination-device-id"},
2926 { 88, "bad-signature"},
2927 { 89, "bad-source-address"},
2928 { 90, "bad-timestamp"},
2929 { 91, "cannot-use-key"},
2930 { 92, "cannot-verify-message-id"},
2931 { 93, "correct-key-revision"},
2932 { 94, "destination-device-id-required"},
2933 { 95, "duplicate-message"},
2934 { 96, "encryption-not-configured"},
2935 { 97, "encryption-required"},
2936 { 98, "incorrect-key"},
2937 { 99, "invalid-key-data"},
2938 { 100, "key-update-in-progress"},
2939 { 101, "malformed-message"},
2940 { 102, "not-key-server"},
2941 { 103, "security-not-configured"},
2942 { 104, "source-security-required"},
2943 { 105, "too-many-keys"},
2944 { 106, "unknown-authentication-type"},
2945 { 107, "unknown-key"},
2946 { 108, "unknown-key-revision"},
2947 { 109, "unknown-source-message"},
2948 { 110, "not-router-to-dnet"},
2949 { 111, "router-busy"},
2950 { 112, "unknown-network-message"},
2951 { 113, "message-too-long"},
2952 { 114, "security-error"},
2953 { 115, "addressing-error"},
2954 { 116, "write-bdt-failed"},
2955 { 117, "read-bdt-failed"},
2956 { 118, "register-foreign-device-failed"},
2957 { 119, "read-fdt-failed"},
2958 { 120, "delete-fdt-entry-failed"},
2959 { 121, "distribute-broadcast-failed"},
2960 { 122, "unknown-file-size"},
2961 { 123, "abort-apdu-too-long"},
2962 { 124, "abort-application-exceeded-reply-time"},
2963 { 125, "abort-out-of-resources"},
2964 { 126, "abort-tsm-timeout"},
2965 { 127, "abort-window-size-out-of-range"},
2966 { 128, "file-full"},
2967 { 129, "inconsistent-configuration"},
2968 { 130, "inconsistent-object-type"},
2969 { 131, "internal-error"},
2970 { 132, "not-configured"},
2971 { 133, "out-of-memory"},
2972 { 134, "value-too-long"},
2973 { 135, "abort-insufficient-security"},
2974 { 136, "abort-security-error"},
2976 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2977 Enumerated values 256-65535 may be used by others subject to the
2978 procedures and constraints described in Clause 23. */
2981 static const value_string
2982 BACnetPropertyIdentifier [] = {
2983 { 0, "acked-transition"},
2984 { 1, "ack-required"},
2986 { 3, "action-text"},
2987 { 4, "active-text"},
2988 { 5, "active-vt-session"},
2989 { 6, "alarm-value"},
2990 { 7, "alarm-values"},
2992 { 9, "all-write-successful"},
2993 { 10, "apdu-segment-timeout"},
2994 { 11, "apdu-timeout"},
2995 { 12, "application-software-version"},
2998 { 15, "change-of-state-count"},
2999 { 16, "change-of-state-time"},
3000 { 17, "notification-class"},
3001 { 18, "the property in this place was deleted"},
3002 { 19, "controlled-variable-reference"},
3003 { 20, "controlled-variable-units"},
3004 { 21, "controlled-variable-value"},
3005 { 22, "cov-increment"},
3007 { 24, "daylights-savings-status"},
3009 { 26, "derivative-constant"},
3010 { 27, "derivative-constant-units"},
3011 { 28, "description"},
3012 { 29, "description-of-halt"},
3013 { 30, "device-address-binding"},
3014 { 31, "device-type"},
3015 { 32, "effective-period"},
3016 { 33, "elapsed-active-time"},
3017 { 34, "error-limit"},
3018 { 35, "event-enable"},
3019 { 36, "event-state"},
3020 { 37, "event-type"},
3021 { 38, "exception-schedule"},
3022 { 39, "fault-values"},
3023 { 40, "feedback-value"},
3024 { 41, "file-access-method"},
3027 { 44, "firmware-revision"},
3028 { 45, "high-limit"},
3029 { 46, "inactive-text"},
3030 { 47, "in-progress"},
3031 { 48, "instance-of"},
3032 { 49, "integral-constant"},
3033 { 50, "integral-constant-units"},
3034 { 51, "issue-confirmed-notifications"},
3035 { 52, "limit-enable"},
3036 { 53, "list-of-group-members"},
3037 { 54, "list-of-object-property-references"},
3038 { 55, "list-of-session-keys"},
3039 { 56, "local-date"},
3040 { 57, "local-time"},
3043 { 60, "manipulated-variable-reference"},
3044 { 61, "maximum-output"},
3045 { 62, "max-apdu-length-accepted"},
3046 { 63, "max-info-frames"},
3047 { 64, "max-master"},
3048 { 65, "max-pres-value"},
3049 { 66, "minimum-off-time"},
3050 { 67, "minimum-on-time"},
3051 { 68, "minimum-output"},
3052 { 69, "min-pres-value"},
3053 { 70, "model-name"},
3054 { 71, "modification-date"},
3055 { 72, "notify-type"},
3056 { 73, "number-of-APDU-retries"},
3057 { 74, "number-of-states"},
3058 { 75, "object-identifier"},
3059 { 76, "object-list"},
3060 { 77, "object-name"},
3061 { 78, "object-property-reference"},
3062 { 79, "object-type"},
3064 { 81, "out-of-service"},
3065 { 82, "output-units"},
3066 { 83, "event-parameters"},
3068 { 85, "present-value"},
3070 { 87, "priority-array"},
3071 { 88, "priority-for-writing"},
3072 { 89, "process-identifier"},
3073 { 90, "program-change"},
3074 { 91, "program-location"},
3075 { 92, "program-state"},
3076 { 93, "proportional-constant"},
3077 { 94, "proportional-constant-units"},
3078 { 95, "protocol-conformance-class"},
3079 { 96, "protocol-object-types-supported"},
3080 { 97, "protocol-services-supported"},
3081 { 98, "protocol-version"},
3083 { 100, "reason-for-halt"},
3084 { 101, "recipient"},
3085 { 102, "recipient-list"},
3086 { 103, "reliability"},
3087 { 104, "relinquish-default"},
3089 { 106, "resolution"},
3090 { 107, "segmentation-supported"},
3092 { 109, "setpoint-reference"},
3093 { 110, "state-text"},
3094 { 111, "status-flags"},
3095 { 112, "system-status"},
3096 { 113, "time-delay"},
3097 { 114, "time-of-active-time-reset"},
3098 { 115, "time-of-state-count-reset"},
3099 { 116, "time-synchronization-recipients"},
3101 { 118, "update-interval"},
3102 { 119, "utc-offset"},
3103 { 120, "vendor-identifier"},
3104 { 121, "vendor-name"},
3105 { 122, "vt-class-supported"},
3106 { 123, "weekly-schedule"},
3107 { 124, "attempted-samples"},
3108 { 125, "average-value"},
3109 { 126, "buffer-size"},
3110 { 127, "client-cov-increment"},
3111 { 128, "cov-resubscription-interval"},
3112 { 129, "current-notify-time"},
3113 { 130, "event-time-stamp"},
3114 { 131, "log-buffer"},
3115 { 132, "log-device-object-property"},
3116 { 133, "enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
3117 { 134, "log-interval"},
3118 { 135, "maximum-value"},
3119 { 136, "minimum-value"},
3120 { 137, "notification-threshold"},
3121 { 138, "previous-notify-time"},
3122 { 139, "protocol-revision"},
3123 { 140, "records-since-notification"},
3124 { 141, "record-count"},
3125 { 142, "start-time"},
3126 { 143, "stop-time"},
3127 { 144, "stop-when-full"},
3128 { 145, "total-record-count"},
3129 { 146, "valid-samples"},
3130 { 147, "window-interval"},
3131 { 148, "window-samples"},
3132 { 149, "maximum-value-time-stamp"},
3133 { 150, "minimum-value-time-stamp"},
3134 { 151, "variance-value"},
3135 { 152, "active-cov-subscriptions"},
3136 { 153, "backup-failure-timeout"},
3137 { 154, "configuration-files"},
3138 { 155, "database-revision"},
3139 { 156, "direct-reading"},
3140 { 157, "last-restore-time"},
3141 { 158, "maintenance-required"},
3142 { 159, "member-of"},
3144 { 161, "operation-expected"},
3147 { 164, "tracking-value"},
3148 { 165, "zone-members"},
3149 { 166, "life-safety-alarm-values"},
3150 { 167, "max-segments-accepted"},
3151 { 168, "profile-name"},
3152 { 169, "auto-slave-discovery"},
3153 { 170, "manual-slave-address-binding"},
3154 { 171, "slave-address-binding"},
3155 { 172, "slave-proxy-enable"},
3156 { 173, "last-notify-record"}, /* bug 4117 */
3157 { 174, "schedule-default"},
3158 { 175, "accepted-modes"},
3159 { 176, "adjust-value"},
3161 { 178, "count-before-change"},
3162 { 179, "count-change-time"},
3163 { 180, "cov-period"},
3164 { 181, "input-reference"},
3165 { 182, "limit-monitoring-interval"},
3166 { 183, "logging-device"},
3167 { 184, "logging-record"},
3169 { 186, "pulse-rate"},
3171 { 188, "scale-factor"},
3172 { 189, "update-time"},
3173 { 190, "value-before-change"},
3174 { 191, "value-set"},
3175 { 192, "value-change-time"},
3176 { 193, "align-intervals"},
3177 { 194, "group-member-names"},
3178 { 195, "interval-offset"},
3179 { 196, "last-restart-reason"},
3180 { 197, "logging-type"},
3181 { 198, "member-status-flags"},
3182 { 199, "notification-period"},
3183 { 200, "previous-notify-record"},
3184 { 201, "requested-update-interval"},
3185 { 202, "restart-notification-recipients"},
3186 { 203, "time-of-device-restart"},
3187 { 204, "time-synchronization-interval"},
3189 { 206, "UTC-time-synchronization-recipients"},
3190 { 207, "node-subtype"},
3191 { 208, "node-type"},
3192 { 209, "structured-object-list"},
3193 { 210, "subordinate-annotations"},
3194 { 211, "subordinate-list"},
3195 { 212, "actual-shed-level"},
3196 { 213, "duty-window"},
3197 { 214, "expected-shed-level"},
3198 { 215, "full-duty-baseline"},
3199 { 216, "node-subtype"},
3200 { 217, "node-type"},
3201 { 218, "requested-shed-level"},
3202 { 219, "shed-duration"},
3203 { 220, "shed-level-descriptions"},
3204 { 221, "shed-levels"},
3205 { 222, "state-description"},
3206 /* enumeration values 223-225 are unassigned */
3207 { 226, "door-alarm-state"},
3208 { 227, "door-extended-pulse-time"},
3209 { 228, "door-members"},
3210 { 229, "door-open-too-long-time"},
3211 { 230, "door-pulse-time"},
3212 { 231, "door-status"},
3213 { 232, "door-unlock-delay-time"},
3214 { 233, "lock-status"},
3215 { 234, "masked-alarm-values"},
3216 { 235, "secured-status"},
3217 /* enumeration values 236-243 are unassigned */
3218 { 244, "absentee-limit"}, /* added with addenda 135-2008j */
3219 { 245, "access-alarm-events"},
3220 { 246, "access-doors"},
3221 { 247, "access-event"},
3222 { 248, "access-event-authentication-factor"},
3223 { 249, "access-event-credential"},
3224 { 250, "access-event-time"},
3225 { 251, "access-transaction-events"},
3226 { 252, "accompaniment"},
3227 { 253, "accompaniment-time"},
3228 { 254, "activation-time"},
3229 { 255, "active-authentication-policy"},
3230 { 256, "assigned-access-rights"},
3231 { 257, "authentication-factors"},
3232 { 258, "authentication-policy-list"},
3233 { 259, "authentication-policy-names"},
3234 { 260, "authentication-status"},
3235 { 261, "authorization-mode"},
3236 { 262, "belongs-to"},
3237 { 263, "credential-disable"},
3238 { 264, "credential-status"},
3239 { 265, "credentials"},
3240 { 266, "credentials-in-zone"},
3241 { 267, "days-remaining"},
3242 { 268, "entry-points"},
3243 { 269, "exit-points"},
3244 { 270, "expiry-time"},
3245 { 271, "extended-time-enable"},
3246 { 272, "failed-attempt-events"},
3247 { 273, "failed-attempts"},
3248 { 274, "failed-attempts-time"},
3249 { 275, "last-access-event"},
3250 { 276, "last-access-point"},
3251 { 277, "last-credential-added"},
3252 { 278, "last-credential-added-time"},
3253 { 279, "last-credential-removed"},
3254 { 280, "last-credential-removed-time"},
3255 { 281, "last-use-time"},
3257 { 283, "lockout-relinquish-time"},
3258 { 284, "master-exemption"},
3259 { 285, "max-failed-attempts"},
3261 { 287, "muster-point"},
3262 { 288, "negative-access-rules"},
3263 { 289, "number-of-authentication-policies"},
3264 { 290, "occupancy-count"},
3265 { 291, "occupancy-count-adjust"},
3266 { 292, "occupancy-count-enable"},
3267 { 293, "occupancy-exemption"},
3268 { 294, "occupancy-lower-limit"},
3269 { 295, "occupancy-lower-limit-enforced"},
3270 { 296, "occupancy-state"},
3271 { 297, "occupancy-upper-limit"},
3272 { 298, "occupancy-upper-limit-enforced"},
3273 { 299, "passback-exemption"},
3274 { 300, "passback-mode"},
3275 { 301, "passback-timeout"},
3276 { 302, "positive-access-rules"},
3277 { 303, "reason-for-disable"},
3278 { 304, "supported-formats"},
3279 { 305, "supported-format-classes"},
3280 { 306, "threat-authority"},
3281 { 307, "threat-level"},
3282 { 308, "trace-flag"},
3283 { 309, "transaction-notification-class"},
3284 { 310, "user-external-identifier"},
3285 { 311, "user-information-reference"},
3286 /* enumeration values 312-316 are unassigned */
3287 { 317, "user-name"},
3288 { 318, "user-type"},
3289 { 319, "uses-remaining"},
3290 { 320, "zone-from"},
3292 { 322, "access-event-tag"},
3293 { 323, "global-identifier"},
3294 /* enumeration values 324-325 reserved for future addenda */
3295 { 326, "verification-time"},
3296 { 327, "base-device-security-policy"},
3297 { 328, "distribution-key-revision"},
3298 { 329, "do-not-hide"},
3300 { 331, "last-key-server"},
3301 { 332, "network-access-security-policies"},
3302 { 333, "packet-reorder-time"},
3303 { 334, "security-pdu-timeout"},
3304 { 335, "security-time-window"},
3305 { 336, "supported-security-algorithms"},
3306 { 337, "update-key-set-timeout"},
3307 { 338, "backup-and-restore-state"},
3308 { 339, "backup-preparation-time"},
3309 { 340, "restore-completion-time"},
3310 { 341, "restore-preparation-time"},
3311 { 342, "bit-mask"}, /* addenda 135-2008w */
3314 { 345, "group-members"},
3315 { 346, "group-member-names"},
3316 { 347, "member-status-flags"},
3317 { 348, "requested-update-interval"},
3318 { 349, "covu-period"},
3319 { 350, "covu-recipients"},
3320 { 351, "event-message-texts"},
3322 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3323 Enumerated values 512-4194303 may be used by others subject to
3324 the procedures and constraints described in Clause 23. */
3327 static const value_string
3328 BACnetBinaryPV [] = {
3336 #define IBM_MS_DBCS 1
3337 #define JIS_C_6226 2
3338 #define ISO_10646_UCS4 3
3339 #define ISO_10646_UCS2 4
3340 #define ISO_18859_1 5
3341 static const value_string
3342 BACnetCharacterSet [] = {
3343 { ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3344 { IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3345 { JIS_C_6226, "JIS C 6226"},
3346 { ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3347 { ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3348 { ISO_18859_1, "ISO 18859-1"},
3352 static const value_string
3353 BACnetStatusFlags [] = {
3357 { 3, "out-of-service"},
3361 static const value_string
3362 BACnetMessagePriority [] = {
3368 static const value_string
3369 BACnetAcknowledgementFilter [] = {
3376 static const value_string
3377 BACnetResultFlags [] = {
3384 static const value_string
3385 BACnetRelationSpecifier [] = {
3389 { 3, "greater-than"},
3390 { 4, "less-than-or-equal"},
3391 { 5, "greater-than-or-equal"},
3395 static const value_string
3396 BACnetSelectionLogic [] = {
3403 static const value_string
3404 BACnetEventStateFilter [] = {
3413 static const value_string
3414 BACnetEventTransitionBits [] = {
3415 { 0, "to-offnormal"},
3421 static const value_string
3422 BACnetSegmentation [] = {
3423 { 0, "segmented-both"},
3424 { 1, "segmented-transmit"},
3425 { 2, "segmented-receive"},
3426 { 3, "no-segmentation"},
3430 static const value_string
3431 BACnetSilencedState [] = {
3433 { 1, "audible-silenced"},
3434 { 2, "visible-silenced"},
3435 { 3, "all-silenced"},
3439 static const value_string
3440 BACnetDeviceStatus [] = {
3441 { 0, "operational"},
3442 { 1, "operational-read-only"},
3443 { 2, "download-required"},
3444 { 3, "download-in-progress"},
3445 { 4, "non-operational"},
3446 { 5, "backup-in-progress"},
3450 static const value_string
3451 BACnetEnableDisable [] = {
3454 { 2, "disable-initiation"},
3458 static const value_string
3472 { 255, "any month" },
3476 static const value_string
3478 { 1, "days numbered 1-7" },
3479 { 2, "days numbered 8-14" },
3480 { 3, "days numbered 15-21" },
3481 { 4, "days numbered 22-28" },
3482 { 5, "days numbered 29-31" },
3483 { 6, "last 7 days of this month" },
3484 { 255, "any week of this month" },
3488 /* note: notification class object recipient-list uses
3489 different day-of-week enum */
3490 static const value_string
3499 { 255, "any day of week" },
3503 static const value_string
3504 BACnetErrorClass [] = {
3512 { 7, "communication" },
3514 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3515 Enumerated values64-65535 may be used by others subject to
3516 the procedures and constraints described in Clause 23. */
3519 static const value_string
3520 BACnetVTClass [] = {
3521 { 0, "default-terminal" },
3522 { 1, "ansi-x3-64" },
3531 static const value_string
3532 BACnetEventType [] = {
3533 { 0, "change-of-bitstring" },
3534 { 1, "change-of-state" },
3535 { 2, "change-of-value" },
3536 { 3, "command-failure" },
3537 { 4, "floating-limit" },
3538 { 5, "out-of-range" },
3539 { 6, "complex-event-type" },
3540 { 7, "buffer-ready" },
3541 { 8, "change-of-life-safety" },
3543 { 10, "buffer-ready" },
3544 { 11, "unsigned-range" },
3545 { 14, "double-out-of-range"}, /* added with addenda 135-2008w */
3546 { 15, "signed-out-of-range"},
3547 { 16, "unsigned-out-of-range"},
3548 { 17, "change-of-characterstring"},
3549 { 18, "change-of-status-flags"},
3551 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3552 Enumerated values 64-65535 may be used by others subject to
3553 the procedures and constraints described in Clause 23.
3554 It is expected that these enumerated values will correspond
3555 to the use of the complex-event-type CHOICE [6] of the
3556 BACnetNotificationParameters production. */
3559 static const value_string
3560 BACnetEventState [] = {
3564 { 3, "high-limit" },
3566 { 5, "life-safety-alarm" },
3568 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3569 Enumerated values 64-65535 may be used by others subject to
3570 the procedures and constraints described in Clause 23. */
3573 static const value_string
3574 BACnetLogStatus [] = {
3575 { 0, "log-disabled" },
3576 { 1, "buffer-purged" },
3577 { 2, "log-interrupted"},
3581 static const value_string
3582 BACnetMaintenance [] = {
3584 { 1, "periodic-test" },
3585 { 2, "need-service-operational" },
3586 { 3, "need-service-inoperative" },
3590 static const value_string
3591 BACnetNotifyType [] = {
3594 { 2, "ack-notification" },
3598 static const value_string
3599 BACnetServicesSupported [] = {
3600 { 0, "acknowledgeAlarm"},
3601 { 1, "confirmedCOVNotification"},
3602 { 2, "confirmedEventNotification"},
3603 { 3, "getAlarmSummary"},
3604 { 4, "getEnrollmentSummary"},
3605 { 5, "subscribeCOV"},
3606 { 6, "atomicReadFile"},
3607 { 7, "atomicWriteFile"},
3608 { 8, "addListElement"},
3609 { 9, "removeListElement"},
3610 { 10, "createObject"},
3611 { 11, "deleteObject"},
3612 { 12, "readProperty"},
3613 { 13, "readPropertyConditional"},
3614 { 14, "readPropertyMultiple"},
3615 { 15, "writeProperty"},
3616 { 16, "writePropertyMultiple"},
3617 { 17, "deviceCommunicationControl"},
3618 { 18, "confirmedPrivateTransfer"},
3619 { 19, "confirmedTextMessage"},
3620 { 20, "reinitializeDevice"},
3624 { 24, "authenticate"},
3625 { 25, "requestKey"},
3628 { 28, "unconfirmedCOVNotification"},
3629 { 29, "unconfirmedEventNotification"},
3630 { 30, "unconfirmedPrivateTransfer"},
3631 { 31, "unconfirmedTextMessage"},
3632 { 32, "timeSynchronization"},
3636 { 36, "utcTimeSynchronization"},
3637 { 37, "lifeSafetyOperation"},
3638 { 38, "subscribeCOVProperty"},
3639 { 39, "getEventInformation"},
3643 static const value_string
3644 BACnetPropertyStates [] = {
3645 { 0, "boolean-value"},
3646 { 1, "binary-value"},
3649 { 4, "program-change"},
3650 { 5, "program-state"},
3651 { 6, "reason-for-halt"},
3652 { 7, "reliability"},
3654 { 9, "system-status"},
3656 { 11, "unsigned-value"},
3657 { 12, "life-safety-mode"},
3658 { 13, "life-safety-state"},
3659 { 14, "restart-reason"},
3660 { 15, "door-alarm-state"},
3662 { 17, "door-secured-status"},
3663 { 18, "door-status"},
3664 { 19, "door-value"},
3665 { 20, "file-access-method"},
3666 { 21, "lock-status"},
3667 { 22, "life-safety-operation"},
3668 { 23, "maintenance"},
3670 { 25, "notify-type"},
3671 { 26, "security-level"},
3672 { 27, "shed-state"},
3673 { 28, "silenced-state"},
3674 /* context tag 29 reserved for future addenda */
3675 { 29, "unknown-29"},
3676 { 30, "access-event"},
3677 { 31, "zone-occupancy-state"},
3678 { 32, "access-credential-disable-reason"},
3679 { 33, "access-credential-disable"},
3680 { 34, "authentication-status"},
3681 { 35, "unknown-35"},
3682 { 36, "backup-state"},
3684 /* Tag values 0-63 are reserved for definition by ASHRAE.
3685 Tag values of 64-254 may be used by others to accommodate
3686 vendor specific properties that have discrete or enumerated values,
3687 subject to the constraints described in Clause 23. */
3690 static const value_string
3691 BACnetProgramError [] = {
3693 { 1, "load-failed"},
3698 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3699 Enumerated values 64-65535 may be used by others subject to
3700 the procedures and constraints described in Clause 23. */
3703 static const value_string
3704 BACnetProgramRequest [] = {
3714 static const value_string
3715 BACnetProgramState [] = {
3725 static const value_string
3726 BACnetReinitializedStateOfDevice [] = {
3729 { 2, "startbackup"},
3731 { 4, "startrestore"},
3733 { 6, "abortrestore"},
3737 static const value_string
3738 BACnetPolarity [] = {
3744 static const value_string
3745 BACnetTagNames[] = {
3746 { 5, "Extended Value" },
3747 { 6, "Opening Tag" },
3748 { 7, "Closing Tag" },
3752 static const value_string
3753 BACnetReadRangeOptions[] = {
3754 { 3, "range byPosition" },
3755 { 4, "range byTime" },
3756 { 5, "range timeRange" },
3757 { 6, "range bySequenceNumber" },
3758 { 7, "range byTime" },
3762 /* Present_Value for Load Control Object */
3763 static const value_string
3764 BACnetShedState[] = {
3765 { 0, "shed-inactive" },
3766 { 1, "shed-request-pending" },
3767 { 2, "shed-compliant" },
3768 { 3, "shed-non-compliant" },
3772 static const value_string
3773 BACnetNodeType [] = {
3778 { 4, "organizational" },
3782 { 8, "collection" },
3784 { 10, "functional" },
3789 static const value_string
3790 BACnetLoggingType [] = {
3797 static const value_string
3798 BACnetDoorStatus [] = {
3805 static const value_string
3806 BACnetLockStatus [] = {
3814 static const value_string
3815 BACnetDoorSecuredStatus [] = {
3822 static const value_string
3823 BACnetDoorAlarmState [] = {
3826 { 2, "door-open-too-long" },
3827 { 3, "forced-open" },
3829 { 5, "door-fault" },
3831 { 7, "free-access" },
3832 { 8, "egress-open" },
3836 static const value_string
3837 BACnetAccumulatorStatus [] = {
3846 static const value_string
3847 BACnetVendorIdentifiers [] = {
3850 { 2, "The Trane Company" },
3851 { 3, "McQuay International" },
3853 { 5, "Johnson Controls, Inc." },
3854 { 6, "American Auto-Matrix" },
3855 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3856 { 8, "Delta Controls" },
3857 { 9, "Siemens Building Technologies, Inc." },
3858 { 10, "Tour Andover Controls Corporation" },
3860 { 12, "Orion Analysis Corporation" },
3861 { 13, "Teletrol Systems Inc." },
3862 { 14, "Cimetrics Technology" },
3863 { 15, "Cornell University" },
3864 { 16, "United Technologies Carrier" },
3865 { 17, "Honeywell Inc." },
3866 { 18, "Alerton / Honeywell" },
3868 { 20, "Hewlett-Packard Company" },
3869 { 21, "Dorsette's Inc." },
3870 { 22, "Cerberus AG" },
3871 { 23, "York Controls Group" },
3872 { 24, "Automated Logic Corporation" },
3873 { 25, "CSI Control Systems International" },
3874 { 26, "Phoenix Controls Corporation" },
3875 { 27, "Innovex Technologies, Inc." },
3876 { 28, "KMC Controls, Inc." },
3877 { 29, "Xn Technologies, Inc." },
3878 { 30, "Hyundai Information Technology Co., Ltd." },
3879 { 31, "Tokimec Inc." },
3881 { 33, "North Communications Limited" },
3883 { 35, "Reliable Controls Corporation" },
3884 { 36, "Tridium Inc." },
3885 { 37, "Sierra Monitor Corp." },
3886 { 38, "Silicon Energy" },
3887 { 39, "Kieback & Peter GmbH & Co KG" },
3888 { 40, "Anacon Systems, Inc." },
3889 { 41, "Systems Controls & Instruments, LLC" },
3890 { 42, "Lithonia Lighting" },
3891 { 43, "Micropower Manufacturing" },
3892 { 44, "Matrix Controls" },
3893 { 45, "METALAIRE" },
3894 { 46, "ESS Engineering" },
3895 { 47, "Sphere Systems Pty Ltd." },
3896 { 48, "Walker Technologies Corporation" },
3897 { 49, "H I Solutions, Inc." },
3899 { 51, "SAMSON AG" },
3900 { 52, "Badger Meter Inc." },
3901 { 53, "DAIKIN Industries Ltd." },
3902 { 54, "NARA Controls Inc." },
3903 { 55, "Mammoth Inc." },
3904 { 56, "Liebert Corporation" },
3905 { 57, "SEMCO Incorporated" },
3906 { 58, "Air Monitor Corporation" },
3907 { 59, "TRIATEK, Inc." },
3909 { 61, "Multistack" },
3910 { 62, "TSI Incorporated" },
3911 { 63, "Weather-Rite, Inc." },
3912 { 64, "Dunham-Bush" },
3913 { 65, "Reliance Electric" },
3915 { 67, "Regulator Australia PTY Ltd." },
3916 { 68, "Touch-Plate Lighting Controls" },
3917 { 69, "Amann GmbH" },
3918 { 70, "RLE Technologies" },
3919 { 71, "Cardkey Systems" },
3920 { 72, "SECOM Co., Ltd." },
3921 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3922 { 74, "KNX Association cvba" },
3923 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3924 { 76, "Nohmi Bosai, Ltd." },
3925 { 77, "Carel S.p.A." },
3926 { 78, "AirSense Technology, Inc." },
3927 { 79, "Hochiki Corporation" },
3928 { 80, "Fr. Sauter AG" },
3929 { 81, "Matsushita Electric Works, Ltd." },
3930 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3931 { 83, "Mitsubishi Heavy Industries, Ltd." },
3932 { 84, "ITT Bell & Gossett" },
3933 { 85, "Yamatake Building Systems Co., Ltd." },
3934 { 86, "The Watt Stopper, Inc." },
3935 { 87, "Aichi Tokei Denki Co., Ltd." },
3936 { 88, "Activation Technologies, LLC" },
3937 { 89, "Saia-Burgess Controls, Ltd." },
3938 { 90, "Hitachi, Ltd." },
3939 { 91, "Novar Corp./Trend Control Systems Ltd." },
3940 { 92, "Mitsubishi Electric Lighting Corporation" },
3941 { 93, "Argus Control Systems, Ltd." },
3942 { 94, "Kyuki Corporation" },
3943 { 95, "Richards-Zeta Building Intelligence, Inc." },
3944 { 96, "Scientech R&D, Inc." },
3945 { 97, "VCI Controls, Inc." },
3946 { 98, "Toshiba Corporation" },
3947 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3948 { 100, "Custom Mechanical Equipment, LLC" },
3949 { 101, "ClimateMaster" },
3950 { 102, "ICP Panel-Tec, Inc." },
3951 { 103, "D-Tek Controls" },
3952 { 104, "NEC Engineering, Ltd." },
3953 { 105, "PRIVA BV" },
3954 { 106, "Meidensha Corporation" },
3955 { 107, "JCI Systems Integration Services" },
3956 { 108, "Freedom Corporation" },
3957 { 109, "Neuberger Gebaudeautomation GmbH" },
3958 { 110, "Sitronix" },
3959 { 111, "Leviton Manufacturing" },
3960 { 112, "Fujitsu Limited" },
3961 { 113, "Emerson Network Power" },
3962 { 114, "S. A. Armstrong, Ltd." },
3963 { 115, "Visonet AG" },
3964 { 116, "M&M Systems, Inc." },
3965 { 117, "Custom Software Engineering" },
3966 { 118, "Nittan Company, Limited" },
3967 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3968 { 120, "Pacom Systems Pty., Ltd." },
3969 { 121, "Unico, Inc." },
3970 { 122, "Ebtron, Inc." },
3971 { 123, "Scada Engine" },
3972 { 124, "AC Technology Corporation" },
3973 { 125, "Eagle Technology" },
3974 { 126, "Data Aire, Inc." },
3975 { 127, "ABB, Inc." },
3976 { 128, "Transbit Sp. z o. o." },
3977 { 129, "Toshiba Carrier Corporation" },
3978 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
3979 { 131, "Tokai Soft" },
3981 { 133, "Veris Industries" },
3982 { 134, "Centaurus Prime" },
3983 { 135, "Sand Network Systems" },
3984 { 136, "Regulvar, Inc." },
3985 { 137, "Fastek International, Ltd." },
3986 { 138, "PowerCold Comfort Air Solutions, Inc." },
3987 { 139, "I Controls" },
3988 { 140, "Viconics Electronics, Inc." },
3989 { 141, "Yaskawa Electric America, Inc." },
3990 { 142, "Plueth Regelsysteme" },
3991 { 143, "Digitale Mess- und Steuersysteme AG" },
3992 { 144, "Fujitsu General Limited" },
3993 { 145, "Project Engineering S.r.l." },
3994 { 146, "Sanyo Electric Co., Ltd." },
3995 { 147, "Integrated Information Systems, Inc." },
3996 { 148, "Temco Controls, Ltd." },
3997 { 149, "Airtek Technologies, Inc." },
3998 { 150, "Advantech Corporation" },
3999 { 151, "Titan Products, Ltd." },
4000 { 152, "Regel Partners" },
4001 { 153, "National Environmental Product" },
4002 { 154, "Unitec Corporation" },
4003 { 155, "Kanden Engineering Company" },
4004 { 156, "Messner Gebaudetechnik GmbH" },
4005 { 157, "Integrated.CH" },
4006 { 158, "EH Price Limited" },
4007 { 159, "SE-Elektronic GmbH" },
4008 { 160, "Rockwell Automation" },
4009 { 161, "Enflex Corp." },
4010 { 162, "ASI Controls" },
4011 { 163, "SysMik GmbH Dresden" },
4012 { 164, "HSC Regelungstechnik GmbH" },
4013 { 165, "Smart Temp Australia Pty. Ltd." },
4014 { 166, "PCI Lighting Control Systems" },
4015 { 167, "Duksan Mecasys Co., Ltd." },
4016 { 168, "Fuji IT Co., Ltd." },
4017 { 169, "Vacon Plc" },
4018 { 170, "Leader Controls" },
4019 { 171, "Cylon Controls, Ltd." },
4021 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
4022 { 174, "Building Control Integrators" },
4023 { 175, "ITG Worldwide (M) Sdn Bhd" },
4024 { 176, "Lutron Electronics Co., Inc." },
4025 { 177, "Cooper-Atkins Corporation" },
4026 { 178, "LOYTEC Electronics GmbH" },
4028 { 180, "Mega Controls Limited" },
4029 { 181, "Micro Control Systems, Inc." },
4030 { 182, "Kiyon, Inc." },
4031 { 183, "Dust Networks" },
4032 { 184, "Advanced Building Automation Systems" },
4033 { 185, "Hermos AG" },
4036 { 188, "Lynxspring" },
4037 { 189, "Schneider Toshiba Inverter Europe" },
4038 { 190, "Danfoss Drives A/S" },
4039 { 191, "Eaton Corporation" },
4040 { 192, "Matyca S.A." },
4041 { 193, "Botech AB" },
4042 { 194, "Noveo, Inc." },
4044 { 196, "Yokogawa Electric Corporation" },
4045 { 197, "GFR Gesellschaft fur Regelungstechnik" },
4046 { 198, "Exact Logic" },
4047 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
4048 { 200, "Kandenko Co., Ltd." },
4049 { 201, "DTF, Daten-Technik Fries" },
4050 { 202, "Klimasoft, Ltd." },
4051 { 203, "Toshiba Schneider Inverter Corporation" },
4052 { 204, "Control Applications, Ltd." },
4053 { 205, "KDT Systems Co., Ltd." },
4054 { 206, "Onicon Incorporated" },
4055 { 207, "Automation Displays, Inc." },
4056 { 208, "Control Solutions, Inc." },
4057 { 209, "Remsdaq Limited" },
4058 { 210, "NTT Facilities, Inc." },
4059 { 211, "VIPA GmbH" },
4060 { 212, "TSC21 Association of Japan" },
4061 { 213, "BBP Energie Ltee" },
4062 { 214, "HRW Limited" },
4063 { 215, "Lighting Control & Design, Inc." },
4064 { 216, "Mercy Electronic and Electrical Industries" },
4065 { 217, "Samsung SDS Co., Ltd" },
4066 { 218, "Impact Facility Solutions, Inc." },
4067 { 219, "Aircuity" },
4068 { 220, "Control Techniques, Ltd." },
4069 { 221, "Evolve Control Systems, LLC" },
4070 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
4071 { 223, "Cerus Industrial" },
4072 { 224, "Chloride Power Protection Company" },
4073 { 225, "Computrols, Inc." },
4074 { 226, "Phoenix Contact GmbH & Co. KG" },
4075 { 227, "Grundfos Management A/S" },
4076 { 228, "Ridder Drive Systems" },
4077 { 229, "Soft Device SDN BHD" },
4078 { 230, "Integrated Control Technology Limited" },
4079 { 231, "AIRxpert Systems, Inc." },
4080 { 232, "Microtrol Limited" },
4081 { 233, "Red Lion Controls" },
4082 { 234, "Digital Electronics Corporation" },
4083 { 235, "Ennovatis GmbH" },
4084 { 236, "Serotonin Software Technologies, Inc." },
4085 { 237, "LS Industrial Systems Co., Ltd." },
4086 { 238, "Square D Company" },
4087 { 239, "S Squared Innovations, Inc." },
4088 { 240, "Aricent Ltd." },
4089 { 241, "EtherMetrics, LLC" },
4090 { 242, "Industrial Control Communications, Inc." },
4091 { 243, "Paragon Controls, Inc." },
4092 { 244, "A. O. Smith Corporation" },
4093 { 245, "Contemporary Control Systems, Inc." },
4094 { 246, "Intesis Software SL" },
4095 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
4096 { 248, "Heat-Timer Corporation" },
4097 { 249, "Ingrasys Technology, Inc." },
4098 { 250, "Costerm Building Automation" },
4100 { 252, "Embedia Technologies Corp." },
4101 { 253, "Technilog" },
4102 { 254, "HR Controls Ltd. & Co. KG" },
4103 { 255, "Lennox International, Inc." },
4104 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
4105 { 257, "Thermomax, Ltd." },
4106 { 258, "ELCON Electronic Control, Ltd." },
4107 { 259, "Larmia Control AB" },
4108 { 260, "BACnet Stack at SourceForge" },
4109 { 261, "G4S Security Services A/S" },
4110 { 262, "Sitek S.p.A." },
4111 { 263, "Cristal Controles" },
4112 { 264, "Regin AB" },
4113 { 265, "Dimension Software, Inc. " },
4114 { 266, "SynapSense Corporation" },
4115 { 267, "Beijing Nantree Electronic Co., Ltd." },
4116 { 268, "Camus Hydronics Ltd." },
4117 { 269, "Kawasaki Heavy Industries, Ltd. " },
4118 { 270, "Critical Environment Technologies" },
4119 { 271, "ILSHIN IBS Co., Ltd." },
4120 { 272, "ELESTA Energy Control AG" },
4121 { 273, "KROPMAN Installatietechniek" },
4122 { 274, "Baldor Electric Company" },
4123 { 275, "INGA mbH" },
4124 { 276, "GE Consumer & Industrial" },
4125 { 277, "Functional Devices, Inc." },
4127 { 279, "M-System Co., Ltd." },
4128 { 280, "Yokota Co., Ltd." },
4129 { 281, "Hitranse Technology Co., LTD" },
4130 { 282, "Federspiel Controls" },
4131 { 283, "Kele, Inc." },
4132 { 284, "Opera Electronics, Inc." },
4134 { 286, "Embedded Science Labs, LLC" },
4135 { 287, "Parker Hannifin Corporation" },
4136 { 288, "MaCaPS International Limited" },
4137 { 289, "Link4 Corporation" },
4138 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
4139 { 291, "Pribusin, Inc." },
4140 { 292, "Advantage Controls" },
4141 { 293, "Critical Room Control" },
4143 { 295, "Tongdy Control Technology Co., Ltd." },
4144 { 296, "ISSARO Integrierte Systemtechnik" },
4145 { 297, "Pro-Dev Industries" },
4146 { 298, "DRI-STEEM" },
4147 { 299, "Creative Electronic GmbH" },
4148 { 300, "Swegon AB" },
4149 { 301, "Jan Brachacek" },
4150 { 302, "Hitachi Appliances, Inc." },
4151 { 303, "Real Time Automation, Inc." },
4152 { 304, "ITEC Hankyu-Hanshin Co." },
4153 { 305, "Cyrus E&M Engineering Co., Ltd." },
4154 { 306, "Racine Federated, Inc." },
4155 { 307, "Verari Systems, Inc." },
4156 { 308, "Elesta GmbH Building Automation" },
4157 { 309, "Securiton" },
4158 { 310, "OSlsoft, Inc." },
4159 { 311, "Hanazeder Electronic GmbH" },
4160 { 312, "Honeywell Security Deutschland, Novar GmbH" },
4161 { 313, "Siemens Energy & Automation, Inc." },
4162 { 314, "ETM Professional Control GmbH" },
4163 { 315, "Meitav-tec, Ltd." },
4164 { 316, "Janitza Electronics GmbH" },
4165 { 317, "MKS Nordhausen" },
4166 { 318, "De Gier Drive Systems B.V." },
4167 { 319, "Cypress Envirosystems" },
4168 { 320, "SMARTron s.r.o." },
4169 { 321, "Verari Systems, Inc." },
4170 { 322, "K-W Electronic Service, Inc." },
4171 { 323, "ALFA-SMART Energy Management" },
4172 { 324, "Telkonet, Inc." },
4173 { 325, "Securiton GmbH" },
4174 { 326, "Cemtrex, Inc." },
4175 { 327, "Performance Technologies, Inc." },
4176 { 328, "Xtralis (Aust) Pty Ltd" },
4177 { 329, "TROX GmbH" },
4178 { 330, "Beijing Hysine Technology Co., Ltd" },
4179 { 331, "RCK Controls, Inc." },
4181 { 333, "Novar/Honeywell" },
4182 { 334, "The S4 Group, Inc." },
4183 { 335, "Schneider Electric" },
4184 { 336, "LHA Systems" },
4185 { 337, "GHM engineering Group, Inc." },
4186 { 338, "Cllimalux S.A." },
4187 { 339, "VAISALA Oyj" },
4188 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
4189 { 342, "POWERPEG NSI Limited" },
4190 { 343, "BACnet Interoperability Testing Services, Inc." },
4191 { 344, "Teco a.s." },
4192 { 345, "Plexus Technology Limited"},
4193 { 346, "Energy Focus, Inc."},
4194 { 347, "Powersmiths International Corp."},
4195 { 348, "Nichibei Co., Ltd."},
4196 { 349, "HKC Technology Ltd."},
4197 { 350, "Ovation Networks, Inc."},
4198 { 351, "Setra Systems"},
4199 { 352, "AVG Automation"},
4201 { 354, "Byte Sphere"},
4202 { 355, "Generiton Co., Ltd."},
4203 { 356, "Holter Regelarmaturen GmbH & Co. KG"},
4204 { 357, "Bedford Instruments, LLC"},
4205 { 358, "Standair Inc."},
4206 { 359, "WEG Automation - R&D"},
4207 { 360, "Prolon Control Systems ApS"},
4208 { 361, "Inneasoft"},
4209 { 362, "ConneXSoft GmbH"},
4210 { 363, "CEAG Notlichtsysteme GmbH"},
4211 { 364, "Distech Controls Inc."},
4212 { 365, "Industrial Technology Research Institute"},
4213 { 366, "ICONICS, Inc."},
4214 { 367, "IQ Controls s.c."},
4215 { 368, "OJ Electronics A/S"},
4216 { 369, "Rolbit Ltd."},
4217 { 370, "Synapsys Solutions Ltd."},
4218 { 371, "ACME Engineering Prod. Ltd."},
4219 { 372, "Zener Electric Pty, Ltd."},
4220 { 373, "Selectronix, Inc."},
4221 { 374, "Gorbet & Banerjee, LLC."},
4223 { 376, "Stephen H. Dawson Computer Service"},
4224 { 377, "Accutrol, LLC"},
4225 { 378, "Schneider Elektronik GmbH"},
4226 { 379, "Alpha-Inno Tec GmbH"},
4227 { 380, "ADMMicro, Inc."},
4228 { 381, "Greystone Energy Systems, Inc."},
4229 { 382, "CAP Technologie"},
4230 { 383, "KeRo Systems"},
4231 { 384, "Domat Control System s.r.o."},
4232 { 385, "Efektronics Pty. Ltd."},
4233 { 386, "Hekatron Vertriebs GmbH"},
4234 { 387, "Securiton AG"},
4235 { 388, "Carlo Gavazzi Controls SpA"},
4236 { 389, "Chipkin Automation Systems"},
4237 { 390, "Savant Systems, LLC"},
4238 { 391, "Simmtronic Lighting Controls"},
4239 { 392, "Abelko Innovation AB"},
4240 { 393, "Seresco Technologies Inc."},
4241 { 394, "IT Watchdogs"},
4242 { 395, "Automation Assist Japan Corp."},
4243 { 396, "Thermokon Sensortechnik GmbH"},
4244 { 397, "EGauge Systems, LLC"},
4245 { 398, "Quantum Automation (ASIA) PTE, Ltd."},
4246 { 399, "Toshiba Lighting & Technology Corp."},
4247 { 400, "SPIN Engenharia de Automaca Ltda."},
4248 { 401, "Logistics Systems & Software Services India PVT. Ltd."},
4249 { 402, "Delta Controls Integration Products"},
4250 { 403, "Focus Media"},
4251 { 404, "LUMEnergi Inc."},
4252 { 405, "Kara Systems"},
4253 { 406, "RF Code, Inc."},
4254 { 407, "Fatek Automation Corp."},
4255 { 408, "JANDA Software Company, LLC"},
4256 { 409, "Open System Solutions Limited"},
4257 { 410, "Intelec Systems PTY Ltd."},
4258 { 411, "Ecolodgix, LLC"},
4259 { 412, "Douglas Lighting Controls"},
4260 { 413, "iSAtech GmbH intelligente Sensoren Aktoren technologie"},
4262 { 415, "Beckhoff Automation GmbH"},
4263 { 416, "IPAS GmbH"},
4264 { 417, "KE2 Therm Solutions"},
4265 { 418, "Base2Products"},
4266 { 419, "DTL Controls, LLC"},
4267 { 420, "INNCOM International, Inc."},
4268 { 421, "BTR Netcom GmbH"},
4269 { 422, "Greentrol Automation, Inc"},
4270 { 423, "BELIMO Automation AG"},
4271 { 424, "Samsung Heavy Industries Co, Ltd"},
4272 { 425, "Triacta Power Technologies, Inc."},
4273 { 426, "Globestar Systems"},
4274 { 427, "MLB Advanced Media, LP"},
4275 { 428, "SWG Stuckmann Wirtschaftliche Gebaudesysteme GmbH"},
4276 { 429, "SensorSwitch"},
4277 { 430, "Multitek Power Limited"},
4278 { 431, "Aquametro AG"},
4279 { 432, "LG Electronics Inc."},
4280 { 433, "Electronic Theatre Controls, Inc."},
4281 { 434, "Mitsubishi Electric Corporation Nagoya Works"},
4282 { 435, "Delta Electronics, Inc."},
4283 { 436, "Elma Kurtalj, Ltd."},
4284 { 437, "ADT Fire and Security Sp. A.o.o."},
4285 { 438, "Nedap Security Management"},
4286 { 439, "ESC Automation Inc."},
4287 { 440, "DSP4YOU Ltd."},
4288 { 441, "GE Sensing and Inspection Technologies"},
4289 { 442, "Embedded Systems SIA"},
4290 { 443, "BEFEGA GmbH"},
4291 { 444, "Baseline Inc."},
4292 { 445, "M2M Systems Integrators"},
4294 { 447, "Clarkson Controls Limited"},
4295 { 448, "Rogerwell Control System Limited"},
4296 { 449, "SCL Elements"},
4297 { 450, "Hitachi Ltd."},
4298 { 451, "Newron System SA"},
4299 { 452, "BEVECO Gebouwautomatisering BV"},
4300 { 453, "Streamside Solutions"},
4301 { 454, "Yellowstone Soft"},
4302 { 455, "Oztech Intelligent Systems Pty Ltd."},
4303 { 456, "Novelan GmbH"},
4304 { 457, "Flexim Americas Corporation"},
4305 { 458, "ICP DAS Co., Ltd."},
4306 { 459, "CARMA Industries Inc."},
4307 { 460, "Log-One Ltd."},
4308 { 461, "TECO Electric & Machinery Co., Ltd."},
4309 { 462, "ConnectEx, Inc."},
4310 { 463, "Turbo DDC Sudwest"},
4311 { 464, "Quatrosense Environmental Ltd."},
4312 { 465, "Fifth Light Technology Ltd."},
4313 { 466, "Scientific Solutions, Ltd."},
4314 { 467, "Controller Area Network Solutions (M) Sdn Bhd"},
4315 { 468, "RESOL - Elektronische Regelungen GmbH"},
4316 { 469, "RPBUS LLC"},
4317 { 470, "BRS Sistemas Eletronicos"},
4318 { 471, "WindowMaster A/S"},
4319 { 472, "Sunlux Technologies Ltd."},
4320 { 473, "Measurlogic"},
4321 { 474, "Frimat GmbH"},
4322 { 475, "Spirax Sarco"},
4324 { 477, "Raypak Inc"},
4325 { 478, "Air Monitor Corporation"},
4326 { 479, "Regler Och Webbteknik Sverige (ROWS)"},
4327 { 480, "Intelligent Lighting Controls Inc."},
4328 { 481, "Sanyo Electric Industry Co., Ltd"},
4329 { 482, "E-Mon Energy Monitoring Products"},
4330 { 483, "Digital Control Systems"},
4331 { 484, "ATI Airtest Technologies, Inc."},
4333 { 486, "HMS Industrial Networks AB"},
4334 { 487, "Shenzhen Universal Intellisys Co Ltd"},
4335 { 488, "EK Intellisys Sdn Bhd"},
4337 { 490, "Firecom, Inc."},
4338 { 491, "ESA Elektroschaltanlagen Grimma GmbH"},
4339 { 492, "Kumahira Co Ltd"},
4341 { 494, "SABO Elektronik GmbH"},
4342 { 495, "Equip'Trans"},
4343 { 496, "TCS Basys Controls"},
4344 { 497, "FlowCon International A/S"},
4345 { 498, "ThyssenKrupp Elevator Americas"},
4346 { 499, "Abatement Technologies"},
4347 { 500, "Continental Control Systems, LLC"},
4348 { 501, "WISAG Automatisierungstechnik GmbH & Co KG"},
4350 { 503, "EAP-Electric GmbH"},
4351 { 504, "Hardmeier"},
4352 { 505, "Mircom Group of Companies"},
4353 { 506, "Quest Controls"},
4354 { 507, "Mestek, Inc"},
4355 { 508, "Pulse Energy"},
4356 { 509, "Tachikawa Corporation"},
4357 { 510, "University of Nebraska-Lincoln"},
4358 { 511, "Redwood Systems"},
4359 { 512, "PASStec Industrie-Elektronik GmbH"},
4360 { 513, "NgEK, Inc."},
4361 { 514, "FAW Electronics Ltd"},
4362 { 515, "Jireh Energy Tech Co., Ltd."},
4363 { 516, "Enlighted Inc."},
4364 { 517, "El-Piast Sp. Z o.o"},
4365 { 518, "NetxAutomation Software GmbH"},
4366 { 519, "Invertek Drives"},
4367 { 520, "Deutschmann Automation GmbH & Co. KG"},
4368 { 521, "EMU Electronic AG"},
4369 { 522, "Phaedrus Limited"},
4370 { 523, "Sigmatek GmbH & Co KG"},
4371 { 524, "Marlin Controls"},
4372 { 525, "Circutor, SA"},
4373 { 526, "UTC Fire & Security"},
4374 { 527, "DENT Instruments, Inc."},
4375 { 528, "FHP Manufacturing Company - Bosch Group"},
4376 { 529, "GE Intelligent Platforms"},
4377 { 530, "Inner Range Pty Ltd"},
4378 { 531, "GLAS Energy Technology"},
4379 { 532, "MSR-Electronic-GmbH"},
4383 static int proto_bacapp = -1;
4384 static int hf_bacapp_type = -1;
4385 static int hf_bacapp_pduflags = -1;
4386 static int hf_bacapp_SEG = -1;
4387 static int hf_bacapp_MOR = -1;
4388 static int hf_bacapp_SA = -1;
4389 static int hf_bacapp_response_segments = -1;
4390 static int hf_bacapp_max_adpu_size = -1;
4391 static int hf_bacapp_invoke_id = -1;
4392 static int hf_bacapp_objectType = -1;
4393 static int hf_bacapp_instanceNumber = -1;
4394 static int hf_bacapp_sequence_number = -1;
4395 static int hf_bacapp_window_size = -1;
4396 static int hf_bacapp_service = -1;
4397 static int hf_bacapp_NAK = -1;
4398 static int hf_bacapp_SRV = -1;
4399 static int hf_Device_Instance_Range_Low_Limit = -1;
4400 static int hf_Device_Instance_Range_High_Limit = -1;
4401 static int hf_BACnetRejectReason = -1;
4402 static int hf_BACnetAbortReason = -1;
4403 static int hf_BACnetApplicationTagNumber = -1;
4404 static int hf_BACnetContextTagNumber = -1;
4405 static int hf_BACnetExtendedTagNumber = -1;
4406 static int hf_BACnetNamedTag = -1;
4407 static int hf_BACnetTagClass = -1;
4408 static int hf_BACnetCharacterSet = -1;
4409 static int hf_bacapp_tag_lvt = -1;
4410 static int hf_bacapp_tag_ProcessId = -1;
4411 static int hf_bacapp_uservice = -1;
4412 static int hf_BACnetPropertyIdentifier = -1;
4413 static int hf_BACnetVendorIdentifier = -1;
4414 static int hf_BACnetRestartReason = -1;
4415 static int hf_bacapp_tag_IPV4 = -1;
4416 static int hf_bacapp_tag_IPV6 = -1;
4417 static int hf_bacapp_tag_PORT = -1;
4418 /* some more variables for segmented messages */
4419 static int hf_msg_fragments = -1;
4420 static int hf_msg_fragment = -1;
4421 static int hf_msg_fragment_overlap = -1;
4422 static int hf_msg_fragment_overlap_conflicts = -1;
4423 static int hf_msg_fragment_multiple_tails = -1;
4424 static int hf_msg_fragment_too_long_fragment = -1;
4425 static int hf_msg_fragment_error = -1;
4426 static int hf_msg_fragment_count = -1;
4427 static int hf_msg_reassembled_in = -1;
4428 static int hf_msg_reassembled_length = -1;
4430 static gint ett_msg_fragment = -1;
4431 static gint ett_msg_fragments = -1;
4433 static gint ett_bacapp = -1;
4434 static gint ett_bacapp_control = -1;
4435 static gint ett_bacapp_tag = -1;
4436 static gint ett_bacapp_list = -1;
4437 static gint ett_bacapp_value = -1;
4439 static dissector_handle_t data_handle;
4440 static gint32 propertyIdentifier = -1;
4441 static gint32 propertyArrayIndex = -1;
4442 static guint32 object_type = 4096;
4444 static guint8 bacapp_flags = 0;
4445 static guint8 bacapp_seq = 0;
4447 /* Defined to allow vendor identifier registration of private transfer dissectors */
4448 static dissector_table_t bacapp_dissector_table;
4451 /* Stat: BACnet Packets sorted by IP */
4452 bacapp_info_value_t bacinfo;
4454 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
4455 static const gchar* st_str_packets_by_ip_dst = "By Destination";
4456 static const gchar* st_str_packets_by_ip_src = "By Source";
4457 static int st_node_packets_by_ip = -1;
4458 static int st_node_packets_by_ip_dst = -1;
4459 static int st_node_packets_by_ip_src = -1;
4462 bacapp_packet_stats_tree_init(stats_tree* st)
4464 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4465 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4466 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4470 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4472 int packets_for_this_dst;
4473 int packets_for_this_src;
4474 int service_for_this_dst;
4475 int service_for_this_src;
4476 int src_for_this_dst;
4477 int dst_for_this_src;
4478 int objectid_for_this_dst;
4479 int objectid_for_this_src;
4480 int instanceid_for_this_dst;
4481 int instanceid_for_this_src;
4484 const bacapp_info_value_t *binfo = p;
4486 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4487 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4489 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4490 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4491 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4492 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4493 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4494 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4495 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4496 if (binfo->service_type) {
4497 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4498 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4499 if (binfo->object_ident) {
4500 instanceid_for_this_dst = tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4501 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4502 instanceid_for_this_src = tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4503 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4510 /* Stat: BACnet Packets sorted by Service */
4511 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4512 static int st_node_packets_by_service = -1;
4515 bacapp_service_stats_tree_init(stats_tree* st)
4517 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4521 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4530 const bacapp_info_value_t *binfo = p;
4532 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4533 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4535 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4536 if (binfo->service_type) {
4537 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4538 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4539 dst = tick_stat_node(st, dststr, src, TRUE);
4540 if (binfo->object_ident) {
4541 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4542 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4549 /* Stat: BACnet Packets sorted by Object Type */
4550 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
4551 static int st_node_packets_by_objectid = -1;
4554 bacapp_objectid_stats_tree_init(stats_tree* st)
4556 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
4560 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4568 const bacapp_info_value_t *binfo = p;
4570 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4571 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4573 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
4574 if (binfo->object_ident) {
4575 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
4576 src = tick_stat_node(st, srcstr, objectid, TRUE);
4577 dst = tick_stat_node(st, dststr, src, TRUE);
4578 if (binfo->service_type) {
4579 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4580 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
4587 /* Stat: BACnet Packets sorted by Instance No */
4588 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
4589 static int st_node_packets_by_instanceid = -1;
4592 bacapp_instanceid_stats_tree_init(stats_tree* st)
4594 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
4598 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4606 const bacapp_info_value_t *binfo = p;
4608 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4609 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4611 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
4612 if (binfo->object_ident) {
4613 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
4614 src = tick_stat_node(st, srcstr, instanceid, TRUE);
4615 dst = tick_stat_node(st, dststr, src, TRUE);
4616 if (binfo->service_type) {
4617 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4618 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
4625 /* register all BACnet Ststistic trees */
4627 register_bacapp_stat_trees(void)
4629 stats_tree_register("bacapp","bacapp_ip","BACnet/Packets sorted by IP", 0,
4630 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
4631 stats_tree_register("bacapp","bacapp_service","BACnet/Packets sorted by Service", 0,
4632 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
4633 stats_tree_register("bacapp","bacapp_objectid","BACnet/Packets sorted by Object Type", 0,
4634 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
4635 stats_tree_register("bacapp","bacapp_instanceid","BACnet/Packets sorted by Instance ID", 0,
4636 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
4639 /* 'data' must be ep_ allocated */
4641 updateBacnetInfoValue(gint whichval, gchar *data)
4643 if (whichval == BACINFO_SERVICE) {
4644 bacinfo.service_type = data;
4647 if (whichval == BACINFO_INVOKEID) {
4648 bacinfo.invoke_id = data;
4651 if (whichval == BACINFO_OBJECTID) {
4652 bacinfo.object_ident = data;
4655 if (whichval == BACINFO_INSTANCEID) {
4656 bacinfo.instance_ident = data;
4662 static const fragment_items msg_frag_items = {
4663 /* Fragment subtrees */
4666 /* Fragment fields */
4669 &hf_msg_fragment_overlap,
4670 &hf_msg_fragment_overlap_conflicts,
4671 &hf_msg_fragment_multiple_tails,
4672 &hf_msg_fragment_too_long_fragment,
4673 &hf_msg_fragment_error,
4674 &hf_msg_fragment_count,
4675 /* Reassembled in field */
4676 &hf_msg_reassembled_in,
4677 /* Reassembled length field */
4678 &hf_msg_reassembled_length,
4683 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
4684 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
4687 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
4689 fGetMaxAPDUSize(guint8 idx)
4691 /* only 16 values are defined, so use & 0x0f */
4692 /* check the size of the Array, deliver either the entry
4693 or the first entry if idx is outside of the array (bug 3736 comment#7) */
4695 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
4696 return MaxAPDUSize[0];
4698 return MaxAPDUSize[idx & 0x0f];
4703 /* Used when there are ranges of reserved and proprietary enumerations */
4705 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
4706 const char *fmt, const char *split_fmt)
4708 if (val < split_val)
4709 return val_to_str(val, vs, fmt);
4711 return val_to_str(val, vs, split_fmt);
4714 /* from clause 20.2.1.3.2 Constructed Data */
4715 /* returns true if the extended value is used */
4717 tag_is_extended_value(guint8 tag)
4719 return (tag & 0x07) == 5;
4723 tag_is_opening(guint8 tag)
4725 return (tag & 0x07) == 6;
4729 tag_is_closing(guint8 tag)
4731 return (tag & 0x07) == 7;
4734 /* from clause 20.2.1.1 Class
4735 class bit shall be one for context specific tags */
4736 /* returns true if the tag is context specific */
4738 tag_is_context_specific(guint8 tag)
4740 return (tag & 0x08) != 0;
4744 tag_is_extended_tag_number(guint8 tag)
4746 return ((tag & 0xF0) == 0xF0);
4750 object_id_type(guint32 object_identifier)
4752 return ((object_identifier >> 22) & 0x3FF);
4756 object_id_instance(guint32 object_identifier)
4758 return (object_identifier & 0x3FFFFF);
4762 fTagNo (tvbuff_t *tvb, guint offset)
4764 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
4768 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
4770 gboolean valid = TRUE;
4774 *val = tvb_get_guint8(tvb, offset);
4777 *val = tvb_get_ntohs(tvb, offset);
4780 *val = tvb_get_ntoh24(tvb, offset);
4783 *val = tvb_get_ntohl(tvb, offset);
4794 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4796 gboolean valid = FALSE;
4800 if (lvt && (lvt <= 8)) {
4802 data = tvb_get_guint8(tvb, offset);
4803 for (i = 0; i < lvt; i++) {
4804 data = tvb_get_guint8(tvb, offset+i);
4805 value = (value << 8) + data;
4813 /* BACnet Signed Value uses 2's complement notation, but with a twist:
4814 All signed integers shall be encoded in the smallest number of octets
4815 possible. That is, the first octet of any multi-octet encoded value
4816 shall not be X'00' if the most significant bit (bit 7) of the second
4817 octet is 0, and the first octet shall not be X'FF' if the most
4818 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4820 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4822 gboolean valid = FALSE;
4827 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4828 if (lvt && (lvt <= 7)) {
4830 data = tvb_get_guint8(tvb, offset);
4831 if ((data & 0x80) != 0)
4832 value = (-1 << 8) | data;
4835 for (i = 1; i < lvt; i++) {
4836 data = tvb_get_guint8(tvb, offset+i);
4837 value = (value << 8) + data;
4846 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
4847 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4852 guint lvt_len = 1; /* used for tree display of lvt */
4853 guint lvt_offset; /* used for tree display of lvt */
4855 proto_tree *subtree;
4857 lvt_offset = offset;
4858 tag = tvb_get_guint8(tvb, offset);
4862 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4863 /* can mean open/close tag or length of 6/7 after the length is */
4864 /* computed below - store whole tag info, not just context bit. */
4865 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4867 if (tag_is_extended_tag_number(tag)) {
4868 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4870 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4871 lvt_offset += tag_len;
4872 value = tvb_get_guint8(tvb, lvt_offset);
4874 if (value == 254) { /* length is encoded with 16 Bits */
4875 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4878 } else if (value == 255) { /* length is encoded with 32 Bits */
4879 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4887 if (tag_is_opening(tag))
4888 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4889 else if (tag_is_closing(tag))
4890 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4891 else if (tag_is_context_specific(tag)) {
4892 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4893 "Context Tag: %u, Length/Value/Type: %u",
4896 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4897 "Application Tag: %s, Length/Value/Type: %u",
4899 BACnetApplicationTagNumber,
4900 ASHRAE_Reserved_Fmt),
4903 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4904 /* details if needed */
4905 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
4906 if (tag_is_extended_tag_number(tag)) {
4907 proto_tree_add_uint_format(subtree,
4908 hf_BACnetContextTagNumber,
4909 tvb, offset, 1, tag,
4910 "Extended Tag Number");
4911 proto_tree_add_item(subtree,
4912 hf_BACnetExtendedTagNumber,
4913 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4915 if (tag_is_context_specific(tag))
4916 proto_tree_add_item(subtree,
4917 hf_BACnetContextTagNumber,
4918 tvb, offset, 1, ENC_BIG_ENDIAN);
4920 proto_tree_add_item(subtree,
4921 hf_BACnetApplicationTagNumber,
4922 tvb, offset, 1, ENC_BIG_ENDIAN);
4924 if (tag_is_closing(tag) || tag_is_opening(tag))
4925 proto_tree_add_item(subtree,
4927 tvb, offset, 1, ENC_BIG_ENDIAN);
4928 else if (tag_is_extended_value(tag)) {
4929 proto_tree_add_item(subtree,
4931 tvb, offset, 1, ENC_BIG_ENDIAN);
4932 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4933 tvb, lvt_offset, lvt_len, *lvt);
4935 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4936 tvb, lvt_offset, lvt_len, *lvt);
4943 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
4946 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
4950 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4952 guint8 tag_no, tag_info;
4955 proto_tree *subtree;
4957 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4958 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4959 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4965 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4967 guint8 tag_no, tag_info;
4970 proto_tree *subtree;
4973 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4974 if (tag_info && lvt == 1) {
4975 lvt = tvb_get_guint8(tvb, offset+1);
4979 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
4980 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
4981 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4982 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4984 return offset + bool_len;
4988 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4991 guint8 tag_no, tag_info;
4995 proto_tree *subtree;
4997 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4998 /* only support up to an 8 byte (64-bit) integer */
4999 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
5000 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5001 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
5003 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5004 "%s - %u octets (Unsigned)", label, lvt);
5005 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5006 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5008 return offset+tag_len+lvt;
5012 fDevice_Instance (tvbuff_t *tvb, proto_tree *tree, guint offset, int hf)
5014 guint8 tag_no, tag_info;
5018 proto_tree *subtree;
5020 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5021 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, lvt, ENC_BIG_ENDIAN);
5022 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5023 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5025 return offset+tag_len+lvt;
5028 /* set split_val to zero when not needed */
5030 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5031 const value_string *vs, guint32 split_val)
5034 guint8 tag_no, tag_info;
5038 proto_tree *subtree;
5040 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5041 /* only support up to a 4 byte (32-bit) enumeration */
5042 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
5044 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5045 "%s %s", label, val_to_split_str(val, split_val, vs,
5046 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
5048 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5049 "%s %u", label, val);
5051 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5052 "%s - %u octets (enumeration)", label, lvt);
5054 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5055 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5057 return offset+tag_len+lvt;
5061 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5062 const value_string *vs)
5064 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
5068 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5071 guint8 tag_no, tag_info;
5075 proto_tree *subtree;
5077 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5078 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
5079 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5080 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
5082 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5083 "%s - %u octets (Signed)", label, lvt);
5084 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5085 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5087 return offset+tag_len+lvt;
5091 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5093 guint8 tag_no, tag_info;
5098 proto_tree *subtree;
5100 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5101 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
5102 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
5103 "%s%f (Real)", label, f_val);
5104 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5105 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5107 return offset+tag_len+4;
5111 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5113 guint8 tag_no, tag_info;
5118 proto_tree *subtree;
5120 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5121 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
5122 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
5123 "%s%f (Double)", label, d_val);
5124 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5125 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5127 return offset+tag_len+8;
5131 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
5133 guint32 val = 0, lvt;
5134 guint8 tag_no, tag_info;
5136 proto_tree *subtree;
5139 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5140 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5141 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
5142 tvb, offset, lvt+tag_len, val);
5144 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5145 "Process Identifier - %u octets (Signed)", lvt);
5146 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5147 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5148 offset += tag_len + lvt;
5154 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5156 guint32 val = 0, lvt;
5157 guint8 tag_no, tag_info;
5159 proto_tree *subtree;
5162 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5163 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5164 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5165 "%s (hh.mm.ss): %d.%02d.%02d%s",
5167 (val / 3600), ((val % 3600) / 60), (val % 60),
5168 val == 0 ? " (indefinite)" : "");
5170 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5171 "%s - %u octets (Signed)", label, lvt);
5172 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5173 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5175 return offset+tag_len+lvt;
5179 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
5181 guint32 month, weekOfMonth, dayOfWeek;
5182 guint8 tag_no, tag_info;
5186 proto_tree *subtree;
5188 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5189 month = tvb_get_guint8(tvb, offset+tag_len);
5190 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
5191 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
5192 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
5193 val_to_str(month, months, "month (%d) not found"),
5194 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
5195 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
5196 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5197 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5199 return offset+tag_len+lvt;
5203 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5205 guint32 year, month, day, weekday;
5206 guint8 tag_no, tag_info;
5210 proto_tree *subtree;
5212 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5213 year = tvb_get_guint8(tvb, offset+tag_len);
5214 month = tvb_get_guint8(tvb, offset+tag_len+1);
5215 day = tvb_get_guint8(tvb, offset+tag_len+2);
5216 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
5217 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
5218 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5221 else if (year != 255) {
5223 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5224 "%s%s %d, %d, (Day of Week = %s)",
5225 label, val_to_str(month,
5227 "month (%d) not found"),
5228 day, year, val_to_str(weekday,
5232 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5233 "%s%s %d, any year, (Day of Week = %s)",
5234 label, val_to_str(month, months, "month (%d) not found"),
5235 day, val_to_str(weekday, day_of_week, "(%d) not found"));
5237 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5238 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5240 return offset+tag_len+lvt;
5244 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5246 guint32 hour, minute, second, msec, lvt;
5247 guint8 tag_no, tag_info;
5250 proto_tree *subtree;
5252 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5253 hour = tvb_get_guint8(tvb, offset+tag_len);
5254 minute = tvb_get_guint8(tvb, offset+tag_len+1);
5255 second = tvb_get_guint8(tvb, offset+tag_len+2);
5256 msec = tvb_get_guint8(tvb, offset+tag_len+3);
5257 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
5258 ti = proto_tree_add_text(tree, tvb, offset,
5259 lvt+tag_len, "%sany", label);
5261 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5262 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
5264 hour > 12 ? hour - 12 : hour,
5265 minute, second, msec,
5266 hour >= 12 ? "P.M." : "A.M.",
5267 hour, minute, second, msec);
5268 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5269 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5271 return offset+tag_len+lvt;
5275 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5277 proto_tree *subtree = tree;
5280 if (label != NULL) {
5281 tt = proto_tree_add_text (subtree, tvb, offset, 10, "%s", label);
5282 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5284 offset = fDate (tvb,subtree,offset,"Date: ");
5285 return fTime (tvb,subtree,offset,"Time: ");
5289 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5291 guint lastoffset = 0;
5292 guint8 tag_no, tag_info;
5295 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5296 lastoffset = offset;
5297 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5298 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
5301 offset = fTime (tvb,tree,offset,"Time: ");
5302 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
5304 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
5310 fCalendarEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
5312 guint8 tag_no, tag_info;
5315 switch (fTagNo(tvb, offset)) {
5317 offset = fDate (tvb, tree, offset, "Date: ");
5319 case 1: /* dateRange */
5320 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5321 offset = fDateRange (tvb, tree, offset);
5322 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5324 case 2: /* BACnetWeekNDay */
5325 offset = fWeekNDay (tvb, tree, offset);
5335 fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
5338 proto_tree* subtree = tree;
5341 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5342 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
5344 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5346 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
5347 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
5348 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
5354 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5356 guint8 tag_no = 0, tag_info = 0;
5359 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
5360 switch (fTagNo(tvb, offset)) {
5362 offset = fTime (tvb, tree, offset, label?label:"time: ");
5364 case 1: /* sequenceNumber */
5365 offset = fUnsignedTag (tvb, tree, offset,
5366 label?label:"sequence number: ");
5368 case 2: /* dateTime */
5369 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5370 offset = fDateTime (tvb, tree, offset, label?label:"date time: ");
5371 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5383 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5385 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5386 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
5391 static const value_string
5392 BACnetDaysOfWeek [] = {
5404 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5406 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5407 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
5408 "valid Days: ", BACnetDaysOfWeek);
5409 offset = fTime (tvb,tree,offset,"from time: ");
5410 offset = fTime (tvb,tree,offset,"to time: ");
5411 offset = fRecipient (tvb,pinfo,tree,offset);
5412 offset = fProcessId (tvb,tree,offset);
5413 offset = fApplicationTypes (tvb,pinfo,tree,offset,
5414 "issue confirmed notifications: ");
5415 offset = fBitStringTagVS (tvb,tree,offset,
5416 "transitions: ", BACnetEventTransitionBits);
5423 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5426 guint start = offset;
5427 guint8 tag_no, tag_info;
5428 proto_tree *subtree = tree;
5431 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5434 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5435 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
5440 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5442 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5448 fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5451 guint start = offset;
5452 guint8 tag_no, tag_info;
5453 proto_tree* subtree = tree;
5456 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5458 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
5461 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
5463 guint32 ip = tvb_get_ipv4(tvb, offset);
5464 guint16 port = tvb_get_ntohs(tvb, offset+4);
5466 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
5467 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
5470 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
5471 struct e_in6_addr addr;
5472 guint16 port = tvb_get_ntohs(tvb, offset+16);
5473 tvb_get_ipv6(tvb, offset, &addr);
5475 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
5476 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
5478 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
5479 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5480 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
5487 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5489 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5495 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
5497 guint8 tag_no, tag_info;
5501 offset = fUnsignedTag (tvb, tree, offset, "network-number");
5502 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5504 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5507 offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
5513 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
5515 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
5516 return fAddress (tvb,tree,offset);
5520 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5522 guint8 tag_no, tag_info;
5526 proto_tree *subtree;
5529 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5530 object_id = tvb_get_ntohl(tvb,offset+tag_length);
5531 object_type = object_id_type(object_id);
5532 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
5533 "ObjectIdentifier: %s, %u",
5534 val_to_split_str(object_type,
5537 ASHRAE_Reserved_Fmt,
5538 Vendor_Proprietary_Fmt),
5539 object_id_instance(object_id));
5540 if (col_get_writable(pinfo->cinfo))
5541 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5542 val_to_split_str(object_type,
5545 ASHRAE_Reserved_Fmt,
5546 Vendor_Proprietary_Fmt),
5547 object_id_instance(object_id));
5549 /* update BACnet Statistics */
5550 updateBacnetInfoValue(BACINFO_OBJECTID,
5551 ep_strdup(val_to_split_str(object_type, 128,
5552 BACnetObjectType, ASHRAE_Reserved_Fmt,
5553 Vendor_Proprietary_Fmt)));
5554 updateBacnetInfoValue(BACINFO_INSTANCEID, ep_strdup_printf("Instance ID: %u",
5555 object_id_instance(object_id)));
5557 /* here are the details of how we arrived at the above text */
5558 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5559 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5560 offset += tag_length;
5561 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
5562 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
5569 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5571 guint8 tag_no, tag_info;
5574 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5576 if (tag_no == 0) { /* device */
5577 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5579 else { /* address */
5580 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5581 offset = fAddress (tvb, tree, offset);
5582 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5589 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5591 guint lastoffset = 0;
5592 guint8 tag_no, tag_info;
5594 proto_tree *orgtree = tree;
5596 proto_tree *subtree;
5598 /* beginning of new item - indent and label */
5599 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
5600 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5602 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5603 lastoffset = offset;
5605 switch (fTagNo(tvb, offset)) {
5606 case 0: /* recipient */
5607 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5608 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5609 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5610 offset = fRecipient (tvb, pinfo, subtree, offset);
5611 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5613 case 1: /* processId */
5614 offset = fProcessId (tvb, tree, offset);
5615 lastoffset = offset;
5620 if (offset == lastoffset) break; /* nothing happened, exit loop */
5626 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5628 guint lastoffset = 0;
5629 guint8 tag_no, tag_info;
5631 proto_tree *subtree;
5633 proto_tree *orgtree = tree;
5636 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5637 lastoffset = offset;
5638 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5639 if (tag_is_closing(tag_info) ) {
5644 case 0: /* recipient */
5645 /* beginning of new item in list */
5646 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
5647 itemno = itemno + 1;
5648 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5650 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5651 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5652 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5653 offset = fRecipientProcess (tvb, pinfo, subtree, offset);
5654 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5655 subtree = tree; /* done with this level - return to previous tree */
5657 case 1: /* MonitoredPropertyReference */
5658 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
5659 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5660 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5661 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
5662 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5665 case 2: /* IssueConfirmedNotifications - boolean */
5666 offset = fBooleanTag (tvb, tree, offset, "Issue Confirmed Notifications: ");
5668 case 3: /* TimeRemaining */
5669 offset = fUnsignedTag (tvb, tree, offset, "Time Remaining: ");
5671 case 4: /* COVIncrement */
5672 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5677 if (offset == lastoffset) break; /* nothing happened, exit loop */
5683 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5685 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5686 return fAddress (tvb, tree, offset);
5690 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
5692 guint lastoffset = 0, len;
5693 guint8 tag_no, tag_info;
5695 proto_tree *subtree = tree;
5697 /* set the optional global properties to indicate not-used */
5698 propertyArrayIndex = -1;
5699 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5700 lastoffset = offset;
5701 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5702 if (tag_is_closing(tag_info) ) {
5703 if (tag_no == tag_match) {
5712 case 0: /* deviceIdentifier */
5713 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5715 case 1: /* objectIdentifier */
5716 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5718 case 2: /* propertyIdentifier */
5719 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
5721 case 3: /* propertyArrayIndex */
5722 offset = fPropertyArrayIndex (tvb, subtree, offset);
5724 case 4: /* propertyValue */
5725 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
5727 case 5: /* priority */
5728 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
5730 case 6: /* postDelay */
5731 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
5733 case 7: /* quitOnFailure */
5734 offset = fBooleanTag(tvb, subtree, offset,
5735 "Quit On Failure: ");
5737 case 8: /* writeSuccessful */
5738 offset = fBooleanTag(tvb, subtree, offset,
5739 "Write Successful: ");
5744 if (offset == lastoffset) break; /* nothing happened, exit loop */
5749 /* BACnetActionList ::= SEQUENCE{
5750 action [0] SEQUENCE OF BACnetActionCommand
5754 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5756 guint lastoffset = 0, len;
5757 guint8 tag_no, tag_info;
5759 proto_tree *subtree = tree;
5762 while (tvb_reported_length_remaining(tvb, offset) > 0) {
5763 lastoffset = offset;
5764 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5765 if (tag_is_closing(tag_info)) {
5767 if ( tag_no != 0 ) /* don't eat the closing property tag, just return */
5772 if (tag_is_opening(tag_info)) {
5773 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
5774 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5775 offset += fTagHeaderTree (tvb, subtree, offset,
5776 &tag_no, &tag_info, &lvt);
5779 case 0: /* BACnetActionCommand */
5780 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
5785 if (offset == lastoffset) break; /* nothing happened, exit loop */
5791 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5793 guint8 tag_no, tag_info;
5797 proto_tree *subtree;
5798 const gchar *label = "Property Identifier";
5800 propertyIdentifier = 0; /* global Variable */
5801 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5802 /* can we decode this value? */
5803 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
5804 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5805 "%s: %s (%u)", label,
5806 val_to_split_str(propertyIdentifier, 512,
5807 BACnetPropertyIdentifier,
5808 ASHRAE_Reserved_Fmt,
5809 Vendor_Proprietary_Fmt), propertyIdentifier);
5810 if (col_get_writable(pinfo->cinfo))
5811 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
5812 val_to_split_str(propertyIdentifier, 512,
5813 BACnetPropertyIdentifier,
5814 ASHRAE_Reserved_Fmt,
5815 Vendor_Proprietary_Fmt));
5817 /* property identifiers cannot be larger than 22-bits */
5820 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5821 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5822 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
5823 offset+tag_len, lvt, ENC_BIG_ENDIAN);
5825 return offset+tag_len+lvt;
5829 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
5831 guint8 tag_no, tag_info;
5835 proto_tree *subtree;
5837 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5838 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
5839 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5840 "property Array Index (Unsigned) %u", propertyArrayIndex);
5842 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5843 "property Array Index - %u octets (Unsigned)", lvt);
5844 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5845 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5847 return offset+tag_len+lvt;
5851 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5853 guint8 tag_no, tag_info, character_set;
5855 gsize inbytesleft, outbytesleft = 512;
5856 guint offs, extra = 1;
5859 guint8 bf_arr[512], *out = &bf_arr[0];
5861 proto_tree *subtree;
5862 guint start = offset;
5864 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5866 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5868 character_set = tvb_get_guint8(tvb, offset+offs);
5869 /* Account for code page if DBCS */
5870 if (character_set == 1) {
5873 offset += (offs+extra);
5877 inbytesleft = l = MIN(lvt, 255);
5879 * XXX - are we guaranteed that these encoding
5880 * names correspond, on *all* platforms with
5881 * iconv(), to the encodings we want?
5882 * If not (and perhaps even if so), we should
5883 * perhaps have our own iconv() implementation,
5884 * with a different name, so that we control the
5885 * encodings it supports and the names of those
5888 * We should also handle that in the general
5889 * string handling code, rather than making it
5890 * specific to the BACAPP dissector, as many
5891 * other dissectors need to handle various
5892 * character encodings.
5894 str_val = tvb_get_ephemeral_string(tvb, offset, l);
5895 /** this decoding may be not correct for multi-byte characters, Lka */
5896 switch (character_set) {
5898 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UTF-8");
5903 coding = "IBM MS DBCS";
5907 coding = "JIS C 6226";
5909 case ISO_10646_UCS4:
5910 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5911 coding = "ISO 10646 UCS-4";
5913 case ISO_10646_UCS2:
5914 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5915 coding = "ISO 10646 UCS-2";
5918 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5919 coding = "ISO 8859-1";
5926 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s '%s'", label, coding, out);
5931 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5933 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
5934 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
5936 if (character_set == 1) {
5937 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5939 /* XXX - put the string value here */
5945 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5946 const value_string *src)
5948 guint8 tag_no, tag_info, tmp;
5949 gint j, unused, skip;
5950 guint start = offset;
5952 guint32 lvt, i, numberOfBytes;
5954 proto_tree* subtree = tree;
5957 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5958 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
5960 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
5961 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
5962 "%s(Bit String)", label);
5964 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5966 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5967 proto_tree_add_text(subtree, tvb, offset, 1,
5968 "Unused bits: %u", unused);
5970 for (i = 0; i < numberOfBytes; i++) {
5971 tmp = tvb_get_guint8(tvb, (offset)+i+1);
5972 if (i == numberOfBytes-1) { skip = unused; }
5973 for (j = 0; j < 8-skip; j++) {
5975 if (tmp & (1 << (7 - j)))
5976 proto_tree_add_text(subtree, tvb,
5979 val_to_str((guint) (i*8 +j),
5981 ASHRAE_Reserved_Fmt));
5983 proto_tree_add_text(subtree, tvb,
5986 val_to_str((guint) (i*8 +j),
5988 ASHRAE_Reserved_Fmt));
5990 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
5996 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
5997 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
6006 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
6008 return fBitStringTagVS (tvb, tree, offset, label, NULL);
6011 /* handles generic application types, as well as enumerated and enumerations
6012 with reserved and proprietarty ranges (split) */
6014 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6015 const gchar *label, const value_string *src, guint32 split_val)
6017 guint8 tag_no, tag_info;
6021 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6023 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6024 if (!tag_is_context_specific(tag_info)) {
6026 case 0: /** NULL 20.2.2 */
6027 offset = fNullTag(tvb, tree, offset, label);
6029 case 1: /** BOOLEAN 20.2.3 */
6030 offset = fBooleanTag(tvb, tree, offset, label);
6032 case 2: /** Unsigned Integer 20.2.4 */
6033 offset = fUnsignedTag(tvb, tree, offset, label);
6035 case 3: /** Signed Integer 20.2.5 */
6036 offset = fSignedTag(tvb, tree, offset, label);
6038 case 4: /** Real 20.2.6 */
6039 offset = fRealTag(tvb, tree, offset, label);
6041 case 5: /** Double 20.2.7 */
6042 offset = fDoubleTag(tvb, tree, offset, label);
6044 case 6: /** Octet String 20.2.8 */
6045 offset = fOctetString (tvb, tree, offset, label, lvt);
6047 case 7: /** Character String 20.2.9 */
6048 offset = fCharacterString (tvb,tree,offset,label);
6050 case 8: /** Bit String 20.2.10 */
6051 offset = fBitStringTagVS (tvb, tree, offset, label, src);
6053 case 9: /** Enumerated 20.2.11 */
6054 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
6056 case 10: /** Date 20.2.12 */
6057 offset = fDate (tvb, tree, offset, label);
6059 case 11: /** Time 20.2.13 */
6060 offset = fTime (tvb, tree, offset, label);
6062 case 12: /** BACnetObjectIdentifier 20.2.14 */
6063 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6065 case 13: /* reserved for ASHRAE */
6068 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
6069 offset += lvt + tag_len;
6081 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
6083 guint lastoffset = 0;
6085 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6086 lastoffset = offset;
6088 switch (fTagNo(tvb,offset)) {
6089 case 0: /* percent */
6090 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
6093 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
6095 case 2: /* amount */
6096 offset = fRealTag(tvb, tree, offset, "shed amount: ");
6101 if (offset == lastoffset) break; /* nothing happened, exit loop */
6107 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6108 const gchar *label, const value_string *vs)
6110 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
6114 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6117 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
6121 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
6123 guint8 tag_no, tag_info;
6127 proto_tree *subtree;
6131 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
6132 /* cap the the suggested length in case of bad data */
6133 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
6134 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
6137 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
6138 "Context Value (as %u DATA octets)", lvt);
6140 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6141 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6143 return offset + tag_len + lvt;
6146 BACnetPrescale ::= SEQUENCE {
6147 multiplier [0] Unsigned,
6148 moduloDivide [1] Unsigned
6152 fPrescale (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6154 guint8 tag_no, tag_info;
6156 guint lastoffset = 0;
6158 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6159 lastoffset = offset;
6160 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6161 if (tag_is_closing(tag_info) ) {
6165 case 0: /* multiplier */
6166 offset = fUnsignedTag (tvb,tree,offset,"Multiplier: ");
6168 case 1: /* moduloDivide */
6169 offset = fUnsignedTag (tvb,tree,offset,"Modulo Divide: ");
6174 if (offset == lastoffset) break; /* nothing happened, exit loop */
6180 BACnetScale ::= CHOICE {
6181 floatScale [0] REAL,
6182 integerScale [1] INTEGER
6186 fScale (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6188 guint8 tag_no, tag_info;
6190 guint lastoffset = 0;
6192 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6193 lastoffset = offset;
6194 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6195 if (tag_is_closing(tag_info) ) {
6199 case 0: /* floatScale */
6200 offset = fRealTag (tvb,tree,offset,"Float Scale: ");
6202 case 1: /* integerScale */
6203 offset = fSignedTag (tvb,tree,offset,"Integer Scale: ");
6208 if (offset == lastoffset) break; /* nothing happened, exit loop */
6213 BACnetAccumulatorRecord ::= SEQUENCE {
6214 timestamp [0] BACnetDateTime,
6215 presentValue [1] Unsigned,
6216 accumulatedValue [2] Unsigned,
6217 accumulatortStatus [3] ENUMERATED {
6227 fLoggingRecord (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6229 guint8 tag_no, tag_info;
6231 guint lastoffset = 0;
6233 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6234 lastoffset = offset;
6235 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6236 if (tag_is_closing(tag_info) ) {
6240 case 0: /* timestamp */
6241 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6242 offset = fDateTime (tvb, tree, offset, "Timestamp: ");
6243 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6245 case 1: /* presentValue */
6246 offset = fUnsignedTag (tvb,tree,offset,"Present Value: ");
6248 case 2: /* accumulatedValue */
6249 offset = fUnsignedTag (tvb,tree,offset,"Accumulated Value: ");
6251 case 3: /* accumulatorStatus */
6252 offset = fEnumeratedTag (tvb, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus);
6257 if (offset == lastoffset) break; /* nothing happened, exit loop */
6263 SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState
6266 fSequenceOfEnums (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, const value_string *vs)
6268 guint8 tag_no, tag_info;
6270 guint lastoffset = 0;
6272 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6273 lastoffset = offset;
6274 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6275 if (tag_is_closing(tag_info) ) {
6278 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs);
6279 if ( offset == lastoffset ) break;
6285 SEQ OF BACnetDeviceObjectReference (accessed as an array)
6289 fDoorMembers (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6291 guint8 tag_no, tag_info;
6293 guint lastoffset = 0;
6295 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6296 lastoffset = offset;
6297 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6298 if (tag_is_closing(tag_info) ) {
6301 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6302 if (offset == lastoffset) break;
6308 SEQ OF ReadAccessSpecification
6311 fListOfGroupMembers (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6313 guint8 tag_no, tag_info;
6315 guint lastoffset = 0;
6317 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6318 lastoffset = offset;
6319 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6320 if (tag_is_closing(tag_info) ) {
6323 offset = fReadAccessSpecification(tvb, pinfo, tree, offset);
6324 if ( offset == lastoffset ) break;
6330 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6332 guint8 tag_no, tag_info;
6334 guint lastoffset = 0, depth = 0;
6336 guint32 save_object_type = object_type;
6338 if (propertyIdentifier >= 0) {
6339 g_snprintf (ar, sizeof(ar), "%s: ",
6340 val_to_split_str(propertyIdentifier, 512,
6341 BACnetPropertyIdentifier,
6342 ASHRAE_Reserved_Fmt,
6343 Vendor_Proprietary_Fmt));
6345 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
6347 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6348 lastoffset = offset;
6349 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6350 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
6351 if (depth <= 0) return offset;
6354 /* Application Tags */
6355 switch (propertyIdentifier) {
6356 case 2: /* action */
6357 /* loop object is application tagged,
6358 command object is context tagged */
6359 if (tag_is_context_specific(tag_info)) {
6360 /* BACnetActionList */
6361 offset = fActionList (tvb, pinfo, tree,offset);
6364 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6368 case 30: /* BACnetAddressBinding */
6369 offset = fAddressBinding (tvb,pinfo,tree,offset);
6371 case 54: /* list of object property reference */
6372 offset = fLOPR (tvb, pinfo, tree,offset);
6374 case 55: /* list-of-session-keys */
6375 fSessionKey (tvb, tree, offset);
6377 case 79: /* object-type */
6378 case 96: /* protocol-object-types-supported */
6379 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
6380 BACnetObjectType, 128);
6382 case 97: /* Protocol-Services-Supported */
6383 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6384 BACnetServicesSupported);
6386 case 102: /* recipient-list */
6387 offset = fDestination (tvb, pinfo, tree, offset);
6389 case 107: /* segmentation-supported */
6390 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6391 BACnetSegmentation);
6393 case 111: /* Status-Flags */
6394 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6397 case 112: /* System-Status */
6398 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6399 BACnetDeviceStatus);
6401 case 117: /* units */
6402 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6403 BACnetEngineeringUnits);
6405 case 87: /* priority-array -- accessed as a BACnetARRAY */
6406 if (propertyArrayIndex == 0) {
6407 /* BACnetARRAY index 0 refers to the length
6408 of the array, not the elements of the array */
6409 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6411 offset = fPriorityArray (tvb, pinfo, tree, offset);
6414 case 38: /* exception-schedule */
6415 if (object_type < 128) {
6416 if (propertyArrayIndex == 0) {
6417 /* BACnetARRAY index 0 refers to the length
6418 of the array, not the elements of the array */
6419 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6421 offset = fSpecialEvent (tvb,pinfo,tree,offset);
6425 case 19: /* controlled-variable-reference */
6426 case 60: /* manipulated-variable-reference */
6427 case 109: /* Setpoint-Reference */
6428 case 132: /* log-device-object-property */
6429 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6431 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
6432 if (object_type < 128) {
6433 if (propertyArrayIndex == 0) {
6434 /* BACnetARRAY index 0 refers to the length
6435 of the array, not the elements of the array */
6436 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6438 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
6442 case 127: /* client COV increment */
6443 offset = fClientCOV (tvb, pinfo, tree, offset);
6445 case 131: /* log-buffer */
6446 if ( object_type == 25 )
6447 offset = fEventLogRecord(tvb, pinfo, tree, offset);
6448 else if ( object_type == 27 )
6449 offset = fLogMultipleRecord (tvb, pinfo, tree, offset);
6451 offset = fLogRecord (tvb, pinfo, tree, offset);
6453 case 159: /* member-of */
6454 case 165: /* zone-members */
6455 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6457 case 196: /* last-restart-reason */
6458 offset = fRestartReason (tvb, pinfo, tree, offset);
6460 case 212: /* actual-shed-level */
6461 case 214: /* expected-shed-level */
6462 case 218: /* requested-shed-level */
6463 offset = fShedLevel (tvb, tree, offset);
6465 case 152: /* active-cov-subscriptions */
6466 offset = fCOVSubscription (tvb, pinfo, tree, offset);
6468 case 23: /* date-list */
6469 offset = fCalendarEntry(tvb, tree, offset);
6471 case 116: /* time-sychronization-recipients */
6472 offset = fRecipient(tvb, pinfo, tree, offset);
6474 case 83: /* event-parameters */
6475 offset = fEventParameter(tvb, pinfo, tree, offset);
6477 case 211: /* subordinate-list */
6478 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6480 case 130: /* event-time-stamp */
6481 offset = fEventTimeStamps(tvb, pinfo, tree, offset);
6483 case 197: /* logging-type */
6484 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType);
6486 case 36: /* event-state */
6487 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64);
6489 case 103: /* reliability */
6490 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability);
6492 case 72: /* notify-type */
6493 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNotifyType);
6495 case 208: /* node-type */
6496 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType);
6498 case 231: /* door-status */
6499 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus);
6501 case 233: /* lock-status */
6502 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus);
6504 case 235: /* secured-status */
6505 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus);
6507 case 158: /* maintenance-required */
6508 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance);
6510 case 92: /* program-state */
6511 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState);
6513 case 90: /* program-change */
6514 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest);
6516 case 100: /* reason-for-halt */
6517 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError);
6519 case 160: /* mode */
6520 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode);
6522 case 163: /* silenced */
6523 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState);
6525 case 161: /* operation-expected */
6526 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation);
6528 case 164: /* tracking-value */
6529 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState);
6531 case 41: /* file-access-method */
6532 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod);
6534 case 185: /* prescale */
6535 offset = fPrescale(tvb, pinfo, tree, offset);
6537 case 187: /* scale */
6538 offset = fScale(tvb, pinfo, tree, offset);
6540 case 184: /* logging-record */
6541 offset = fLoggingRecord(tvb, pinfo, tree, offset);
6543 case 228: /* door-members */
6544 offset = fDoorMembers(tvb, pinfo, tree, offset);
6546 case 181: /* input-reference */
6547 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6549 case 78: /* object-property-reference */
6550 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6552 case 234: /* masked-alarm-values */
6553 offset = fSequenceOfEnums(tvb, pinfo, tree, offset, "masked-alarm-value: ", BACnetDoorAlarmState);
6555 case 53: /* list-of-group-members */
6556 save_object_type = object_type;
6557 offset = fListOfGroupMembers(tvb, pinfo, tree, offset);
6558 object_type = save_object_type;
6560 case 85: /* present-value */
6561 if ( object_type == 11 ) /* group object handling of present-value */
6563 offset = fReadAccessResult(tvb, pinfo, tree, offset);
6566 /* intentially fall through here so don't reorder this case statement */
6569 if (tag_is_opening(tag_info)) {
6571 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6572 } else if (tag_is_closing(tag_info)) {
6574 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6576 offset = fContextTaggedValue(tvb, tree, offset, ar);
6579 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6583 if (offset == lastoffset) break; /* nothing happened, exit loop */
6590 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
6595 if (tag_is_opening(tag_info)) {
6596 offset += fTagHeaderTree(tvb, tree, offset,
6597 &tag_no, &tag_info, &lvt);
6598 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6599 if (tvb_length_remaining(tvb, offset) > 0) {
6600 offset += fTagHeaderTree(tvb, tree, offset,
6601 &tag_no, &tag_info, &lvt);
6604 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
6605 "expected Opening Tag!");
6606 offset = tvb_length(tvb);
6614 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
6616 guint lastoffset = offset;
6617 guint8 tag_no, tag_info;
6620 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
6621 if (offset > lastoffset) {
6622 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6623 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
6624 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
6631 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6633 guint lastoffset = 0;
6634 guint8 tag_no, tag_info;
6637 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6638 lastoffset = offset;
6639 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
6640 if (offset > lastoffset) {
6641 /* detect optional priority
6642 by looking to see if the next tag is context tag number 3 */
6643 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6644 if (tag_is_context_specific(tag_info) && (tag_no == 3))
6645 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
6647 if (offset == lastoffset) break; /* nothing happened, exit loop */
6653 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6655 guint lastoffset = 0, len;
6656 guint8 tag_no, tag_info;
6658 proto_tree *subtree = tree;
6661 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6662 lastoffset = offset;
6663 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6664 if (tag_is_closing(tag_info)) {
6671 case 0: /* ProcessId */
6672 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
6674 case 1: /* monitored ObjectId */
6675 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6677 case 2: /* issueConfirmedNotifications */
6678 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
6680 case 3: /* life time */
6681 offset = fTimeSpan (tvb,tree,offset,"life time");
6683 case 4: /* monitoredPropertyIdentifier */
6684 if (tag_is_opening(tag_info)) {
6685 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
6687 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6689 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6690 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
6695 case 5: /* covIncrement */
6696 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
6701 if (offset == lastoffset) break; /* nothing happened, exit loop */
6707 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6709 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
6713 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6715 guint lastoffset = 0;
6717 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6718 lastoffset = offset;
6720 switch (fTagNo(tvb, offset)) {
6721 case 0: /* deviceInstanceLowLimit */
6722 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
6724 case 1: /* deviceInstanceHighLimit */
6725 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
6727 case 2: /* BACnetObjectId */
6728 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6730 case 3: /* messageText */
6731 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
6736 if (offset == lastoffset) break; /* nothing happened, exit loop */
6743 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
6745 guint lastoffset = 0;
6746 guint8 tag_no, tag_info;
6749 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6750 if (tag_is_opening(tag_info) && tag_no == 0) {
6751 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
6752 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6753 lastoffset = offset;
6754 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6755 if (tag_is_closing(tag_info)) {
6756 /* should be closing context tag 0 */
6757 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6761 offset = fTimeValue (tvb, pinfo, subtree, offset);
6762 if (offset == lastoffset) break; /* nothing happened, exit loop */
6764 } else if (tag_no == 0 && lvt == 0) {
6765 /* not sure null (empty array element) is legal */
6766 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6772 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6774 guint lastoffset = 0;
6775 guint8 tag_no, tag_info;
6777 guint i = 1; /* day of week array index */
6778 proto_tree *subtree = tree;
6781 if (propertyArrayIndex > 0) {
6782 /* BACnetARRAY index 0 refers to the length
6783 of the array, not the elements of the array.
6784 BACnetARRAY index -1 is our internal flag that
6785 the optional index was not used.
6786 BACnetARRAY refers to this as all elements of the array.
6787 If the optional index is specified for a BACnetARRAY,
6788 then that specific array element is referenced. */
6789 i = propertyArrayIndex;
6791 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6792 lastoffset = offset;
6793 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6794 if (tag_is_closing(tag_info)) {
6795 return offset; /* outer encoding will print out closing tag */
6797 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
6798 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6799 offset = fDailySchedule (tvb, pinfo, subtree, offset);
6800 if (offset == lastoffset) break; /* nothing happened, exit loop */
6807 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
6809 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6812 return fDateTime (tvb, tree, offset, "UTC-Time: ");
6816 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
6818 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6821 return fDateTime (tvb, tree, offset, NULL);
6825 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
6827 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6829 offset = fDate (tvb,tree,offset,"Start Date: ");
6830 return fDate (tvb, tree, offset, "End Date: ");
6834 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6837 guint8 tag_no, tag_info;
6841 proto_tree *subtree;
6842 const gchar *label = "Vendor ID";
6844 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6845 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6846 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6847 "%s: %s (%u)", label,
6848 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
6850 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6851 "%s - %u octets (Unsigned)", label, lvt);
6852 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6853 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6855 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
6856 proto_item *expert_item;
6857 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6858 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6859 PROTO_ITEM_SET_GENERATED(expert_item);
6860 return offset+tag_len+lvt;
6863 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
6864 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6866 return offset+tag_len+lvt;
6870 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6873 guint8 tag_no, tag_info;
6877 proto_tree *subtree;
6878 const gchar *label = "Restart Reason";
6880 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6881 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6882 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6883 "%s: %s (%u)", label,
6884 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
6886 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6887 "%s - %u octets (Unsigned)", label, lvt);
6888 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6889 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6892 proto_item *expert_item;
6893 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
6894 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
6895 PROTO_ITEM_SET_GENERATED(expert_item);
6896 return offset+tag_len+lvt;
6899 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
6900 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6902 return offset+tag_len+lvt;
6906 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6908 guint lastoffset = 0;
6910 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6911 lastoffset = offset;
6912 switch (fTagNo(tvb, offset)) {
6914 case 0: /* textMessageSourceDevice */
6915 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6917 case 1: /* messageClass */
6918 switch (fTagNo(tvb, offset)) {
6919 case 0: /* numeric */
6920 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
6922 case 1: /* character */
6923 offset = fCharacterString (tvb, tree, offset, "message Class: ");
6927 case 2: /* messagePriority */
6928 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
6929 BACnetMessagePriority);
6931 case 3: /* message */
6932 offset = fCharacterString (tvb, tree, offset, "message: ");
6937 if (offset == lastoffset) break; /* nothing happened, exit loop */
6943 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6945 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
6949 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6951 guint lastoffset = 0, len;
6952 guint8 tag_no, tag_info;
6954 proto_tree *subtree = tree;
6957 guint vendor_identifier = 0;
6958 guint service_number = 0;
6960 lastoffset = offset;
6961 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6962 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
6963 if (col_get_writable(pinfo->cinfo))
6964 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
6965 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6967 next_tvb = tvb_new_subset_remaining(tvb,offset);
6968 if (dissector_try_uint(bacapp_dissector_table,
6969 vendor_identifier, next_tvb, pinfo, tree)) {
6970 /* we parsed it so skip over length and we are done */
6971 offset += tvb_length(next_tvb);
6975 /* Not handled by vendor dissector */
6977 /* exit loop if nothing happens inside */
6978 while (tvb_reported_length_remaining(tvb, offset) > 0) {
6979 lastoffset = offset;
6980 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6981 if (tag_is_closing(tag_info)) {
6982 if (tag_no == 2) { /* Make sure it's the expected tag */
6987 break; /* End loop if incorrect closing tag */
6992 /* vendorID is now parsed above */
6993 case 1: /* serviceNumber */
6994 fUnsigned32(tvb, offset+len, lvt, &service_number);
6995 if (col_get_writable(pinfo->cinfo))
6996 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
6997 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
6999 case 2: /*serviceParameters */
7000 if (tag_is_opening(tag_info)) {
7001 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
7002 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7003 propertyIdentifier = -1;
7004 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7012 if (offset == lastoffset) break; /* nothing happened, exit loop */
7019 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7021 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7025 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7027 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7031 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
7033 guint lastoffset = 0;
7034 guint8 tag_no, tag_info;
7036 proto_tree *subtree = tree;
7039 if (label != NULL) {
7040 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
7041 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7044 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7045 lastoffset = offset;
7046 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7049 case 0: /* subscriberProcessId */
7050 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
7052 case 1: /* requestingSource */
7053 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
7055 case 2: /* request */
7056 offset = fEnumeratedTagSplit (tvb, tree, offset,
7057 "request: ", BACnetLifeSafetyOperation, 64);
7059 case 3: /* objectId */
7060 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7065 if (offset == lastoffset) break; /* nothing happened, exit loop */
7070 typedef struct _value_string_enum {
7071 const value_string *valstr;
7072 } value_string_enum;
7074 static const value_string_enum
7075 BACnetPropertyStatesEnums[] = {
7080 {BACnetProgramRequest },
7081 {BACnetProgramState },
7082 {BACnetProgramError },
7083 {BACnetReliability },
7084 {BACnetEventState },
7085 {BACnetDeviceStatus },
7086 {BACnetEngineeringUnits },
7088 {BACnetLifeSafetyMode },
7089 {BACnetLifeSafetyState },
7090 {BACnetRestartReason },
7091 {BACnetDoorAlarmState },
7093 {BACnetDoorSecuredStatus },
7094 {BACnetDoorStatus },
7095 { NULL }, /* {BACnetDoorValue }, */
7096 {BACnetFileAccessMethod },
7097 {BACnetLockStatus },
7098 {BACnetLifeSafetyOperation },
7099 {BACnetMaintenance },
7101 {BACnetNotifyType },
7102 { NULL }, /* {BACnetSecurityLevel }, */
7104 {BACnetSilencedState },
7106 { NULL }, /* {BACnetAccessEvent }, */
7107 { NULL }, /* {BACnetZoneOccupancyState }, */
7108 { NULL }, /* {BACnetAccessCredentialDisableReason }, */
7109 { NULL }, /* {BACnetAccessCredentialDisable }, */
7110 { NULL }, /* {BACnetAuthenticationStatus }, */
7112 { NULL }, /* {BACnetBackupState }, */
7114 #define BACnetPropertyStatesEnums_Size 36
7117 fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
7119 guint8 tag_no, tag_info;
7121 const gchar* label = NULL;
7123 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7124 label = ep_strdup_printf( "%s: ", val_to_str_const( tag_no, VALS(BACnetPropertyStates), "unknown-"+tag_no ));
7128 offset = fBooleanTag (tvb, tree, offset, label);
7131 offset = fUnsignedTag(tvb, tree, offset, label);
7134 if ( (tag_no > BACnetPropertyStatesEnums_Size) ||
7135 VALS(BACnetPropertyStatesEnums[tag_no].valstr) == NULL)
7137 offset = fEnumeratedTag(tvb, tree, offset, "Unknown State: ", NULL);
7138 /* don't use Abstract type here because it is context tagged and therefore we don't know app type */
7142 offset = fEnumeratedTagSplit(tvb, tree, offset, label,
7143 VALS(BACnetPropertyStatesEnums[tag_no].valstr), 64);
7152 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
7153 deviceIdentifier [0] BACnetObjectIdentifier,
7154 objectIdentifier [1] BACnetObjectIdentifier,
7155 propertyIdentifier [2] BACnetPropertyIdentifier,
7156 arrayIndex [3] Unsigned OPTIONAL,
7157 value [4] ABSTRACT-SYNTAX.&Type
7161 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7163 guint lastoffset = 0;
7164 guint8 tag_no, tag_info;
7167 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7168 lastoffset = offset;
7169 /* check the tag. A closing tag means we are done */
7170 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7171 if (tag_is_closing(tag_info)) {
7175 case 0: /* deviceIdentifier */
7176 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7178 case 1: /* objectIdentifier */
7179 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7181 case 2: /* propertyIdentifier */
7182 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7184 case 3: /* arrayIndex - OPTIONAL */
7185 offset = fUnsignedTag (tvb, tree, offset,
7189 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7190 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7191 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7196 if (offset == lastoffset) break; /* nothing happened, exit loop */
7202 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7203 objectIdentifier [0] BACnetObjectIdentifier,
7204 propertyIdentifier [1] BACnetPropertyIdentifier,
7205 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7206 -- if omitted with an array then
7207 -- the entire array is referenced
7208 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7212 fObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7214 return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7218 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7219 objectIdentifier [0] BACnetObjectIdentifier,
7220 propertyIdentifier [1] BACnetPropertyIdentifier,
7221 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7222 -- if omitted with an array then
7223 -- the entire array is referenced
7224 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7228 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7230 guint lastoffset = 0;
7231 guint8 tag_no, tag_info;
7234 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7235 lastoffset = offset;
7236 /* check the tag. A closing tag means we are done */
7237 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7238 if (tag_is_closing(tag_info)) {
7242 case 0: /* objectIdentifier */
7243 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7245 case 1: /* propertyIdentifier */
7246 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7248 case 2: /* arrayIndex - OPTIONAL */
7249 offset = fUnsignedTag (tvb, tree, offset,
7252 case 3: /* deviceIdentifier - OPTIONAL */
7253 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7258 if (offset == lastoffset) break; /* nothing happened, exit loop */
7264 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7266 guint lastoffset = offset;
7267 guint8 tag_no, tag_info;
7269 proto_tree *subtree = tree;
7272 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7273 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
7274 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
7275 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7276 /* Opening tag for parameter choice */
7277 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7280 case 0: /* change-of-bitstring */
7281 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7282 lastoffset = offset;
7283 switch (fTagNo(tvb, offset)) {
7285 offset = fBitStringTag (tvb, subtree, offset,
7286 "referenced-bitstring: ");
7289 offset = fBitStringTagVS (tvb, subtree, offset,
7290 "status-flags: ", BACnetStatusFlags);
7291 lastoffset = offset;
7296 if (offset == lastoffset) break; /* nothing happened, exit loop */
7299 case 1: /* change-of-state */
7300 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7301 lastoffset = offset;
7302 switch (fTagNo(tvb, offset)) {
7304 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7305 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7306 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7309 offset = fBitStringTagVS (tvb, subtree, offset,
7310 "status-flags: ", BACnetStatusFlags);
7311 lastoffset = offset;
7316 if (offset == lastoffset) break; /* nothing happened, exit loop */
7319 case 2: /* change-of-value */
7320 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7321 lastoffset = offset;
7322 switch (fTagNo(tvb, offset)) {
7324 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7325 switch (fTagNo(tvb, offset)) {
7327 offset = fBitStringTag (tvb, subtree, offset,
7331 offset = fRealTag (tvb, subtree, offset,
7337 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7340 offset = fBitStringTagVS (tvb, subtree, offset,
7341 "status-flags: ", BACnetStatusFlags);
7342 lastoffset = offset;
7347 if (offset == lastoffset) break; /* nothing happened, exit loop */
7350 case 3: /* command-failure */
7351 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7352 lastoffset = offset;
7353 switch (fTagNo(tvb, offset)) {
7354 case 0: /* "command-value: " */
7355 /* from BACnet Table 13-3,
7356 Standard Object Property Values Returned in Notifications */
7357 propertyIdentifier = 85; /* PRESENT_VALUE */
7358 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7359 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7360 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7363 offset = fBitStringTagVS (tvb, subtree, offset,
7364 "status-flags: ", BACnetStatusFlags);
7366 case 2: /* "feedback-value: " */
7367 propertyIdentifier = 40; /* FEEDBACK_VALUE */
7368 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7369 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7370 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7371 lastoffset = offset;
7376 if (offset == lastoffset) break; /* nothing happened, exit loop */
7379 case 4: /* floating-limit */
7380 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7381 lastoffset = offset;
7382 switch (fTagNo(tvb, offset)) {
7384 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
7387 offset = fBitStringTagVS (tvb, subtree, offset,
7388 "status-flags: ", BACnetStatusFlags);
7391 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
7394 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
7395 lastoffset = offset;
7400 if (offset == lastoffset) break; /* nothing happened, exit loop */
7403 case 5: /* out-of-range */
7404 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7405 lastoffset = offset;
7406 switch (fTagNo(tvb, offset)) {
7408 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
7411 offset = fBitStringTagVS (tvb, subtree, offset,
7412 "status-flags: ", BACnetStatusFlags);
7415 offset = fRealTag (tvb, subtree, offset, "deadband: ");
7418 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
7419 lastoffset = offset;
7424 if (offset == lastoffset) break; /* nothing happened, exit loop */
7428 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7429 lastoffset = offset;
7430 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
7431 if (offset == lastoffset) break; /* nothing happened, exit loop */
7434 case 7: /* buffer-ready */
7435 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7436 lastoffset = offset;
7437 switch (fTagNo(tvb, offset)) {
7439 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
7442 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
7445 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7446 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
7447 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7450 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7451 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
7452 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7453 lastoffset = offset;
7458 if (offset == lastoffset) break; /* nothing happened, exit loop */
7461 case 8: /* change-of-life-safety */
7462 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7463 lastoffset = offset;
7464 switch (fTagNo(tvb, offset)) {
7466 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7467 "new-state: ", BACnetLifeSafetyState, 256);
7470 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7471 "new-mode: ", BACnetLifeSafetyMode, 256);
7474 offset = fBitStringTagVS (tvb, subtree, offset,
7475 "status-flags: ", BACnetStatusFlags);
7478 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7479 "operation-expected: ", BACnetLifeSafetyOperation, 64);
7480 lastoffset = offset;
7485 if (offset == lastoffset) break; /* nothing happened, exit loop */
7488 case 9: /* extended */
7489 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7490 lastoffset = offset;
7491 switch (fTagNo(tvb, offset)) {
7493 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
7496 offset = fUnsignedTag (tvb, subtree, offset,
7497 "extended-event-type: ");
7499 case 2: /* parameters */
7500 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7501 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
7502 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
7503 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7504 lastoffset = offset;
7509 if (offset == lastoffset) break; /* nothing happened, exit loop */
7512 case 10: /* buffer ready */
7513 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7514 lastoffset = offset;
7515 switch (fTagNo(tvb, offset)) {
7516 case 0: /* buffer-property */
7517 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7518 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7519 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7522 offset = fUnsignedTag (tvb, subtree, offset,
7523 "previous-notification: ");
7526 offset = fUnsignedTag (tvb, subtree, offset,
7527 "current-notification: ");
7528 lastoffset = offset;
7533 if (offset == lastoffset) break; /* nothing happened, exit loop */
7536 case 11: /* unsigned range */
7537 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7538 lastoffset = offset;
7539 switch (fTagNo(tvb, offset)) {
7541 offset = fUnsignedTag (tvb, subtree, offset,
7542 "exceeding-value: ");
7545 offset = fBitStringTagVS (tvb, subtree, offset,
7546 "status-flags: ", BACnetStatusFlags);
7549 offset = fUnsignedTag (tvb, subtree, offset,
7550 "exceeded-limit: ");
7551 lastoffset = offset;
7556 if (offset == lastoffset) break; /* nothing happened, exit loop */
7559 /* todo: add new parameters here ... */
7561 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7565 /* Closing tag for parameter choice */
7566 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7572 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7574 guint lastoffset = offset;
7575 guint8 tag_no, tag_info;
7577 proto_tree *subtree = tree;
7580 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7581 tt = proto_tree_add_text(subtree, tvb, offset, 0, "event parameters (%d) %s",
7582 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
7583 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7584 /* Opening tag for parameter choice */
7585 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7588 case 0: /* change-of-bitstring */
7589 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7590 lastoffset = offset;
7591 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7592 if (tag_is_closing(tag_info)) {
7597 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7600 offset = fBitStringTag (tvb, subtree, offset, "bitmask: ");
7602 case 2: /* SEQUENCE OF BIT STRING */
7603 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7604 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7605 lastoffset = offset;
7606 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7607 if (tag_is_closing(tag_info)) {
7610 offset = fBitStringTag(tvb, subtree, offset,
7611 "bitstring value: ");
7613 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7620 case 1: /* change-of-state */
7621 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7622 lastoffset = offset;
7623 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7624 if (tag_is_closing(tag_info)) {
7629 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7631 case 1: /* SEQUENCE OF BACnetPropertyStates */
7632 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7633 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7634 lastoffset = offset;
7635 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7636 if (tag_is_closing(tag_info)) {
7639 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7641 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7648 case 2: /* change-of-value */
7649 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7650 lastoffset = offset;
7651 switch (fTagNo(tvb, offset)) {
7653 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7655 case 1: /* don't loop it, it's a CHOICE */
7656 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7657 switch (fTagNo(tvb, offset)) {
7659 offset = fBitStringTag (tvb, subtree, offset, "bitmask: ");
7662 offset = fRealTag (tvb, subtree, offset,
7663 "referenced Property Increment: ");
7668 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7675 case 3: /* command-failure */
7676 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7677 lastoffset = offset;
7678 tag_no = fTagNo(tvb, offset);
7681 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7684 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7685 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7686 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7693 case 4: /* floating-limit */
7694 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7695 lastoffset = offset;
7696 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7697 if (tag_is_closing(tag_info)) {
7702 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7705 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7706 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7707 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7710 offset = fRealTag (tvb, subtree, offset, "low diff limit: ");
7713 offset = fRealTag (tvb, subtree, offset, "high diff limit: ");
7716 offset = fRealTag (tvb, subtree, offset, "deadband: ");
7723 case 5: /* out-of-range */
7724 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7725 lastoffset = offset;
7726 switch (fTagNo(tvb, offset)) {
7728 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7731 offset = fRealTag (tvb, subtree, offset, "low limit: ");
7734 offset = fRealTag (tvb, subtree, offset, "high limit: ");
7737 offset = fRealTag (tvb, subtree, offset, "deadband: ");
7746 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
7750 case 7: /* buffer-ready */
7753 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
7754 lastoffset = offset;
7755 switch (fTagNo(tvb, offset)) {
7757 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
7760 offset = fUnsignedTag (tvb,tree,offset,
7761 "previous notification count: ");
7769 case 8: /* change-of-life-safety */
7770 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7771 lastoffset = offset;
7772 switch (fTagNo(tvb, offset)) {
7774 offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
7777 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7778 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7779 lastoffset = offset;
7780 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7781 if (tag_is_closing(tag_info)) {
7784 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7785 "life safety alarm value: ", BACnetLifeSafetyState, 256);
7787 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7790 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7791 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7792 lastoffset = offset;
7793 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7794 if (tag_is_closing(tag_info)) {
7797 offset = fEnumeratedTagSplit (tvb, subtree, offset,
7798 "alarm value: ", BACnetLifeSafetyState, 256);
7800 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7803 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7804 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7805 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7812 case 9: /* extended */
7813 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7814 lastoffset = offset;
7815 switch (fTagNo(tvb, offset)) {
7817 offset = fVendorIdentifier (tvb, pinfo, tree, offset);
7820 offset = fUnsignedTag (tvb, tree, offset,
7821 "extended-event-type: ");
7823 case 2: /* parameters */
7824 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7825 offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
7826 offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
7827 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
7828 lastoffset = offset;
7833 if (offset == lastoffset) break; /* nothing happened, exit loop */
7836 case 10: /* buffer-ready */
7837 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7838 lastoffset = offset;
7839 switch (fTagNo(tvb, offset)) {
7841 offset = fUnsignedTag (tvb, subtree, offset,
7842 "notification-threshold: ");
7845 offset = fUnsignedTag (tvb, subtree, offset,
7846 "previous-notification-count: ");
7853 case 11: /* unsigned-range */
7854 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7855 lastoffset = offset;
7856 switch (fTagNo(tvb, offset)) {
7858 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
7861 offset = fUnsignedTag (tvb, tree, offset,
7865 offset = fUnsignedTag (tvb, tree, offset,
7873 /* todo: add new event-parameter cases here */
7878 /* Closing tag for parameter choice */
7879 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7884 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7886 guint lastoffset = 0;
7887 guint8 tag_no, tag_info;
7889 proto_tree *subtree = tree;
7892 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7893 lastoffset = offset;
7894 switch (fTagNo(tvb, offset)) {
7895 case 0: /* timestamp */
7896 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7897 offset = fDate (tvb,tree,offset,"Date: ");
7898 offset = fTime (tvb,tree,offset,"Time: ");
7899 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7901 case 1: /* logDatum: don't loop, it's a CHOICE */
7902 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7903 switch (fTagNo(tvb, offset)) {
7904 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
7905 offset = fBitStringTagVS(tvb, tree, offset, "log status:", BACnetLogStatus);
7907 case 1: /* todo: move this to new method fConfirmedEventNotificationRequestTag... */
7908 tt = proto_tree_add_text(tree, tvb, offset, 1, "notification: ");
7909 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7910 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7911 offset = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset);
7912 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7915 offset = fRealTag (tvb, tree, offset, "time-change: ");
7920 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7925 if (offset == lastoffset) break; /* nothing happened, exit loop */
7931 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7933 guint lastoffset = 0;
7934 guint8 tag_no, tag_info;
7937 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7938 lastoffset = offset;
7939 switch (fTagNo(tvb, offset)) {
7940 case 0: /* timestamp */
7941 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7942 offset = fDate (tvb,tree,offset,"Date: ");
7943 offset = fTime (tvb,tree,offset,"Time: ");
7944 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7946 case 1: /* logDatum: don't loop, it's a CHOICE */
7947 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7948 switch (fTagNo(tvb, offset)) {
7949 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
7950 offset = fBitStringTagVS(tvb, tree, offset, "log status:", BACnetLogStatus);
7953 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
7956 offset = fRealTag (tvb, tree, offset, "real value: ");
7959 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
7962 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
7965 offset = fSignedTag (tvb, tree, offset, "signed value: ");
7968 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
7971 offset = fNullTag(tvb, tree, offset, "null value: ");
7974 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7975 offset = fError (tvb, pinfo, tree, offset);
7976 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7979 offset = fRealTag (tvb, tree, offset, "time change: ");
7981 case 10: /* any Value */
7982 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7983 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7984 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7989 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7992 /* Changed this to BitString per BACnet Spec. */
7993 offset = fBitStringTagVS(tvb, tree, offset, "Status Flags:", BACnetStatusFlags);
7998 if (offset == lastoffset) break; /* nothing happened, exit loop */
8004 fLogMultipleRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8006 guint lastoffset = 0;
8007 guint8 tag_no, tag_info;
8010 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8011 lastoffset = offset;
8012 switch (fTagNo(tvb, offset)) {
8013 case 0: /* timestamp */
8014 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8015 offset = fDate (tvb,tree,offset,"Date: ");
8016 offset = fTime (tvb,tree,offset,"Time: ");
8017 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8019 case 1: /* logData: don't loop, it's a CHOICE */
8020 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8021 switch (fTagNo(tvb, offset)) {
8022 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8023 offset = fBitStringTagVS(tvb, tree, offset, "log status:", BACnetLogStatus);
8025 case 1: /* log-data: SEQUENCE OF CHOICE */
8026 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8027 while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset != lastoffset)) { /* exit loop if nothing happens inside */
8028 lastoffset = offset;
8029 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8030 if (tag_is_closing(tag_info)) {
8031 lastoffset = offset;
8036 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
8039 offset = fRealTag (tvb, tree, offset, "real value: ");
8042 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
8045 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
8048 offset = fSignedTag (tvb, tree, offset, "signed value: ");
8051 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
8054 offset = fNullTag(tvb, tree, offset, "null value: ");
8057 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8058 offset = fError (tvb, pinfo, tree, offset);
8059 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8061 case 8: /* any Value */
8062 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8063 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
8064 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8070 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8073 offset = fRealTag (tvb, tree, offset, "time-change: ");
8078 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8083 if (offset == lastoffset) break; /* nothing happened, exit loop */
8090 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8092 guint lastoffset = 0;
8093 guint8 tag_no, tag_info;
8096 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8097 lastoffset = offset;
8098 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8099 if (tag_is_closing(tag_info)) {
8100 lastoffset = offset;
8105 case 0: /* ProcessId */
8106 offset = fProcessId (tvb,tree,offset);
8108 case 1: /* initiating ObjectId */
8109 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8111 case 2: /* event ObjectId */
8112 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8114 case 3: /* time stamp */
8115 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8116 offset = fTimeStamp (tvb, tree, offset, NULL);
8117 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8119 case 4: /* notificationClass */
8120 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
8122 case 5: /* Priority */
8123 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
8125 case 6: /* EventType */
8126 offset = fEnumeratedTagSplit (tvb, tree, offset,
8127 "Event Type: ", BACnetEventType, 64);
8129 case 7: /* messageText */
8130 offset = fCharacterString (tvb, tree, offset, "message Text: ");
8132 case 8: /* NotifyType */
8133 offset = fEnumeratedTag (tvb, tree, offset,
8134 "Notify Type: ", BACnetNotifyType);
8136 case 9: /* ackRequired */
8137 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
8139 case 10: /* fromState */
8140 offset = fEnumeratedTagSplit (tvb, tree, offset,
8141 "from State: ", BACnetEventState, 64);
8143 case 11: /* toState */
8144 offset = fEnumeratedTagSplit (tvb, tree, offset,
8145 "to State: ", BACnetEventState, 64);
8147 case 12: /* NotificationParameters */
8148 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8149 offset = fNotificationParameters (tvb, pinfo, tree, offset);
8150 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8155 if (offset == lastoffset) break; /* nothing happened, exit loop */
8161 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8163 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8167 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8169 guint lastoffset = 0, len;
8170 guint8 tag_no, tag_info;
8172 proto_tree *subtree = tree;
8175 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8176 lastoffset = offset;
8177 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8178 if (tag_is_closing(tag_info)) {
8185 case 0: /* ProcessId */
8186 offset = fProcessId (tvb,tree,offset);
8188 case 1: /* initiating DeviceId */
8189 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8191 case 2: /* monitored ObjectId */
8192 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8194 case 3: /* time remaining */
8195 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
8197 case 4: /* List of Values */
8198 if (tag_is_opening(tag_info)) {
8199 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
8200 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8201 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8202 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8210 if (offset == lastoffset) break; /* nothing happened, exit loop */
8216 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8218 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8222 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8224 guint lastoffset = 0;
8225 guint8 tag_no = 0, tag_info = 0;
8228 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8229 lastoffset = offset;
8230 switch (fTagNo(tvb, offset)) {
8231 case 0: /* acknowledgingProcessId */
8232 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
8234 case 1: /* eventObjectId */
8235 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8237 case 2: /* eventStateAcknowledged */
8238 offset = fEnumeratedTagSplit (tvb, tree, offset,
8239 "event State Acknowledged: ", BACnetEventState, 64);
8241 case 3: /* timeStamp */
8242 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8243 offset = fTimeStamp(tvb, tree, offset, NULL);
8244 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8246 case 4: /* acknowledgementSource */
8247 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
8249 case 5: /* timeOfAcknowledgement */
8250 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8251 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
8252 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8257 if (offset == lastoffset) break; /* nothing happened, exit loop */
8263 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8265 guint lastoffset = 0;
8267 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8268 lastoffset = offset;
8269 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8270 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8271 "alarm State: ", BACnetEventState, 64);
8272 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8273 "acknowledged Transitions: ", BACnetEventTransitionBits);
8274 if (offset == lastoffset) break; /* nothing happened, exit loop */
8280 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8282 guint lastoffset = 0;
8283 guint8 tag_no, tag_info;
8286 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8287 lastoffset = offset;
8288 switch (fTagNo(tvb, offset)) {
8289 case 0: /* acknowledgmentFilter */
8290 offset = fEnumeratedTag (tvb, tree, offset,
8291 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
8293 case 1: /* eventObjectId - OPTIONAL */
8294 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8295 offset = fRecipientProcess (tvb, pinfo, tree, offset);
8296 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8298 case 2: /* eventStateFilter */
8299 offset = fEnumeratedTag (tvb, tree, offset,
8300 "event State Filter: ", BACnetEventStateFilter);
8302 case 3: /* eventTypeFilter - OPTIONAL */
8303 offset = fEnumeratedTag (tvb, tree, offset,
8304 "event Type Filter: ", BACnetEventType);
8306 case 4: /* priorityFilter */
8307 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8308 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
8309 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
8310 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8312 case 5: /* notificationClassFilter - OPTIONAL */
8313 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
8318 if (offset == lastoffset) break; /* nothing happened, exit loop */
8324 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8326 guint lastoffset = 0;
8328 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8329 lastoffset = offset;
8330 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8331 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8332 "event Type: ", BACnetEventType, 64);
8333 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8334 "event State: ", BACnetEventState);
8335 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
8336 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
8337 if (offset == lastoffset) break; /* nothing happened, exit loop */
8344 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8346 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8347 if (fTagNo(tvb, offset) == 0) {
8348 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8355 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8357 guint lastoffset = 0;
8358 guint8 tag_no, tag_info;
8360 proto_tree* subtree = tree;
8363 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8364 lastoffset = offset;
8365 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8366 /* we are finished here if we spot a closing tag */
8367 if (tag_is_closing(tag_info)) {
8371 case 0: /* ObjectId */
8372 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8374 case 1: /* eventState */
8375 offset = fEnumeratedTag (tvb, tree, offset,
8376 "event State: ", BACnetEventState);
8378 case 2: /* acknowledgedTransitions */
8379 offset = fBitStringTagVS (tvb, tree, offset,
8380 "acknowledged Transitions: ", BACnetEventTransitionBits);
8382 case 3: /* eventTimeStamps */
8383 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
8385 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8387 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8388 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
8389 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
8390 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
8391 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8393 case 4: /* notifyType */
8394 offset = fEnumeratedTag (tvb, tree, offset,
8395 "Notify Type: ", BACnetNotifyType);
8397 case 5: /* eventEnable */
8398 offset = fBitStringTagVS (tvb, tree, offset,
8399 "event Enable: ", BACnetEventTransitionBits);
8401 case 6: /* eventPriorities */
8402 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
8404 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8406 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8407 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
8408 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
8409 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
8410 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8415 if (offset == lastoffset) break; /* nothing happened, exit loop */
8421 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8423 guint lastoffset = 0;
8424 guint8 tag_no, tag_info;
8427 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8428 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8429 lastoffset = offset;
8430 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8431 /* we are finished here if we spot a closing tag */
8432 if (tag_is_closing(tag_info)) {
8435 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
8436 if (offset == lastoffset) break; /* nothing happened, exit loop */
8442 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8444 guint lastoffset = 0;
8445 guint8 tag_no, tag_info;
8448 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8449 lastoffset = offset;
8450 switch (fTagNo(tvb, offset)) {
8451 case 0: /* listOfEventSummaries */
8452 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8453 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
8454 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
8456 case 1: /* moreEvents */
8457 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
8462 if (offset == lastoffset) break; /* nothing happened, exit loop */
8468 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8470 guint lastoffset = 0, len;
8471 guint8 tag_no, tag_info;
8473 proto_tree *subtree = tree;
8476 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8478 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8479 lastoffset = offset;
8480 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8481 if (tag_is_closing(tag_info)) {
8488 case 0: /* ObjectId */
8489 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
8491 case 3: /* listOfElements */
8492 if (tag_is_opening(tag_info)) {
8493 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
8494 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8495 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8496 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8504 if (offset == lastoffset) break; /* nothing happened, exit loop */
8510 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8512 return fObjectIdentifier (tvb, pinfo, tree, offset);
8516 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
8518 guint lastoffset = 0;
8520 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8521 lastoffset = offset;
8523 switch (fTagNo(tvb, offset)) {
8524 case 0: /* timeDuration */
8525 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
8527 case 1: /* enable-disable */
8528 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
8529 BACnetEnableDisable);
8531 case 2: /* password - OPTIONAL */
8532 offset = fCharacterString (tvb, tree, offset, "Password: ");
8537 if (offset == lastoffset) break; /* nothing happened, exit loop */
8543 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
8545 guint lastoffset = 0;
8547 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8548 lastoffset = offset;
8550 switch (fTagNo(tvb, offset)) {
8551 case 0: /* reinitializedStateOfDevice */
8552 offset = fEnumeratedTag (tvb, tree, offset,
8553 "reinitialized State Of Device: ",
8554 BACnetReinitializedStateOfDevice);
8556 case 1: /* password - OPTIONAL */
8557 offset = fCharacterString (tvb, tree, offset, "Password: ");
8562 if (offset == lastoffset) break; /* nothing happened, exit loop */
8568 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8570 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8571 "vtClass: ", BACnetVTClass);
8572 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
8576 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8578 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
8582 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8584 guint lastoffset = 0;
8586 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8587 lastoffset = offset;
8588 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
8589 if (offset == lastoffset) break; /* nothing happened, exit loop */
8595 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8597 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
8598 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
8599 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
8603 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
8605 guint lastoffset = 0;
8607 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8608 lastoffset = offset;
8610 switch (fTagNo(tvb,offset)) {
8611 case 0: /* BOOLEAN */
8612 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
8614 case 1: /* Unsigned OPTIONAL */
8615 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
8620 if (offset == lastoffset) break; /* nothing happened, exit loop */
8626 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
8628 guint lastoffset = 0;
8630 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8631 lastoffset = offset;
8633 switch (fTagNo(tvb,offset)) {
8634 case 0: /* Unsigned32 */
8635 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
8637 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
8638 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
8640 case 2: /* Chararacter String OPTIONAL */
8641 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
8643 case 3: /* Chararacter String OPTIONAL */
8644 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
8646 case 4: /* Boolean OPTIONAL */
8647 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
8652 if (offset == lastoffset) break; /* nothing happened, exit loop */
8658 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8660 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
8664 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8666 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
8667 offset = fAddress (tvb, tree, offset);
8668 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
8669 return fAddress (tvb, tree, offset);
8673 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8675 /* Same as AddListElement request after service choice */
8676 return fAddListElementRequest(tvb, pinfo, tree, offset);
8680 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8682 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8686 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8688 guint lastoffset = 0, len;
8689 guint8 tag_no, tag_info;
8691 proto_tree *subtree = tree;
8693 /* set the optional global properties to indicate not-used */
8694 propertyArrayIndex = -1;
8695 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8696 lastoffset = offset;
8697 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8698 if (tag_is_closing(tag_info)) {
8704 case 0: /* objectIdentifier */
8705 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8707 case 1: /* propertyIdentifier */
8708 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8710 case 2: /* propertyArrayIndex */
8711 offset = fPropertyArrayIndex (tvb, subtree, offset);
8713 case 3: /* propertyValue */
8714 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8719 if (offset == lastoffset) break; /* nothing happened, exit loop */
8725 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8727 guint lastoffset = 0;
8728 guint8 tag_no, tag_info;
8730 proto_tree *subtree = tree;
8732 /* set the optional global properties to indicate not-used */
8733 propertyArrayIndex = -1;
8734 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8735 lastoffset = offset;
8736 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8737 /* quit loop if we spot a closing tag */
8738 if (tag_is_closing(tag_info)) {
8744 case 0: /* objectIdentifier */
8745 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8747 case 1: /* propertyIdentifier */
8748 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8750 case 2: /* propertyArrayIndex */
8751 offset = fPropertyArrayIndex (tvb, subtree, offset);
8753 case 3: /* propertyValue */
8754 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8756 case 4: /* Priority (only used for write) */
8757 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
8762 if (offset == lastoffset) break; /* nothing happened, exit loop */
8768 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8770 guint lastoffset = 0, len;
8771 guint8 tag_no, tag_info;
8774 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8775 lastoffset = offset;
8776 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8777 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
8778 if (tag_is_closing(tag_info)) {
8784 case 0: /* objectIdentifier */
8785 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8787 case 1: /* listOfPropertyValues */
8788 if (tag_is_opening(tag_info)) {
8789 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8790 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8798 if (offset == lastoffset) break; /* nothing happened, exit loop */
8804 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8806 if (offset >= tvb_reported_length(tvb))
8809 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8810 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
8814 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
8816 guint lastoffset = 0;
8817 guint8 tag_no, tag_info;
8820 /* set the optional global properties to indicate not-used */
8821 propertyArrayIndex = -1;
8822 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8823 lastoffset = offset;
8824 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8825 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
8827 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
8830 switch (tag_no-tagoffset) {
8831 case 0: /* PropertyIdentifier */
8832 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
8834 case 1: /* propertyArrayIndex */
8835 offset = fPropertyArrayIndex (tvb, tree, offset);
8836 if (list != 0) break; /* Continue decoding if this may be a list */
8838 lastoffset = offset; /* Set loop end condition */
8841 if (offset == lastoffset) break; /* nothing happened, exit loop */
8847 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
8849 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8850 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
8854 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8856 guint lastoffset = 0;
8858 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8859 lastoffset = offset;
8861 switch (fTagNo(tvb,offset)) {
8862 case 0: /* ObjectIdentifier */
8863 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8865 case 1: /* PropertyIdentifier and propertyArrayIndex */
8866 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
8867 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8869 lastoffset = offset; /* Set loop end condition */
8872 if (offset == lastoffset) break; /* nothing happened, exit loop */
8879 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
8881 guint lastoffset = 0;
8882 guint8 tag_no, tag_info;
8884 proto_tree* subtree = tree;
8887 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8888 lastoffset = offset;
8889 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8890 if (tag_is_closing(tag_info)) {
8891 offset += fTagHeaderTree (tvb, subtree, offset,
8892 &tag_no, &tag_info, &lvt);
8896 case 0: /* ObjectIdentifier */
8897 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8899 case 1: /* PropertyIdentifier */
8900 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8902 case 2: /* propertyArrayIndex */
8903 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
8906 offset = fPropertyValue (tvb, subtree, offset, tag_info);
8908 case 4: /* Priority */
8909 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
8920 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8922 char i = 1, ar[256];
8923 guint lastoffset = 0;
8925 if (propertyArrayIndex > 0) {
8926 /* BACnetARRAY index 0 refers to the length
8927 of the array, not the elements of the array.
8928 BACnetARRAY index -1 is our internal flag that
8929 the optional index was not used.
8930 BACnetARRAY refers to this as all elements of the array.
8931 If the optional index is specified for a BACnetARRAY,
8932 then that specific array element is referenced. */
8933 i = propertyArrayIndex;
8935 while (tvb_reported_length_remaining(tvb, offset) > 0) {
8936 /* exit loop if nothing happens inside */
8937 lastoffset = offset;
8938 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
8939 val_to_split_str(87 , 512,
8940 BACnetPropertyIdentifier,
8941 ASHRAE_Reserved_Fmt,
8942 Vendor_Proprietary_Fmt),
8944 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
8945 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
8946 /* there are only 16 priority array elements */
8950 if (offset == lastoffset) break; /* nothing happened, exit loop */
8957 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8959 guint lastoffset = 0;
8961 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8962 lastoffset = offset;
8964 switch (fTagNo(tvb,offset)) {
8965 case 0: /* deviceIdentifier - OPTIONAL */
8966 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8968 case 1: /* ObjectIdentifier */
8969 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8974 if (offset == lastoffset) break; /* nothing happened, exit loop */
8980 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8982 guint8 tag_no, tag_info;
8984 guint lastoffset = 0, len;
8985 gboolean closing_found = FALSE; /* tracks when we are done decoding the fSpecialEvent entries */
8987 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8988 lastoffset = offset;
8989 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8990 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
8991 if (tag_is_closing(tag_info)) {
8992 /* if we find 2 closing tags in succession we need to exit without incrementing the offset again */
8993 /* This handles the special case where we have a special event entry in an RPM-ACK msg */
8994 if ( closing_found == TRUE )
8997 closing_found = TRUE;
9002 case 0: /* calendarEntry */
9003 if (tag_is_opening(tag_info)) {
9004 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9005 offset = fCalendarEntry (tvb, subtree, offset);
9006 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9009 case 1: /* calendarReference */
9010 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9012 case 2: /* list of BACnetTimeValue */
9013 if (tag_is_opening(tag_info)) {
9014 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9015 offset = fTimeValue (tvb, pinfo, subtree, offset);
9016 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9021 case 3: /* eventPriority */
9022 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
9027 closing_found = FALSE; /* reset our closing tag status, we processed another open tag */
9028 if (offset == lastoffset) break; /* nothing happened, exit loop */
9034 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9036 guint lastoffset = 0, len;
9037 guint8 tag_no, tag_info;
9040 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9041 lastoffset = offset;
9042 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9043 /* maybe a listOfSelectionCriteria if we spot a closing tag */
9044 if (tag_is_closing(tag_info)) {
9049 switch (fTagNo(tvb,offset)) {
9050 case 0: /* propertyIdentifier */
9051 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
9053 case 1: /* propertyArrayIndex */
9054 offset = fPropertyArrayIndex (tvb, tree, offset);
9056 case 2: /* relationSpecifier */
9057 offset = fEnumeratedTag (tvb, tree, offset,
9058 "relation Specifier: ", BACnetRelationSpecifier);
9060 case 3: /* comparisonValue */
9061 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
9062 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
9063 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
9068 if (offset == lastoffset) break; /* nothing happened, exit loop */
9074 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9076 guint lastoffset = 0;
9077 guint8 tag_no, tag_info;
9080 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9081 lastoffset = offset;
9082 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9083 /* quit loop if we spot a closing tag */
9084 if (tag_is_closing(tag_info)) {
9089 case 0: /* selectionLogic */
9090 offset = fEnumeratedTag (tvb, subtree, offset,
9091 "selection Logic: ", BACnetSelectionLogic);
9093 case 1: /* listOfSelectionCriteria */
9094 if (tag_is_opening(tag_info)) {
9095 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9096 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
9097 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9105 if (offset == lastoffset) break; /* nothing happened, exit loop */
9112 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
9114 guint lastoffset = 0;
9115 guint8 tag_no, tag_info;
9118 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9119 lastoffset = offset;
9120 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9122 if (tag_is_opening(tag_info) && tag_no < 2) {
9123 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9125 case 0: /* objectSelectionCriteria */
9126 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
9128 case 1: /* listOfPropertyReferences */
9129 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
9134 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9136 if (offset == lastoffset) break; /* nothing happened, exit loop */
9142 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9144 guint lastoffset = 0;
9145 guint8 tag_no, tag_info;
9148 proto_tree *subtree = tree;
9150 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9151 lastoffset = offset;
9152 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9154 case 0: /* objectIdentifier */
9155 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9157 case 1: /* listOfPropertyReferences */
9158 if (tag_is_opening(tag_info)) {
9159 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
9160 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9161 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9162 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
9163 } else if (tag_is_closing(tag_info)) {
9164 offset += fTagHeaderTree (tvb, subtree, offset,
9165 &tag_no, &tag_info, &lvt);
9168 /* error condition: let caller handle */
9175 if (offset == lastoffset) break; /* nothing happened, exit loop */
9181 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9183 guint lastoffset = 0, len;
9187 proto_tree *subtree = tree;
9190 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9191 lastoffset = offset;
9192 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9193 /* maybe a listOfReadAccessResults if we spot a closing tag here */
9194 if (tag_is_closing(tag_info)) {
9196 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
9201 case 0: /* objectSpecifier */
9202 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9204 case 1: /* list of Results */
9205 if (tag_is_opening(tag_info)) {
9206 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
9207 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9208 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9213 case 2: /* propertyIdentifier */
9214 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
9216 case 5: /* propertyAccessError */
9217 if (tag_is_opening(tag_info)) {
9218 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
9219 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9220 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9221 /* Error Code follows */
9222 offset = fError(tvb, pinfo, subtree, offset);
9230 if (offset == lastoffset) break; /* nothing happened, exit loop */
9237 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9239 /* listOfReadAccessResults */
9240 return fReadAccessResult (tvb, pinfo, tree, offset);
9245 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9247 guint lastoffset = 0;
9248 guint8 tag_no, tag_info;
9251 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9252 lastoffset = offset;
9253 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9256 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9258 case 0: /* objectSpecifier */
9259 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
9260 case 0: /* objectType */
9261 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
9263 case 1: /* objectIdentifier */
9264 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9270 case 1: /* propertyValue */
9271 if (tag_is_opening(tag_info)) {
9272 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
9280 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9282 if (offset == lastoffset) break; /* nothing happened, exit loop */
9288 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9290 return fObjectIdentifier (tvb, pinfo, tree, offset);
9294 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9296 guint8 tag_no, tag_info;
9298 proto_tree *subtree = tree;
9301 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9303 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9304 /* optional range choice */
9305 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9306 if (tag_is_opening(tag_info)) {
9307 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
9308 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9309 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9311 case 3: /* range byPosition */
9312 case 6: /* range bySequenceNumber, 2004 spec */
9313 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
9314 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
9316 case 4: /* range byTime - deprecated in 2004 */
9317 case 7: /* 2004 spec */
9318 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
9319 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
9321 case 5: /* range timeRange - deprecated in 2004 */
9322 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
9323 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
9328 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9335 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9337 guint8 tag_no, tag_info;
9339 proto_tree *subtree = tree;
9342 /* set the optional global properties to indicate not-used */
9343 propertyArrayIndex = -1;
9344 /* objectIdentifier, propertyIdentifier, and
9345 OPTIONAL propertyArrayIndex */
9346 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9347 /* resultFlags => BACnetResultFlags ::= BIT STRING */
9348 offset = fBitStringTagVS (tvb, tree, offset,
9352 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
9354 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9355 if (tag_is_opening(tag_info)) {
9356 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9357 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
9358 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9359 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9360 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
9361 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9363 /* firstSequenceNumber - OPTIONAL */
9364 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9365 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
9372 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9374 guint lastoffset = 0;
9376 guint8 tag_no, tag_info;
9378 proto_tree* subtree = NULL;
9380 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9382 if (tag_is_opening(tag_info)) {
9383 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
9384 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9385 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9386 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
9387 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
9390 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
9391 /* exit loop if nothing happens inside */
9392 lastoffset = offset;
9393 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
9397 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
9398 /* More Flag is not set, so we can look for closing tag in this segment */
9399 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9400 if (tag_is_closing(tag_info)) {
9401 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9409 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9411 guint8 tag_no, tag_info;
9413 proto_tree *subtree = tree;
9416 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9418 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9420 if (tag_is_opening(tag_info)) {
9421 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
9422 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9423 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9424 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
9425 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
9426 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9432 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9435 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
9436 offset = fAccessMethod(tvb, pinfo, tree, offset);
9442 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
9444 guint tag_no = fTagNo(tvb, offset);
9445 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
9449 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9451 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
9452 offset = fAccessMethod(tvb,pinfo, tree, offset);
9458 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9460 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9461 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
9465 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9467 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9468 return fReadAccessResult (tvb,pinfo,tree,offset);
9472 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9474 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9477 switch (service_choice) {
9478 case 0: /* acknowledgeAlarm */
9479 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
9481 case 1: /* confirmedCOVNotification */
9482 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
9484 case 2: /* confirmedEventNotification */
9485 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
9487 case 3: /* confirmedGetAlarmSummary conveys no parameters */
9489 case 4: /* getEnrollmentSummaryRequest */
9490 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
9492 case 5: /* subscribeCOVRequest */
9493 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
9495 case 6: /* atomicReadFile-Request */
9496 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
9498 case 7: /* atomicWriteFile-Request */
9499 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
9501 case 8: /* AddListElement-Request */
9502 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
9504 case 9: /* removeListElement-Request */
9505 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
9507 case 10: /* createObjectRequest */
9508 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
9510 case 11: /* deleteObject */
9511 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
9514 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
9517 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
9520 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
9523 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
9526 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
9529 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
9532 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
9535 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
9538 offset = fReinitializeDeviceRequest(tvb, tree, offset);
9541 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
9544 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
9547 offset = fVtDataRequest (tvb, pinfo, tree, offset);
9550 offset = fAuthenticateRequest (tvb, tree, offset);
9553 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
9556 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
9559 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
9562 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
9565 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
9574 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9576 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9579 switch (service_choice) {
9580 case 3: /* confirmedEventNotificationAck */
9581 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
9583 case 4: /* getEnrollmentSummaryAck */
9584 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
9586 case 6: /* atomicReadFile */
9587 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
9589 case 7: /* atomicReadFileAck */
9590 offset = fAtomicWriteFileAck (tvb, tree, offset);
9592 case 10: /* createObject */
9593 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
9596 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
9599 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
9602 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
9605 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
9608 offset = fVtOpenAck (tvb, pinfo, tree, offset);
9611 offset = fVtDataAck (tvb, tree, offset);
9614 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
9617 offset = fReadRangeAck (tvb, pinfo, tree, offset);
9620 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
9629 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9631 /* BACnetObjectIdentifier */
9632 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
9634 /* MaxAPDULengthAccepted */
9635 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
9637 /* segmentationSupported */
9638 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
9639 "Segmentation Supported: ", BACnetSegmentation);
9642 return fVendorIdentifier (tvb, pinfo, tree, offset);
9646 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9648 /* BACnetDeviceIdentifier */
9649 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
9651 /* BACnetObjectIdentifier */
9652 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
9655 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
9660 fWhoIsRequest (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
9662 guint lastoffset = 0;
9666 guint8 tag_no, tag_info;
9669 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9670 lastoffset = offset;
9672 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9676 /* DeviceInstanceRangeLowLimit Optional */
9677 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
9678 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
9679 offset = fDevice_Instance (tvb, tree, offset,
9680 hf_Device_Instance_Range_Low_Limit);
9683 /* DeviceInstanceRangeHighLimit Optional but
9684 required if DeviceInstanceRangeLowLimit is there */
9685 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
9686 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
9687 offset = fDevice_Instance (tvb, tree, offset,
9688 hf_Device_Instance_Range_High_Limit);
9693 if (offset == lastoffset) break; /* nothing happened, exit loop */
9699 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9701 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9704 switch (service_choice) {
9705 case 0: /* I-Am-Request */
9706 offset = fIAmRequest (tvb, pinfo, tree, offset);
9708 case 1: /* i-Have Request */
9709 offset = fIHaveRequest (tvb, pinfo, tree, offset);
9711 case 2: /* unconfirmedCOVNotification */
9712 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
9714 case 3: /* unconfirmedEventNotification */
9715 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
9717 case 4: /* unconfirmedPrivateTransfer */
9718 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
9720 case 5: /* unconfirmedTextMessage */
9721 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
9723 case 6: /* timeSynchronization */
9724 offset = fTimeSynchronizationRequest (tvb, tree, offset);
9726 case 7: /* who-Has */
9727 offset = fWhoHas (tvb, pinfo, tree, offset);
9729 case 8: /* who-Is */
9730 offset = fWhoIsRequest (tvb, pinfo, tree, offset);
9732 case 9: /* utcTimeSynchronization */
9733 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
9742 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
9743 gint *svc, proto_item **tt)
9746 proto_tree *bacapp_tree_control;
9751 tmp = (gint) tvb_get_guint8(tvb, offset);
9752 bacapp_flags = tmp & 0x0f;
9757 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
9758 if (bacapp_flags & 0x08)
9759 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
9761 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9762 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
9763 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
9765 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
9766 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
9767 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
9768 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
9769 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
9770 offset, 1, ENC_BIG_ENDIAN);
9771 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
9772 offset, 1, ENC_BIG_ENDIAN);
9775 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
9776 if (bacapp_flags & 0x08) {
9777 bacapp_seq = tvb_get_guint8(tvb, offset);
9778 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
9779 offset++, 1, ENC_BIG_ENDIAN);
9780 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
9781 offset++, 1, ENC_BIG_ENDIAN);
9783 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
9784 offset++, 1, ENC_BIG_ENDIAN);
9789 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
9790 { /* BACnet-Confirmed-Request */
9791 /* ASHRAE 135-2001 20.1.2 */
9793 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
9797 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9798 { /* BACnet-Confirmed-Request */
9799 /* ASHRAE 135-2001 20.1.2 */
9803 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
9804 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
9808 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9809 { /* BACnet-Unconfirmed-Request-PDU */
9810 /* ASHRAE 135-2001 20.1.3 */
9814 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9816 tmp = tvb_get_guint8(tvb, offset);
9817 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
9818 offset++, 1, ENC_BIG_ENDIAN);
9819 /* Service Request follows... Variable Encoding 20.2ff */
9820 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
9824 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9825 { /* BACnet-Simple-Ack-PDU */
9826 /* ASHRAE 135-2001 20.1.4 */
9828 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9830 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
9831 offset++, 1, ENC_BIG_ENDIAN);
9832 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
9833 offset++, 1, ENC_BIG_ENDIAN);
9839 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
9840 { /* BACnet-Complex-Ack-PDU */
9841 /* ASHRAE 135-2001 20.1.5 */
9843 /* Service ACK follows... */
9844 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
9848 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9849 { /* BACnet-Complex-Ack-PDU */
9850 /* ASHRAE 135-2001 20.1.5 */
9854 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
9855 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
9859 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9860 { /* BACnet-SegmentAck-PDU */
9861 /* ASHRAE 135-2001 20.1.6 */
9864 proto_tree *bacapp_tree_control;
9866 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9867 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9869 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
9870 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
9871 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9872 offset++, 1, ENC_BIG_ENDIAN);
9873 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
9874 offset++, 1, ENC_BIG_ENDIAN);
9875 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
9876 offset++, 1, ENC_BIG_ENDIAN);
9881 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9883 guint8 tag_info = 0;
9884 guint8 parsed_tag = 0;
9887 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
9888 offset = fError(tvb, pinfo, tree, offset);
9889 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
9893 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9895 guint lastoffset = 0;
9896 guint8 tag_no = 0, tag_info = 0;
9898 proto_tree *subtree = tree;
9901 guint vendor_identifier = 0;
9902 guint service_number = 0;
9905 while (tvb_reported_length_remaining(tvb, offset) > 0) {
9906 /* exit loop if nothing happens inside */
9907 lastoffset = offset;
9908 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
9910 case 0: /* errorType */
9911 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
9913 case 1: /* vendorID */
9914 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
9915 if (col_get_writable(pinfo->cinfo))
9916 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
9917 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
9919 case 2: /* serviceNumber */
9920 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
9921 if (col_get_writable(pinfo->cinfo))
9922 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
9923 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
9925 case 3: /* errorParameters */
9926 if (tag_is_opening(tag_info)) {
9927 tt = proto_tree_add_text(subtree, tvb, offset, 1,
9928 "error Parameters");
9929 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9930 propertyIdentifier = -1;
9931 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
9932 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
9933 } else if (tag_is_closing(tag_info)) {
9934 offset += fTagHeaderTree (tvb, subtree, offset,
9935 &tag_no, &tag_info, &lvt);
9938 /* error condition: let caller handle */
9945 if (offset == lastoffset) break; /* nothing happened, exit loop */
9951 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9953 guint lastoffset = 0;
9955 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9956 lastoffset = offset;
9957 switch (fTagNo(tvb, offset)) {
9958 case 0: /* errorType */
9959 offset = fContextTaggedError(tvb, pinfo, tree, offset);
9961 case 1: /* firstFailedElementNumber */
9962 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
9967 if (offset == lastoffset) break; /* nothing happened, exit loop */
9973 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9975 /* Identical to CreateObjectError */
9976 return fCreateObjectError(tvb, pinfo, tree, offset);
9980 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9982 guint8 tag_no = 0, tag_info = 0;
9985 if (fTagNo(tvb, offset) == 0) {
9987 offset = fContextTaggedError(tvb, pinfo, tree,offset);
9988 if (fTagNo(tvb, offset) == 1) {
9989 /* listOfVTSessionIdentifiers [OPTIONAL] */
9990 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
9991 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
9992 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
9995 /* should report bad packet if initial tag wasn't 0 */
10000 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10002 guint lastoffset = 0;
10003 guint8 tag_no = 0, tag_info = 0;
10006 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10007 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10008 lastoffset = offset;
10009 switch (fTagNo(tvb, offset)) {
10010 case 0: /* errorType */
10011 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10013 case 1: /* firstFailedWriteAttempt */
10014 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
10015 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
10016 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
10021 if (offset == lastoffset) break; /* nothing happened, exit loop */
10027 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10029 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
10030 "error Class: ", BACnetErrorClass, 64);
10031 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
10032 "error Code: ", BACnetErrorCode, 256);
10036 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
10039 case 8: /* no break here !!!! */
10041 offset = fChangeListError (tvb, pinfo, tree, offset);
10044 offset = fCreateObjectError (tvb, pinfo, tree, offset);
10047 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
10050 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
10053 offset = fVTCloseError (tvb, pinfo, tree, offset);
10056 return fError (tvb, pinfo, tree, offset);
10062 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10063 { /* BACnet-Error-PDU */
10064 /* ASHRAE 135-2001 20.1.7 */
10067 proto_tree *bacapp_tree_control;
10070 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10071 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10073 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10074 offset++, 1, ENC_BIG_ENDIAN);
10075 tmp = tvb_get_guint8(tvb, offset);
10076 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
10077 offset++, 1, ENC_BIG_ENDIAN);
10078 /* Error Handling follows... */
10079 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
10083 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10084 { /* BACnet-Reject-PDU */
10085 /* ASHRAE 135-2001 20.1.8 */
10088 proto_tree *bacapp_tree_control;
10090 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10091 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10093 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10094 offset++, 1, ENC_BIG_ENDIAN);
10095 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
10096 offset++, 1, ENC_BIG_ENDIAN);
10101 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10102 { /* BACnet-Abort-PDU */
10103 /* ASHRAE 135-2001 20.1.9 */
10106 proto_tree *bacapp_tree_control;
10108 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10109 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10111 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10112 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10113 offset++, 1, ENC_BIG_ENDIAN);
10114 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
10115 offset++, 1, ENC_BIG_ENDIAN);
10120 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10122 guint8 flag, bacapp_type;
10125 flag = (gint) tvb_get_guint8(tvb, 0);
10126 bacapp_type = (flag >> 4) & 0x0f;
10132 /* ASHRAE 135-2001 20.1.1 */
10133 switch (bacapp_type) {
10134 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
10135 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
10137 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
10138 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
10140 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
10141 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
10143 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
10144 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
10146 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
10147 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
10149 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
10150 offset = fErrorPDU(tvb, pinfo, tree, offset);
10152 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
10153 offset = fRejectPDU(tvb, pinfo, tree, offset);
10155 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
10156 offset = fAbortPDU(tvb, pinfo, tree, offset);
10163 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10165 guint8 flag, bacapp_type;
10166 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
10167 tvbuff_t* new_tvb = NULL;
10169 guint8 bacapp_seqno = 0;
10170 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
10171 guint8 bacapp_invoke_id = 0;
10173 proto_tree *bacapp_tree = NULL;
10176 proto_item *tt = 0;
10179 /* Strings for BACnet Statistics */
10180 const gchar errstr[] = "ERROR: ";
10181 const gchar rejstr[] = "REJECTED: ";
10182 const gchar abortstr[] = "ABORTED: ";
10183 const gchar sackstr[] = " (SimpleAck)";
10184 const gchar cackstr[] = " (ComplexAck)";
10185 const gchar uconfsreqstr[] = " (Unconfirmed Service Request)";
10186 const gchar confsreqstr[] = " (Confirmed Service Request)";
10188 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
10189 col_clear (pinfo->cinfo, COL_INFO);
10191 flag = tvb_get_guint8(tvb, 0);
10192 bacapp_type = (flag >> 4) & 0x0f;
10194 /* show some descriptive text in the INFO column */
10195 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
10196 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
10198 bacinfo.service_type = NULL;
10199 bacinfo.invoke_id = NULL;
10200 bacinfo.instance_ident = NULL;
10201 bacinfo.object_ident = NULL;
10203 switch (bacapp_type) {
10204 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10205 /* segmented messages have 2 additional bytes */
10206 if (flag & BACAPP_SEGMENTED_REQUEST) {
10209 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
10210 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10211 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
10212 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
10213 bacapp_service = tvb_get_guint8(tvb, offset + 5);
10216 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10217 bacapp_service = tvb_get_guint8(tvb, offset + 3);
10219 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
10220 val_to_str(bacapp_service,
10221 BACnetConfirmedServiceChoice,
10222 bacapp_unknown_service_str),bacapp_invoke_id);
10224 updateBacnetInfoValue(BACINFO_INVOKEID,
10225 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10227 updateBacnetInfoValue(BACINFO_SERVICE,
10228 ep_strconcat(val_to_str(bacapp_service,
10229 BACnetConfirmedServiceChoice,
10230 bacapp_unknown_service_str),
10231 confsreqstr, NULL));
10233 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
10234 bacapp_service = tvb_get_guint8(tvb, offset + 1);
10235 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
10236 val_to_str(bacapp_service,
10237 BACnetUnconfirmedServiceChoice,
10238 bacapp_unknown_service_str));
10240 updateBacnetInfoValue(BACINFO_SERVICE,
10241 ep_strconcat(val_to_str(bacapp_service,
10242 BACnetUnconfirmedServiceChoice,
10243 bacapp_unknown_service_str),
10244 uconfsreqstr, NULL));
10246 case BACAPP_TYPE_SIMPLE_ACK:
10247 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10248 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10249 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10250 val_to_str(bacapp_service,
10251 BACnetConfirmedServiceChoice,
10252 bacapp_unknown_service_str), bacapp_invoke_id);
10254 updateBacnetInfoValue(BACINFO_INVOKEID,
10255 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10257 updateBacnetInfoValue(BACINFO_SERVICE,
10258 ep_strconcat(val_to_str(bacapp_service,
10259 BACnetConfirmedServiceChoice,
10260 bacapp_unknown_service_str),
10263 case BACAPP_TYPE_COMPLEX_ACK:
10264 /* segmented messages have 2 additional bytes */
10265 if (flag & BACAPP_SEGMENTED_REQUEST) {
10268 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
10269 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10270 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
10271 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
10272 bacapp_service = tvb_get_guint8(tvb, offset + 4);
10275 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10276 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10278 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10279 val_to_str(bacapp_service,
10280 BACnetConfirmedServiceChoice,
10281 bacapp_unknown_service_str), bacapp_invoke_id);
10283 updateBacnetInfoValue(BACINFO_INVOKEID,
10284 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10286 updateBacnetInfoValue(BACINFO_SERVICE,
10287 ep_strconcat(val_to_str(bacapp_service,
10288 BACnetConfirmedServiceChoice,
10289 bacapp_unknown_service_str),
10292 case BACAPP_TYPE_SEGMENT_ACK:
10293 /* nothing more to add */
10295 case BACAPP_TYPE_ERROR:
10296 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10297 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10298 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10299 val_to_str(bacapp_service,
10300 BACnetConfirmedServiceChoice,
10301 bacapp_unknown_service_str), bacapp_invoke_id);
10303 updateBacnetInfoValue(BACINFO_INVOKEID,
10304 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10306 updateBacnetInfoValue(BACINFO_SERVICE,
10307 ep_strconcat(errstr,
10308 val_to_str(bacapp_service,
10309 BACnetConfirmedServiceChoice,
10310 bacapp_unknown_service_str),
10313 case BACAPP_TYPE_REJECT:
10314 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10315 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10316 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10317 val_to_split_str(bacapp_reason,
10319 BACnetRejectReason,
10320 ASHRAE_Reserved_Fmt,
10321 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10323 updateBacnetInfoValue(BACINFO_INVOKEID,
10324 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10326 updateBacnetInfoValue(BACINFO_SERVICE,
10327 ep_strconcat(rejstr,
10328 val_to_split_str(bacapp_reason, 64,
10329 BACnetRejectReason,
10330 ASHRAE_Reserved_Fmt,
10331 Vendor_Proprietary_Fmt),
10334 case BACAPP_TYPE_ABORT:
10335 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10336 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10337 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10338 val_to_split_str(bacapp_reason,
10341 ASHRAE_Reserved_Fmt,
10342 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10344 updateBacnetInfoValue(BACINFO_INVOKEID,
10345 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10347 updateBacnetInfoValue(BACINFO_SERVICE,
10348 ep_strconcat(abortstr,
10349 val_to_split_str(bacapp_reason,
10352 ASHRAE_Reserved_Fmt,
10353 Vendor_Proprietary_Fmt),
10358 /* nothing more to add */
10362 save_fragmented = pinfo->fragmented;
10364 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA);
10365 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
10368 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
10370 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
10371 /* not resetting the offset so the remaining can be done */
10373 if (fragment) { /* fragmented */
10374 fragment_data *frag_msg = NULL;
10377 pinfo->fragmented = TRUE;
10379 frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
10380 bacapp_invoke_id, /* ID for fragments belonging together */
10381 msg_fragment_table, /* list of message fragments */
10382 msg_reassembled_table, /* list of reassembled messages */
10383 bacapp_seqno, /* fragment sequence number */
10384 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
10385 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
10386 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
10387 "Reassembled BACapp", frag_msg, &msg_frag_items,
10390 if (new_tvb) { /* Reassembled */
10391 col_append_str(pinfo->cinfo, COL_INFO,
10392 " (Message Reassembled)");
10393 } else { /* Not last packet of reassembled Short Message */
10394 col_append_fstr(pinfo->cinfo, COL_INFO,
10395 " (Message fragment %u)", bacapp_seqno);
10397 if (new_tvb) { /* take it all */
10398 switch (bacapp_type) {
10399 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10400 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10402 case BACAPP_TYPE_COMPLEX_ACK:
10403 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10412 pinfo->fragmented = save_fragmented;
10415 tap_queue_packet(bacapp_tap,pinfo,&bacinfo);
10419 bacapp_init_routine(void)
10421 fragment_table_init(&msg_fragment_table);
10422 reassembled_table_init(&msg_reassembled_table);
10426 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
10431 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
10432 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
10433 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
10436 g_iconv_close (icd);
10440 uni_to_string(in,*inbytesleft,out);
10441 out[*inbytesleft] = '\0';
10442 *outbytesleft -= *inbytesleft;
10449 uni_to_string(char * data, gsize str_length, char *dest_buf)
10453 gsize length_remaining = 0;
10455 length_remaining = str_length;
10456 dest_buf[0] = '\0';
10457 if(str_length == 0) {
10460 for ( i = 0; i < (gint) str_length; i++ ) {
10462 if (c_char<0x20 || c_char>0x7e) {
10463 if (c_char != 0x00) {
10465 dest_buf[i] = c_char & 0xff;
10471 dest_buf[i] = c_char & 0xff;
10473 length_remaining--;
10475 if(length_remaining==0) {
10476 dest_buf[i+1] = '\0';
10483 dest_buf[i] = '\0';
10488 proto_register_bacapp(void)
10490 static hf_register_info hf[] = {
10492 { "APDU Type", "bacapp.type",
10493 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
10495 { &hf_bacapp_pduflags,
10496 { "PDU Flags", "bacapp.pduflags",
10497 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
10500 { "Segmented Request", "bacapp.segmented_request",
10501 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
10504 { "More Segments", "bacapp.more_segments",
10505 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
10508 { "SA", "bacapp.SA",
10509 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
10511 { &hf_bacapp_max_adpu_size,
10512 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
10513 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
10515 { &hf_bacapp_response_segments,
10516 { "Max Response Segments accepted", "bacapp.response_segments",
10517 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
10519 { &hf_bacapp_objectType,
10520 { "Object Type", "bacapp.objectType",
10521 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
10523 { &hf_bacapp_instanceNumber,
10524 { "Instance Number", "bacapp.instance_number",
10525 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
10527 { &hf_BACnetPropertyIdentifier,
10528 { "Property Identifier", "bacapp.property_identifier",
10529 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
10531 { &hf_BACnetVendorIdentifier,
10532 { "Vendor Identifier", "bacapp.vendor_identifier",
10533 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
10535 { &hf_BACnetRestartReason,
10536 { "Restart Reason", "bacapp.restart_reason",
10537 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
10539 { &hf_bacapp_invoke_id,
10540 { "Invoke ID", "bacapp.invoke_id",
10541 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10543 { &hf_bacapp_sequence_number,
10544 { "Sequence Number", "bacapp.sequence_number",
10545 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10547 { &hf_bacapp_window_size,
10548 { "Proposed Window Size", "bacapp.window_size",
10549 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10551 { &hf_bacapp_service,
10552 { "Service Choice", "bacapp.confirmed_service",
10553 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
10555 { &hf_bacapp_uservice,
10556 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
10557 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
10560 { "NAK", "bacapp.NAK",
10561 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
10564 { "SRV", "bacapp.SRV",
10565 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
10567 { &hf_Device_Instance_Range_Low_Limit,
10568 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
10569 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
10571 { &hf_Device_Instance_Range_High_Limit,
10572 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
10573 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
10575 { &hf_BACnetRejectReason,
10576 { "Reject Reason", "bacapp.reject_reason",
10577 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
10579 { &hf_BACnetAbortReason,
10580 { "Abort Reason", "bacapp.abort_reason",
10581 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
10583 { &hf_BACnetApplicationTagNumber,
10584 { "Application Tag Number",
10585 "bacapp.application_tag_number",
10586 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
10589 { &hf_BACnetContextTagNumber,
10590 { "Context Tag Number",
10591 "bacapp.context_tag_number",
10592 FT_UINT8, BASE_DEC, NULL, 0xF0,
10595 { &hf_BACnetExtendedTagNumber,
10596 { "Extended Tag Number",
10597 "bacapp.extended_tag_number",
10598 FT_UINT8, BASE_DEC, NULL, 0,
10601 { &hf_BACnetNamedTag,
10603 "bacapp.named_tag",
10604 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
10607 { &hf_BACnetCharacterSet,
10608 { "String Character Set",
10609 "bacapp.string_character_set",
10610 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet),0,
10613 { &hf_BACnetTagClass,
10614 { "Tag Class", "bacapp.tag_class",
10615 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
10617 { &hf_bacapp_tag_lvt,
10618 { "Length Value Type",
10620 FT_UINT8, BASE_DEC, NULL, 0,
10623 { &hf_bacapp_tag_ProcessId,
10624 { "ProcessIdentifier", "bacapp.processId",
10625 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
10627 { &hf_bacapp_tag_IPV4,
10628 { "IPV4", "bacapp.IPV4",
10629 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
10631 { &hf_bacapp_tag_IPV6,
10632 { "IPV6", "bacapp.IPV6",
10633 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
10635 { &hf_bacapp_tag_PORT,
10636 { "Port", "bacapp.Port",
10637 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
10639 {&hf_msg_fragments,
10640 {"Message fragments", "bacapp.fragments",
10641 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10643 {"Message fragment", "bacapp.fragment",
10644 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10645 {&hf_msg_fragment_overlap,
10646 {"Message fragment overlap", "bacapp.fragment.overlap",
10647 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10648 {&hf_msg_fragment_overlap_conflicts,
10649 {"Message fragment overlapping with conflicting data",
10650 "bacapp.fragment.overlap.conflicts",
10651 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10652 {&hf_msg_fragment_multiple_tails,
10653 {"Message has multiple tail fragments",
10654 "bacapp.fragment.multiple_tails",
10655 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10656 {&hf_msg_fragment_too_long_fragment,
10657 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
10658 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10659 {&hf_msg_fragment_error,
10660 {"Message defragmentation error", "bacapp.fragment.error",
10661 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10662 {&hf_msg_fragment_count,
10663 {"Message fragment count", "bacapp.fragment.count",
10664 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
10665 {&hf_msg_reassembled_in,
10666 {"Reassembled in", "bacapp.reassembled.in",
10667 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10668 {&hf_msg_reassembled_length,
10669 {"Reassembled BACapp length", "bacapp.reassembled.length",
10670 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
10672 static gint *ett[] = {
10674 &ett_bacapp_control,
10683 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
10684 "BACapp", "bacapp");
10686 proto_register_field_array(proto_bacapp, hf, array_length(hf));
10687 proto_register_subtree_array(ett, array_length(ett));
10688 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
10689 register_init_routine (&bacapp_init_routine);
10691 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
10692 "BACapp Vendor Identifier",
10693 FT_UINT8, BASE_HEX);
10695 /* Register BACnet Statistic trees */
10696 register_bacapp_stat_trees();
10697 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
10701 proto_reg_handoff_bacapp(void)
10703 data_handle = find_dissector("data");