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
254 * @return modified offset
257 fUnsignedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
260 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
266 * @return modified offset
269 fSignedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
272 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
278 * @param lvt length of String
279 * @return modified offset
282 fOctetString (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
285 * 20.2.12, adds the label with Date Value to tree
291 * @return modified offset
294 fDate (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
297 * 20.2.13, adds the label with Time Value to tree
303 * @return modified offset
306 fTime (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
309 * 20.2.14, adds Object Identifier to tree
310 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
315 * @return modified offset
318 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
321 * BACnet-Confirmed-Service-Request ::= CHOICE {
327 * @param service_choice
331 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
334 * BACnet-Confirmed-Service-ACK ::= CHOICE {
340 * @param service_choice
344 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
347 * AcknowledgeAlarm-Request ::= SEQUENCE {
348 * acknowledgingProcessIdentifier [0] Unsigned32,
349 * eventObjectIdentifier [1] BACnetObjectIdentifer,
350 * eventStateAcknowledge [2] BACnetEventState,
351 * timeStamp [3] BACnetTimeStamp,
352 * acknowledgementSource [4] Character String,
353 * timeOfAcknowledgement [5] BACnetTimeStamp
359 * @return modified offset
362 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
365 * ConfirmedCOVNotification-Request ::= SEQUENCE {
366 * subscriberProcessIdentifier [0] Unsigned32,
367 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
368 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
369 * timeRemaining [3] unsigned,
370 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
376 * @return modified offset
379 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
382 * ConfirmedEventNotification-Request ::= SEQUENCE {
383 * ProcessIdentifier [0] Unsigned32,
384 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
385 * eventObjectIdentifier [2] BACnetObjectIdentifer,
386 * timeStamp [3] BACnetTimeStamp,
387 * notificationClass [4] unsigned,
388 * priority [5] unsigned8,
389 * eventType [6] BACnetEventType,
390 * messageText [7] CharacterString OPTIONAL,
391 * notifyType [8] BACnetNotifyType,
392 * ackRequired [9] BOOLEAN OPTIONAL,
393 * fromState [10] BACnetEventState OPTIONAL,
394 * toState [11] BACnetEventState,
395 * eventValues [12] BACnetNotificationParameters OPTIONAL
401 * @return modified offset
404 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
407 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
408 * objectIdentifier BACnetObjectIdentifer,
409 * alarmState BACnetEventState,
410 * acknowledgedTransitions BACnetEventTransitionBits
416 * @return modified offset
419 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
422 * GetEnrollmentSummary-Request ::= SEQUENCE {
423 * acknowledgmentFilter [0] ENUMERATED {
428 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
429 * eventStateFilter [2] ENUMERATED {
436 * eventTypeFilter [3] BACnetEventType OPTIONAL,
437 * priorityFilter [4] SEQUENCE {
438 * minPriority [0] Unsigned8,
439 * maxPriority [1] Unsigned8
441 * notificationClassFilter [5] Unsigned OPTIONAL
447 * @return modified offset
450 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
453 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
454 * objectIdentifier BACnetObjectIdentifer,
455 * eventType BACnetEventType,
456 * eventState BACnetEventState,
457 * priority Unsigned8,
458 * notificationClass Unsigned OPTIONAL
464 * @return modified offset
467 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
470 * GetEventInformation-Request ::= SEQUENCE {
471 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
477 * @return modified offset
480 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
483 * GetEventInformation-ACK ::= SEQUENCE {
484 * listOfEventSummaries [0] listOfEventSummaries,
485 * moreEvents [1] BOOLEAN
491 * @return modified offset
494 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
497 * LifeSafetyOperation-Request ::= SEQUENCE {
498 * requestingProcessIdentifier [0] Unsigned32
499 * requestingSource [1] CharacterString
500 * request [2] BACnetLifeSafetyOperation
501 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
507 * @return modified offset
510 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
513 * SubscribeCOV-Request ::= SEQUENCE {
514 * subscriberProcessIdentifier [0] Unsigned32
515 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
516 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
517 * lifetime [3] Unsigned OPTIONAL
525 * @return modified offset
528 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
531 * SubscribeCOVProperty-Request ::= SEQUENCE {
532 * subscriberProcessIdentifier [0] Unsigned32
533 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
534 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
535 * lifetime [3] Unsigned OPTIONAL
536 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
537 * covIncrement [5] Unsigned OPTIONAL
543 * @return modified offset
546 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
549 * AtomicReadFile-Request ::= SEQUENCE {
550 * fileIdentifier BACnetObjectIdentifier,
551 * accessMethod CHOICE {
552 * streamAccess [0] SEQUENCE {
553 * fileStartPosition INTEGER,
554 * requestedOctetCount Unsigned
556 * recordAccess [1] SEQUENCE {
557 * fileStartRecord INTEGER,
558 * requestedRecordCount Unsigned
566 * @return modified offset
569 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
572 * AtomicWriteFile-ACK ::= SEQUENCE {
574 * accessMethod CHOICE {
575 * streamAccess [0] SEQUENCE {
576 * fileStartPosition INTEGER,
577 * fileData OCTET STRING
579 * recordAccess [1] SEQUENCE {
580 * fileStartRecord INTEGER,
581 * returnedRecordCount Unsigned,
582 * fileRecordData SEQUENCE OF OCTET STRING
590 * @return modified offset
593 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
596 * AtomicWriteFile-Request ::= SEQUENCE {
597 * fileIdentifier BACnetObjectIdentifier,
598 * accessMethod CHOICE {
599 * streamAccess [0] SEQUENCE {
600 * fileStartPosition INTEGER,
601 * fileData OCTET STRING
603 * recordAccess [1] SEQUENCE {
604 * fileStartRecord INTEGER,
605 * recordCount Unsigned,
606 * fileRecordData SEQUENCE OF OCTET STRING
614 * @return modified offset
617 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
620 * AtomicWriteFile-ACK ::= SEQUENCE {
621 * fileStartPosition [0] INTEGER,
622 * fileStartRecord [1] INTEGER,
628 * @return modified offset
631 fAtomicWriteFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
634 * AddListElement-Request ::= SEQUENCE {
635 * objectIdentifier [0] BACnetObjectIdentifier,
636 * propertyIdentifier [1] BACnetPropertyIdentifier,
637 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
638 * listOfElements [3] ABSTRACT-SYNTAX.&Type
644 * @return modified offset
647 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
650 * CreateObject-Request ::= SEQUENCE {
651 * objectSpecifier [0] ObjectSpecifier,
652 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
658 * @return modified offset
661 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
664 * CreateObject-Request ::= BACnetObjectIdentifier
669 * @return modified offset
672 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
675 * DeleteObject-Request ::= SEQUENCE {
676 * ObjectIdentifier BACnetObjectIdentifer
682 * @return modified offset
685 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
688 * ReadProperty-Request ::= SEQUENCE {
689 * objectIdentifier [0] BACnetObjectIdentifier,
690 * propertyIdentifier [1] BACnetPropertyIdentifier,
691 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
697 * @return modified offset
700 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
703 * ReadProperty-ACK ::= SEQUENCE {
704 * objectIdentifier [0] BACnetObjectIdentifier,
705 * propertyIdentifier [1] BACnetPropertyIdentifier,
706 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
707 * propertyValue [3] ABSTRACT-SYNTAX.&Type
713 * @return modified offset
716 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
719 * ReadPropertyConditional-Request ::= SEQUENCE {
720 * objectSelectionCriteria [0] objectSelectionCriteria,
721 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
727 * @return modified offset
730 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
733 * ReadPropertyConditional-ACK ::= SEQUENCE {
734 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
740 * @return modified offset
743 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
746 * ReadPropertyMultiple-Request ::= SEQUENCE {
747 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
753 * @return offset modified
756 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
759 * ReadPropertyMultiple-Ack ::= SEQUENCE {
760 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
766 * @return offset modified
769 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
772 * ReadRange-Request ::= SEQUENCE {
773 * objectIdentifier [0] BACnetObjectIdentifier,
774 * propertyIdentifier [1] BACnetPropertyIdentifier,
775 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
777 * byPosition [3] SEQUENCE {
778 * referencedIndex Unsigned,
781 * byTime [4] SEQUENCE {
782 * referenceTime BACnetDateTime,
785 * timeRange [5] SEQUENCE {
786 * beginningTime BACnetDateTime,
787 * endingTime BACnetDateTime
795 * @return modified offset
798 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
801 * ReadRange-ACK ::= SEQUENCE {
802 * objectIdentifier [0] BACnetObjectIdentifier,
803 * propertyIdentifier [1] BACnetPropertyIdentifier,
804 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
805 * resultFlags [3] BACnetResultFlags,
806 * itemCount [4] Unsigned,
807 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
813 * @return modified offset
816 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
819 * RemoveListElement-Request ::= SEQUENCE {
820 * objectIdentifier [0] BACnetObjectIdentifier,
821 * propertyIdentifier [1] BACnetPropertyIdentifier,
822 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
823 * listOfElements [3] ABSTRACT-SYNTAX.&Type
829 * @return modified offset
832 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
835 * WriteProperty-Request ::= SEQUENCE {
836 * objectIdentifier [0] BACnetObjectIdentifier,
837 * propertyIdentifier [1] BACnetPropertyIdentifier,
838 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
839 * propertyValue [3] ABSTRACT-SYNTAX.&Type
840 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
846 * @return modified offset
849 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
852 * WritePropertyMultiple-Request ::= SEQUENCE {
853 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
859 * @return modified offset
862 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
865 * DeviceCommunicationControl-Request ::= SEQUENCE {
866 * timeDuration [0] Unsigned16 OPTIONAL,
867 * enable-disable [1] ENUMERATED {
871 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
877 * @return modified offset
880 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
883 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
884 * vendorID [0] Unsigned,
885 * serviceNumber [1] Unsigned,
886 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
892 * @return modified offset
895 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
898 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
899 * vendorID [0] Unsigned,
900 * serviceNumber [1] Unsigned,
901 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
907 * @return modified offset
910 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
913 * ConfirmedTextMessage-Request ::= SEQUENCE {
914 * textMessageSourceDevice [0] BACnetObjectIdentifier,
915 * messageClass [1] CHOICE {
916 * numeric [0] Unsigned,
917 * character [1] CharacterString
919 * messagePriority [2] ENUMERATED {
923 * message [3] CharacterString
929 * @return modified offset
932 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
935 * ReinitializeDevice-Request ::= SEQUENCE {
936 * reinitializedStateOfDevice [0] ENUMERATED {
945 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
951 * @return modified offset
954 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
957 * VTOpen-Request ::= SEQUENCE {
958 * vtClass BACnetVTClass,
959 * localVTSessionIdentifier Unsigned8
965 * @return modified offset
968 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
971 * VTOpen-ACK ::= SEQUENCE {
972 * remoteVTSessionIdentifier Unsigned8
978 * @return modified offset
981 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
984 * VTClose-Request ::= SEQUENCE {
985 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
991 * @return modified offset
994 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
997 * VTData-Request ::= SEQUENCE {
998 * vtSessionIdentifier Unsigned8,
999 * vtNewData OCTET STRING,
1000 * vtDataFlag Unsigned (0..1)
1006 * @return modified offset
1009 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1012 * VTData-ACK ::= SEQUENCE {
1013 * allNewDataAccepted [0] BOOLEAN,
1014 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1020 * @return modified offset
1023 fVtDataAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1026 * Authenticate-Request ::= SEQUENCE {
1027 * pseudoRandomNumber [0] Unsigned32,
1028 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1029 * operatorName [2] CharacterString OPTIONAL,
1030 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1031 * startEncypheredSession [4] BOOLEAN OPTIONAL
1037 * @return modified offset
1040 fAuthenticateRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1043 * Authenticate-ACK ::= SEQUENCE {
1044 * modifiedRandomNumber Unsigned32,
1050 * @return modified offset
1053 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1056 * RequestKey-Request ::= SEQUENCE {
1057 * requestingDeviceIdentifier BACnetObjectIdentifier,
1058 * requestingDeviceAddress BACnetAddress,
1059 * remoteDeviceIdentifier BACnetObjectIdentifier,
1060 * remoteDeviceAddress BACnetAddress
1066 * @return modified offset
1069 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1072 * Unconfirmed-Service-Request ::= CHOICE {
1078 * @param service_choice
1079 * @return modified offset
1082 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1085 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1086 * subscriberProcessIdentifier [0] Unsigned32,
1087 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1088 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1089 * timeRemaining [3] unsigned,
1090 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1096 * @return modified offset
1099 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1102 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1103 * ProcessIdentifier [0] Unsigned32,
1104 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1105 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1106 * timeStamp [3] BACnetTimeStamp,
1107 * notificationClass [4] unsigned,
1108 * priority [5] unsigned8,
1109 * eventType [6] BACnetEventType,
1110 * messageText [7] CharacterString OPTIONAL,
1111 * notifyType [8] BACnetNotifyType,
1112 * ackRequired [9] BOOLEAN OPTIONAL,
1113 * fromState [10] BACnetEventState OPTIONAL,
1114 * toState [11] BACnetEventState,
1115 * eventValues [12] BACnetNotificationParameters OPTIONAL
1121 * @return modified offset
1124 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1127 * I-Am-Request ::= SEQUENCE {
1128 * aAmDeviceIdentifier BACnetObjectIdentifier,
1129 * maxAPDULengthAccepted Unsigned,
1130 * segmentationSupported BACnetSegmentation,
1137 * @return modified offset
1140 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1144 * I-Have-Request ::= SEQUENCE {
1145 * deviceIdentifier BACnetObjectIdentifier,
1146 * objectIdentifier BACnetObjectIdentifier,
1147 * objectName CharacterString
1153 * @return modified offset
1156 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1159 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1160 * vendorID [0] Unsigned,
1161 * serviceNumber [1] Unsigned,
1162 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1168 * @return modified offset
1171 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1174 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1175 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1176 * messageClass [1] CHOICE {
1177 * numeric [0] Unsigned,
1178 * character [1] CharacterString
1180 * messagePriority [2] ENUMERATED {
1184 * message [3] CharacterString
1190 * @return modified offset
1193 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1196 * TimeSynchronization-Request ::= SEQUENCE {
1203 * @return modified offset
1206 fTimeSynchronizationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1209 * UTCTimeSynchronization-Request ::= SEQUENCE {
1216 * @return modified offset
1219 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1222 * Who-Has-Request ::= SEQUENCE {
1224 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1225 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1228 * objectIdentifier [2] BACnetObjectIdentifier,
1229 * objectName [3] CharacterString
1236 * @return modified offset
1239 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1242 * Who-Is-Request ::= SEQUENCE {
1243 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1244 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1249 * @return modified offset
1252 fWhoIsRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1255 * BACnet-Error ::= CHOICE {
1256 * addListElement [8] ChangeList-Error,
1257 * removeListElement [9] ChangeList-Error,
1258 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1259 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1260 * vtClose [22] VTClose-Error,
1261 * readRange [26] ObjectAccessService-Error
1269 * @return modified offset
1272 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1275 * Dissect a BACnetError in a context tag
1281 * @return modified offset
1283 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1286 * ChangeList-Error ::= SEQUENCE {
1287 * errorType [0] Error,
1288 * firstFailedElementNumber [1] Unsigned
1295 * @return modified offset
1298 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1301 * CreateObject-Error ::= SEQUENCE {
1302 * errorType [0] Error,
1303 * firstFailedElementNumber [1] Unsigned
1310 * @return modified offset
1313 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1316 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1317 * errorType [0] Error,
1318 * vendorID [1] Unsigned,
1319 * serviceNumber [2] Unsigned,
1320 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1327 * @return modified offset
1330 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1333 * WritePropertyMultiple-Error ::= SEQUENCE {
1334 * errorType [0] Error,
1335 * firstFailedWriteAttempt [1] Unsigned
1342 * @return modified offset
1345 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1348 * VTClose-Error ::= SEQUENCE {
1349 * errorType [0] Error,
1350 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1357 * @return modified offset
1360 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1363 * BACnet Application Types chapter 20.2.1
1369 * @return modified offset
1372 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1375 * BACnetActionCommand ::= SEQUENCE {
1376 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1377 * objectIdentifier [1] BACnetObjectIdentifier,
1378 * propertyIdentifier [2] BACnetPropertyIdentifier,
1379 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1380 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1381 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1382 * postDelay [6] Unsigned OPTIONAL,
1383 * quitOnFailure [7] BOOLEAN,
1384 * writeSuccessful [8] BOOLEAN
1390 * @param matching tag number
1391 * @return modified offset
1394 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1397 * BACnetActionList ::= SEQUENCE {
1398 * action [0] SEQUENCE of BACnetActionCommand
1404 * @return modified offset
1407 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1409 /** BACnetAddress ::= SEQUENCE {
1410 * network-number Unsigned16, -- A value 0 indicates the local network
1411 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1417 * @return modified offset
1420 fAddress (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1423 * BACnetAddressBinding ::= SEQUENCE {
1424 * deviceObjectID BACnetObjectIdentifier
1425 * deviceAddress BacnetAddress
1431 * @return modified offset
1434 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1437 * BACnetCalendarEntry ::= CHOICE {
1439 * dateRange [1] BACnetDateRange,
1440 * weekNDay [2] BacnetWeekNday
1446 * @return modified offset
1449 fCalendarEntry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1452 * BACnetClientCOV ::= CHOICE {
1453 * real-increment REAL,
1454 * default-increment NULL
1459 * @return modified offset
1462 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1466 * BACnetDailySchedule ::= SEQUENCE {
1467 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1473 * @return modified offset
1476 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1479 * BACnetWeeklySchedule ::= SEQUENCE {
1480 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1486 * @return modified offset
1489 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1492 * BACnetDateRange ::= SEQUENCE {
1500 * @return modified offset
1503 fDateRange (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1506 * BACnetDateTime ::= SEQUENCE {
1515 * @return modified offset
1518 fDateTime (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1521 * BACnetDestination ::= SEQUENCE {
1522 * validDays BACnetDaysOfWeek,
1525 * recipient BACnetRecipient,
1526 * processIdentifier Unsigned32,
1527 * issueConfirmedNotifications BOOLEAN,
1528 * transitions BACnetEventTransitionBits
1534 * @return modified offset
1537 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1540 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1541 * objectIdentifier [0] BACnetObjectIdentifier,
1542 * propertyIdentifier [1] BACnetPropertyIdentifier,
1543 * propertyArrayIndex [2] Unsigend OPTIONAL,
1544 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1550 * @return modified offset
1553 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1556 * BACnetObjectPropertyReference ::= SEQUENCE {
1557 * objectIdentifier [0] BACnetObjectIdentifier,
1558 * propertyIdentifier [1] BACnetPropertyIdentifier,
1559 * propertyArrayIndex [2] Unsigend OPTIONAL,
1565 * @return modified offset
1568 fObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1571 * BACnetDeviceObjectReference ::= SEQUENCE {
1572 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1573 * objectIdentifier [1] BACnetObjectIdentifier
1579 * @return modified offset
1582 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1585 * BACnetEventParameter ::= CHOICE {
1586 * change-of-bitstring [0] SEQUENCE {
1587 * time-delay [0] Unsigned,
1588 * bitmask [1] BIT STRING,
1589 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1591 * change-of-state [1] SEQUENCE {
1592 * time-delay [0] Unsigned,
1593 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1595 * change-of-value [2] SEQUENCE {
1596 * time-delay [0] Unsigned,
1597 * cov-criteria [1] CHOICE {
1598 * bitmask [0] BIT STRING,
1599 * referenced-property-increment [1] REAL
1602 * command-failure [3] SEQUENCE {
1603 * time-delay [0] Unsigned,
1604 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1606 * floating-limit [4] SEQUENCE {
1607 * time-delay [0] Unsigned,
1608 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1609 * low-diff-limit [2] REAL,
1610 * high-diff-limit [3] REAL,
1613 * out-of-range [5] SEQUENCE {
1614 * time-delay [0] Unsigned,
1615 * low-limit [1] REAL,
1616 * high-limit [2] REAL,
1619 * buffer-ready [7] SEQUENCE {
1620 * notification-threshold [0] Unsigned,
1621 * previous-notification-count [1] Unsigned32
1623 * change-of-life-safety [8] SEQUENCE {
1624 * time-delay [0] Unsigned,
1625 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1626 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1627 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1633 * @return modified offset
1636 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1641 * BACnetLogRecord ::= SEQUENCE {
1642 * timestamp [0] BACnetDateTime,
1643 * logDatum [1] CHOICE {
1644 * log-status [0] BACnetLogStatus,
1645 * boolean-value [1] BOOLEAN,
1646 * real-value [2] REAL,
1647 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1648 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1649 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1650 * bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
1651 * null-value [7] NULL,
1652 * failure [8] Error,
1653 * time-change [9] REAL,
1654 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1656 * statusFlags [2] BACnetStatusFlags OPTIONAL
1662 * @return modified offset
1665 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1668 * BACnetEventLogRecord ::= SEQUENCE {
1669 * timestamp [0] BACnetDateTime,
1670 * logDatum [1] CHOICE {
1671 * log-status [0] BACnetLogStatus,
1672 * notification [1] ConfirmedEventNotification-Request,
1673 * time-change [2] REAL,
1680 * @return modified offset
1683 fEventLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1686 fLogMultipleRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1689 * BACnetNotificationParameters ::= CHOICE {
1690 * change-of-bitstring [0] SEQUENCE {
1691 * referenced-bitstring [0] BIT STRING,
1692 * status-flags [1] BACnetStatusFlags
1694 * change-of-state [1] SEQUENCE {
1695 * new-state [0] BACnetPropertyStatus,
1696 * status-flags [1] BACnetStatusFlags
1698 * change-of-value [2] SEQUENCE {
1699 * new-value [0] CHOICE {
1700 * changed-bits [0] BIT STRING,
1701 * changed-value [1] REAL
1703 * status-flags [1] BACnetStatusFlags
1705 * command-failure [3] SEQUENCE {
1706 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1707 * status-flags [1] BACnetStatusFlags
1708 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1710 * floating-limit [4] SEQUENCE {
1711 * reference-value [0] REAL,
1712 * status-flags [1] BACnetStatusFlags
1713 * setpoint-value [2] REAL,
1714 * error-limit [3] REAL
1716 * out-of-range [5] SEQUENCE {
1717 * exceeding-value [0] REAL,
1718 * status-flags [1] BACnetStatusFlags
1719 * deadband [2] REAL,
1720 * exceeded-limit [0] REAL
1722 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1723 * buffer-ready [7] SEQUENCE {
1724 * buffer-device [0] BACnetObjectIdentifier,
1725 * buffer-object [1] BACnetObjectIdentifier
1726 * previous-notification[2] BACnetDateTime,
1727 * current-notification [3] BACnetDateTime
1729 * change-of-life-safety [8] SEQUENCE {
1730 * new-state [0] BACnetLifeSafetyState,
1731 * new-mode [1] BACnetLifeSafetyState
1732 * status-flags [2] BACnetStatusFlags,
1733 * operation-expected [3] BACnetLifeSafetyOperation
1740 * @return modified offset
1743 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1746 * BACnetObjectPropertyReference ::= SEQUENCE {
1747 * objectIdentifier [0] BACnetObjectIdentifier,
1748 * propertyIdentifier [1] BACnetPropertyIdentifier,
1749 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1755 * @return modified offset
1758 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1762 * BACnetObjectPropertyValue ::= SEQUENCE {
1763 * objectIdentifier [0] BACnetObjectIdentifier,
1764 * propertyIdentifier [1] BACnetPropertyIdentifier,
1765 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1766 * -- if omitted with an array the entire array is referenced
1767 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1768 * priority [4] Unsigned (1..16) OPTIONAL
1773 * @return modified offset
1776 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
1780 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1785 * @return modified offset
1788 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1791 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1794 * BACnetPropertyReference ::= SEQUENCE {
1795 * propertyIdentifier [0] BACnetPropertyIdentifier,
1796 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1802 * @return modified offset
1805 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1808 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1811 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1814 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1817 * BACnetPropertyValue ::= SEQUENCE {
1818 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1819 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1820 * -- if omitted with an array the entire array is referenced
1821 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1822 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1828 * @return modified offset
1831 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1834 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1837 * BACnet Application PDUs chapter 21
1838 * BACnetRecipient::= CHOICE {
1839 * device [0] BACnetObjectIdentifier
1840 * address [1] BACnetAddress
1846 * @return modified offset
1849 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1852 * BACnet Application PDUs chapter 21
1853 * BACnetRecipientProcess::= SEQUENCE {
1854 * recipient [0] BACnetRecipient
1855 * processID [1] Unsigned32
1861 * @return modified offset
1864 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1867 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1871 * BACnetSessionKey ::= SEQUENCE {
1872 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1873 * peerAddress BACnetAddress
1878 * @return modified offset
1879 * @todo check if checksum is displayed correctly
1882 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1886 * BACnetSpecialEvent ::= SEQUENCE {
1888 * calendarEntry [0] BACnetCalendarEntry,
1889 * calendarRefernce [1] BACnetObjectIdentifier
1891 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1892 * eventPriority [3] Unsigned (1..16)
1898 * @return modified offset
1901 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1904 * BACnetTimeStamp ::= CHOICE {
1906 * sequenceNumber [1] Unsigned (0..65535),
1907 * dateTime [2] BACnetDateTime
1914 * @return modified offset
1917 fTimeStamp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1920 fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1923 * BACnetTimeValue ::= SEQUENCE {
1925 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1931 * @return modified offset
1934 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1938 * BACnetVTSession ::= SEQUENCE {
1939 * local-vtSessionID Unsigned8,
1940 * remote-vtSessionID Unsigned8,
1941 * remote-vtAddress BACnetAddress
1946 * @return modified offset
1949 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1953 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1954 * -- first octet month (1..12) January = 1, X'FF' = any month
1955 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1956 * -- 2 = days numbered 8-14
1957 * -- 3 = days numbered 15-21
1958 * -- 4 = days numbered 22-28
1959 * -- 5 = days numbered 29-31
1960 * -- 6 = last 7 days of this month
1961 * -- X'FF' = any week of this month
1962 * -- third octet dayOfWeek (1..7) where 1 = Monday
1964 * -- X'FF' = any day of week
1969 * @return modified offset
1972 fWeekNDay (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1975 * ReadAccessResult ::= SEQUENCE {
1976 * objectIdentifier [0] BACnetObjectIdentifier,
1977 * listOfResults [1] SEQUENCE OF SEQUENCE {
1978 * propertyIdentifier [2] BACnetPropertyIdentifier,
1979 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1980 * readResult CHOICE {
1981 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1982 * propertyAccessError [5] Error
1990 * @return modified offset
1993 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1996 * ReadAccessSpecification ::= SEQUENCE {
1997 * objectIdentifier [0] BACnetObjectIdentifier,
1998 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
2004 * @return modified offset
2007 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2010 * WriteAccessSpecification ::= SEQUENCE {
2011 * objectIdentifier [0] BACnetObjectIdentifier,
2012 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
2018 * @return modified offset
2021 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2024 /********************************************************* Helper functions *******************************************/
2027 * extracts the tag number from the tag header.
2028 * @param tvb "TestyVirtualBuffer"
2029 * @param offset in actual tvb
2030 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
2033 fTagNo (tvbuff_t *tvb, guint offset);
2036 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
2037 * @param tvb = "TestyVirtualBuffer"
2038 * @param pinfo = packet info
2039 * @param offset = offset in actual tvb
2040 * @return tag_no BACnet 20.2.1.2 Tag Number
2041 * @return class_tag BACnet 20.2.1.1 Class
2042 * @return lvt BACnet 20.2.1.3 Length/Value/Type
2043 * @return offs = length of this header
2047 fTagHeader (tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
2051 * adds processID with max 32Bit unsigned Integer Value to tree
2056 * @return modified offset
2059 fProcessId (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2062 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2067 * @return modified offset
2070 fTimeSpan (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2073 * BACnet Application PDUs chapter 21
2074 * BACnetPropertyIdentifier::= ENUMERATED {
2075 * @see bacapp_property_identifier
2081 * @param tt returnvalue of this item
2082 * @return modified offset
2085 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2088 * BACnet Application PDUs chapter 21
2089 * BACnetPropertyArrayIndex::= ENUMERATED {
2090 * @see bacapp_property_array_index
2095 * @param tt returnvalue of this item
2096 * @return modified offset
2099 fPropertyArrayIndex (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2102 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2103 * objectIdentifier [0] BACnetObjectIdentifier,
2104 * eventState [1] BACnetEventState,
2105 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2106 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2107 * notifyType [4] BACnetNotifyType,
2108 * eventEnable [5] BACnetEventTransitionBits,
2109 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2115 * @return modified offset
2118 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2121 * SelectionCriteria ::= SEQUENCE {
2122 * propertyIdentifier [0] BACnetPropertyIdentifier,
2123 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2124 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2125 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2131 * @return modified offset
2134 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2137 * objectSelectionCriteria ::= SEQUENCE {
2138 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2139 * listOfSelectionCriteria [1] SelectionCriteria
2145 * @return modified offset
2148 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2151 * BACnet-Error ::= SEQUENCE {
2152 * error-class ENUMERATED {},
2153 * error-code ENUMERATED {}
2160 * @return modified offset
2163 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2166 * Generic handler for context tagged values. Mostly for handling
2167 * vendor-defined properties and services.
2172 * @return modified offset
2173 * @todo beautify this ugly construct
2176 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2179 * realizes some ABSTRACT-SYNTAX.&Type
2184 * @return modified offset
2185 * @todo beautify this ugly construct
2188 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2192 fBitStringTagVS (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
2193 const value_string *src);
2199 proto_register_bacapp(void);
2202 * proto_reg_handoff_bacapp
2205 proto_reg_handoff_bacapp(void);
2208 * converts XXX coded strings to UTF-8
2209 * else 'in' is copied to 'out'
2210 * @param in -- pointer to string
2211 * @param inbytesleft
2212 * @param out -- pointer to string
2213 * @param outbytesleft
2215 * @return count of modified characters of returned string, -1 for errors
2218 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2221 uni_to_string(char * data, gsize str_length, char *dest_buf);
2223 /* <<<< formerly bacapp.h */
2225 /* some hashes for segmented messages */
2226 static GHashTable *msg_fragment_table = NULL;
2227 static GHashTable *msg_reassembled_table = NULL;
2229 /* some necessary forward function prototypes */
2231 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2232 const gchar *label, const value_string *vs);
2234 static const char *bacapp_unknown_service_str = "unknown service";
2235 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2236 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2238 static const value_string
2239 BACnetTypeName[] = {
2240 { 0, "Confirmed-REQ"},
2241 { 1, "Unconfirmed-REQ"},
2243 { 3, "Complex-ACK"},
2244 { 4, "Segment-ACK"},
2251 static const true_false_string segments_follow = {
2252 "Segmented Request",
2253 "Unsegmented Request"
2256 static const true_false_string more_follow = {
2257 "More Segments Follow",
2258 "No More Segments Follow"
2261 static const true_false_string segmented_accept = {
2262 "Segmented Response accepted",
2263 "Segmented Response not accepted"
2266 static const true_false_string
2268 "Context Specific Tag",
2272 static const value_string
2273 BACnetMaxSegmentsAccepted [] = {
2274 { 0, "Unspecified"},
2278 { 4, "16 segments"},
2279 { 5, "32 segments"},
2280 { 6, "64 segments"},
2281 { 7, "Greater than 64 segments"},
2285 static const value_string
2286 BACnetMaxAPDULengthAccepted [] = {
2287 { 0, "Up to MinimumMessageSize (50 octets)"},
2288 { 1, "Up to 128 octets"},
2289 { 2, "Up to 206 octets (fits in a LonTalk frame)"},
2290 { 3, "Up to 480 octets (fits in an ARCNET frame)"},
2291 { 4, "Up to 1024 octets"},
2292 { 5, "Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2293 { 6, "reserved by ASHRAE"},
2294 { 7, "reserved by ASHRAE"},
2295 { 8, "reserved by ASHRAE"},
2296 { 9, "reserved by ASHRAE"},
2297 { 10, "reserved by ASHRAE"},
2298 { 11, "reserved by ASHRAE"},
2299 { 12, "reserved by ASHRAE"},
2300 { 13, "reserved by ASHRAE"},
2301 { 14, "reserved by ASHRAE"},
2302 { 15, "reserved by ASHRAE"},
2306 static const value_string
2307 BACnetRejectReason [] = {
2309 {1, "buffer-overflow"},
2310 {2, "inconsistent-parameters"},
2311 {3, "invalid-parameter-data-type"},
2313 {5, "missing-required-parameter"},
2314 {6, "parameter-out-of-range"},
2315 {7, "too-many-arguments"},
2316 {8, "undefined-enumeration"},
2317 {9, "unrecognized-service"},
2321 static const value_string
2322 BACnetRestartReason [] = {
2326 { 3, "detected-power-lost"},
2327 { 4, "detected-powered-off"},
2328 { 5, "hardware-watchdog"},
2329 { 6, "software-watchdog"},
2334 static const value_string
2335 BACnetApplicationTagNumber [] = {
2338 { 2, "Unsigned Integer"},
2339 { 3, "Signed Integer (2's complement notation)"},
2340 { 4, "Real (ANSI/IEE-754 floating point)"},
2341 { 5, "Double (ANSI/IEE-754 double precision floating point)"},
2342 { 6, "Octet String"},
2343 { 7, "Character String"},
2348 { 12, "BACnetObjectIdentifier"},
2349 { 13, "reserved by ASHRAE"},
2350 { 14, "reserved by ASHRAE"},
2351 { 15, "reserved by ASHRAE"},
2355 static const value_string
2362 static const value_string
2363 BACnetFileAccessMethod [] = {
2364 { 0, "record-access"},
2365 { 1, "stream-access"},
2369 /* For some reason, BACnet defines the choice parameter
2370 in the file read and write services backwards from the
2371 BACnetFileAccessMethod enumeration.
2373 static const value_string
2374 BACnetFileAccessOption [] = {
2375 { 0, "stream access"},
2376 { 1, "record access"},
2380 static const value_string
2381 BACnetFileStartOption [] = {
2382 { 0, "File Start Position: "},
2383 { 1, "File Start Record: "},
2387 static const value_string
2388 BACnetFileRequestCount [] = {
2389 { 0, "Requested Octet Count: "},
2390 { 1, "Requested Record Count: "},
2394 static const value_string
2395 BACnetFileWriteInfo [] = {
2396 { 0, "File Data: "},
2397 { 1, "Record Count: "},
2401 static const value_string
2402 BACnetAbortReason [] = {
2404 { 1, "buffer-overflow"},
2405 { 2, "invalid-apdu-in-this-state"},
2406 { 3, "preempted-by-higher-priority-task"},
2407 { 4, "segmentation-not-supported"},
2411 static const value_string
2412 BACnetLifeSafetyMode [] = {
2423 { 10, "disconnected"},
2426 { 13, "atomic-release-disabled"},
2429 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2430 Enumerated values 256-65535 may be used by others subject to
2431 procedures and constraints described in Clause 23. */
2434 static const value_string
2435 BACnetLifeSafetyOperation [] = {
2438 { 2, "silence-audible"},
2439 { 3, "silence-visual"},
2441 { 5, "reset-alarm"},
2442 { 6, "reset-fault"},
2444 { 8, "unsilence-audible"},
2445 { 9, "unsilence-visual"},
2447 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2448 Enumerated values 64-65535 may be used by others subject to
2449 procedures and constraints described in Clause 23. */
2452 static const value_string
2453 BACnetLimitEnable [] = {
2454 { 0, "lowLimitEnable"},
2455 { 1, "highLimitEnable"},
2459 static const value_string
2460 BACnetLifeSafetyState [] = {
2465 { 4, "fault-pre-alarm"},
2466 { 5, "fault-alarm"},
2471 { 10, "test-active"},
2472 { 11, "test-fault"},
2473 { 12, "test-fault-alarm"},
2476 { 15, "tamper-alarm"},
2478 { 17, "emergency-power"},
2481 { 20, "local-alarm"},
2482 { 21, "general-alarm"},
2483 { 22, "supervisory"},
2484 { 23, "test-supervisory"},
2486 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2487 Enumerated values 256-65535 may be used by others subject to
2488 procedures and constraints described in Clause 23. */
2491 static const value_string
2492 BACnetConfirmedServiceChoice [] = {
2493 { 0, "acknowledgeAlarm"},
2494 { 1, "confirmedCOVNotification"},
2495 { 2, "confirmedEventNotification"},
2496 { 3, "getAlarmSummary"},
2497 { 4, "getEnrollmentSummary"},
2498 { 5, "subscribeCOV"},
2499 { 6, "atomicReadFile"},
2500 { 7, "atomicWriteFile"},
2501 { 8, "addListElement"},
2502 { 9, "removeListElement"},
2503 { 10, "createObject"},
2504 { 11, "deleteObject"},
2505 { 12, "readProperty"},
2506 { 13, "readPropertyConditional"},
2507 { 14, "readPropertyMultiple"},
2508 { 15, "writeProperty"},
2509 { 16, "writePropertyMultiple"},
2510 { 17, "deviceCommunicationControl"},
2511 { 18, "confirmedPrivateTransfer"},
2512 { 19, "confirmedTextMessage"},
2513 { 20, "reinitializeDevice"},
2517 { 24, "authenticate"},
2518 { 25, "requestKey"},
2520 { 27, "lifeSafetyOperation"},
2521 { 28, "subscribeCOVProperty"},
2522 { 29, "getEventInformation"},
2523 { 30, "reserved by ASHRAE"},
2527 static const value_string
2528 BACnetReliability [] = {
2529 { 0, "no-fault-detected"},
2532 { 3, "under-range"},
2534 { 5, "shorted-loop"},
2536 { 7, "unreliable-other"},
2537 { 8, "process-error"},
2538 { 9, "multi-state-fault"},
2539 { 10, "configuration-error"},
2540 /* enumeration value 11 is reserved for a future addendum */
2541 { 12, "communication-failure"},
2542 { 13, "member-fault"},
2546 static const value_string
2547 BACnetUnconfirmedServiceChoice [] = {
2550 { 2, "unconfirmedCOVNotification"},
2551 { 3, "unconfirmedEventNotification"},
2552 { 4, "unconfirmedPrivateTransfer"},
2553 { 5, "unconfirmedTextMessage"},
2554 { 6, "timeSynchronization"},
2557 { 9, "utcTimeSynchonization"},
2561 static const value_string
2562 BACnetUnconfirmedServiceRequest [] = {
2563 { 0, "i-Am-Request"},
2564 { 1, "i-Have-Request"},
2565 { 2, "unconfirmedCOVNotification-Request"},
2566 { 3, "unconfirmedEventNotification-Request"},
2567 { 4, "unconfirmedPrivateTransfer-Request"},
2568 { 5, "unconfirmedTextMessage-Request"},
2569 { 6, "timeSynchronization-Request"},
2570 { 7, "who-Has-Request"},
2571 { 8, "who-Is-Request"},
2572 { 9, "utcTimeSynchonization-Request"},
2576 static const value_string
2577 BACnetObjectType [] = {
2578 { 0, "analog-input"},
2579 { 1, "analog-output"},
2580 { 2, "analog-value"},
2581 { 3, "binary-input"},
2582 { 4, "binary-output"},
2583 { 5, "binary-value"},
2587 { 9, "event-enrollment"},
2591 { 13, "multi-state-input"},
2592 { 14, "multi-state-output"},
2593 { 15, "notification-class"},
2597 { 19, "multi-state-value"},
2599 { 21, "life-safety-point"},
2600 { 22, "life-safety-zone"},
2601 { 23, "accumulator"},
2602 { 24, "pulse-converter"},
2604 { 26, "global-group"},
2605 { 27, "trend-log-multiple"},
2606 { 28, "load-control"},
2607 { 29, "structured-view"},
2608 { 30, "access-door"}, /* 30-37 added with addanda 135-2008j */
2609 /* value 31 is unassigned */
2610 { 32, "access-credential"},
2611 { 33, "access-point"},
2612 { 34, "access-rights"},
2613 { 35, "access-user"},
2614 { 36, "access-zone"},
2615 { 37, "credential-data-input"},
2616 { 38, "network-security"},
2617 { 39, "bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2618 { 40, "characterstring-value"},
2619 { 41, "date-pattern-value"},
2620 { 42, "date-value"},
2621 { 43, "datetime-pattern-value"},
2622 { 44, "datetime-value"},
2623 { 45, "integer-value"},
2624 { 46, "large-analog-value"},
2625 { 47, "octetstring-value"},
2626 { 48, "positive-integer-value"},
2627 { 49, "time-pattern-value"},
2628 { 50, "time-value"},
2630 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2631 Enumerated values 128-1023 may be used by others subject to
2632 the procedures and constraints described in Clause 23. */
2635 static const value_string
2636 BACnetEngineeringUnits [] = {
2639 { 2, "Milliamperes"},
2645 { 8, "Volt Amperes"},
2646 { 9, "Kilovolt Amperes"},
2647 { 10, "Megavolt Amperes"},
2648 { 11, "Volt Amperes Reactive"},
2649 { 12, "Kilovolt Amperes Reactive"},
2650 { 13, "Megavolt Amperes Reactive"},
2651 { 14, "Degrees Phase"},
2652 { 15, "Power Factor"},
2654 { 17, "Kilojoules"},
2655 { 18, "Watt Hours"},
2656 { 19, "Kilowatt Hours"},
2660 { 23, "Joules Per Kg Dry Air"},
2661 { 24, "BTUs Per Pound Dry Air"},
2662 { 25, "Cycles Per Hour"},
2663 { 26, "Cycles Per Minute"},
2665 { 28, "Grams Of Water Per Kilogram Dry Air"},
2666 { 29, "Relative Humidity"},
2667 { 30, "Millimeters"},
2671 { 34, "Watts Per Sq Foot"},
2672 { 35, "Watts Per Sq meter"},
2675 { 38, "Foot Candles"},
2677 { 40, "Pounds Mass"},
2679 { 42, "Kgs per Second"},
2680 { 43, "Kgs Per Minute"},
2681 { 44, "Kgs Per Hour"},
2682 { 45, "Pounds Mass Per Minute"},
2683 { 46, "Pounds Mass Per Hour"},
2687 { 50, "BTUs Per Hour"},
2688 { 51, "Horsepower"},
2689 { 52, "Tons Refrigeration"},
2691 { 54, "Kilopascals"},
2693 { 56, "Pounds Force Per Square Inch"},
2694 { 57, "Centimeters Of Water"},
2695 { 58, "Inches Of Water"},
2696 { 59, "Millimeters Of Mercury"},
2697 { 60, "Centimeters Of Mercury"},
2698 { 61, "Inches Of Mercury"},
2699 { 62, "Degrees Celsius"},
2700 { 63, "Degrees Kelvin"},
2701 { 64, "Degrees Fahrenheit"},
2702 { 65, "Degree Days Celsius"},
2703 { 66, "Degree Days Fahrenheit"},
2711 { 74, "Meters Per Second"},
2712 { 75, "Kilometers Per Hour"},
2713 { 76, "Feed Per Second"},
2714 { 77, "Feet Per Minute"},
2715 { 78, "Miles Per Hour"},
2716 { 79, "Cubic Feet"},
2717 { 80, "Cubic Meters"},
2718 { 81, "Imperial Gallons"},
2720 { 83, "US Gallons"},
2721 { 84, "Cubic Feet Per Minute"},
2722 { 85, "Cubic Meters Per Second"},
2723 { 86, "Imperial Gallons Per Minute"},
2724 { 87, "Liters Per Second"},
2725 { 88, "Liters Per Minute"},
2726 { 89, "US Gallons Per Minute"},
2727 { 90, "Degrees Angular"},
2728 { 91, "Degrees Celsius Per Hour"},
2729 { 92, "Degrees Celsius Per Minute"},
2730 { 93, "Degrees Fahrenheit Per Hour"},
2731 { 94, "Degrees Fahrenheit Per Minute"},
2733 { 96, "Parts Per Million"},
2734 { 97, "Parts Per Billion"},
2736 { 99, "Pecent Per Second"},
2737 { 100, "Per Minute"},
2738 { 101, "Per Second"},
2739 { 102, "Psi Per Degree Fahrenheit"},
2741 { 104, "Revolutions Per Min"},
2742 { 105, "Currency1"},
2743 { 106, "Currency2"},
2744 { 107, "Currency3"},
2745 { 108, "Currency4"},
2746 { 109, "Currency5"},
2747 { 110, "Currency6"},
2748 { 111, "Currency7"},
2749 { 112, "Currency8"},
2750 { 113, "Currency9"},
2751 { 114, "Currency10"},
2752 { 115, "Sq Inches"},
2753 { 116, "Sq Centimeters"},
2754 { 117, "BTUs Per Pound"},
2755 { 118, "Centimeters"},
2756 { 119, "Pounds Mass Per Second"},
2757 { 120, "Delta Degrees Fahrenheit"},
2758 { 121, "Delta Degrees Kelvin"},
2761 { 124, "Millivolts"},
2762 { 125, "Kilojoules Per Kg"},
2763 { 126, "Megajoules"},
2764 { 127, "Joules Per Degree Kelvin"},
2765 { 128, "Joules Per Kg Degree Kelvin"},
2766 { 129, "Kilohertz"},
2767 { 130, "Megahertz"},
2769 { 132, "Milliwatts"},
2770 { 133, "Hectopascals"},
2771 { 134, "Millibars"},
2772 { 135, "Cubic Meters Per Hour"},
2773 { 136, "Liters Per Hour"},
2774 { 137, "KWatt Hours Per Square Meter"},
2775 { 138, "KWatt Hours Per Square Foot"},
2776 { 139, "Megajoules Per Square Meter"},
2777 { 140, "Megajoules Per Square Foot"},
2778 { 141, "Watts Per Sq Meter Degree Kelvin"},
2779 { 142, "Cubic Feet Per Second"},
2780 { 143, "Percent Obstruction Per Foot"},
2781 { 144, "Percent Obstruction Per Meter"},
2782 { 145, "milliohms"},
2783 { 146, "megawatt-hours"},
2784 { 147, "kilo-btus"},
2785 { 148, "mega-btus"},
2786 { 149, "kilojoules-per-kilogram-dry-air"},
2787 { 150, "megajoules-per-kilogram-dry-air"},
2788 { 151, "kilojoules-per-degree-Kelvin"},
2789 { 152, "megajoules-per-degree-Kelvin"},
2791 { 154, "grams-per-second"},
2792 { 155, "grams-per-minute"},
2793 { 156, "tons-per-hour"},
2794 { 157, "kilo-btus-per-hour"},
2795 { 158, "hundredths-seconds"},
2796 { 159, "milliseconds"},
2797 { 160, "newton-meters"},
2798 { 161, "millimeters-per-second"},
2799 { 162, "millimeters-per-minute"},
2800 { 163, "meters-per-minute"},
2801 { 164, "meters-per-hour"},
2802 { 165, "cubic-meters-per-minute"},
2803 { 166, "meters-per-second-per-second"},
2804 { 167, "amperes-per-meter"},
2805 { 168, "amperes-per-square-meter"},
2806 { 169, "ampere-square-meters"},
2809 { 172, "ohm-meters"},
2811 { 174, "siemens-per-meter"},
2813 { 176, "volts-per-degree-Kelvin"},
2814 { 177, "volts-per-meter"},
2817 { 180, "candelas-per-square-meter"},
2818 { 181, "degrees-Kelvin-per-hour"},
2819 { 182, "degrees-Kelvin-per-minute"},
2820 { 183, "joule-seconds"},
2821 { 184, "radians-per-second"},
2822 { 185, "square-meters-per-Newton"},
2823 { 186, "kilograms-per-cubic-meter"},
2824 { 187, "newton-seconds"},
2825 { 188, "newtons-per-meter"},
2826 { 189, "watts-per-meter-per-degree-Kelvin"},
2827 { 190, "micro-siemens"},
2828 { 191, "cubic-feet-per-hour"},
2829 { 192, "us-gallons-per-hour"},
2830 { 193, "kilometers"},
2831 { 194, "micrometers"},
2833 { 196, "milligrams"},
2834 { 197, "milliliters"},
2835 { 198, "milliliters-per-second"},
2837 { 200, "decibels-millivolt"},
2838 { 201, "decibels-volt"},
2839 { 202, "millisiemens"},
2840 { 203, "watt-hours-reactive"},
2841 { 204, "kilowatt-hours-reactive"},
2842 { 205, "megawatt-hours-reactive"},
2843 { 206, "millimeters-of-water"},
2844 { 207, "per-mille"},
2845 { 208, "grams-per-gram"},
2846 { 209, "kilograms-per-kilogram"},
2847 { 210, "grams-per-kilogram"},
2848 { 211, "milligrams-per-gram"},
2849 { 212, "milligrams-per-kilogram"},
2850 { 213, "grams-per-milliliter"},
2851 { 214, "grams-per-liter"},
2852 { 215, "milligrams-per-liter"},
2853 { 216, "micrograms-per-liter"},
2854 { 217, "grams-per-cubic-meter"},
2855 { 218, "milligrams-per-cubic-meter"},
2856 { 219, "micrograms-per-cubic-meter"},
2857 { 220, "nanograms-per-cubic-meter"},
2858 { 221, "grams-per-cubic-centimeter"},
2859 { 222, "becquerels"},
2860 { 223, "kilobecquerels"},
2861 { 224, "megabecquerels"},
2863 { 226, "milligray"},
2864 { 227, "microgray"},
2866 { 229, "millisieverts"},
2867 { 230, "microsieverts"},
2868 { 231, "microsieverts-per-hour"},
2869 { 232, "decibels-a"},
2870 { 233, "nephelometric-turbidity-unit"},
2872 { 235, "grams-per-square-meter"},
2873 { 236, "minutes-per-degree-kelvin"},
2875 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2876 Enumerated values 256-65535 may be used by others subject to
2877 the procedures and constraints described in Clause 23. */
2880 static const value_string
2881 BACnetErrorCode [] = {
2883 { 1, "authentication-failed"},
2884 { 2, "configuration-in-progress"},
2885 { 3, "device-busy"},
2886 { 4, "dynamic-creation-not-supported"},
2887 { 5, "file-access-denied"},
2888 { 6, "incompatible-security-levels"},
2889 { 7, "inconsistent-parameters"},
2890 { 8, "inconsistent-selection-criterion"},
2891 { 9, "invalid-data-type"},
2892 { 10, "invalid-file-access-method"},
2893 { 11, "invalid-file-start-position"},
2894 { 12, "invalid-operator-name"},
2895 { 13, "invalid-parameter-data-type"},
2896 { 14, "invalid-time-stamp"},
2897 { 15, "key-generation-error"},
2898 { 16, "missing-required-parameter"},
2899 { 17, "no-objects-of-specified-type"},
2900 { 18, "no-space-for-object"},
2901 { 19, "no-space-to-add-list-element"},
2902 { 20, "no-space-to-write-property"},
2903 { 21, "no-vt-sessions-available"},
2904 { 22, "property-is-not-a-list"},
2905 { 23, "object-deletion-not-permitted"},
2906 { 24, "object-identifier-already-exists"},
2907 { 25, "operational-problem"},
2908 { 26, "password-failure"},
2909 { 27, "read-access-denied"},
2910 { 28, "security-not-supported"},
2911 { 29, "service-request-denied"},
2913 { 31, "unknown-object"},
2914 { 32, "unknown-property"},
2915 { 33, "removed enumeration"},
2916 { 34, "unknown-vt-class"},
2917 { 35, "unknown-vt-session"},
2918 { 36, "unsupported-object-type"},
2919 { 37, "value-out-of-range"},
2920 { 38, "vt-session-already-closed"},
2921 { 39, "vt-session-termination-failure"},
2922 { 40, "write-access-denied"},
2923 { 41, "character-set-not-supported"},
2924 { 42, "invalid-array-index"},
2925 { 43, "cov-subscription-failed"},
2926 { 44, "not-cov-property"},
2927 { 45, "optional-functionality-not-supported"},
2928 { 46, "invalid-configuration-data"},
2929 { 47, "datatype-not-supported"},
2930 { 48, "duplicate-name"},
2931 { 49, "duplicate-object-id"},
2932 { 50, "property-is-not-an-array"},
2933 { 73, "invalid-event-state"},
2934 { 74, "no-alarm-configured"},
2935 { 75, "log-buffer-full"},
2936 { 76, "logged-value-purged"},
2937 { 77, "no-property-specified"},
2938 { 78, "not-configured-for-triggered-logging"},
2939 { 79, "unknown-subscription"},
2940 { 80, "parameter-out-of-range"},
2941 { 81, "list-element-not-found"},
2943 { 83, "communication-disabled"},
2945 { 85, "access-denied"},
2946 { 86, "bad-destination-address"},
2947 { 87, "bad-destination-device-id"},
2948 { 88, "bad-signature"},
2949 { 89, "bad-source-address"},
2950 { 90, "bad-timestamp"},
2951 { 91, "cannot-use-key"},
2952 { 92, "cannot-verify-message-id"},
2953 { 93, "correct-key-revision"},
2954 { 94, "destination-device-id-required"},
2955 { 95, "duplicate-message"},
2956 { 96, "encryption-not-configured"},
2957 { 97, "encryption-required"},
2958 { 98, "incorrect-key"},
2959 { 99, "invalid-key-data"},
2960 { 100, "key-update-in-progress"},
2961 { 101, "malformed-message"},
2962 { 102, "not-key-server"},
2963 { 103, "security-not-configured"},
2964 { 104, "source-security-required"},
2965 { 105, "too-many-keys"},
2966 { 106, "unknown-authentication-type"},
2967 { 107, "unknown-key"},
2968 { 108, "unknown-key-revision"},
2969 { 109, "unknown-source-message"},
2970 { 110, "not-router-to-dnet"},
2971 { 111, "router-busy"},
2972 { 112, "unknown-network-message"},
2973 { 113, "message-too-long"},
2974 { 114, "security-error"},
2975 { 115, "addressing-error"},
2976 { 116, "write-bdt-failed"},
2977 { 117, "read-bdt-failed"},
2978 { 118, "register-foreign-device-failed"},
2979 { 119, "read-fdt-failed"},
2980 { 120, "delete-fdt-entry-failed"},
2981 { 121, "distribute-broadcast-failed"},
2982 { 122, "unknown-file-size"},
2983 { 123, "abort-apdu-too-long"},
2984 { 124, "abort-application-exceeded-reply-time"},
2985 { 125, "abort-out-of-resources"},
2986 { 126, "abort-tsm-timeout"},
2987 { 127, "abort-window-size-out-of-range"},
2988 { 128, "file-full"},
2989 { 129, "inconsistent-configuration"},
2990 { 130, "inconsistent-object-type"},
2991 { 131, "internal-error"},
2992 { 132, "not-configured"},
2993 { 133, "out-of-memory"},
2994 { 134, "value-too-long"},
2995 { 135, "abort-insufficient-security"},
2996 { 136, "abort-security-error"},
2998 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2999 Enumerated values 256-65535 may be used by others subject to the
3000 procedures and constraints described in Clause 23. */
3003 static const value_string
3004 BACnetPropertyIdentifier [] = {
3005 { 0, "acked-transition"},
3006 { 1, "ack-required"},
3008 { 3, "action-text"},
3009 { 4, "active-text"},
3010 { 5, "active-vt-session"},
3011 { 6, "alarm-value"},
3012 { 7, "alarm-values"},
3014 { 9, "all-write-successful"},
3015 { 10, "apdu-segment-timeout"},
3016 { 11, "apdu-timeout"},
3017 { 12, "application-software-version"},
3020 { 15, "change-of-state-count"},
3021 { 16, "change-of-state-time"},
3022 { 17, "notification-class"},
3023 { 18, "the property in this place was deleted"},
3024 { 19, "controlled-variable-reference"},
3025 { 20, "controlled-variable-units"},
3026 { 21, "controlled-variable-value"},
3027 { 22, "cov-increment"},
3029 { 24, "daylights-savings-status"},
3031 { 26, "derivative-constant"},
3032 { 27, "derivative-constant-units"},
3033 { 28, "description"},
3034 { 29, "description-of-halt"},
3035 { 30, "device-address-binding"},
3036 { 31, "device-type"},
3037 { 32, "effective-period"},
3038 { 33, "elapsed-active-time"},
3039 { 34, "error-limit"},
3040 { 35, "event-enable"},
3041 { 36, "event-state"},
3042 { 37, "event-type"},
3043 { 38, "exception-schedule"},
3044 { 39, "fault-values"},
3045 { 40, "feedback-value"},
3046 { 41, "file-access-method"},
3049 { 44, "firmware-revision"},
3050 { 45, "high-limit"},
3051 { 46, "inactive-text"},
3052 { 47, "in-progress"},
3053 { 48, "instance-of"},
3054 { 49, "integral-constant"},
3055 { 50, "integral-constant-units"},
3056 { 51, "issue-confirmed-notifications"},
3057 { 52, "limit-enable"},
3058 { 53, "list-of-group-members"},
3059 { 54, "list-of-object-property-references"},
3060 { 55, "list-of-session-keys"},
3061 { 56, "local-date"},
3062 { 57, "local-time"},
3065 { 60, "manipulated-variable-reference"},
3066 { 61, "maximum-output"},
3067 { 62, "max-apdu-length-accepted"},
3068 { 63, "max-info-frames"},
3069 { 64, "max-master"},
3070 { 65, "max-pres-value"},
3071 { 66, "minimum-off-time"},
3072 { 67, "minimum-on-time"},
3073 { 68, "minimum-output"},
3074 { 69, "min-pres-value"},
3075 { 70, "model-name"},
3076 { 71, "modification-date"},
3077 { 72, "notify-type"},
3078 { 73, "number-of-APDU-retries"},
3079 { 74, "number-of-states"},
3080 { 75, "object-identifier"},
3081 { 76, "object-list"},
3082 { 77, "object-name"},
3083 { 78, "object-property-reference"},
3084 { 79, "object-type"},
3086 { 81, "out-of-service"},
3087 { 82, "output-units"},
3088 { 83, "event-parameters"},
3090 { 85, "present-value"},
3092 { 87, "priority-array"},
3093 { 88, "priority-for-writing"},
3094 { 89, "process-identifier"},
3095 { 90, "program-change"},
3096 { 91, "program-location"},
3097 { 92, "program-state"},
3098 { 93, "proportional-constant"},
3099 { 94, "proportional-constant-units"},
3100 { 95, "protocol-conformance-class"},
3101 { 96, "protocol-object-types-supported"},
3102 { 97, "protocol-services-supported"},
3103 { 98, "protocol-version"},
3105 { 100, "reason-for-halt"},
3106 { 101, "recipient"},
3107 { 102, "recipient-list"},
3108 { 103, "reliability"},
3109 { 104, "relinquish-default"},
3111 { 106, "resolution"},
3112 { 107, "segmentation-supported"},
3114 { 109, "setpoint-reference"},
3115 { 110, "state-text"},
3116 { 111, "status-flags"},
3117 { 112, "system-status"},
3118 { 113, "time-delay"},
3119 { 114, "time-of-active-time-reset"},
3120 { 115, "time-of-state-count-reset"},
3121 { 116, "time-synchronization-recipients"},
3123 { 118, "update-interval"},
3124 { 119, "utc-offset"},
3125 { 120, "vendor-identifier"},
3126 { 121, "vendor-name"},
3127 { 122, "vt-class-supported"},
3128 { 123, "weekly-schedule"},
3129 { 124, "attempted-samples"},
3130 { 125, "average-value"},
3131 { 126, "buffer-size"},
3132 { 127, "client-cov-increment"},
3133 { 128, "cov-resubscription-interval"},
3134 { 129, "current-notify-time"},
3135 { 130, "event-time-stamp"},
3136 { 131, "log-buffer"},
3137 { 132, "log-device-object-property"},
3138 { 133, "enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
3139 { 134, "log-interval"},
3140 { 135, "maximum-value"},
3141 { 136, "minimum-value"},
3142 { 137, "notification-threshold"},
3143 { 138, "previous-notify-time"},
3144 { 139, "protocol-revision"},
3145 { 140, "records-since-notification"},
3146 { 141, "record-count"},
3147 { 142, "start-time"},
3148 { 143, "stop-time"},
3149 { 144, "stop-when-full"},
3150 { 145, "total-record-count"},
3151 { 146, "valid-samples"},
3152 { 147, "window-interval"},
3153 { 148, "window-samples"},
3154 { 149, "maximum-value-time-stamp"},
3155 { 150, "minimum-value-time-stamp"},
3156 { 151, "variance-value"},
3157 { 152, "active-cov-subscriptions"},
3158 { 153, "backup-failure-timeout"},
3159 { 154, "configuration-files"},
3160 { 155, "database-revision"},
3161 { 156, "direct-reading"},
3162 { 157, "last-restore-time"},
3163 { 158, "maintenance-required"},
3164 { 159, "member-of"},
3166 { 161, "operation-expected"},
3169 { 164, "tracking-value"},
3170 { 165, "zone-members"},
3171 { 166, "life-safety-alarm-values"},
3172 { 167, "max-segments-accepted"},
3173 { 168, "profile-name"},
3174 { 169, "auto-slave-discovery"},
3175 { 170, "manual-slave-address-binding"},
3176 { 171, "slave-address-binding"},
3177 { 172, "slave-proxy-enable"},
3178 { 173, "last-notify-record"}, /* bug 4117 */
3179 { 174, "schedule-default"},
3180 { 175, "accepted-modes"},
3181 { 176, "adjust-value"},
3183 { 178, "count-before-change"},
3184 { 179, "count-change-time"},
3185 { 180, "cov-period"},
3186 { 181, "input-reference"},
3187 { 182, "limit-monitoring-interval"},
3188 { 183, "logging-device"},
3189 { 184, "logging-record"},
3191 { 186, "pulse-rate"},
3193 { 188, "scale-factor"},
3194 { 189, "update-time"},
3195 { 190, "value-before-change"},
3196 { 191, "value-set"},
3197 { 192, "value-change-time"},
3198 { 193, "align-intervals"},
3199 { 194, "group-member-names"},
3200 { 195, "interval-offset"},
3201 { 196, "last-restart-reason"},
3202 { 197, "logging-type"},
3203 { 198, "member-status-flags"},
3204 { 199, "notification-period"},
3205 { 200, "previous-notify-record"},
3206 { 201, "requested-update-interval"},
3207 { 202, "restart-notification-recipients"},
3208 { 203, "time-of-device-restart"},
3209 { 204, "time-synchronization-interval"},
3211 { 206, "UTC-time-synchronization-recipients"},
3212 { 207, "node-subtype"},
3213 { 208, "node-type"},
3214 { 209, "structured-object-list"},
3215 { 210, "subordinate-annotations"},
3216 { 211, "subordinate-list"},
3217 { 212, "actual-shed-level"},
3218 { 213, "duty-window"},
3219 { 214, "expected-shed-level"},
3220 { 215, "full-duty-baseline"},
3221 { 216, "node-subtype"},
3222 { 217, "node-type"},
3223 { 218, "requested-shed-level"},
3224 { 219, "shed-duration"},
3225 { 220, "shed-level-descriptions"},
3226 { 221, "shed-levels"},
3227 { 222, "state-description"},
3228 /* enumeration values 223-225 are unassigned */
3229 { 226, "door-alarm-state"},
3230 { 227, "door-extended-pulse-time"},
3231 { 228, "door-members"},
3232 { 229, "door-open-too-long-time"},
3233 { 230, "door-pulse-time"},
3234 { 231, "door-status"},
3235 { 232, "door-unlock-delay-time"},
3236 { 233, "lock-status"},
3237 { 234, "masked-alarm-values"},
3238 { 235, "secured-status"},
3239 /* enumeration values 236-243 are unassigned */
3240 { 244, "absentee-limit"}, /* added with addenda 135-2008j */
3241 { 245, "access-alarm-events"},
3242 { 246, "access-doors"},
3243 { 247, "access-event"},
3244 { 248, "access-event-authentication-factor"},
3245 { 249, "access-event-credential"},
3246 { 250, "access-event-time"},
3247 { 251, "access-transaction-events"},
3248 { 252, "accompaniment"},
3249 { 253, "accompaniment-time"},
3250 { 254, "activation-time"},
3251 { 255, "active-authentication-policy"},
3252 { 256, "assigned-access-rights"},
3253 { 257, "authentication-factors"},
3254 { 258, "authentication-policy-list"},
3255 { 259, "authentication-policy-names"},
3256 { 260, "authentication-status"},
3257 { 261, "authorization-mode"},
3258 { 262, "belongs-to"},
3259 { 263, "credential-disable"},
3260 { 264, "credential-status"},
3261 { 265, "credentials"},
3262 { 266, "credentials-in-zone"},
3263 { 267, "days-remaining"},
3264 { 268, "entry-points"},
3265 { 269, "exit-points"},
3266 { 270, "expiry-time"},
3267 { 271, "extended-time-enable"},
3268 { 272, "failed-attempt-events"},
3269 { 273, "failed-attempts"},
3270 { 274, "failed-attempts-time"},
3271 { 275, "last-access-event"},
3272 { 276, "last-access-point"},
3273 { 277, "last-credential-added"},
3274 { 278, "last-credential-added-time"},
3275 { 279, "last-credential-removed"},
3276 { 280, "last-credential-removed-time"},
3277 { 281, "last-use-time"},
3279 { 283, "lockout-relinquish-time"},
3280 { 284, "master-exemption"},
3281 { 285, "max-failed-attempts"},
3283 { 287, "muster-point"},
3284 { 288, "negative-access-rules"},
3285 { 289, "number-of-authentication-policies"},
3286 { 290, "occupancy-count"},
3287 { 291, "occupancy-count-adjust"},
3288 { 292, "occupancy-count-enable"},
3289 { 293, "occupancy-exemption"},
3290 { 294, "occupancy-lower-limit"},
3291 { 295, "occupancy-lower-limit-enforced"},
3292 { 296, "occupancy-state"},
3293 { 297, "occupancy-upper-limit"},
3294 { 298, "occupancy-upper-limit-enforced"},
3295 { 299, "passback-exemption"},
3296 { 300, "passback-mode"},
3297 { 301, "passback-timeout"},
3298 { 302, "positive-access-rules"},
3299 { 303, "reason-for-disable"},
3300 { 304, "supported-formats"},
3301 { 305, "supported-format-classes"},
3302 { 306, "threat-authority"},
3303 { 307, "threat-level"},
3304 { 308, "trace-flag"},
3305 { 309, "transaction-notification-class"},
3306 { 310, "user-external-identifier"},
3307 { 311, "user-information-reference"},
3308 /* enumeration values 312-316 are unassigned */
3309 { 317, "user-name"},
3310 { 318, "user-type"},
3311 { 319, "uses-remaining"},
3312 { 320, "zone-from"},
3314 { 322, "access-event-tag"},
3315 { 323, "global-identifier"},
3316 /* enumeration values 324-325 reserved for future addenda */
3317 { 326, "verification-time"},
3318 { 327, "base-device-security-policy"},
3319 { 328, "distribution-key-revision"},
3320 { 329, "do-not-hide"},
3322 { 331, "last-key-server"},
3323 { 332, "network-access-security-policies"},
3324 { 333, "packet-reorder-time"},
3325 { 334, "security-pdu-timeout"},
3326 { 335, "security-time-window"},
3327 { 336, "supported-security-algorithms"},
3328 { 337, "update-key-set-timeout"},
3329 { 338, "backup-and-restore-state"},
3330 { 339, "backup-preparation-time"},
3331 { 340, "restore-completion-time"},
3332 { 341, "restore-preparation-time"},
3333 { 342, "bit-mask"}, /* addenda 135-2008w */
3336 { 345, "group-members"},
3337 { 346, "group-member-names"},
3338 { 347, "member-status-flags"},
3339 { 348, "requested-update-interval"},
3340 { 349, "covu-period"},
3341 { 350, "covu-recipients"},
3342 { 351, "event-message-texts"},
3344 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3345 Enumerated values 512-4194303 may be used by others subject to
3346 the procedures and constraints described in Clause 23. */
3349 static const value_string
3350 BACnetBinaryPV [] = {
3358 #define IBM_MS_DBCS 1
3359 #define JIS_C_6226 2
3360 #define ISO_10646_UCS4 3
3361 #define ISO_10646_UCS2 4
3362 #define ISO_18859_1 5
3363 static const value_string
3364 BACnetCharacterSet [] = {
3365 { ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3366 { IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3367 { JIS_C_6226, "JIS C 6226"},
3368 { ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3369 { ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3370 { ISO_18859_1, "ISO 18859-1"},
3374 static const value_string
3375 BACnetStatusFlags [] = {
3379 { 3, "out-of-service"},
3383 static const value_string
3384 BACnetMessagePriority [] = {
3390 static const value_string
3391 BACnetAcknowledgementFilter [] = {
3398 static const value_string
3399 BACnetResultFlags [] = {
3406 static const value_string
3407 BACnetRelationSpecifier [] = {
3411 { 3, "greater-than"},
3412 { 4, "less-than-or-equal"},
3413 { 5, "greater-than-or-equal"},
3417 static const value_string
3418 BACnetSelectionLogic [] = {
3425 static const value_string
3426 BACnetEventStateFilter [] = {
3435 static const value_string
3436 BACnetEventTransitionBits [] = {
3437 { 0, "to-offnormal"},
3443 static const value_string
3444 BACnetSegmentation [] = {
3445 { 0, "segmented-both"},
3446 { 1, "segmented-transmit"},
3447 { 2, "segmented-receive"},
3448 { 3, "no-segmentation"},
3452 static const value_string
3453 BACnetSilencedState [] = {
3455 { 1, "audible-silenced"},
3456 { 2, "visible-silenced"},
3457 { 3, "all-silenced"},
3461 static const value_string
3462 BACnetDeviceStatus [] = {
3463 { 0, "operational"},
3464 { 1, "operational-read-only"},
3465 { 2, "download-required"},
3466 { 3, "download-in-progress"},
3467 { 4, "non-operational"},
3468 { 5, "backup-in-progress"},
3472 static const value_string
3473 BACnetEnableDisable [] = {
3476 { 2, "disable-initiation"},
3480 static const value_string
3494 { 255, "any month" },
3498 static const value_string
3500 { 1, "days numbered 1-7" },
3501 { 2, "days numbered 8-14" },
3502 { 3, "days numbered 15-21" },
3503 { 4, "days numbered 22-28" },
3504 { 5, "days numbered 29-31" },
3505 { 6, "last 7 days of this month" },
3506 { 255, "any week of this month" },
3510 /* note: notification class object recipient-list uses
3511 different day-of-week enum */
3512 static const value_string
3521 { 255, "any day of week" },
3525 static const value_string
3526 BACnetErrorClass [] = {
3534 { 7, "communication" },
3536 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3537 Enumerated values64-65535 may be used by others subject to
3538 the procedures and constraints described in Clause 23. */
3541 static const value_string
3542 BACnetVTClass [] = {
3543 { 0, "default-terminal" },
3544 { 1, "ansi-x3-64" },
3553 static const value_string
3554 BACnetEventType [] = {
3555 { 0, "change-of-bitstring" },
3556 { 1, "change-of-state" },
3557 { 2, "change-of-value" },
3558 { 3, "command-failure" },
3559 { 4, "floating-limit" },
3560 { 5, "out-of-range" },
3561 { 6, "complex-event-type" },
3562 { 7, "buffer-ready" },
3563 { 8, "change-of-life-safety" },
3565 { 10, "buffer-ready" },
3566 { 11, "unsigned-range" },
3567 { 14, "double-out-of-range"}, /* added with addenda 135-2008w */
3568 { 15, "signed-out-of-range"},
3569 { 16, "unsigned-out-of-range"},
3570 { 17, "change-of-characterstring"},
3571 { 18, "change-of-status-flags"},
3573 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3574 Enumerated values 64-65535 may be used by others subject to
3575 the procedures and constraints described in Clause 23.
3576 It is expected that these enumerated values will correspond
3577 to the use of the complex-event-type CHOICE [6] of the
3578 BACnetNotificationParameters production. */
3581 static const value_string
3582 BACnetEventState [] = {
3586 { 3, "high-limit" },
3588 { 5, "life-safety-alarm" },
3590 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3591 Enumerated values 64-65535 may be used by others subject to
3592 the procedures and constraints described in Clause 23. */
3595 static const value_string
3596 BACnetLogStatus [] = {
3597 { 0, "log-disabled" },
3598 { 1, "buffer-purged" },
3599 { 2, "log-interrupted"},
3603 static const value_string
3604 BACnetMaintenance [] = {
3606 { 1, "periodic-test" },
3607 { 2, "need-service-operational" },
3608 { 3, "need-service-inoperative" },
3612 static const value_string
3613 BACnetNotifyType [] = {
3616 { 2, "ack-notification" },
3620 static const value_string
3621 BACnetServicesSupported [] = {
3622 { 0, "acknowledgeAlarm"},
3623 { 1, "confirmedCOVNotification"},
3624 { 2, "confirmedEventNotification"},
3625 { 3, "getAlarmSummary"},
3626 { 4, "getEnrollmentSummary"},
3627 { 5, "subscribeCOV"},
3628 { 6, "atomicReadFile"},
3629 { 7, "atomicWriteFile"},
3630 { 8, "addListElement"},
3631 { 9, "removeListElement"},
3632 { 10, "createObject"},
3633 { 11, "deleteObject"},
3634 { 12, "readProperty"},
3635 { 13, "readPropertyConditional"},
3636 { 14, "readPropertyMultiple"},
3637 { 15, "writeProperty"},
3638 { 16, "writePropertyMultiple"},
3639 { 17, "deviceCommunicationControl"},
3640 { 18, "confirmedPrivateTransfer"},
3641 { 19, "confirmedTextMessage"},
3642 { 20, "reinitializeDevice"},
3646 { 24, "authenticate"},
3647 { 25, "requestKey"},
3650 { 28, "unconfirmedCOVNotification"},
3651 { 29, "unconfirmedEventNotification"},
3652 { 30, "unconfirmedPrivateTransfer"},
3653 { 31, "unconfirmedTextMessage"},
3654 { 32, "timeSynchronization"},
3658 { 36, "utcTimeSynchronization"},
3659 { 37, "lifeSafetyOperation"},
3660 { 38, "subscribeCOVProperty"},
3661 { 39, "getEventInformation"},
3665 static const value_string
3666 BACnetPropertyStates [] = {
3667 { 0, "boolean-value"},
3668 { 1, "binary-value"},
3671 { 4, "program-change"},
3672 { 5, "program-state"},
3673 { 6, "reason-for-halt"},
3674 { 7, "reliability"},
3676 { 9, "system-status"},
3678 { 11, "unsigned-value"},
3679 { 12, "life-safety-mode"},
3680 { 13, "life-safety-state"},
3681 { 14, "restart-reason"},
3682 { 15, "door-alarm-state"},
3684 { 17, "door-secured-status"},
3685 { 18, "door-status"},
3686 { 19, "door-value"},
3687 { 20, "file-access-method"},
3688 { 21, "lock-status"},
3689 { 22, "life-safety-operation"},
3690 { 23, "maintenance"},
3692 { 25, "notify-type"},
3693 { 26, "security-level"},
3694 { 27, "shed-state"},
3695 { 28, "silenced-state"},
3696 /* context tag 29 reserved for future addenda */
3697 { 29, "unknown-29"},
3698 { 30, "access-event"},
3699 { 31, "zone-occupancy-state"},
3700 { 32, "access-credential-disable-reason"},
3701 { 33, "access-credential-disable"},
3702 { 34, "authentication-status"},
3703 { 35, "unknown-35"},
3704 { 36, "backup-state"},
3706 /* Tag values 0-63 are reserved for definition by ASHRAE.
3707 Tag values of 64-254 may be used by others to accommodate
3708 vendor specific properties that have discrete or enumerated values,
3709 subject to the constraints described in Clause 23. */
3712 static const value_string
3713 BACnetProgramError [] = {
3715 { 1, "load-failed"},
3720 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3721 Enumerated values 64-65535 may be used by others subject to
3722 the procedures and constraints described in Clause 23. */
3725 static const value_string
3726 BACnetProgramRequest [] = {
3736 static const value_string
3737 BACnetProgramState [] = {
3747 static const value_string
3748 BACnetReinitializedStateOfDevice [] = {
3751 { 2, "startbackup"},
3753 { 4, "startrestore"},
3755 { 6, "abortrestore"},
3759 static const value_string
3760 BACnetPolarity [] = {
3766 static const value_string
3767 BACnetTagNames[] = {
3768 { 5, "Extended Value" },
3769 { 6, "Opening Tag" },
3770 { 7, "Closing Tag" },
3774 static const value_string
3775 BACnetReadRangeOptions[] = {
3776 { 3, "range byPosition" },
3777 { 4, "range byTime" },
3778 { 5, "range timeRange" },
3779 { 6, "range bySequenceNumber" },
3780 { 7, "range byTime" },
3784 /* Present_Value for Load Control Object */
3785 static const value_string
3786 BACnetShedState[] = {
3787 { 0, "shed-inactive" },
3788 { 1, "shed-request-pending" },
3789 { 2, "shed-compliant" },
3790 { 3, "shed-non-compliant" },
3794 static const value_string
3795 BACnetNodeType [] = {
3800 { 4, "organizational" },
3804 { 8, "collection" },
3806 { 10, "functional" },
3811 static const value_string
3812 BACnetLoggingType [] = {
3819 static const value_string
3820 BACnetDoorStatus [] = {
3827 static const value_string
3828 BACnetLockStatus [] = {
3836 static const value_string
3837 BACnetDoorSecuredStatus [] = {
3844 static const value_string
3845 BACnetDoorAlarmState [] = {
3848 { 2, "door-open-too-long" },
3849 { 3, "forced-open" },
3851 { 5, "door-fault" },
3853 { 7, "free-access" },
3854 { 8, "egress-open" },
3858 static const value_string
3859 BACnetAccumulatorStatus [] = {
3868 static const value_string
3869 BACnetVendorIdentifiers [] = {
3872 { 2, "The Trane Company" },
3873 { 3, "McQuay International" },
3875 { 5, "Johnson Controls, Inc." },
3876 { 6, "American Auto-Matrix" },
3877 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3878 { 8, "Delta Controls" },
3879 { 9, "Siemens Building Technologies, Inc." },
3880 { 10, "Tour Andover Controls Corporation" },
3882 { 12, "Orion Analysis Corporation" },
3883 { 13, "Teletrol Systems Inc." },
3884 { 14, "Cimetrics Technology" },
3885 { 15, "Cornell University" },
3886 { 16, "United Technologies Carrier" },
3887 { 17, "Honeywell Inc." },
3888 { 18, "Alerton / Honeywell" },
3890 { 20, "Hewlett-Packard Company" },
3891 { 21, "Dorsette's Inc." },
3892 { 22, "Cerberus AG" },
3893 { 23, "York Controls Group" },
3894 { 24, "Automated Logic Corporation" },
3895 { 25, "CSI Control Systems International" },
3896 { 26, "Phoenix Controls Corporation" },
3897 { 27, "Innovex Technologies, Inc." },
3898 { 28, "KMC Controls, Inc." },
3899 { 29, "Xn Technologies, Inc." },
3900 { 30, "Hyundai Information Technology Co., Ltd." },
3901 { 31, "Tokimec Inc." },
3903 { 33, "North Communications Limited" },
3905 { 35, "Reliable Controls Corporation" },
3906 { 36, "Tridium Inc." },
3907 { 37, "Sierra Monitor Corp." },
3908 { 38, "Silicon Energy" },
3909 { 39, "Kieback & Peter GmbH & Co KG" },
3910 { 40, "Anacon Systems, Inc." },
3911 { 41, "Systems Controls & Instruments, LLC" },
3912 { 42, "Lithonia Lighting" },
3913 { 43, "Micropower Manufacturing" },
3914 { 44, "Matrix Controls" },
3915 { 45, "METALAIRE" },
3916 { 46, "ESS Engineering" },
3917 { 47, "Sphere Systems Pty Ltd." },
3918 { 48, "Walker Technologies Corporation" },
3919 { 49, "H I Solutions, Inc." },
3921 { 51, "SAMSON AG" },
3922 { 52, "Badger Meter Inc." },
3923 { 53, "DAIKIN Industries Ltd." },
3924 { 54, "NARA Controls Inc." },
3925 { 55, "Mammoth Inc." },
3926 { 56, "Liebert Corporation" },
3927 { 57, "SEMCO Incorporated" },
3928 { 58, "Air Monitor Corporation" },
3929 { 59, "TRIATEK, Inc." },
3931 { 61, "Multistack" },
3932 { 62, "TSI Incorporated" },
3933 { 63, "Weather-Rite, Inc." },
3934 { 64, "Dunham-Bush" },
3935 { 65, "Reliance Electric" },
3937 { 67, "Regulator Australia PTY Ltd." },
3938 { 68, "Touch-Plate Lighting Controls" },
3939 { 69, "Amann GmbH" },
3940 { 70, "RLE Technologies" },
3941 { 71, "Cardkey Systems" },
3942 { 72, "SECOM Co., Ltd." },
3943 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3944 { 74, "KNX Association cvba" },
3945 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3946 { 76, "Nohmi Bosai, Ltd." },
3947 { 77, "Carel S.p.A." },
3948 { 78, "AirSense Technology, Inc." },
3949 { 79, "Hochiki Corporation" },
3950 { 80, "Fr. Sauter AG" },
3951 { 81, "Matsushita Electric Works, Ltd." },
3952 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3953 { 83, "Mitsubishi Heavy Industries, Ltd." },
3954 { 84, "ITT Bell & Gossett" },
3955 { 85, "Yamatake Building Systems Co., Ltd." },
3956 { 86, "The Watt Stopper, Inc." },
3957 { 87, "Aichi Tokei Denki Co., Ltd." },
3958 { 88, "Activation Technologies, LLC" },
3959 { 89, "Saia-Burgess Controls, Ltd." },
3960 { 90, "Hitachi, Ltd." },
3961 { 91, "Novar Corp./Trend Control Systems Ltd." },
3962 { 92, "Mitsubishi Electric Lighting Corporation" },
3963 { 93, "Argus Control Systems, Ltd." },
3964 { 94, "Kyuki Corporation" },
3965 { 95, "Richards-Zeta Building Intelligence, Inc." },
3966 { 96, "Scientech R&D, Inc." },
3967 { 97, "VCI Controls, Inc." },
3968 { 98, "Toshiba Corporation" },
3969 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3970 { 100, "Custom Mechanical Equipment, LLC" },
3971 { 101, "ClimateMaster" },
3972 { 102, "ICP Panel-Tec, Inc." },
3973 { 103, "D-Tek Controls" },
3974 { 104, "NEC Engineering, Ltd." },
3975 { 105, "PRIVA BV" },
3976 { 106, "Meidensha Corporation" },
3977 { 107, "JCI Systems Integration Services" },
3978 { 108, "Freedom Corporation" },
3979 { 109, "Neuberger Gebaudeautomation GmbH" },
3980 { 110, "Sitronix" },
3981 { 111, "Leviton Manufacturing" },
3982 { 112, "Fujitsu Limited" },
3983 { 113, "Emerson Network Power" },
3984 { 114, "S. A. Armstrong, Ltd." },
3985 { 115, "Visonet AG" },
3986 { 116, "M&M Systems, Inc." },
3987 { 117, "Custom Software Engineering" },
3988 { 118, "Nittan Company, Limited" },
3989 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3990 { 120, "Pacom Systems Pty., Ltd." },
3991 { 121, "Unico, Inc." },
3992 { 122, "Ebtron, Inc." },
3993 { 123, "Scada Engine" },
3994 { 124, "AC Technology Corporation" },
3995 { 125, "Eagle Technology" },
3996 { 126, "Data Aire, Inc." },
3997 { 127, "ABB, Inc." },
3998 { 128, "Transbit Sp. z o. o." },
3999 { 129, "Toshiba Carrier Corporation" },
4000 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
4001 { 131, "Tokai Soft" },
4003 { 133, "Veris Industries" },
4004 { 134, "Centaurus Prime" },
4005 { 135, "Sand Network Systems" },
4006 { 136, "Regulvar, Inc." },
4007 { 137, "Fastek International, Ltd." },
4008 { 138, "PowerCold Comfort Air Solutions, Inc." },
4009 { 139, "I Controls" },
4010 { 140, "Viconics Electronics, Inc." },
4011 { 141, "Yaskawa Electric America, Inc." },
4012 { 142, "Plueth Regelsysteme" },
4013 { 143, "Digitale Mess- und Steuersysteme AG" },
4014 { 144, "Fujitsu General Limited" },
4015 { 145, "Project Engineering S.r.l." },
4016 { 146, "Sanyo Electric Co., Ltd." },
4017 { 147, "Integrated Information Systems, Inc." },
4018 { 148, "Temco Controls, Ltd." },
4019 { 149, "Airtek Technologies, Inc." },
4020 { 150, "Advantech Corporation" },
4021 { 151, "Titan Products, Ltd." },
4022 { 152, "Regel Partners" },
4023 { 153, "National Environmental Product" },
4024 { 154, "Unitec Corporation" },
4025 { 155, "Kanden Engineering Company" },
4026 { 156, "Messner Gebaudetechnik GmbH" },
4027 { 157, "Integrated.CH" },
4028 { 158, "EH Price Limited" },
4029 { 159, "SE-Elektronic GmbH" },
4030 { 160, "Rockwell Automation" },
4031 { 161, "Enflex Corp." },
4032 { 162, "ASI Controls" },
4033 { 163, "SysMik GmbH Dresden" },
4034 { 164, "HSC Regelungstechnik GmbH" },
4035 { 165, "Smart Temp Australia Pty. Ltd." },
4036 { 166, "PCI Lighting Control Systems" },
4037 { 167, "Duksan Mecasys Co., Ltd." },
4038 { 168, "Fuji IT Co., Ltd." },
4039 { 169, "Vacon Plc" },
4040 { 170, "Leader Controls" },
4041 { 171, "Cylon Controls, Ltd." },
4043 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
4044 { 174, "Building Control Integrators" },
4045 { 175, "ITG Worldwide (M) Sdn Bhd" },
4046 { 176, "Lutron Electronics Co., Inc." },
4047 { 177, "Cooper-Atkins Corporation" },
4048 { 178, "LOYTEC Electronics GmbH" },
4050 { 180, "Mega Controls Limited" },
4051 { 181, "Micro Control Systems, Inc." },
4052 { 182, "Kiyon, Inc." },
4053 { 183, "Dust Networks" },
4054 { 184, "Advanced Building Automation Systems" },
4055 { 185, "Hermos AG" },
4058 { 188, "Lynxspring" },
4059 { 189, "Schneider Toshiba Inverter Europe" },
4060 { 190, "Danfoss Drives A/S" },
4061 { 191, "Eaton Corporation" },
4062 { 192, "Matyca S.A." },
4063 { 193, "Botech AB" },
4064 { 194, "Noveo, Inc." },
4066 { 196, "Yokogawa Electric Corporation" },
4067 { 197, "GFR Gesellschaft fur Regelungstechnik" },
4068 { 198, "Exact Logic" },
4069 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
4070 { 200, "Kandenko Co., Ltd." },
4071 { 201, "DTF, Daten-Technik Fries" },
4072 { 202, "Klimasoft, Ltd." },
4073 { 203, "Toshiba Schneider Inverter Corporation" },
4074 { 204, "Control Applications, Ltd." },
4075 { 205, "KDT Systems Co., Ltd." },
4076 { 206, "Onicon Incorporated" },
4077 { 207, "Automation Displays, Inc." },
4078 { 208, "Control Solutions, Inc." },
4079 { 209, "Remsdaq Limited" },
4080 { 210, "NTT Facilities, Inc." },
4081 { 211, "VIPA GmbH" },
4082 { 212, "TSC21 Association of Japan" },
4083 { 213, "BBP Energie Ltee" },
4084 { 214, "HRW Limited" },
4085 { 215, "Lighting Control & Design, Inc." },
4086 { 216, "Mercy Electronic and Electrical Industries" },
4087 { 217, "Samsung SDS Co., Ltd" },
4088 { 218, "Impact Facility Solutions, Inc." },
4089 { 219, "Aircuity" },
4090 { 220, "Control Techniques, Ltd." },
4091 { 221, "Evolve Control Systems, LLC" },
4092 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
4093 { 223, "Cerus Industrial" },
4094 { 224, "Chloride Power Protection Company" },
4095 { 225, "Computrols, Inc." },
4096 { 226, "Phoenix Contact GmbH & Co. KG" },
4097 { 227, "Grundfos Management A/S" },
4098 { 228, "Ridder Drive Systems" },
4099 { 229, "Soft Device SDN BHD" },
4100 { 230, "Integrated Control Technology Limited" },
4101 { 231, "AIRxpert Systems, Inc." },
4102 { 232, "Microtrol Limited" },
4103 { 233, "Red Lion Controls" },
4104 { 234, "Digital Electronics Corporation" },
4105 { 235, "Ennovatis GmbH" },
4106 { 236, "Serotonin Software Technologies, Inc." },
4107 { 237, "LS Industrial Systems Co., Ltd." },
4108 { 238, "Square D Company" },
4109 { 239, "S Squared Innovations, Inc." },
4110 { 240, "Aricent Ltd." },
4111 { 241, "EtherMetrics, LLC" },
4112 { 242, "Industrial Control Communications, Inc." },
4113 { 243, "Paragon Controls, Inc." },
4114 { 244, "A. O. Smith Corporation" },
4115 { 245, "Contemporary Control Systems, Inc." },
4116 { 246, "Intesis Software SL" },
4117 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
4118 { 248, "Heat-Timer Corporation" },
4119 { 249, "Ingrasys Technology, Inc." },
4120 { 250, "Costerm Building Automation" },
4122 { 252, "Embedia Technologies Corp." },
4123 { 253, "Technilog" },
4124 { 254, "HR Controls Ltd. & Co. KG" },
4125 { 255, "Lennox International, Inc." },
4126 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
4127 { 257, "Thermomax, Ltd." },
4128 { 258, "ELCON Electronic Control, Ltd." },
4129 { 259, "Larmia Control AB" },
4130 { 260, "BACnet Stack at SourceForge" },
4131 { 261, "G4S Security Services A/S" },
4132 { 262, "Sitek S.p.A." },
4133 { 263, "Cristal Controles" },
4134 { 264, "Regin AB" },
4135 { 265, "Dimension Software, Inc. " },
4136 { 266, "SynapSense Corporation" },
4137 { 267, "Beijing Nantree Electronic Co., Ltd." },
4138 { 268, "Camus Hydronics Ltd." },
4139 { 269, "Kawasaki Heavy Industries, Ltd. " },
4140 { 270, "Critical Environment Technologies" },
4141 { 271, "ILSHIN IBS Co., Ltd." },
4142 { 272, "ELESTA Energy Control AG" },
4143 { 273, "KROPMAN Installatietechniek" },
4144 { 274, "Baldor Electric Company" },
4145 { 275, "INGA mbH" },
4146 { 276, "GE Consumer & Industrial" },
4147 { 277, "Functional Devices, Inc." },
4149 { 279, "M-System Co., Ltd." },
4150 { 280, "Yokota Co., Ltd." },
4151 { 281, "Hitranse Technology Co., LTD" },
4152 { 282, "Federspiel Controls" },
4153 { 283, "Kele, Inc." },
4154 { 284, "Opera Electronics, Inc." },
4156 { 286, "Embedded Science Labs, LLC" },
4157 { 287, "Parker Hannifin Corporation" },
4158 { 288, "MaCaPS International Limited" },
4159 { 289, "Link4 Corporation" },
4160 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
4161 { 291, "Pribusin, Inc." },
4162 { 292, "Advantage Controls" },
4163 { 293, "Critical Room Control" },
4165 { 295, "Tongdy Control Technology Co., Ltd." },
4166 { 296, "ISSARO Integrierte Systemtechnik" },
4167 { 297, "Pro-Dev Industries" },
4168 { 298, "DRI-STEEM" },
4169 { 299, "Creative Electronic GmbH" },
4170 { 300, "Swegon AB" },
4171 { 301, "Jan Brachacek" },
4172 { 302, "Hitachi Appliances, Inc." },
4173 { 303, "Real Time Automation, Inc." },
4174 { 304, "ITEC Hankyu-Hanshin Co." },
4175 { 305, "Cyrus E&M Engineering Co., Ltd." },
4176 { 306, "Racine Federated, Inc." },
4177 { 307, "Verari Systems, Inc." },
4178 { 308, "Elesta GmbH Building Automation" },
4179 { 309, "Securiton" },
4180 { 310, "OSlsoft, Inc." },
4181 { 311, "Hanazeder Electronic GmbH" },
4182 { 312, "Honeywell Security Deutschland, Novar GmbH" },
4183 { 313, "Siemens Energy & Automation, Inc." },
4184 { 314, "ETM Professional Control GmbH" },
4185 { 315, "Meitav-tec, Ltd." },
4186 { 316, "Janitza Electronics GmbH" },
4187 { 317, "MKS Nordhausen" },
4188 { 318, "De Gier Drive Systems B.V." },
4189 { 319, "Cypress Envirosystems" },
4190 { 320, "SMARTron s.r.o." },
4191 { 321, "Verari Systems, Inc." },
4192 { 322, "K-W Electronic Service, Inc." },
4193 { 323, "ALFA-SMART Energy Management" },
4194 { 324, "Telkonet, Inc." },
4195 { 325, "Securiton GmbH" },
4196 { 326, "Cemtrex, Inc." },
4197 { 327, "Performance Technologies, Inc." },
4198 { 328, "Xtralis (Aust) Pty Ltd" },
4199 { 329, "TROX GmbH" },
4200 { 330, "Beijing Hysine Technology Co., Ltd" },
4201 { 331, "RCK Controls, Inc." },
4203 { 333, "Novar/Honeywell" },
4204 { 334, "The S4 Group, Inc." },
4205 { 335, "Schneider Electric" },
4206 { 336, "LHA Systems" },
4207 { 337, "GHM engineering Group, Inc." },
4208 { 338, "Cllimalux S.A." },
4209 { 339, "VAISALA Oyj" },
4210 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
4211 { 342, "POWERPEG NSI Limited" },
4212 { 343, "BACnet Interoperability Testing Services, Inc." },
4213 { 344, "Teco a.s." },
4214 { 345, "Plexus Technology Limited"},
4215 { 346, "Energy Focus, Inc."},
4216 { 347, "Powersmiths International Corp."},
4217 { 348, "Nichibei Co., Ltd."},
4218 { 349, "HKC Technology Ltd."},
4219 { 350, "Ovation Networks, Inc."},
4220 { 351, "Setra Systems"},
4221 { 352, "AVG Automation"},
4223 { 354, "Byte Sphere"},
4224 { 355, "Generiton Co., Ltd."},
4225 { 356, "Holter Regelarmaturen GmbH & Co. KG"},
4226 { 357, "Bedford Instruments, LLC"},
4227 { 358, "Standair Inc."},
4228 { 359, "WEG Automation - R&D"},
4229 { 360, "Prolon Control Systems ApS"},
4230 { 361, "Inneasoft"},
4231 { 362, "ConneXSoft GmbH"},
4232 { 363, "CEAG Notlichtsysteme GmbH"},
4233 { 364, "Distech Controls Inc."},
4234 { 365, "Industrial Technology Research Institute"},
4235 { 366, "ICONICS, Inc."},
4236 { 367, "IQ Controls s.c."},
4237 { 368, "OJ Electronics A/S"},
4238 { 369, "Rolbit Ltd."},
4239 { 370, "Synapsys Solutions Ltd."},
4240 { 371, "ACME Engineering Prod. Ltd."},
4241 { 372, "Zener Electric Pty, Ltd."},
4242 { 373, "Selectronix, Inc."},
4243 { 374, "Gorbet & Banerjee, LLC."},
4245 { 376, "Stephen H. Dawson Computer Service"},
4246 { 377, "Accutrol, LLC"},
4247 { 378, "Schneider Elektronik GmbH"},
4248 { 379, "Alpha-Inno Tec GmbH"},
4249 { 380, "ADMMicro, Inc."},
4250 { 381, "Greystone Energy Systems, Inc."},
4251 { 382, "CAP Technologie"},
4252 { 383, "KeRo Systems"},
4253 { 384, "Domat Control System s.r.o."},
4254 { 385, "Efektronics Pty. Ltd."},
4255 { 386, "Hekatron Vertriebs GmbH"},
4256 { 387, "Securiton AG"},
4257 { 388, "Carlo Gavazzi Controls SpA"},
4258 { 389, "Chipkin Automation Systems"},
4259 { 390, "Savant Systems, LLC"},
4260 { 391, "Simmtronic Lighting Controls"},
4261 { 392, "Abelko Innovation AB"},
4262 { 393, "Seresco Technologies Inc."},
4263 { 394, "IT Watchdogs"},
4264 { 395, "Automation Assist Japan Corp."},
4265 { 396, "Thermokon Sensortechnik GmbH"},
4266 { 397, "EGauge Systems, LLC"},
4267 { 398, "Quantum Automation (ASIA) PTE, Ltd."},
4268 { 399, "Toshiba Lighting & Technology Corp."},
4269 { 400, "SPIN Engenharia de Automaca Ltda."},
4270 { 401, "Logistics Systems & Software Services India PVT. Ltd."},
4271 { 402, "Delta Controls Integration Products"},
4272 { 403, "Focus Media"},
4273 { 404, "LUMEnergi Inc."},
4274 { 405, "Kara Systems"},
4275 { 406, "RF Code, Inc."},
4276 { 407, "Fatek Automation Corp."},
4277 { 408, "JANDA Software Company, LLC"},
4278 { 409, "Open System Solutions Limited"},
4279 { 410, "Intelec Systems PTY Ltd."},
4280 { 411, "Ecolodgix, LLC"},
4281 { 412, "Douglas Lighting Controls"},
4282 { 413, "iSAtech GmbH intelligente Sensoren Aktoren technologie"},
4284 { 415, "Beckhoff Automation GmbH"},
4285 { 416, "IPAS GmbH"},
4286 { 417, "KE2 Therm Solutions"},
4287 { 418, "Base2Products"},
4288 { 419, "DTL Controls, LLC"},
4289 { 420, "INNCOM International, Inc."},
4290 { 421, "BTR Netcom GmbH"},
4291 { 422, "Greentrol Automation, Inc"},
4292 { 423, "BELIMO Automation AG"},
4293 { 424, "Samsung Heavy Industries Co, Ltd"},
4294 { 425, "Triacta Power Technologies, Inc."},
4295 { 426, "Globestar Systems"},
4296 { 427, "MLB Advanced Media, LP"},
4297 { 428, "SWG Stuckmann Wirtschaftliche Gebaudesysteme GmbH"},
4298 { 429, "SensorSwitch"},
4299 { 430, "Multitek Power Limited"},
4300 { 431, "Aquametro AG"},
4301 { 432, "LG Electronics Inc."},
4302 { 433, "Electronic Theatre Controls, Inc."},
4303 { 434, "Mitsubishi Electric Corporation Nagoya Works"},
4304 { 435, "Delta Electronics, Inc."},
4305 { 436, "Elma Kurtalj, Ltd."},
4306 { 437, "ADT Fire and Security Sp. A.o.o."},
4307 { 438, "Nedap Security Management"},
4308 { 439, "ESC Automation Inc."},
4309 { 440, "DSP4YOU Ltd."},
4310 { 441, "GE Sensing and Inspection Technologies"},
4311 { 442, "Embedded Systems SIA"},
4312 { 443, "BEFEGA GmbH"},
4313 { 444, "Baseline Inc."},
4314 { 445, "M2M Systems Integrators"},
4316 { 447, "Clarkson Controls Limited"},
4317 { 448, "Rogerwell Control System Limited"},
4318 { 449, "SCL Elements"},
4319 { 450, "Hitachi Ltd."},
4320 { 451, "Newron System SA"},
4321 { 452, "BEVECO Gebouwautomatisering BV"},
4322 { 453, "Streamside Solutions"},
4323 { 454, "Yellowstone Soft"},
4324 { 455, "Oztech Intelligent Systems Pty Ltd."},
4325 { 456, "Novelan GmbH"},
4326 { 457, "Flexim Americas Corporation"},
4327 { 458, "ICP DAS Co., Ltd."},
4328 { 459, "CARMA Industries Inc."},
4329 { 460, "Log-One Ltd."},
4330 { 461, "TECO Electric & Machinery Co., Ltd."},
4331 { 462, "ConnectEx, Inc."},
4332 { 463, "Turbo DDC Sudwest"},
4333 { 464, "Quatrosense Environmental Ltd."},
4334 { 465, "Fifth Light Technology Ltd."},
4335 { 466, "Scientific Solutions, Ltd."},
4336 { 467, "Controller Area Network Solutions (M) Sdn Bhd"},
4337 { 468, "RESOL - Elektronische Regelungen GmbH"},
4338 { 469, "RPBUS LLC"},
4339 { 470, "BRS Sistemas Eletronicos"},
4340 { 471, "WindowMaster A/S"},
4341 { 472, "Sunlux Technologies Ltd."},
4342 { 473, "Measurlogic"},
4343 { 474, "Frimat GmbH"},
4344 { 475, "Spirax Sarco"},
4346 { 477, "Raypak Inc"},
4347 { 478, "Air Monitor Corporation"},
4348 { 479, "Regler Och Webbteknik Sverige (ROWS)"},
4349 { 480, "Intelligent Lighting Controls Inc."},
4350 { 481, "Sanyo Electric Industry Co., Ltd"},
4351 { 482, "E-Mon Energy Monitoring Products"},
4352 { 483, "Digital Control Systems"},
4353 { 484, "ATI Airtest Technologies, Inc."},
4355 { 486, "HMS Industrial Networks AB"},
4356 { 487, "Shenzhen Universal Intellisys Co Ltd"},
4357 { 488, "EK Intellisys Sdn Bhd"},
4359 { 490, "Firecom, Inc."},
4360 { 491, "ESA Elektroschaltanlagen Grimma GmbH"},
4361 { 492, "Kumahira Co Ltd"},
4363 { 494, "SABO Elektronik GmbH"},
4364 { 495, "Equip'Trans"},
4365 { 496, "TCS Basys Controls"},
4366 { 497, "FlowCon International A/S"},
4367 { 498, "ThyssenKrupp Elevator Americas"},
4368 { 499, "Abatement Technologies"},
4369 { 500, "Continental Control Systems, LLC"},
4370 { 501, "WISAG Automatisierungstechnik GmbH & Co KG"},
4372 { 503, "EAP-Electric GmbH"},
4373 { 504, "Hardmeier"},
4374 { 505, "Mircom Group of Companies"},
4375 { 506, "Quest Controls"},
4376 { 507, "Mestek, Inc"},
4377 { 508, "Pulse Energy"},
4378 { 509, "Tachikawa Corporation"},
4379 { 510, "University of Nebraska-Lincoln"},
4380 { 511, "Redwood Systems"},
4381 { 512, "PASStec Industrie-Elektronik GmbH"},
4382 { 513, "NgEK, Inc."},
4383 { 514, "FAW Electronics Ltd"},
4384 { 515, "Jireh Energy Tech Co., Ltd."},
4385 { 516, "Enlighted Inc."},
4386 { 517, "El-Piast Sp. Z o.o"},
4387 { 518, "NetxAutomation Software GmbH"},
4388 { 519, "Invertek Drives"},
4389 { 520, "Deutschmann Automation GmbH & Co. KG"},
4390 { 521, "EMU Electronic AG"},
4391 { 522, "Phaedrus Limited"},
4392 { 523, "Sigmatek GmbH & Co KG"},
4393 { 524, "Marlin Controls"},
4394 { 525, "Circutor, SA"},
4395 { 526, "UTC Fire & Security"},
4396 { 527, "DENT Instruments, Inc."},
4397 { 528, "FHP Manufacturing Company - Bosch Group"},
4398 { 529, "GE Intelligent Platforms"},
4399 { 530, "Inner Range Pty Ltd"},
4400 { 531, "GLAS Energy Technology"},
4401 { 532, "MSR-Electronic-GmbH"},
4405 static int proto_bacapp = -1;
4406 static int hf_bacapp_type = -1;
4407 static int hf_bacapp_pduflags = -1;
4408 static int hf_bacapp_SEG = -1;
4409 static int hf_bacapp_MOR = -1;
4410 static int hf_bacapp_SA = -1;
4411 static int hf_bacapp_response_segments = -1;
4412 static int hf_bacapp_max_adpu_size = -1;
4413 static int hf_bacapp_invoke_id = -1;
4414 static int hf_bacapp_objectType = -1;
4415 static int hf_bacapp_instanceNumber = -1;
4416 static int hf_bacapp_sequence_number = -1;
4417 static int hf_bacapp_window_size = -1;
4418 static int hf_bacapp_service = -1;
4419 static int hf_bacapp_NAK = -1;
4420 static int hf_bacapp_SRV = -1;
4421 static int hf_Device_Instance_Range_Low_Limit = -1;
4422 static int hf_Device_Instance_Range_High_Limit = -1;
4423 static int hf_BACnetRejectReason = -1;
4424 static int hf_BACnetAbortReason = -1;
4425 static int hf_BACnetApplicationTagNumber = -1;
4426 static int hf_BACnetContextTagNumber = -1;
4427 static int hf_BACnetExtendedTagNumber = -1;
4428 static int hf_BACnetNamedTag = -1;
4429 static int hf_BACnetTagClass = -1;
4430 static int hf_BACnetCharacterSet = -1;
4431 static int hf_bacapp_tag_lvt = -1;
4432 static int hf_bacapp_tag_ProcessId = -1;
4433 static int hf_bacapp_uservice = -1;
4434 static int hf_BACnetPropertyIdentifier = -1;
4435 static int hf_BACnetVendorIdentifier = -1;
4436 static int hf_BACnetRestartReason = -1;
4437 static int hf_bacapp_tag_IPV4 = -1;
4438 static int hf_bacapp_tag_IPV6 = -1;
4439 static int hf_bacapp_tag_PORT = -1;
4440 /* some more variables for segmented messages */
4441 static int hf_msg_fragments = -1;
4442 static int hf_msg_fragment = -1;
4443 static int hf_msg_fragment_overlap = -1;
4444 static int hf_msg_fragment_overlap_conflicts = -1;
4445 static int hf_msg_fragment_multiple_tails = -1;
4446 static int hf_msg_fragment_too_long_fragment = -1;
4447 static int hf_msg_fragment_error = -1;
4448 static int hf_msg_fragment_count = -1;
4449 static int hf_msg_reassembled_in = -1;
4450 static int hf_msg_reassembled_length = -1;
4452 static gint ett_msg_fragment = -1;
4453 static gint ett_msg_fragments = -1;
4455 static gint ett_bacapp = -1;
4456 static gint ett_bacapp_control = -1;
4457 static gint ett_bacapp_tag = -1;
4458 static gint ett_bacapp_list = -1;
4459 static gint ett_bacapp_value = -1;
4461 static dissector_handle_t data_handle;
4462 static gint32 propertyIdentifier = -1;
4463 static gint32 propertyArrayIndex = -1;
4464 static guint32 object_type = 4096;
4466 static guint8 bacapp_flags = 0;
4467 static guint8 bacapp_seq = 0;
4469 /* Defined to allow vendor identifier registration of private transfer dissectors */
4470 static dissector_table_t bacapp_dissector_table;
4473 /* Stat: BACnet Packets sorted by IP */
4474 bacapp_info_value_t bacinfo;
4476 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
4477 static const gchar* st_str_packets_by_ip_dst = "By Destination";
4478 static const gchar* st_str_packets_by_ip_src = "By Source";
4479 static int st_node_packets_by_ip = -1;
4480 static int st_node_packets_by_ip_dst = -1;
4481 static int st_node_packets_by_ip_src = -1;
4484 bacapp_packet_stats_tree_init(stats_tree* st)
4486 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4487 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4488 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4492 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4494 int packets_for_this_dst;
4495 int packets_for_this_src;
4496 int service_for_this_dst;
4497 int service_for_this_src;
4498 int src_for_this_dst;
4499 int dst_for_this_src;
4500 int objectid_for_this_dst;
4501 int objectid_for_this_src;
4502 int instanceid_for_this_dst;
4503 int instanceid_for_this_src;
4506 const bacapp_info_value_t *binfo = p;
4508 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4509 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4511 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4512 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4513 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4514 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4515 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4516 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4517 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4518 if (binfo->service_type) {
4519 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4520 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4521 if (binfo->object_ident) {
4522 instanceid_for_this_dst = tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4523 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4524 instanceid_for_this_src = tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4525 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4532 /* Stat: BACnet Packets sorted by Service */
4533 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4534 static int st_node_packets_by_service = -1;
4537 bacapp_service_stats_tree_init(stats_tree* st)
4539 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4543 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4552 const bacapp_info_value_t *binfo = p;
4554 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4555 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4557 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4558 if (binfo->service_type) {
4559 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4560 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4561 dst = tick_stat_node(st, dststr, src, TRUE);
4562 if (binfo->object_ident) {
4563 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4564 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4571 /* Stat: BACnet Packets sorted by Object Type */
4572 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
4573 static int st_node_packets_by_objectid = -1;
4576 bacapp_objectid_stats_tree_init(stats_tree* st)
4578 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
4582 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4590 const bacapp_info_value_t *binfo = p;
4592 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4593 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4595 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
4596 if (binfo->object_ident) {
4597 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
4598 src = tick_stat_node(st, srcstr, objectid, TRUE);
4599 dst = tick_stat_node(st, dststr, src, TRUE);
4600 if (binfo->service_type) {
4601 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4602 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
4609 /* Stat: BACnet Packets sorted by Instance No */
4610 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
4611 static int st_node_packets_by_instanceid = -1;
4614 bacapp_instanceid_stats_tree_init(stats_tree* st)
4616 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
4620 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4628 const bacapp_info_value_t *binfo = p;
4630 srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
4631 dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
4633 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
4634 if (binfo->object_ident) {
4635 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
4636 src = tick_stat_node(st, srcstr, instanceid, TRUE);
4637 dst = tick_stat_node(st, dststr, src, TRUE);
4638 if (binfo->service_type) {
4639 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4640 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
4647 /* register all BACnet Ststistic trees */
4649 register_bacapp_stat_trees(void)
4651 stats_tree_register("bacapp","bacapp_ip","BACnet/Packets sorted by IP", 0,
4652 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
4653 stats_tree_register("bacapp","bacapp_service","BACnet/Packets sorted by Service", 0,
4654 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
4655 stats_tree_register("bacapp","bacapp_objectid","BACnet/Packets sorted by Object Type", 0,
4656 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
4657 stats_tree_register("bacapp","bacapp_instanceid","BACnet/Packets sorted by Instance ID", 0,
4658 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
4661 /* 'data' must be ep_ allocated */
4663 updateBacnetInfoValue(gint whichval, gchar *data)
4665 if (whichval == BACINFO_SERVICE) {
4666 bacinfo.service_type = data;
4669 if (whichval == BACINFO_INVOKEID) {
4670 bacinfo.invoke_id = data;
4673 if (whichval == BACINFO_OBJECTID) {
4674 bacinfo.object_ident = data;
4677 if (whichval == BACINFO_INSTANCEID) {
4678 bacinfo.instance_ident = data;
4684 static const fragment_items msg_frag_items = {
4685 /* Fragment subtrees */
4688 /* Fragment fields */
4691 &hf_msg_fragment_overlap,
4692 &hf_msg_fragment_overlap_conflicts,
4693 &hf_msg_fragment_multiple_tails,
4694 &hf_msg_fragment_too_long_fragment,
4695 &hf_msg_fragment_error,
4696 &hf_msg_fragment_count,
4697 /* Reassembled in field */
4698 &hf_msg_reassembled_in,
4699 /* Reassembled length field */
4700 &hf_msg_reassembled_length,
4705 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
4706 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
4709 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
4711 fGetMaxAPDUSize(guint8 idx)
4713 /* only 16 values are defined, so use & 0x0f */
4714 /* check the size of the Array, deliver either the entry
4715 or the first entry if idx is outside of the array (bug 3736 comment#7) */
4717 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
4718 return MaxAPDUSize[0];
4720 return MaxAPDUSize[idx & 0x0f];
4725 /* Used when there are ranges of reserved and proprietary enumerations */
4727 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
4728 const char *fmt, const char *split_fmt)
4730 if (val < split_val)
4731 return val_to_str(val, vs, fmt);
4733 return val_to_str(val, vs, split_fmt);
4736 /* from clause 20.2.1.3.2 Constructed Data */
4737 /* returns true if the extended value is used */
4739 tag_is_extended_value(guint8 tag)
4741 return (tag & 0x07) == 5;
4745 tag_is_opening(guint8 tag)
4747 return (tag & 0x07) == 6;
4751 tag_is_closing(guint8 tag)
4753 return (tag & 0x07) == 7;
4756 /* from clause 20.2.1.1 Class
4757 class bit shall be one for context specific tags */
4758 /* returns true if the tag is context specific */
4760 tag_is_context_specific(guint8 tag)
4762 return (tag & 0x08) != 0;
4766 tag_is_extended_tag_number(guint8 tag)
4768 return ((tag & 0xF0) == 0xF0);
4772 object_id_type(guint32 object_identifier)
4774 return ((object_identifier >> 22) & 0x3FF);
4778 object_id_instance(guint32 object_identifier)
4780 return (object_identifier & 0x3FFFFF);
4784 fTagNo (tvbuff_t *tvb, guint offset)
4786 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
4790 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
4792 gboolean valid = TRUE;
4796 *val = tvb_get_guint8(tvb, offset);
4799 *val = tvb_get_ntohs(tvb, offset);
4802 *val = tvb_get_ntoh24(tvb, offset);
4805 *val = tvb_get_ntohl(tvb, offset);
4816 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4818 gboolean valid = FALSE;
4822 if (lvt && (lvt <= 8)) {
4824 data = tvb_get_guint8(tvb, offset);
4825 for (i = 0; i < lvt; i++) {
4826 data = tvb_get_guint8(tvb, offset+i);
4827 value = (value << 8) + data;
4835 /* BACnet Signed Value uses 2's complement notation, but with a twist:
4836 All signed integers shall be encoded in the smallest number of octets
4837 possible. That is, the first octet of any multi-octet encoded value
4838 shall not be X'00' if the most significant bit (bit 7) of the second
4839 octet is 0, and the first octet shall not be X'FF' if the most
4840 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4842 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4844 gboolean valid = FALSE;
4849 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4850 if (lvt && (lvt <= 7)) {
4852 data = tvb_get_guint8(tvb, offset);
4853 if ((data & 0x80) != 0)
4854 value = (-1 << 8) | data;
4857 for (i = 1; i < lvt; i++) {
4858 data = tvb_get_guint8(tvb, offset+i);
4859 value = (value << 8) + data;
4868 fTagHeaderTree (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4869 guint offset, guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4871 proto_item *ti = NULL;
4875 guint lvt_len = 1; /* used for tree display of lvt */
4876 guint lvt_offset; /* used for tree display of lvt */
4878 lvt_offset = offset;
4879 tag = tvb_get_guint8(tvb, offset);
4883 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4884 /* can mean open/close tag or length of 6/7 after the length is */
4885 /* computed below - store whole tag info, not just context bit. */
4886 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4888 if (tag_is_extended_tag_number(tag)) {
4889 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4891 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4892 lvt_offset += tag_len;
4893 value = tvb_get_guint8(tvb, lvt_offset);
4895 if (value == 254) { /* length is encoded with 16 Bits */
4896 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4899 } else if (value == 255) { /* length is encoded with 32 Bits */
4900 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4908 proto_tree *subtree;
4909 if (tag_is_opening(tag))
4910 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4911 else if (tag_is_closing(tag))
4912 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4913 else if (tag_is_context_specific(tag)) {
4914 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4915 "Context Tag: %u, Length/Value/Type: %u",
4918 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4919 "Application Tag: %s, Length/Value/Type: %u",
4921 BACnetApplicationTagNumber,
4922 ASHRAE_Reserved_Fmt),
4925 /* details if needed */
4926 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4927 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
4928 if (tag_is_extended_tag_number(tag)) {
4929 proto_tree_add_uint_format(subtree,
4930 hf_BACnetContextTagNumber,
4931 tvb, offset, 1, tag,
4932 "Extended Tag Number");
4933 proto_tree_add_item(subtree,
4934 hf_BACnetExtendedTagNumber,
4935 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4937 if (tag_is_context_specific(tag))
4938 proto_tree_add_item(subtree,
4939 hf_BACnetContextTagNumber,
4940 tvb, offset, 1, ENC_BIG_ENDIAN);
4942 proto_tree_add_item(subtree,
4943 hf_BACnetApplicationTagNumber,
4944 tvb, offset, 1, ENC_BIG_ENDIAN);
4946 if (tag_is_closing(tag) || tag_is_opening(tag))
4947 proto_tree_add_item(subtree,
4949 tvb, offset, 1, ENC_BIG_ENDIAN);
4950 else if (tag_is_extended_value(tag)) {
4951 proto_tree_add_item(subtree,
4953 tvb, offset, 1, ENC_BIG_ENDIAN);
4954 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4955 tvb, lvt_offset, lvt_len, *lvt);
4957 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4958 tvb, lvt_offset, lvt_len, *lvt);
4961 if (*lvt > tvb_length(tvb)) {
4962 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
4963 "LVT length too long: %d > %d", *lvt,
4972 fTagHeader (tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* tag_info,
4975 return fTagHeaderTree (tvb, pinfo, NULL, offset, tag_no, tag_info, lvt);
4979 fNullTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
4981 guint8 tag_no, tag_info;
4984 proto_tree *subtree;
4986 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4987 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4988 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
4994 fBooleanTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
4996 guint8 tag_no, tag_info;
4999 proto_tree *subtree;
5002 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5003 if (tag_info && lvt == 1) {
5004 lvt = tvb_get_guint8(tvb, offset+1);
5008 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
5009 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
5010 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5011 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5013 return offset + bool_len;
5017 fUnsignedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5020 guint8 tag_no, tag_info;
5024 proto_tree *subtree;
5026 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5027 /* only support up to an 8 byte (64-bit) integer */
5028 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
5029 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5030 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
5032 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5033 "%s - %u octets (Unsigned)", label, lvt);
5034 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5035 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5037 return offset+tag_len+lvt;
5041 fDevice_Instance (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, int hf)
5043 guint8 tag_no, tag_info;
5044 guint32 lvt, safe_lvt;
5047 proto_tree *subtree;
5049 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5056 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, safe_lvt, ENC_BIG_ENDIAN);
5058 if (lvt != safe_lvt)
5059 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
5060 "This field claims to be an impossible %u bytes, while the max is %u", lvt, safe_lvt);
5062 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5063 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5065 return offset+tag_len+lvt;
5068 /* set split_val to zero when not needed */
5070 fEnumeratedTagSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5071 guint offset, const gchar *label, const value_string *vs, guint32 split_val)
5074 guint8 tag_no, tag_info;
5078 proto_tree *subtree;
5080 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5081 /* only support up to a 4 byte (32-bit) enumeration */
5082 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
5084 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5085 "%s %s", label, val_to_split_str(val, split_val, vs,
5086 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
5088 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5089 "%s %u", label, val);
5091 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5092 "%s - %u octets (enumeration)", label, lvt);
5094 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5095 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5097 return offset+tag_len+lvt;
5101 fEnumeratedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5102 guint offset, const gchar *label, const value_string *vs)
5104 return fEnumeratedTagSplit (tvb, pinfo, tree, offset, label, vs, 0);
5108 fSignedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5111 guint8 tag_no, tag_info;
5115 proto_tree *subtree;
5117 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5118 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
5119 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5120 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
5122 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5123 "%s - %u octets (Signed)", label, lvt);
5124 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5125 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5127 return offset+tag_len+lvt;
5131 fRealTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5133 guint8 tag_no, tag_info;
5138 proto_tree *subtree;
5140 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5141 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
5142 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
5143 "%s%f (Real)", label, f_val);
5144 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5145 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5147 return offset+tag_len+4;
5151 fDoubleTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5153 guint8 tag_no, tag_info;
5158 proto_tree *subtree;
5160 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5161 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
5162 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
5163 "%s%f (Double)", label, d_val);
5164 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5165 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5167 return offset+tag_len+8;
5171 fProcessId (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5173 guint32 val = 0, lvt;
5174 guint8 tag_no, tag_info;
5176 proto_tree *subtree;
5179 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5180 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5181 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
5182 tvb, offset, lvt+tag_len, val);
5184 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5185 "Process Identifier - %u octets (Signed)", lvt);
5186 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5187 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5188 offset += tag_len + lvt;
5194 fTimeSpan (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5196 guint32 val = 0, lvt;
5197 guint8 tag_no, tag_info;
5199 proto_tree *subtree;
5202 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5203 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5204 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5205 "%s (hh.mm.ss): %d.%02d.%02d%s",
5207 (val / 3600), ((val % 3600) / 60), (val % 60),
5208 val == 0 ? " (indefinite)" : "");
5210 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5211 "%s - %u octets (Signed)", label, lvt);
5212 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5213 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5215 return offset+tag_len+lvt;
5219 fWeekNDay (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5221 guint32 month, weekOfMonth, dayOfWeek;
5222 guint8 tag_no, tag_info;
5226 proto_tree *subtree;
5228 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5229 month = tvb_get_guint8(tvb, offset+tag_len);
5230 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
5231 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
5232 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
5233 val_to_str(month, months, "month (%d) not found"),
5234 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
5235 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
5236 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5237 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5239 return offset+tag_len+lvt;
5243 fDate (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5245 guint32 year, month, day, weekday;
5246 guint8 tag_no, tag_info;
5250 proto_tree *subtree;
5252 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5253 year = tvb_get_guint8(tvb, offset+tag_len);
5254 month = tvb_get_guint8(tvb, offset+tag_len+1);
5255 day = tvb_get_guint8(tvb, offset+tag_len+2);
5256 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
5257 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
5258 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5261 else if (year != 255) {
5263 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5264 "%s%s %d, %d, (Day of Week = %s)",
5265 label, val_to_str(month,
5267 "month (%d) not found"),
5268 day, year, val_to_str(weekday,
5272 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5273 "%s%s %d, any year, (Day of Week = %s)",
5274 label, val_to_str(month, months, "month (%d) not found"),
5275 day, val_to_str(weekday, day_of_week, "(%d) not found"));
5277 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5278 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5280 return offset+tag_len+lvt;
5284 fTime (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5286 guint32 hour, minute, second, msec, lvt;
5287 guint8 tag_no, tag_info;
5290 proto_tree *subtree;
5292 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5293 hour = tvb_get_guint8(tvb, offset+tag_len);
5294 minute = tvb_get_guint8(tvb, offset+tag_len+1);
5295 second = tvb_get_guint8(tvb, offset+tag_len+2);
5296 msec = tvb_get_guint8(tvb, offset+tag_len+3);
5297 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
5298 ti = proto_tree_add_text(tree, tvb, offset,
5299 lvt+tag_len, "%sany", label);
5301 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5302 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
5304 hour > 12 ? hour - 12 : hour,
5305 minute, second, msec,
5306 hour >= 12 ? "P.M." : "A.M.",
5307 hour, minute, second, msec);
5308 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5309 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5311 return offset+tag_len+lvt;
5315 fDateTime (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5317 proto_tree *subtree = tree;
5320 if (label != NULL) {
5321 tt = proto_tree_add_text (subtree, tvb, offset, 10, "%s", label);
5322 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5324 offset = fDate (tvb,pinfo,subtree,offset,"Date: ");
5325 return fTime (tvb,pinfo,subtree,offset,"Time: ");
5329 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5331 guint lastoffset = 0;
5332 guint8 tag_no, tag_info;
5335 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5336 lastoffset = offset;
5337 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5338 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
5341 offset = fTime (tvb,pinfo,tree,offset,"Time: ");
5342 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
5344 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
5350 fCalendarEntry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5352 guint8 tag_no, tag_info;
5355 switch (fTagNo(tvb, offset)) {
5357 offset = fDate (tvb, pinfo, tree, offset, "Date: ");
5359 case 1: /* dateRange */
5360 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5361 offset = fDateRange (tvb, pinfo, tree, offset);
5362 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5364 case 2: /* BACnetWeekNDay */
5365 offset = fWeekNDay (tvb, pinfo, tree, offset);
5375 fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
5378 proto_tree* subtree = tree;
5381 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5382 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
5384 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5386 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-OFFNORMAL timestamp: ");
5387 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-FAULT timestamp: ");
5388 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-NORMAL timestamp: ");
5394 fTimeStamp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5396 guint8 tag_no = 0, tag_info = 0;
5399 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
5400 switch (fTagNo(tvb, offset)) {
5402 offset = fTime (tvb, pinfo, tree, offset, label?label:"time: ");
5404 case 1: /* sequenceNumber */
5405 offset = fUnsignedTag (tvb, pinfo, tree, offset,
5406 label?label:"sequence number: ");
5408 case 2: /* dateTime */
5409 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5410 offset = fDateTime (tvb, pinfo, tree, offset, label?label:"date time: ");
5411 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5423 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5425 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5426 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
5431 static const value_string
5432 BACnetDaysOfWeek [] = {
5444 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5446 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5447 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
5448 "valid Days: ", BACnetDaysOfWeek);
5449 offset = fTime (tvb,pinfo,tree,offset,"from time: ");
5450 offset = fTime (tvb,pinfo,tree,offset,"to time: ");
5451 offset = fRecipient (tvb,pinfo,tree,offset);
5452 offset = fProcessId (tvb,pinfo,tree,offset);
5453 offset = fApplicationTypes (tvb,pinfo,tree,offset,
5454 "issue confirmed notifications: ");
5455 offset = fBitStringTagVS (tvb,pinfo,tree,offset,
5456 "transitions: ", BACnetEventTransitionBits);
5463 fOctetString (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5466 guint start = offset;
5467 guint8 tag_no, tag_info;
5468 proto_tree *subtree = tree;
5471 offset += fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5474 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5475 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
5480 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5482 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5488 fMacAddress (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5491 guint start = offset;
5492 guint8 tag_no, tag_info;
5493 proto_tree* subtree = tree;
5496 offset += fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5498 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
5501 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
5503 guint32 ip = tvb_get_ipv4(tvb, offset);
5504 guint16 port = tvb_get_ntohs(tvb, offset+4);
5506 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
5507 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
5510 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
5511 struct e_in6_addr addr;
5512 guint16 port = tvb_get_ntohs(tvb, offset+16);
5513 tvb_get_ipv6(tvb, offset, &addr);
5515 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
5516 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
5518 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
5519 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5520 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
5527 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5529 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5535 fAddress (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5537 guint8 tag_no, tag_info;
5541 offset = fUnsignedTag (tvb, pinfo, tree, offset, "network-number");
5542 offs = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5544 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5547 offset = fMacAddress (tvb, pinfo, tree, offset, "MAC-address: ", lvt);
5553 fSessionKey (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5555 offset = fOctetString (tvb,pinfo,tree,offset,"session key: ", 8);
5556 return fAddress (tvb,pinfo,tree,offset);
5560 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5562 guint8 tag_no, tag_info;
5566 proto_tree *subtree;
5569 tag_length = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5570 object_id = tvb_get_ntohl(tvb,offset+tag_length);
5571 object_type = object_id_type(object_id);
5572 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
5573 "ObjectIdentifier: %s, %u",
5574 val_to_split_str(object_type,
5577 ASHRAE_Reserved_Fmt,
5578 Vendor_Proprietary_Fmt),
5579 object_id_instance(object_id));
5580 if (col_get_writable(pinfo->cinfo))
5581 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5582 val_to_split_str(object_type,
5585 ASHRAE_Reserved_Fmt,
5586 Vendor_Proprietary_Fmt),
5587 object_id_instance(object_id));
5589 /* update BACnet Statistics */
5590 updateBacnetInfoValue(BACINFO_OBJECTID,
5591 ep_strdup(val_to_split_str(object_type, 128,
5592 BACnetObjectType, ASHRAE_Reserved_Fmt,
5593 Vendor_Proprietary_Fmt)));
5594 updateBacnetInfoValue(BACINFO_INSTANCEID, ep_strdup_printf("Instance ID: %u",
5595 object_id_instance(object_id)));
5597 /* here are the details of how we arrived at the above text */
5598 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5599 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5600 offset += tag_length;
5601 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
5602 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
5609 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5611 guint8 tag_no, tag_info;
5614 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5616 if (tag_no == 0) { /* device */
5617 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5619 else { /* address */
5620 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5621 offset = fAddress (tvb, pinfo, tree, offset);
5622 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5629 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5631 guint lastoffset = 0;
5632 guint8 tag_no, tag_info;
5634 proto_tree *orgtree = tree;
5636 proto_tree *subtree;
5638 /* beginning of new item - indent and label */
5639 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
5640 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5642 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5643 lastoffset = offset;
5645 switch (fTagNo(tvb, offset)) {
5646 case 0: /* recipient */
5647 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5648 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5649 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5650 offset = fRecipient (tvb, pinfo, subtree, offset);
5651 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5653 case 1: /* processId */
5654 offset = fProcessId (tvb, pinfo, tree, offset);
5655 lastoffset = offset;
5660 if (offset == lastoffset) break; /* nothing happened, exit loop */
5666 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5668 guint lastoffset = 0;
5669 guint8 tag_no, tag_info;
5671 proto_tree *subtree;
5673 proto_tree *orgtree = tree;
5676 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5677 lastoffset = offset;
5678 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5679 if (tag_is_closing(tag_info) ) {
5684 case 0: /* recipient */
5685 /* beginning of new item in list */
5686 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
5687 itemno = itemno + 1;
5688 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5690 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5691 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5692 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5693 offset = fRecipientProcess (tvb, pinfo, subtree, offset);
5694 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5695 subtree = tree; /* done with this level - return to previous tree */
5697 case 1: /* MonitoredPropertyReference */
5698 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
5699 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5700 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5701 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
5702 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5705 case 2: /* IssueConfirmedNotifications - boolean */
5706 offset = fBooleanTag (tvb, pinfo, tree, offset, "Issue Confirmed Notifications: ");
5708 case 3: /* TimeRemaining */
5709 offset = fUnsignedTag (tvb, pinfo, tree, offset, "Time Remaining: ");
5711 case 4: /* COVIncrement */
5712 offset = fRealTag (tvb, pinfo, tree, offset, "COV Increment: ");
5717 if (offset == lastoffset) break; /* nothing happened, exit loop */
5723 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5725 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5726 return fAddress (tvb, pinfo, tree, offset);
5730 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
5732 guint lastoffset = 0, len;
5733 guint8 tag_no, tag_info;
5735 proto_tree *subtree = tree;
5737 /* set the optional global properties to indicate not-used */
5738 propertyArrayIndex = -1;
5739 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5740 lastoffset = offset;
5741 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5742 if (tag_is_closing(tag_info) ) {
5743 if (tag_no == tag_match) {
5752 case 0: /* deviceIdentifier */
5753 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5755 case 1: /* objectIdentifier */
5756 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5758 case 2: /* propertyIdentifier */
5759 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
5761 case 3: /* propertyArrayIndex */
5762 offset = fPropertyArrayIndex (tvb, pinfo, subtree, offset);
5764 case 4: /* propertyValue */
5765 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
5767 case 5: /* priority */
5768 offset = fUnsignedTag (tvb,pinfo,subtree,offset,"Priority: ");
5770 case 6: /* postDelay */
5771 offset = fUnsignedTag (tvb,pinfo,subtree,offset,"Post Delay: ");
5773 case 7: /* quitOnFailure */
5774 offset = fBooleanTag(tvb, pinfo, subtree, offset,
5775 "Quit On Failure: ");
5777 case 8: /* writeSuccessful */
5778 offset = fBooleanTag(tvb, pinfo, subtree, offset,
5779 "Write Successful: ");
5784 if (offset == lastoffset) break; /* nothing happened, exit loop */
5789 /* BACnetActionList ::= SEQUENCE{
5790 action [0] SEQUENCE OF BACnetActionCommand
5794 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5796 guint lastoffset = 0, len;
5797 guint8 tag_no, tag_info;
5799 proto_tree *subtree = tree;
5802 while (tvb_reported_length_remaining(tvb, offset) > 0) {
5803 lastoffset = offset;
5804 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5805 if (tag_is_closing(tag_info)) {
5807 if ( tag_no != 0 ) /* don't eat the closing property tag, just return */
5812 if (tag_is_opening(tag_info)) {
5813 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
5814 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5815 offset += fTagHeaderTree (tvb, pinfo, subtree, offset,
5816 &tag_no, &tag_info, &lvt);
5819 case 0: /* BACnetActionCommand */
5820 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
5825 if (offset == lastoffset) break; /* nothing happened, exit loop */
5831 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5833 guint8 tag_no, tag_info;
5837 proto_tree *subtree;
5838 const gchar *label = "Property Identifier";
5840 propertyIdentifier = 0; /* global Variable */
5841 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5842 /* can we decode this value? */
5843 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
5844 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5845 "%s: %s (%u)", label,
5846 val_to_split_str(propertyIdentifier, 512,
5847 BACnetPropertyIdentifier,
5848 ASHRAE_Reserved_Fmt,
5849 Vendor_Proprietary_Fmt), propertyIdentifier);
5850 if (col_get_writable(pinfo->cinfo))
5851 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
5852 val_to_split_str(propertyIdentifier, 512,
5853 BACnetPropertyIdentifier,
5854 ASHRAE_Reserved_Fmt,
5855 Vendor_Proprietary_Fmt));
5857 /* property identifiers cannot be larger than 22-bits */
5860 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5861 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5862 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
5863 offset+tag_len, lvt, ENC_BIG_ENDIAN);
5865 return offset+tag_len+lvt;
5869 fPropertyArrayIndex (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5871 guint8 tag_no, tag_info;
5875 proto_tree *subtree;
5877 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5878 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
5879 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5880 "property Array Index (Unsigned) %u", propertyArrayIndex);
5882 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5883 "property Array Index - %u octets (Unsigned)", lvt);
5884 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5885 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5887 return offset+tag_len+lvt;
5891 fCharacterString (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5893 guint8 tag_no, tag_info, character_set;
5895 gsize inbytesleft, outbytesleft = 512;
5896 guint offs, extra = 1;
5899 guint8 bf_arr[512], *out = &bf_arr[0];
5901 proto_tree *subtree;
5902 guint start = offset;
5904 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5906 offs = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5908 character_set = tvb_get_guint8(tvb, offset+offs);
5909 /* Account for code page if DBCS */
5910 if (character_set == 1) {
5913 offset += (offs+extra);
5917 inbytesleft = l = MIN(lvt, 255);
5919 * XXX - are we guaranteed that these encoding
5920 * names correspond, on *all* platforms with
5921 * iconv(), to the encodings we want?
5922 * If not (and perhaps even if so), we should
5923 * perhaps have our own iconv() implementation,
5924 * with a different name, so that we control the
5925 * encodings it supports and the names of those
5928 * We should also handle that in the general
5929 * string handling code, rather than making it
5930 * specific to the BACAPP dissector, as many
5931 * other dissectors need to handle various
5932 * character encodings.
5934 str_val = tvb_get_ephemeral_string(tvb, offset, l);
5935 /** this decoding may be not correct for multi-byte characters, Lka */
5936 switch (character_set) {
5938 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UTF-8");
5943 coding = "IBM MS DBCS";
5947 coding = "JIS C 6226";
5949 case ISO_10646_UCS4:
5950 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5951 coding = "ISO 10646 UCS-4";
5953 case ISO_10646_UCS2:
5954 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5955 coding = "ISO 10646 UCS-2";
5958 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5959 coding = "ISO 8859-1";
5966 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s '%s'", label, coding, out);
5971 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5973 fTagHeaderTree (tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5974 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
5976 if (character_set == 1) {
5977 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5979 /* XXX - put the string value here */
5985 fBitStringTagVS (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
5986 const value_string *src)
5988 guint8 tag_no, tag_info, tmp;
5989 gint j, unused, skip;
5990 guint start = offset;
5992 guint32 lvt, i, numberOfBytes;
5994 proto_tree* subtree = tree;
5997 offs = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5998 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
6000 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
6001 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
6002 "%s(Bit String)", label);
6004 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6006 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6007 proto_tree_add_text(subtree, tvb, offset, 1,
6008 "Unused bits: %u", unused);
6010 for (i = 0; i < numberOfBytes; i++) {
6011 tmp = tvb_get_guint8(tvb, (offset)+i+1);
6012 if (i == numberOfBytes-1) { skip = unused; }
6013 for (j = 0; j < 8-skip; j++) {
6015 if (tmp & (1 << (7 - j)))
6016 proto_tree_add_text(subtree, tvb,
6019 val_to_str((guint) (i*8 +j),
6021 ASHRAE_Reserved_Fmt));
6023 proto_tree_add_text(subtree, tvb,
6026 val_to_str((guint) (i*8 +j),
6028 ASHRAE_Reserved_Fmt));
6030 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
6036 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
6037 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
6046 fBitStringTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6048 return fBitStringTagVS (tvb, pinfo, tree, offset, label, NULL);
6051 /* handles generic application types, as well as enumerated and enumerations
6052 with reserved and proprietarty ranges (split) */
6054 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6055 const gchar *label, const value_string *src, guint32 split_val)
6057 guint8 tag_no, tag_info;
6061 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6063 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6064 if (!tag_is_context_specific(tag_info)) {
6066 case 0: /** NULL 20.2.2 */
6067 offset = fNullTag(tvb, pinfo, tree, offset, label);
6069 case 1: /** BOOLEAN 20.2.3 */
6070 offset = fBooleanTag(tvb, pinfo, tree, offset, label);
6072 case 2: /** Unsigned Integer 20.2.4 */
6073 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
6075 case 3: /** Signed Integer 20.2.5 */
6076 offset = fSignedTag(tvb, pinfo, tree, offset, label);
6078 case 4: /** Real 20.2.6 */
6079 offset = fRealTag(tvb, pinfo, tree, offset, label);
6081 case 5: /** Double 20.2.7 */
6082 offset = fDoubleTag(tvb, pinfo, tree, offset, label);
6084 case 6: /** Octet String 20.2.8 */
6085 offset = fOctetString (tvb, pinfo, tree, offset, label, lvt);
6087 case 7: /** Character String 20.2.9 */
6088 offset = fCharacterString (tvb,pinfo,tree,offset,label);
6090 case 8: /** Bit String 20.2.10 */
6091 offset = fBitStringTagVS (tvb, pinfo, tree, offset, label, src);
6093 case 9: /** Enumerated 20.2.11 */
6094 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset, label, src, split_val);
6096 case 10: /** Date 20.2.12 */
6097 offset = fDate (tvb, pinfo, tree, offset, label);
6099 case 11: /** Time 20.2.13 */
6100 offset = fTime (tvb, pinfo, tree, offset, label);
6102 case 12: /** BACnetObjectIdentifier 20.2.14 */
6103 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6105 case 13: /* reserved for ASHRAE */
6108 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
6109 offset += lvt + tag_len;
6121 fShedLevel (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6123 guint lastoffset = 0;
6125 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6126 lastoffset = offset;
6128 switch (fTagNo(tvb,offset)) {
6129 case 0: /* percent */
6130 offset = fUnsignedTag (tvb, pinfo, tree, offset, "shed percent: ");
6133 offset = fUnsignedTag (tvb, pinfo, tree, offset, "shed level: ");
6135 case 2: /* amount */
6136 offset = fRealTag(tvb, pinfo, tree, offset, "shed amount: ");
6141 if (offset == lastoffset) break; /* nothing happened, exit loop */
6147 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6148 const gchar *label, const value_string *vs)
6150 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
6154 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6157 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
6161 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6163 guint8 tag_no, tag_info;
6167 proto_tree *subtree;
6171 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6172 /* cap the the suggested length in case of bad data */
6173 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
6174 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
6177 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
6178 "Context Value (as %u DATA octets)", lvt);
6180 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6181 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6183 return offset + tag_len + lvt;
6186 BACnetPrescale ::= SEQUENCE {
6187 multiplier [0] Unsigned,
6188 moduloDivide [1] Unsigned
6192 fPrescale (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6194 guint8 tag_no, tag_info;
6196 guint lastoffset = 0;
6198 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6199 lastoffset = offset;
6200 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6201 if (tag_is_closing(tag_info) ) {
6205 case 0: /* multiplier */
6206 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Multiplier: ");
6208 case 1: /* moduloDivide */
6209 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Modulo Divide: ");
6214 if (offset == lastoffset) break; /* nothing happened, exit loop */
6220 BACnetScale ::= CHOICE {
6221 floatScale [0] REAL,
6222 integerScale [1] INTEGER
6226 fScale (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6228 guint8 tag_no, tag_info;
6230 guint lastoffset = 0;
6232 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6233 lastoffset = offset;
6234 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6235 if (tag_is_closing(tag_info) ) {
6239 case 0: /* floatScale */
6240 offset = fRealTag (tvb,pinfo,tree,offset,"Float Scale: ");
6242 case 1: /* integerScale */
6243 offset = fSignedTag (tvb,pinfo,tree,offset,"Integer Scale: ");
6248 if (offset == lastoffset) break; /* nothing happened, exit loop */
6253 BACnetAccumulatorRecord ::= SEQUENCE {
6254 timestamp [0] BACnetDateTime,
6255 presentValue [1] Unsigned,
6256 accumulatedValue [2] Unsigned,
6257 accumulatortStatus [3] ENUMERATED {
6267 fLoggingRecord (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6269 guint8 tag_no, tag_info;
6271 guint lastoffset = 0;
6273 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6274 lastoffset = offset;
6275 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6276 if (tag_is_closing(tag_info) ) {
6280 case 0: /* timestamp */
6281 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6282 offset = fDateTime (tvb, pinfo, tree, offset, "Timestamp: ");
6283 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6285 case 1: /* presentValue */
6286 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Present Value: ");
6288 case 2: /* accumulatedValue */
6289 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Accumulated Value: ");
6291 case 3: /* accumulatorStatus */
6292 offset = fEnumeratedTag (tvb, pinfo, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus);
6297 if (offset == lastoffset) break; /* nothing happened, exit loop */
6303 SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState
6306 fSequenceOfEnums (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, const value_string *vs)
6308 guint8 tag_no, tag_info;
6310 guint lastoffset = 0;
6312 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6313 lastoffset = offset;
6314 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6315 if (tag_is_closing(tag_info) ) {
6318 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs);
6319 if ( offset == lastoffset ) break;
6325 SEQ OF BACnetDeviceObjectReference (accessed as an array)
6329 fDoorMembers (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6331 guint8 tag_no, tag_info;
6333 guint lastoffset = 0;
6335 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6336 lastoffset = offset;
6337 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6338 if (tag_is_closing(tag_info) ) {
6341 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6342 if (offset == lastoffset) break;
6348 SEQ OF ReadAccessSpecification
6351 fListOfGroupMembers (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6353 guint8 tag_no, tag_info;
6355 guint lastoffset = 0;
6357 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6358 lastoffset = offset;
6359 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6360 if (tag_is_closing(tag_info) ) {
6363 offset = fReadAccessSpecification(tvb, pinfo, tree, offset);
6364 if ( offset == lastoffset ) break;
6370 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6372 guint8 tag_no, tag_info;
6374 guint lastoffset = 0, depth = 0;
6376 guint32 save_object_type;
6378 if (propertyIdentifier >= 0) {
6379 g_snprintf (ar, sizeof(ar), "%s: ",
6380 val_to_split_str(propertyIdentifier, 512,
6381 BACnetPropertyIdentifier,
6382 ASHRAE_Reserved_Fmt,
6383 Vendor_Proprietary_Fmt));
6385 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
6387 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6388 lastoffset = offset;
6389 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6390 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
6391 if (depth <= 0) return offset;
6394 /* Application Tags */
6395 switch (propertyIdentifier) {
6396 case 2: /* action */
6397 /* loop object is application tagged,
6398 command object is context tagged */
6399 if (tag_is_context_specific(tag_info)) {
6400 /* BACnetActionList */
6401 offset = fActionList (tvb, pinfo, tree,offset);
6404 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6408 case 30: /* BACnetAddressBinding */
6409 offset = fAddressBinding (tvb,pinfo,tree,offset);
6411 case 54: /* list of object property reference */
6412 offset = fLOPR (tvb, pinfo, tree,offset);
6414 case 55: /* list-of-session-keys */
6415 fSessionKey (tvb, pinfo, tree, offset);
6417 case 79: /* object-type */
6418 case 96: /* protocol-object-types-supported */
6419 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
6420 BACnetObjectType, 128);
6422 case 97: /* Protocol-Services-Supported */
6423 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6424 BACnetServicesSupported);
6426 case 102: /* recipient-list */
6427 offset = fDestination (tvb, pinfo, tree, offset);
6429 case 107: /* segmentation-supported */
6430 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6431 BACnetSegmentation);
6433 case 111: /* Status-Flags */
6434 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6437 case 112: /* System-Status */
6438 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6439 BACnetDeviceStatus);
6441 case 117: /* units */
6442 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6443 BACnetEngineeringUnits);
6445 case 87: /* priority-array -- accessed as a BACnetARRAY */
6446 if (propertyArrayIndex == 0) {
6447 /* BACnetARRAY index 0 refers to the length
6448 of the array, not the elements of the array */
6449 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6451 offset = fPriorityArray (tvb, pinfo, tree, offset);
6454 case 38: /* exception-schedule */
6455 if (object_type < 128) {
6456 if (propertyArrayIndex == 0) {
6457 /* BACnetARRAY index 0 refers to the length
6458 of the array, not the elements of the array */
6459 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6461 offset = fSpecialEvent (tvb,pinfo,tree,offset);
6465 case 19: /* controlled-variable-reference */
6466 case 60: /* manipulated-variable-reference */
6467 case 109: /* Setpoint-Reference */
6468 case 132: /* log-device-object-property */
6469 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6471 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
6472 if (object_type < 128) {
6473 if (propertyArrayIndex == 0) {
6474 /* BACnetARRAY index 0 refers to the length
6475 of the array, not the elements of the array */
6476 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6478 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
6482 case 127: /* client COV increment */
6483 offset = fClientCOV (tvb, pinfo, tree, offset);
6485 case 131: /* log-buffer */
6486 if ( object_type == 25 )
6487 offset = fEventLogRecord(tvb, pinfo, tree, offset);
6488 else if ( object_type == 27 )
6489 offset = fLogMultipleRecord (tvb, pinfo, tree, offset);
6491 offset = fLogRecord (tvb, pinfo, tree, offset);
6493 case 159: /* member-of */
6494 case 165: /* zone-members */
6495 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6497 case 196: /* last-restart-reason */
6498 offset = fRestartReason (tvb, pinfo, tree, offset);
6500 case 212: /* actual-shed-level */
6501 case 214: /* expected-shed-level */
6502 case 218: /* requested-shed-level */
6503 offset = fShedLevel (tvb, pinfo, tree, offset);
6505 case 152: /* active-cov-subscriptions */
6506 offset = fCOVSubscription (tvb, pinfo, tree, offset);
6508 case 23: /* date-list */
6509 offset = fCalendarEntry(tvb, pinfo, tree, offset);
6511 case 116: /* time-sychronization-recipients */
6512 offset = fRecipient(tvb, pinfo, tree, offset);
6514 case 83: /* event-parameters */
6515 offset = fEventParameter(tvb, pinfo, tree, offset);
6517 case 211: /* subordinate-list */
6518 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6520 case 130: /* event-time-stamp */
6521 offset = fEventTimeStamps(tvb, pinfo, tree, offset);
6523 case 197: /* logging-type */
6524 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType);
6526 case 36: /* event-state */
6527 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64);
6529 case 103: /* reliability */
6530 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability);
6532 case 72: /* notify-type */
6533 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNotifyType);
6535 case 208: /* node-type */
6536 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType);
6538 case 231: /* door-status */
6539 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus);
6541 case 233: /* lock-status */
6542 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus);
6544 case 235: /* secured-status */
6545 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus);
6547 case 158: /* maintenance-required */
6548 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance);
6550 case 92: /* program-state */
6551 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState);
6553 case 90: /* program-change */
6554 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest);
6556 case 100: /* reason-for-halt */
6557 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError);
6559 case 160: /* mode */
6560 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode);
6562 case 163: /* silenced */
6563 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState);
6565 case 161: /* operation-expected */
6566 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation);
6568 case 164: /* tracking-value */
6569 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState);
6571 case 41: /* file-access-method */
6572 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod);
6574 case 185: /* prescale */
6575 offset = fPrescale(tvb, pinfo, tree, offset);
6577 case 187: /* scale */
6578 offset = fScale(tvb, pinfo, tree, offset);
6580 case 184: /* logging-record */
6581 offset = fLoggingRecord(tvb, pinfo, tree, offset);
6583 case 228: /* door-members */
6584 offset = fDoorMembers(tvb, pinfo, tree, offset);
6586 case 181: /* input-reference */
6587 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6589 case 78: /* object-property-reference */
6590 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6592 case 234: /* masked-alarm-values */
6593 offset = fSequenceOfEnums(tvb, pinfo, tree, offset, "masked-alarm-value: ", BACnetDoorAlarmState);
6595 case 53: /* list-of-group-members */
6596 save_object_type = object_type;
6597 offset = fListOfGroupMembers(tvb, pinfo, tree, offset);
6598 object_type = save_object_type;
6600 case 85: /* present-value */
6601 if ( object_type == 11 ) /* group object handling of present-value */
6603 offset = fReadAccessResult(tvb, pinfo, tree, offset);
6606 /* intentially fall through here so don't reorder this case statement */
6609 if (tag_is_opening(tag_info)) {
6611 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6612 } else if (tag_is_closing(tag_info)) {
6614 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6616 offset = fContextTaggedValue(tvb, pinfo, tree, offset, ar);
6619 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6623 if (offset == lastoffset) break; /* nothing happened, exit loop */
6630 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
6635 if (tag_is_opening(tag_info)) {
6636 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
6637 &tag_no, &tag_info, &lvt);
6638 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6639 if (tvb_length_remaining(tvb, offset) > 0) {
6640 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
6641 &tag_no, &tag_info, &lvt);
6644 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
6645 "expected Opening Tag!");
6646 offset = tvb_length(tvb);
6654 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
6656 guint lastoffset = offset;
6657 guint8 tag_no, tag_info;
6660 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
6661 if (offset > lastoffset) {
6662 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6663 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
6664 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
6671 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6673 guint lastoffset = 0;
6674 guint8 tag_no, tag_info;
6677 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6678 lastoffset = offset;
6679 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
6680 if (offset > lastoffset) {
6681 /* detect optional priority
6682 by looking to see if the next tag is context tag number 3 */
6683 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6684 if (tag_is_context_specific(tag_info) && (tag_no == 3))
6685 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Priority: ");
6687 if (offset == lastoffset) break; /* nothing happened, exit loop */
6693 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6695 guint lastoffset = 0, len;
6696 guint8 tag_no, tag_info;
6698 proto_tree *subtree = tree;
6701 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6702 lastoffset = offset;
6703 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6704 if (tag_is_closing(tag_info)) {
6711 case 0: /* ProcessId */
6712 offset = fUnsignedTag (tvb, pinfo, tree, offset, "subscriber Process Id: ");
6714 case 1: /* monitored ObjectId */
6715 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6717 case 2: /* issueConfirmedNotifications */
6718 offset = fBooleanTag (tvb, pinfo, tree, offset, "issue Confirmed Notifications: ");
6720 case 3: /* life time */
6721 offset = fTimeSpan (tvb,pinfo,tree,offset,"life time");
6723 case 4: /* monitoredPropertyIdentifier */
6724 if (tag_is_opening(tag_info)) {
6725 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
6727 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6729 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6730 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
6735 case 5: /* covIncrement */
6736 offset = fRealTag (tvb, pinfo, tree, offset, "COV Increment: ");
6741 if (offset == lastoffset) break; /* nothing happened, exit loop */
6747 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6749 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
6753 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6755 guint lastoffset = 0;
6757 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6758 lastoffset = offset;
6760 switch (fTagNo(tvb, offset)) {
6761 case 0: /* deviceInstanceLowLimit */
6762 offset = fUnsignedTag (tvb, pinfo, tree, offset, "device Instance Low Limit: ");
6764 case 1: /* deviceInstanceHighLimit */
6765 offset = fUnsignedTag (tvb, pinfo, tree, offset, "device Instance High Limit: ");
6767 case 2: /* BACnetObjectId */
6768 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6770 case 3: /* messageText */
6771 offset = fCharacterString (tvb,pinfo,tree,offset, "Object Name: ");
6776 if (offset == lastoffset) break; /* nothing happened, exit loop */
6783 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
6785 guint lastoffset = 0;
6786 guint8 tag_no, tag_info;
6789 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6790 if (tag_is_opening(tag_info) && tag_no == 0) {
6791 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
6792 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6793 lastoffset = offset;
6794 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6795 if (tag_is_closing(tag_info)) {
6796 /* should be closing context tag 0 */
6797 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6801 offset = fTimeValue (tvb, pinfo, subtree, offset);
6802 if (offset == lastoffset) break; /* nothing happened, exit loop */
6804 } else if (tag_no == 0 && lvt == 0) {
6805 /* not sure null (empty array element) is legal */
6806 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6812 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6814 guint lastoffset = 0;
6815 guint8 tag_no, tag_info;
6817 guint i = 1; /* day of week array index */
6818 proto_tree *subtree = tree;
6821 if (propertyArrayIndex > 0) {
6822 /* BACnetARRAY index 0 refers to the length
6823 of the array, not the elements of the array.
6824 BACnetARRAY index -1 is our internal flag that
6825 the optional index was not used.
6826 BACnetARRAY refers to this as all elements of the array.
6827 If the optional index is specified for a BACnetARRAY,
6828 then that specific array element is referenced. */
6829 i = propertyArrayIndex;
6831 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6832 lastoffset = offset;
6833 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6834 if (tag_is_closing(tag_info)) {
6835 return offset; /* outer encoding will print out closing tag */
6837 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
6838 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6839 offset = fDailySchedule (tvb, pinfo, subtree, offset);
6840 if (offset == lastoffset) break; /* nothing happened, exit loop */
6847 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6849 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6852 return fDateTime (tvb, pinfo, tree, offset, "UTC-Time: ");
6856 fTimeSynchronizationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6858 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6861 return fDateTime (tvb, pinfo, tree, offset, NULL);
6865 fDateRange (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6867 if (tvb_reported_length_remaining(tvb, offset) <= 0)
6869 offset = fDate (tvb,pinfo,tree,offset,"Start Date: ");
6870 return fDate (tvb, pinfo, tree, offset, "End Date: ");
6874 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6877 guint8 tag_no, tag_info;
6881 proto_tree *subtree;
6882 const gchar *label = "Vendor ID";
6884 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6885 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6886 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6887 "%s: %s (%u)", label,
6888 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
6890 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6891 "%s - %u octets (Unsigned)", label, lvt);
6892 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6893 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6895 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
6896 proto_item *expert_item;
6897 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6898 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
6899 PROTO_ITEM_SET_GENERATED(expert_item);
6900 return offset+tag_len+lvt;
6903 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
6904 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6906 return offset+tag_len+lvt;
6910 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6913 guint8 tag_no, tag_info;
6917 proto_tree *subtree;
6918 const gchar *label = "Restart Reason";
6920 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6921 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
6922 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6923 "%s: %s (%u)", label,
6924 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
6926 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6927 "%s - %u octets (Unsigned)", label, lvt);
6928 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6929 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6932 proto_item *expert_item;
6933 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
6934 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
6935 PROTO_ITEM_SET_GENERATED(expert_item);
6936 return offset+tag_len+lvt;
6939 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
6940 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6942 return offset+tag_len+lvt;
6946 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6948 guint lastoffset = 0;
6950 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6951 lastoffset = offset;
6952 switch (fTagNo(tvb, offset)) {
6954 case 0: /* textMessageSourceDevice */
6955 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6957 case 1: /* messageClass */
6958 switch (fTagNo(tvb, offset)) {
6959 case 0: /* numeric */
6960 offset = fUnsignedTag (tvb, pinfo, tree, offset, "message Class: ");
6962 case 1: /* character */
6963 offset = fCharacterString (tvb, pinfo, tree, offset, "message Class: ");
6967 case 2: /* messagePriority */
6968 offset = fEnumeratedTag (tvb, pinfo, tree, offset, "message Priority: ",
6969 BACnetMessagePriority);
6971 case 3: /* message */
6972 offset = fCharacterString (tvb, pinfo, tree, offset, "message: ");
6977 if (offset == lastoffset) break; /* nothing happened, exit loop */
6983 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6985 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
6989 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6991 guint lastoffset = 0, len;
6992 guint8 tag_no, tag_info;
6994 proto_tree *subtree = tree;
6997 guint vendor_identifier = 0;
6998 guint service_number = 0;
7000 lastoffset = offset;
7001 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7002 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
7003 if (col_get_writable(pinfo->cinfo))
7004 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
7005 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
7007 next_tvb = tvb_new_subset_remaining(tvb,offset);
7008 if (dissector_try_uint(bacapp_dissector_table,
7009 vendor_identifier, next_tvb, pinfo, tree)) {
7010 /* we parsed it so skip over length and we are done */
7011 offset += tvb_length(next_tvb);
7015 /* Not handled by vendor dissector */
7017 /* exit loop if nothing happens inside */
7018 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7019 lastoffset = offset;
7020 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7021 if (tag_is_closing(tag_info)) {
7022 if (tag_no == 2) { /* Make sure it's the expected tag */
7027 break; /* End loop if incorrect closing tag */
7032 /* vendorID is now parsed above */
7033 case 1: /* serviceNumber */
7034 fUnsigned32(tvb, offset+len, lvt, &service_number);
7035 if (col_get_writable(pinfo->cinfo))
7036 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
7037 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "service Number: ");
7039 case 2: /*serviceParameters */
7040 if (tag_is_opening(tag_info)) {
7041 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
7042 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7043 propertyIdentifier = -1;
7044 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7052 if (offset == lastoffset) break; /* nothing happened, exit loop */
7059 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7061 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7065 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7067 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7071 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
7073 guint lastoffset = 0;
7074 guint8 tag_no, tag_info;
7076 proto_tree *subtree = tree;
7079 if (label != NULL) {
7080 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
7081 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7084 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7085 lastoffset = offset;
7086 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7089 case 0: /* subscriberProcessId */
7090 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "requesting Process Id: ");
7092 case 1: /* requestingSource */
7093 offset = fCharacterString (tvb, pinfo, tree, offset, "requesting Source: ");
7095 case 2: /* request */
7096 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
7097 "request: ", BACnetLifeSafetyOperation, 64);
7099 case 3: /* objectId */
7100 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7105 if (offset == lastoffset) break; /* nothing happened, exit loop */
7110 typedef struct _value_string_enum {
7111 const value_string *valstr;
7112 } value_string_enum;
7114 static const value_string_enum
7115 BACnetPropertyStatesEnums[] = {
7120 {BACnetProgramRequest },
7121 {BACnetProgramState },
7122 {BACnetProgramError },
7123 {BACnetReliability },
7124 {BACnetEventState },
7125 {BACnetDeviceStatus },
7126 {BACnetEngineeringUnits },
7128 {BACnetLifeSafetyMode },
7129 {BACnetLifeSafetyState },
7130 {BACnetRestartReason },
7131 {BACnetDoorAlarmState },
7133 {BACnetDoorSecuredStatus },
7134 {BACnetDoorStatus },
7135 { NULL }, /* {BACnetDoorValue }, */
7136 {BACnetFileAccessMethod },
7137 {BACnetLockStatus },
7138 {BACnetLifeSafetyOperation },
7139 {BACnetMaintenance },
7141 {BACnetNotifyType },
7142 { NULL }, /* {BACnetSecurityLevel }, */
7144 {BACnetSilencedState },
7146 { NULL }, /* {BACnetAccessEvent }, */
7147 { NULL }, /* {BACnetZoneOccupancyState }, */
7148 { NULL }, /* {BACnetAccessCredentialDisableReason }, */
7149 { NULL }, /* {BACnetAccessCredentialDisable }, */
7150 { NULL }, /* {BACnetAuthenticationStatus }, */
7152 { NULL }, /* {BACnetBackupState }, */
7154 #define BACnetPropertyStatesEnums_Size 36
7157 fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
7159 guint8 tag_no, tag_info;
7161 const gchar* label = NULL;
7163 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7164 label = ep_strdup_printf( "%s: ", val_to_str_const( tag_no, VALS(BACnetPropertyStates), "unknown-"+tag_no ));
7168 offset = fBooleanTag (tvb, pinfo, tree, offset, label);
7171 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
7174 if ( (tag_no > BACnetPropertyStatesEnums_Size) ||
7175 VALS(BACnetPropertyStatesEnums[tag_no].valstr) == NULL)
7177 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "Unknown State: ", NULL);
7178 /* don't use Abstract type here because it is context tagged and therefore we don't know app type */
7182 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label,
7183 VALS(BACnetPropertyStatesEnums[tag_no].valstr), 64);
7192 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
7193 deviceIdentifier [0] BACnetObjectIdentifier,
7194 objectIdentifier [1] BACnetObjectIdentifier,
7195 propertyIdentifier [2] BACnetPropertyIdentifier,
7196 arrayIndex [3] Unsigned OPTIONAL,
7197 value [4] ABSTRACT-SYNTAX.&Type
7201 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7203 guint lastoffset = 0;
7204 guint8 tag_no, tag_info;
7207 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7208 lastoffset = offset;
7209 /* check the tag. A closing tag means we are done */
7210 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7211 if (tag_is_closing(tag_info)) {
7215 case 0: /* deviceIdentifier */
7216 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7218 case 1: /* objectIdentifier */
7219 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7221 case 2: /* propertyIdentifier */
7222 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7224 case 3: /* arrayIndex - OPTIONAL */
7225 offset = fUnsignedTag (tvb, pinfo, tree, offset,
7229 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7230 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7231 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7236 if (offset == lastoffset) break; /* nothing happened, exit loop */
7242 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7243 objectIdentifier [0] BACnetObjectIdentifier,
7244 propertyIdentifier [1] BACnetPropertyIdentifier,
7245 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7246 -- if omitted with an array then
7247 -- the entire array is referenced
7248 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7252 fObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7254 return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7258 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7259 objectIdentifier [0] BACnetObjectIdentifier,
7260 propertyIdentifier [1] BACnetPropertyIdentifier,
7261 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7262 -- if omitted with an array then
7263 -- the entire array is referenced
7264 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7268 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7270 guint lastoffset = 0;
7271 guint8 tag_no, tag_info;
7274 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7275 lastoffset = offset;
7276 /* check the tag. A closing tag means we are done */
7277 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7278 if (tag_is_closing(tag_info)) {
7282 case 0: /* objectIdentifier */
7283 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7285 case 1: /* propertyIdentifier */
7286 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7288 case 2: /* arrayIndex - OPTIONAL */
7289 offset = fUnsignedTag (tvb, pinfo, tree, offset,
7292 case 3: /* deviceIdentifier - OPTIONAL */
7293 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7298 if (offset == lastoffset) break; /* nothing happened, exit loop */
7304 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7306 guint lastoffset = offset;
7307 guint8 tag_no, tag_info;
7309 proto_tree *subtree = tree;
7312 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7313 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
7314 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
7315 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7316 /* Opening tag for parameter choice */
7317 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7320 case 0: /* change-of-bitstring */
7321 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7322 lastoffset = offset;
7323 switch (fTagNo(tvb, offset)) {
7325 offset = fBitStringTag (tvb, pinfo, subtree, offset,
7326 "referenced-bitstring: ");
7329 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7330 "status-flags: ", BACnetStatusFlags);
7331 lastoffset = offset;
7336 if (offset == lastoffset) break; /* nothing happened, exit loop */
7339 case 1: /* change-of-state */
7340 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7341 lastoffset = offset;
7342 switch (fTagNo(tvb, offset)) {
7344 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7345 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7346 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7349 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7350 "status-flags: ", BACnetStatusFlags);
7351 lastoffset = offset;
7356 if (offset == lastoffset) break; /* nothing happened, exit loop */
7359 case 2: /* change-of-value */
7360 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7361 lastoffset = offset;
7362 switch (fTagNo(tvb, offset)) {
7364 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7365 switch (fTagNo(tvb, offset)) {
7367 offset = fBitStringTag (tvb, pinfo, subtree, offset,
7371 offset = fRealTag (tvb, pinfo, subtree, offset,
7377 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7380 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7381 "status-flags: ", BACnetStatusFlags);
7382 lastoffset = offset;
7387 if (offset == lastoffset) break; /* nothing happened, exit loop */
7390 case 3: /* command-failure */
7391 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7392 lastoffset = offset;
7393 switch (fTagNo(tvb, offset)) {
7394 case 0: /* "command-value: " */
7395 /* from BACnet Table 13-3,
7396 Standard Object Property Values Returned in Notifications */
7397 propertyIdentifier = 85; /* PRESENT_VALUE */
7398 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7399 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7400 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7403 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7404 "status-flags: ", BACnetStatusFlags);
7406 case 2: /* "feedback-value: " */
7407 propertyIdentifier = 40; /* FEEDBACK_VALUE */
7408 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7409 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7410 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7411 lastoffset = offset;
7416 if (offset == lastoffset) break; /* nothing happened, exit loop */
7419 case 4: /* floating-limit */
7420 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7421 lastoffset = offset;
7422 switch (fTagNo(tvb, offset)) {
7424 offset = fRealTag (tvb, pinfo, subtree, offset, "reference-value: ");
7427 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7428 "status-flags: ", BACnetStatusFlags);
7431 offset = fRealTag (tvb, pinfo, subtree, offset, "setpoint-value: ");
7434 offset = fRealTag (tvb, pinfo, subtree, offset, "error-limit: ");
7435 lastoffset = offset;
7440 if (offset == lastoffset) break; /* nothing happened, exit loop */
7443 case 5: /* out-of-range */
7444 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7445 lastoffset = offset;
7446 switch (fTagNo(tvb, offset)) {
7448 offset = fRealTag (tvb, pinfo, subtree, offset, "exceeding-value: ");
7451 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7452 "status-flags: ", BACnetStatusFlags);
7455 offset = fRealTag (tvb, pinfo, subtree, offset, "deadband: ");
7458 offset = fRealTag (tvb, pinfo, subtree, offset, "exceeded-limit: ");
7459 lastoffset = offset;
7464 if (offset == lastoffset) break; /* nothing happened, exit loop */
7468 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7469 lastoffset = offset;
7470 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
7471 if (offset == lastoffset) break; /* nothing happened, exit loop */
7474 case 7: /* buffer-ready */
7475 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7476 lastoffset = offset;
7477 switch (fTagNo(tvb, offset)) {
7479 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
7482 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
7485 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7486 offset = fDateTime (tvb, pinfo, subtree, offset, "previous-notification: ");
7487 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7490 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7491 offset = fDateTime (tvb, pinfo, subtree, offset, "current-notification: ");
7492 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7493 lastoffset = offset;
7498 if (offset == lastoffset) break; /* nothing happened, exit loop */
7501 case 8: /* change-of-life-safety */
7502 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7503 lastoffset = offset;
7504 switch (fTagNo(tvb, offset)) {
7506 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
7507 "new-state: ", BACnetLifeSafetyState, 256);
7510 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
7511 "new-mode: ", BACnetLifeSafetyMode, 256);
7514 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7515 "status-flags: ", BACnetStatusFlags);
7518 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
7519 "operation-expected: ", BACnetLifeSafetyOperation, 64);
7520 lastoffset = offset;
7525 if (offset == lastoffset) break; /* nothing happened, exit loop */
7528 case 9: /* extended */
7529 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7530 lastoffset = offset;
7531 switch (fTagNo(tvb, offset)) {
7533 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
7536 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7537 "extended-event-type: ");
7539 case 2: /* parameters */
7540 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7541 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
7542 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
7543 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7544 lastoffset = offset;
7549 if (offset == lastoffset) break; /* nothing happened, exit loop */
7552 case 10: /* buffer ready */
7553 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7554 lastoffset = offset;
7555 switch (fTagNo(tvb, offset)) {
7556 case 0: /* buffer-property */
7557 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7558 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7559 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7562 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7563 "previous-notification: ");
7566 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7567 "current-notification: ");
7568 lastoffset = offset;
7573 if (offset == lastoffset) break; /* nothing happened, exit loop */
7576 case 11: /* unsigned range */
7577 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7578 lastoffset = offset;
7579 switch (fTagNo(tvb, offset)) {
7581 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7582 "exceeding-value: ");
7585 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7586 "status-flags: ", BACnetStatusFlags);
7589 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7590 "exceeded-limit: ");
7591 lastoffset = offset;
7596 if (offset == lastoffset) break; /* nothing happened, exit loop */
7599 /* todo: add new parameters here ... */
7601 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7605 /* Closing tag for parameter choice */
7606 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7612 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7614 guint lastoffset = offset;
7615 guint8 tag_no, tag_info;
7617 proto_tree *subtree = tree;
7620 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7621 tt = proto_tree_add_text(subtree, tvb, offset, 0, "event parameters (%d) %s",
7622 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
7623 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7624 /* Opening tag for parameter choice */
7625 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7628 case 0: /* change-of-bitstring */
7629 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7630 lastoffset = offset;
7631 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7632 if (tag_is_closing(tag_info)) {
7637 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7640 offset = fBitStringTag (tvb, pinfo, subtree, offset, "bitmask: ");
7642 case 2: /* SEQUENCE OF BIT STRING */
7643 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7644 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7645 lastoffset = offset;
7646 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7647 if (tag_is_closing(tag_info)) {
7650 offset = fBitStringTag(tvb, pinfo, subtree, offset,
7651 "bitstring value: ");
7653 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7660 case 1: /* change-of-state */
7661 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7662 lastoffset = offset;
7663 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7664 if (tag_is_closing(tag_info)) {
7669 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7671 case 1: /* SEQUENCE OF BACnetPropertyStates */
7672 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7673 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7674 lastoffset = offset;
7675 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7676 if (tag_is_closing(tag_info)) {
7679 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7681 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7688 case 2: /* change-of-value */
7689 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7690 lastoffset = offset;
7691 switch (fTagNo(tvb, offset)) {
7693 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7695 case 1: /* don't loop it, it's a CHOICE */
7696 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7697 switch (fTagNo(tvb, offset)) {
7699 offset = fBitStringTag (tvb, pinfo, subtree, offset, "bitmask: ");
7702 offset = fRealTag (tvb, pinfo, subtree, offset,
7703 "referenced Property Increment: ");
7708 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7715 case 3: /* command-failure */
7716 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7717 lastoffset = offset;
7718 tag_no = fTagNo(tvb, offset);
7721 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7724 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7725 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7726 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7733 case 4: /* floating-limit */
7734 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7735 lastoffset = offset;
7736 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7737 if (tag_is_closing(tag_info)) {
7742 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7745 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7746 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7747 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7750 offset = fRealTag (tvb, pinfo, subtree, offset, "low diff limit: ");
7753 offset = fRealTag (tvb, pinfo, subtree, offset, "high diff limit: ");
7756 offset = fRealTag (tvb, pinfo, subtree, offset, "deadband: ");
7763 case 5: /* out-of-range */
7764 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7765 lastoffset = offset;
7766 switch (fTagNo(tvb, offset)) {
7768 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7771 offset = fRealTag (tvb, pinfo, subtree, offset, "low limit: ");
7774 offset = fRealTag (tvb, pinfo, subtree, offset, "high limit: ");
7777 offset = fRealTag (tvb, pinfo, subtree, offset, "deadband: ");
7786 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
7790 case 7: /* buffer-ready */
7793 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
7794 lastoffset = offset;
7795 switch (fTagNo(tvb, offset)) {
7797 offset = fUnsignedTag (tvb,pinfo,tree,offset,"notification threshold");
7800 offset = fUnsignedTag (tvb,pinfo,tree,offset,
7801 "previous notification count: ");
7809 case 8: /* change-of-life-safety */
7810 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7811 lastoffset = offset;
7812 switch (fTagNo(tvb, offset)) {
7814 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7817 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7818 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7819 lastoffset = offset;
7820 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7821 if (tag_is_closing(tag_info)) {
7824 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
7825 "life safety alarm value: ", BACnetLifeSafetyState, 256);
7827 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7830 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7831 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7832 lastoffset = offset;
7833 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7834 if (tag_is_closing(tag_info)) {
7837 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
7838 "alarm value: ", BACnetLifeSafetyState, 256);
7840 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7843 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7844 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7845 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7852 case 9: /* extended */
7853 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7854 lastoffset = offset;
7855 switch (fTagNo(tvb, offset)) {
7857 offset = fVendorIdentifier (tvb, pinfo, tree, offset);
7860 offset = fUnsignedTag (tvb, pinfo, tree, offset,
7861 "extended-event-type: ");
7863 case 2: /* parameters */
7864 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7865 offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
7866 offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
7867 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7868 lastoffset = offset;
7873 if (offset == lastoffset) break; /* nothing happened, exit loop */
7876 case 10: /* buffer-ready */
7877 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7878 lastoffset = offset;
7879 switch (fTagNo(tvb, offset)) {
7881 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7882 "notification-threshold: ");
7885 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7886 "previous-notification-count: ");
7893 case 11: /* unsigned-range */
7894 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7895 lastoffset = offset;
7896 switch (fTagNo(tvb, offset)) {
7898 offset = fTimeSpan (tvb, pinfo, tree, offset, "Time Delay");
7901 offset = fUnsignedTag (tvb, pinfo, tree, offset,
7905 offset = fUnsignedTag (tvb, pinfo, tree, offset,
7913 /* todo: add new event-parameter cases here */
7918 /* Closing tag for parameter choice */
7919 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7924 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7926 guint lastoffset = 0;
7927 guint8 tag_no, tag_info;
7929 proto_tree *subtree = tree;
7932 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7933 lastoffset = offset;
7934 switch (fTagNo(tvb, offset)) {
7935 case 0: /* timestamp */
7936 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7937 offset = fDate (tvb,pinfo,tree,offset,"Date: ");
7938 offset = fTime (tvb,pinfo,tree,offset,"Time: ");
7939 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7941 case 1: /* logDatum: don't loop, it's a CHOICE */
7942 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7943 switch (fTagNo(tvb, offset)) {
7944 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
7945 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
7947 case 1: /* todo: move this to new method fConfirmedEventNotificationRequestTag... */
7948 tt = proto_tree_add_text(tree, tvb, offset, 1, "notification: ");
7949 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7950 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7951 offset = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset);
7952 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7955 offset = fRealTag (tvb, pinfo, tree, offset, "time-change: ");
7960 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7965 if (offset == lastoffset) break; /* nothing happened, exit loop */
7971 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7973 guint lastoffset = 0;
7974 guint8 tag_no, tag_info;
7977 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7978 lastoffset = offset;
7979 switch (fTagNo(tvb, offset)) {
7980 case 0: /* timestamp */
7981 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7982 offset = fDate (tvb,pinfo,tree,offset,"Date: ");
7983 offset = fTime (tvb,pinfo,tree,offset,"Time: ");
7984 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7986 case 1: /* logDatum: don't loop, it's a CHOICE */
7987 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7988 switch (fTagNo(tvb, offset)) {
7989 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
7990 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
7993 offset = fBooleanTag (tvb, pinfo, tree, offset, "boolean-value: ");
7996 offset = fRealTag (tvb, pinfo, tree, offset, "real value: ");
7999 offset = fUnsignedTag (tvb, pinfo, tree, offset, "enum value: ");
8002 offset = fUnsignedTag (tvb, pinfo, tree, offset, "unsigned value: ");
8005 offset = fSignedTag (tvb, pinfo, tree, offset, "signed value: ");
8008 offset = fBitStringTag (tvb, pinfo, tree, offset, "bitstring value: ");
8011 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8014 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8015 offset = fError (tvb, pinfo, tree, offset);
8016 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8019 offset = fRealTag (tvb, pinfo, tree, offset, "time change: ");
8021 case 10: /* any Value */
8022 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8023 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
8024 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8029 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8032 /* Changed this to BitString per BACnet Spec. */
8033 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "Status Flags:", BACnetStatusFlags);
8038 if (offset == lastoffset) break; /* nothing happened, exit loop */
8044 fLogMultipleRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8046 guint lastoffset = 0;
8047 guint8 tag_no, tag_info;
8050 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8051 lastoffset = offset;
8052 switch (fTagNo(tvb, offset)) {
8053 case 0: /* timestamp */
8054 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8055 offset = fDate (tvb,pinfo,tree,offset,"Date: ");
8056 offset = fTime (tvb,pinfo,tree,offset,"Time: ");
8057 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8059 case 1: /* logData: don't loop, it's a CHOICE */
8060 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8061 switch (fTagNo(tvb, offset)) {
8062 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8063 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8065 case 1: /* log-data: SEQUENCE OF CHOICE */
8066 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8067 while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset != lastoffset)) { /* exit loop if nothing happens inside */
8068 lastoffset = offset;
8069 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8070 if (tag_is_closing(tag_info)) {
8071 lastoffset = offset;
8076 offset = fBooleanTag (tvb, pinfo, tree, offset, "boolean-value: ");
8079 offset = fRealTag (tvb, pinfo, tree, offset, "real value: ");
8082 offset = fUnsignedTag (tvb, pinfo, tree, offset, "enum value: ");
8085 offset = fUnsignedTag (tvb, pinfo, tree, offset, "unsigned value: ");
8088 offset = fSignedTag (tvb, pinfo, tree, offset, "signed value: ");
8091 offset = fBitStringTag (tvb, pinfo, tree, offset, "bitstring value: ");
8094 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8097 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8098 offset = fError (tvb, pinfo, tree, offset);
8099 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8101 case 8: /* any Value */
8102 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8103 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
8104 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8110 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8113 offset = fRealTag (tvb, pinfo, tree, offset, "time-change: ");
8118 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8123 if (offset == lastoffset) break; /* nothing happened, exit loop */
8130 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8132 guint lastoffset = 0;
8133 guint8 tag_no, tag_info;
8136 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8137 lastoffset = offset;
8138 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8139 if (tag_is_closing(tag_info)) {
8140 lastoffset = offset;
8145 case 0: /* ProcessId */
8146 offset = fProcessId (tvb,pinfo,tree,offset);
8148 case 1: /* initiating ObjectId */
8149 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8151 case 2: /* event ObjectId */
8152 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8154 case 3: /* time stamp */
8155 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8156 offset = fTimeStamp (tvb, pinfo, tree, offset, NULL);
8157 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8159 case 4: /* notificationClass */
8160 offset = fUnsignedTag (tvb, pinfo, tree, offset, "Notification Class: ");
8162 case 5: /* Priority */
8163 offset = fUnsignedTag (tvb, pinfo, tree, offset, "Priority: ");
8165 case 6: /* EventType */
8166 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
8167 "Event Type: ", BACnetEventType, 64);
8169 case 7: /* messageText */
8170 offset = fCharacterString (tvb, pinfo, tree, offset, "message Text: ");
8172 case 8: /* NotifyType */
8173 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8174 "Notify Type: ", BACnetNotifyType);
8176 case 9: /* ackRequired */
8177 offset = fBooleanTag (tvb, pinfo, tree, offset, "ack Required: ");
8179 case 10: /* fromState */
8180 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
8181 "from State: ", BACnetEventState, 64);
8183 case 11: /* toState */
8184 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
8185 "to State: ", BACnetEventState, 64);
8187 case 12: /* NotificationParameters */
8188 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8189 offset = fNotificationParameters (tvb, pinfo, tree, offset);
8190 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8195 if (offset == lastoffset) break; /* nothing happened, exit loop */
8201 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8203 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8207 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8209 guint lastoffset = 0, len;
8210 guint8 tag_no, tag_info;
8212 proto_tree *subtree = tree;
8215 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8216 lastoffset = offset;
8217 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8218 if (tag_is_closing(tag_info)) {
8225 case 0: /* ProcessId */
8226 offset = fProcessId (tvb,pinfo,tree,offset);
8228 case 1: /* initiating DeviceId */
8229 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8231 case 2: /* monitored ObjectId */
8232 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8234 case 3: /* time remaining */
8235 offset = fTimeSpan (tvb, pinfo, tree, offset, "Time remaining");
8237 case 4: /* List of Values */
8238 if (tag_is_opening(tag_info)) {
8239 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
8240 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8241 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8242 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8250 if (offset == lastoffset) break; /* nothing happened, exit loop */
8256 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8258 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8262 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8264 guint lastoffset = 0;
8265 guint8 tag_no = 0, tag_info = 0;
8268 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8269 lastoffset = offset;
8270 switch (fTagNo(tvb, offset)) {
8271 case 0: /* acknowledgingProcessId */
8272 offset = fUnsignedTag (tvb, pinfo, tree, offset, "acknowledging Process Id: ");
8274 case 1: /* eventObjectId */
8275 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8277 case 2: /* eventStateAcknowledged */
8278 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
8279 "event State Acknowledged: ", BACnetEventState, 64);
8281 case 3: /* timeStamp */
8282 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8283 offset = fTimeStamp(tvb, pinfo, tree, offset, NULL);
8284 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8286 case 4: /* acknowledgementSource */
8287 offset = fCharacterString (tvb, pinfo, tree, offset, "acknowledgement Source: ");
8289 case 5: /* timeOfAcknowledgement */
8290 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8291 offset = fTimeStamp(tvb, pinfo, tree, offset, "acknowledgement timestamp: ");
8292 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8297 if (offset == lastoffset) break; /* nothing happened, exit loop */
8303 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8305 guint lastoffset = 0;
8307 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8308 lastoffset = offset;
8309 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8310 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8311 "alarm State: ", BACnetEventState, 64);
8312 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8313 "acknowledged Transitions: ", BACnetEventTransitionBits);
8314 if (offset == lastoffset) break; /* nothing happened, exit loop */
8320 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8322 guint lastoffset = 0;
8323 guint8 tag_no, tag_info;
8326 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8327 lastoffset = offset;
8328 switch (fTagNo(tvb, offset)) {
8329 case 0: /* acknowledgmentFilter */
8330 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8331 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
8333 case 1: /* eventObjectId - OPTIONAL */
8334 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8335 offset = fRecipientProcess (tvb, pinfo, tree, offset);
8336 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8338 case 2: /* eventStateFilter */
8339 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8340 "event State Filter: ", BACnetEventStateFilter);
8342 case 3: /* eventTypeFilter - OPTIONAL */
8343 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8344 "event Type Filter: ", BACnetEventType);
8346 case 4: /* priorityFilter */
8347 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8348 offset = fUnsignedTag (tvb, pinfo, tree, offset, "min Priority: ");
8349 offset = fUnsignedTag (tvb, pinfo, tree, offset, "max Priority: ");
8350 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8352 case 5: /* notificationClassFilter - OPTIONAL */
8353 offset = fUnsignedTag (tvb, pinfo, tree, offset, "notification Class Filter: ");
8358 if (offset == lastoffset) break; /* nothing happened, exit loop */
8364 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8366 guint lastoffset = 0;
8368 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8369 lastoffset = offset;
8370 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8371 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8372 "event Type: ", BACnetEventType, 64);
8373 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8374 "event State: ", BACnetEventState);
8375 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
8376 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
8377 if (offset == lastoffset) break; /* nothing happened, exit loop */
8384 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8386 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8387 if (fTagNo(tvb, offset) == 0) {
8388 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8395 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8397 guint lastoffset = 0;
8398 guint8 tag_no, tag_info;
8400 proto_tree* subtree = tree;
8403 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8404 lastoffset = offset;
8405 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8406 /* we are finished here if we spot a closing tag */
8407 if (tag_is_closing(tag_info)) {
8411 case 0: /* ObjectId */
8412 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8414 case 1: /* eventState */
8415 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8416 "event State: ", BACnetEventState);
8418 case 2: /* acknowledgedTransitions */
8419 offset = fBitStringTagVS (tvb, pinfo, tree, offset,
8420 "acknowledged Transitions: ", BACnetEventTransitionBits);
8422 case 3: /* eventTimeStamps */
8423 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
8425 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8427 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8428 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-OFFNORMAL timestamp: ");
8429 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-FAULT timestamp: ");
8430 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-NORMAL timestamp: ");
8431 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8433 case 4: /* notifyType */
8434 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8435 "Notify Type: ", BACnetNotifyType);
8437 case 5: /* eventEnable */
8438 offset = fBitStringTagVS (tvb, pinfo, tree, offset,
8439 "event Enable: ", BACnetEventTransitionBits);
8441 case 6: /* eventPriorities */
8442 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
8444 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8446 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8447 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "TO-OFFNORMAL Priority: ");
8448 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "TO-FAULT Priority: ");
8449 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "TO-NORMAL Priority: ");
8450 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8455 if (offset == lastoffset) break; /* nothing happened, exit loop */
8461 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8463 guint lastoffset = 0;
8464 guint8 tag_no, tag_info;
8467 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8468 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8469 lastoffset = offset;
8470 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8471 /* we are finished here if we spot a closing tag */
8472 if (tag_is_closing(tag_info)) {
8475 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
8476 if (offset == lastoffset) break; /* nothing happened, exit loop */
8482 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8484 guint lastoffset = 0;
8485 guint8 tag_no, tag_info;
8488 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8489 lastoffset = offset;
8490 switch (fTagNo(tvb, offset)) {
8491 case 0: /* listOfEventSummaries */
8492 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8493 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
8494 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8496 case 1: /* moreEvents */
8497 offset = fBooleanTag (tvb, pinfo, tree, offset, "more Events: ");
8502 if (offset == lastoffset) break; /* nothing happened, exit loop */
8508 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8510 guint lastoffset = 0, len;
8511 guint8 tag_no, tag_info;
8513 proto_tree *subtree = tree;
8516 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8518 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8519 lastoffset = offset;
8520 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8521 if (tag_is_closing(tag_info)) {
8528 case 0: /* ObjectId */
8529 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
8531 case 3: /* listOfElements */
8532 if (tag_is_opening(tag_info)) {
8533 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
8534 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8535 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8536 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8544 if (offset == lastoffset) break; /* nothing happened, exit loop */
8550 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8552 return fObjectIdentifier (tvb, pinfo, tree, offset);
8556 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8558 guint lastoffset = 0;
8560 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8561 lastoffset = offset;
8563 switch (fTagNo(tvb, offset)) {
8564 case 0: /* timeDuration */
8565 offset = fUnsignedTag (tvb,pinfo,tree,offset,"time Duration: ");
8567 case 1: /* enable-disable */
8568 offset = fEnumeratedTag (tvb, pinfo, tree, offset, "enable-disable: ",
8569 BACnetEnableDisable);
8571 case 2: /* password - OPTIONAL */
8572 offset = fCharacterString (tvb, pinfo, tree, offset, "Password: ");
8577 if (offset == lastoffset) break; /* nothing happened, exit loop */
8583 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8585 guint lastoffset = 0;
8587 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8588 lastoffset = offset;
8590 switch (fTagNo(tvb, offset)) {
8591 case 0: /* reinitializedStateOfDevice */
8592 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8593 "reinitialized State Of Device: ",
8594 BACnetReinitializedStateOfDevice);
8596 case 1: /* password - OPTIONAL */
8597 offset = fCharacterString (tvb, pinfo, tree, offset, "Password: ");
8602 if (offset == lastoffset) break; /* nothing happened, exit loop */
8608 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8610 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8611 "vtClass: ", BACnetVTClass);
8612 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
8616 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8618 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
8622 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8624 guint lastoffset = 0;
8626 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8627 lastoffset = offset;
8628 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
8629 if (offset == lastoffset) break; /* nothing happened, exit loop */
8635 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8637 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
8638 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
8639 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");
8643 fVtDataAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8645 guint lastoffset = 0;
8647 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8648 lastoffset = offset;
8650 switch (fTagNo(tvb,offset)) {
8651 case 0: /* BOOLEAN */
8652 offset = fBooleanTag (tvb, pinfo, tree, offset, "all New Data Accepted: ");
8654 case 1: /* Unsigned OPTIONAL */
8655 offset = fUnsignedTag (tvb, pinfo, tree, offset, "accepted Octet Count: ");
8660 if (offset == lastoffset) break; /* nothing happened, exit loop */
8666 fAuthenticateRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8668 guint lastoffset = 0;
8670 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8671 lastoffset = offset;
8673 switch (fTagNo(tvb,offset)) {
8674 case 0: /* Unsigned32 */
8675 offset = fUnsignedTag (tvb, pinfo, tree, offset, "pseudo Random Number: ");
8677 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
8678 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
8680 case 2: /* Chararacter String OPTIONAL */
8681 offset = fCharacterString (tvb, pinfo, tree, offset, "operator Name: ");
8683 case 3: /* Chararacter String OPTIONAL */
8684 offset = fCharacterString (tvb, pinfo, tree, offset, "operator Password: ");
8686 case 4: /* Boolean OPTIONAL */
8687 offset = fBooleanTag (tvb, pinfo, tree, offset, "start Encyphered Session: ");
8692 if (offset == lastoffset) break; /* nothing happened, exit loop */
8698 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8700 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
8704 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8706 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
8707 offset = fAddress (tvb, pinfo, tree, offset);
8708 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
8709 return fAddress (tvb, pinfo, tree, offset);
8713 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8715 /* Same as AddListElement request after service choice */
8716 return fAddListElementRequest(tvb, pinfo, tree, offset);
8720 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8722 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8726 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8728 guint lastoffset = 0, len;
8729 guint8 tag_no, tag_info;
8731 proto_tree *subtree = tree;
8733 /* set the optional global properties to indicate not-used */
8734 propertyArrayIndex = -1;
8735 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8736 lastoffset = offset;
8737 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
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, pinfo, subtree, offset);
8753 case 3: /* propertyValue */
8754 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8759 if (offset == lastoffset) break; /* nothing happened, exit loop */
8765 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8767 guint lastoffset = 0;
8768 guint8 tag_no, tag_info;
8770 proto_tree *subtree = tree;
8772 /* set the optional global properties to indicate not-used */
8773 propertyArrayIndex = -1;
8774 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8775 lastoffset = offset;
8776 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8777 /* quit loop 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: /* propertyIdentifier */
8788 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8790 case 2: /* propertyArrayIndex */
8791 offset = fPropertyArrayIndex (tvb, pinfo, subtree, offset);
8793 case 3: /* propertyValue */
8794 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8796 case 4: /* Priority (only used for write) */
8797 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "Priority: ");
8802 if (offset == lastoffset) break; /* nothing happened, exit loop */
8808 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8810 guint lastoffset = 0, len;
8811 guint8 tag_no, tag_info;
8814 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8815 lastoffset = offset;
8816 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8817 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
8818 if (tag_is_closing(tag_info)) {
8824 case 0: /* objectIdentifier */
8825 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8827 case 1: /* listOfPropertyValues */
8828 if (tag_is_opening(tag_info)) {
8829 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8830 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8838 if (offset == lastoffset) break; /* nothing happened, exit loop */
8844 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8846 if (offset >= tvb_reported_length(tvb))
8849 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8850 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
8854 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
8856 guint lastoffset = 0;
8857 guint8 tag_no, tag_info;
8860 /* set the optional global properties to indicate not-used */
8861 propertyArrayIndex = -1;
8862 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8863 lastoffset = offset;
8864 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8865 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
8867 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
8870 switch (tag_no-tagoffset) {
8871 case 0: /* PropertyIdentifier */
8872 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
8874 case 1: /* propertyArrayIndex */
8875 offset = fPropertyArrayIndex (tvb, pinfo, tree, offset);
8876 if (list != 0) break; /* Continue decoding if this may be a list */
8878 lastoffset = offset; /* Set loop end condition */
8881 if (offset == lastoffset) break; /* nothing happened, exit loop */
8887 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
8889 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8890 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
8894 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8896 guint lastoffset = 0;
8898 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8899 lastoffset = offset;
8901 switch (fTagNo(tvb,offset)) {
8902 case 0: /* ObjectIdentifier */
8903 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8905 case 1: /* PropertyIdentifier and propertyArrayIndex */
8906 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
8907 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8909 lastoffset = offset; /* Set loop end condition */
8912 if (offset == lastoffset) break; /* nothing happened, exit loop */
8919 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
8921 guint lastoffset = 0;
8922 guint8 tag_no, tag_info;
8924 proto_tree* subtree = tree;
8927 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8928 lastoffset = offset;
8929 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8930 if (tag_is_closing(tag_info)) {
8931 offset += fTagHeaderTree (tvb, pinfo, subtree, offset,
8932 &tag_no, &tag_info, &lvt);
8936 case 0: /* ObjectIdentifier */
8937 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8939 case 1: /* PropertyIdentifier */
8940 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
8942 case 2: /* propertyArrayIndex */
8943 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "property Array Index: ");
8946 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
8948 case 4: /* Priority */
8949 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "Priority: ");
8960 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8962 char i = 1, ar[256];
8963 guint lastoffset = 0;
8965 if (propertyArrayIndex > 0) {
8966 /* BACnetARRAY index 0 refers to the length
8967 of the array, not the elements of the array.
8968 BACnetARRAY index -1 is our internal flag that
8969 the optional index was not used.
8970 BACnetARRAY refers to this as all elements of the array.
8971 If the optional index is specified for a BACnetARRAY,
8972 then that specific array element is referenced. */
8973 i = propertyArrayIndex;
8975 while (tvb_reported_length_remaining(tvb, offset) > 0) {
8976 /* exit loop if nothing happens inside */
8977 lastoffset = offset;
8978 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
8979 val_to_split_str(87 , 512,
8980 BACnetPropertyIdentifier,
8981 ASHRAE_Reserved_Fmt,
8982 Vendor_Proprietary_Fmt),
8984 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
8985 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
8986 /* there are only 16 priority array elements */
8990 if (offset == lastoffset) break; /* nothing happened, exit loop */
8997 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8999 guint lastoffset = 0;
9001 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9002 lastoffset = offset;
9004 switch (fTagNo(tvb,offset)) {
9005 case 0: /* deviceIdentifier - OPTIONAL */
9006 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9008 case 1: /* ObjectIdentifier */
9009 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9014 if (offset == lastoffset) break; /* nothing happened, exit loop */
9020 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9022 guint8 tag_no, tag_info;
9024 guint lastoffset = 0, len;
9025 gboolean closing_found = FALSE; /* tracks when we are done decoding the fSpecialEvent entries */
9027 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9028 lastoffset = offset;
9029 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9030 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
9031 if (tag_is_closing(tag_info)) {
9032 /* if we find 2 closing tags in succession we need to exit without incrementing the offset again */
9033 /* This handles the special case where we have a special event entry in an RPM-ACK msg */
9034 if ( closing_found == TRUE )
9037 closing_found = TRUE;
9042 case 0: /* calendarEntry */
9043 if (tag_is_opening(tag_info)) {
9044 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9045 offset = fCalendarEntry (tvb, pinfo, subtree, offset);
9046 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9049 case 1: /* calendarReference */
9050 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9052 case 2: /* list of BACnetTimeValue */
9053 if (tag_is_opening(tag_info)) {
9054 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9055 offset = fTimeValue (tvb, pinfo, subtree, offset);
9056 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9061 case 3: /* eventPriority */
9062 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "event priority: ");
9067 closing_found = FALSE; /* reset our closing tag status, we processed another open tag */
9068 if (offset == lastoffset) break; /* nothing happened, exit loop */
9074 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9076 guint lastoffset = 0, len;
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 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9083 /* maybe a listOfSelectionCriteria if we spot a closing tag */
9084 if (tag_is_closing(tag_info)) {
9089 switch (fTagNo(tvb,offset)) {
9090 case 0: /* propertyIdentifier */
9091 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
9093 case 1: /* propertyArrayIndex */
9094 offset = fPropertyArrayIndex (tvb, pinfo, tree, offset);
9096 case 2: /* relationSpecifier */
9097 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
9098 "relation Specifier: ", BACnetRelationSpecifier);
9100 case 3: /* comparisonValue */
9101 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9102 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
9103 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9108 if (offset == lastoffset) break; /* nothing happened, exit loop */
9114 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9116 guint lastoffset = 0;
9117 guint8 tag_no, tag_info;
9120 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9121 lastoffset = offset;
9122 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9123 /* quit loop if we spot a closing tag */
9124 if (tag_is_closing(tag_info)) {
9129 case 0: /* selectionLogic */
9130 offset = fEnumeratedTag (tvb, pinfo, subtree, offset,
9131 "selection Logic: ", BACnetSelectionLogic);
9133 case 1: /* listOfSelectionCriteria */
9134 if (tag_is_opening(tag_info)) {
9135 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9136 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
9137 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9145 if (offset == lastoffset) break; /* nothing happened, exit loop */
9152 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
9154 guint lastoffset = 0;
9155 guint8 tag_no, tag_info;
9158 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9159 lastoffset = offset;
9160 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9162 if (tag_is_opening(tag_info) && tag_no < 2) {
9163 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9165 case 0: /* objectSelectionCriteria */
9166 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
9168 case 1: /* listOfPropertyReferences */
9169 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
9174 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9176 if (offset == lastoffset) break; /* nothing happened, exit loop */
9182 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9184 guint lastoffset = 0;
9185 guint8 tag_no, tag_info;
9188 proto_tree *subtree = tree;
9190 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9191 lastoffset = offset;
9192 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9194 case 0: /* objectIdentifier */
9195 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9197 case 1: /* listOfPropertyReferences */
9198 if (tag_is_opening(tag_info)) {
9199 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
9200 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9201 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9202 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
9203 } else if (tag_is_closing(tag_info)) {
9204 offset += fTagHeaderTree (tvb, pinfo, subtree, offset,
9205 &tag_no, &tag_info, &lvt);
9208 /* error condition: let caller handle */
9215 if (offset == lastoffset) break; /* nothing happened, exit loop */
9221 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9223 guint lastoffset = 0, len;
9227 proto_tree *subtree = tree;
9230 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9231 lastoffset = offset;
9232 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9233 /* maybe a listOfReadAccessResults if we spot a closing tag here */
9234 if (tag_is_closing(tag_info)) {
9236 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
9241 case 0: /* objectSpecifier */
9242 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9244 case 1: /* list of Results */
9245 if (tag_is_opening(tag_info)) {
9246 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
9247 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9248 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9253 case 2: /* propertyIdentifier */
9254 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
9256 case 5: /* propertyAccessError */
9257 if (tag_is_opening(tag_info)) {
9258 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
9259 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9260 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9261 /* Error Code follows */
9262 offset = fError(tvb, pinfo, subtree, offset);
9270 if (offset == lastoffset) break; /* nothing happened, exit loop */
9277 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9279 /* listOfReadAccessResults */
9280 return fReadAccessResult (tvb, pinfo, tree, offset);
9285 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9287 guint lastoffset = 0;
9288 guint8 tag_no, tag_info;
9291 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9292 lastoffset = offset;
9293 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9296 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9298 case 0: /* objectSpecifier */
9299 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
9300 case 0: /* objectType */
9301 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset, "Object Type: ", BACnetObjectType, 128);
9303 case 1: /* objectIdentifier */
9304 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9310 case 1: /* propertyValue */
9311 if (tag_is_opening(tag_info)) {
9312 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
9320 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9322 if (offset == lastoffset) break; /* nothing happened, exit loop */
9328 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9330 return fObjectIdentifier (tvb, pinfo, tree, offset);
9334 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9336 guint8 tag_no, tag_info;
9338 proto_tree *subtree = tree;
9341 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9343 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9344 /* optional range choice */
9345 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9346 if (tag_is_opening(tag_info)) {
9347 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
9348 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9349 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9351 case 3: /* range byPosition */
9352 case 6: /* range bySequenceNumber, 2004 spec */
9353 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
9354 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
9356 case 4: /* range byTime - deprecated in 2004 */
9357 case 7: /* 2004 spec */
9358 offset = fDateTime(tvb, pinfo, subtree, offset, "reference Date/Time: ");
9359 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
9361 case 5: /* range timeRange - deprecated in 2004 */
9362 offset = fDateTime(tvb, pinfo, subtree, offset, "beginning Time: ");
9363 offset = fDateTime(tvb, pinfo, subtree, offset, "ending Time: ");
9368 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9375 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9377 guint8 tag_no, tag_info;
9379 proto_tree *subtree = tree;
9382 /* set the optional global properties to indicate not-used */
9383 propertyArrayIndex = -1;
9384 /* objectIdentifier, propertyIdentifier, and
9385 OPTIONAL propertyArrayIndex */
9386 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9387 /* resultFlags => BACnetResultFlags ::= BIT STRING */
9388 offset = fBitStringTagVS (tvb, pinfo, tree, offset,
9392 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "item Count: ");
9394 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9395 if (tag_is_opening(tag_info)) {
9396 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9397 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
9398 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9399 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9400 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
9401 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9403 /* firstSequenceNumber - OPTIONAL */
9404 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9405 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "first Sequence Number: ");
9412 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9414 guint lastoffset = 0;
9416 guint8 tag_no, tag_info;
9418 proto_tree* subtree = NULL;
9420 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9422 if (tag_is_opening(tag_info)) {
9423 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
9424 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9425 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9426 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
9427 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
9430 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
9431 /* exit loop if nothing happens inside */
9432 lastoffset = offset;
9433 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
9437 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
9438 /* More Flag is not set, so we can look for closing tag in this segment */
9439 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9440 if (tag_is_closing(tag_info)) {
9441 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9449 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9451 guint8 tag_no, tag_info;
9453 proto_tree *subtree = tree;
9456 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9458 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9460 if (tag_is_opening(tag_info)) {
9461 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
9462 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9463 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9464 offset = fSignedTag (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
9465 offset = fUnsignedTag (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
9466 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9472 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9475 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
9476 offset = fAccessMethod(tvb, pinfo, tree, offset);
9482 fAtomicWriteFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9484 guint tag_no = fTagNo(tvb, offset);
9485 return fSignedTag (tvb, pinfo, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
9489 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9491 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
9492 offset = fAccessMethod(tvb,pinfo, tree, offset);
9498 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9500 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9501 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
9505 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9507 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9508 return fReadAccessResult (tvb,pinfo,tree,offset);
9512 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9514 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9517 switch (service_choice) {
9518 case 0: /* acknowledgeAlarm */
9519 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
9521 case 1: /* confirmedCOVNotification */
9522 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
9524 case 2: /* confirmedEventNotification */
9525 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
9527 case 3: /* confirmedGetAlarmSummary conveys no parameters */
9529 case 4: /* getEnrollmentSummaryRequest */
9530 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
9532 case 5: /* subscribeCOVRequest */
9533 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
9535 case 6: /* atomicReadFile-Request */
9536 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
9538 case 7: /* atomicWriteFile-Request */
9539 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
9541 case 8: /* AddListElement-Request */
9542 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
9544 case 9: /* removeListElement-Request */
9545 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
9547 case 10: /* createObjectRequest */
9548 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
9550 case 11: /* deleteObject */
9551 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
9554 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
9557 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
9560 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
9563 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
9566 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
9569 offset = fDeviceCommunicationControlRequest(tvb, pinfo, tree, offset);
9572 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
9575 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
9578 offset = fReinitializeDeviceRequest(tvb, pinfo, tree, offset);
9581 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
9584 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
9587 offset = fVtDataRequest (tvb, pinfo, tree, offset);
9590 offset = fAuthenticateRequest (tvb, pinfo, tree, offset);
9593 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
9596 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
9599 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
9602 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
9605 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
9614 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9616 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9619 switch (service_choice) {
9620 case 3: /* confirmedEventNotificationAck */
9621 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
9623 case 4: /* getEnrollmentSummaryAck */
9624 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
9626 case 6: /* atomicReadFile */
9627 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
9629 case 7: /* atomicReadFileAck */
9630 offset = fAtomicWriteFileAck (tvb, pinfo, tree, offset);
9632 case 10: /* createObject */
9633 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
9636 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
9639 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
9642 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
9645 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
9648 offset = fVtOpenAck (tvb, pinfo, tree, offset);
9651 offset = fVtDataAck (tvb, pinfo, tree, offset);
9654 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
9657 offset = fReadRangeAck (tvb, pinfo, tree, offset);
9660 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
9669 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9671 /* BACnetObjectIdentifier */
9672 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
9674 /* MaxAPDULengthAccepted */
9675 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
9677 /* segmentationSupported */
9678 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
9679 "Segmentation Supported: ", BACnetSegmentation);
9682 return fVendorIdentifier (tvb, pinfo, tree, offset);
9686 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9688 /* BACnetDeviceIdentifier */
9689 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
9691 /* BACnetObjectIdentifier */
9692 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
9695 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
9700 fWhoIsRequest (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
9702 guint lastoffset = 0;
9706 guint8 tag_no, tag_info;
9709 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9710 lastoffset = offset;
9712 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9716 /* DeviceInstanceRangeLowLimit Optional */
9717 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
9718 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
9719 offset = fDevice_Instance (tvb, pinfo, tree, offset,
9720 hf_Device_Instance_Range_Low_Limit);
9723 /* DeviceInstanceRangeHighLimit Optional but
9724 required if DeviceInstanceRangeLowLimit is there */
9725 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
9726 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
9727 offset = fDevice_Instance (tvb, pinfo, tree, offset,
9728 hf_Device_Instance_Range_High_Limit);
9733 if (offset == lastoffset) break; /* nothing happened, exit loop */
9739 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9741 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9744 switch (service_choice) {
9745 case 0: /* I-Am-Request */
9746 offset = fIAmRequest (tvb, pinfo, tree, offset);
9748 case 1: /* i-Have Request */
9749 offset = fIHaveRequest (tvb, pinfo, tree, offset);
9751 case 2: /* unconfirmedCOVNotification */
9752 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
9754 case 3: /* unconfirmedEventNotification */
9755 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
9757 case 4: /* unconfirmedPrivateTransfer */
9758 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
9760 case 5: /* unconfirmedTextMessage */
9761 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
9763 case 6: /* timeSynchronization */
9764 offset = fTimeSynchronizationRequest (tvb, pinfo, tree, offset);
9766 case 7: /* who-Has */
9767 offset = fWhoHas (tvb, pinfo, tree, offset);
9769 case 8: /* who-Is */
9770 offset = fWhoIsRequest (tvb, pinfo, tree, offset);
9772 case 9: /* utcTimeSynchronization */
9773 offset = fUTCTimeSynchronizationRequest (tvb, pinfo, tree, offset);
9782 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
9783 gint *svc, proto_item **tt)
9786 proto_tree *bacapp_tree_control;
9791 tmp = (gint) tvb_get_guint8(tvb, offset);
9792 bacapp_flags = tmp & 0x0f;
9797 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
9798 if (bacapp_flags & 0x08)
9799 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
9801 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9802 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
9803 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
9805 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
9806 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
9807 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
9808 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
9809 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
9810 offset, 1, ENC_BIG_ENDIAN);
9811 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
9812 offset, 1, ENC_BIG_ENDIAN);
9815 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
9816 if (bacapp_flags & 0x08) {
9817 bacapp_seq = tvb_get_guint8(tvb, offset);
9818 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
9819 offset++, 1, ENC_BIG_ENDIAN);
9820 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
9821 offset++, 1, ENC_BIG_ENDIAN);
9823 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
9824 offset++, 1, ENC_BIG_ENDIAN);
9829 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
9830 { /* BACnet-Confirmed-Request */
9831 /* ASHRAE 135-2001 20.1.2 */
9833 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
9837 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9838 { /* BACnet-Confirmed-Request */
9839 /* ASHRAE 135-2001 20.1.2 */
9843 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
9844 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
9848 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9849 { /* BACnet-Unconfirmed-Request-PDU */
9850 /* ASHRAE 135-2001 20.1.3 */
9854 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9856 tmp = tvb_get_guint8(tvb, offset);
9857 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
9858 offset++, 1, ENC_BIG_ENDIAN);
9859 /* Service Request follows... Variable Encoding 20.2ff */
9860 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
9864 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9865 { /* BACnet-Simple-Ack-PDU */
9866 /* ASHRAE 135-2001 20.1.4 */
9868 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
9870 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
9871 offset++, 1, ENC_BIG_ENDIAN);
9872 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
9873 offset++, 1, ENC_BIG_ENDIAN);
9879 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
9880 { /* BACnet-Complex-Ack-PDU */
9881 /* ASHRAE 135-2001 20.1.5 */
9883 /* Service ACK follows... */
9884 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
9888 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
9889 { /* BACnet-Complex-Ack-PDU */
9890 /* ASHRAE 135-2001 20.1.5 */
9894 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
9895 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
9899 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
9900 { /* BACnet-SegmentAck-PDU */
9901 /* ASHRAE 135-2001 20.1.6 */
9904 proto_tree *bacapp_tree_control;
9906 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
9907 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
9909 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
9910 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
9911 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
9912 offset++, 1, ENC_BIG_ENDIAN);
9913 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
9914 offset++, 1, ENC_BIG_ENDIAN);
9915 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
9916 offset++, 1, ENC_BIG_ENDIAN);
9921 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9923 guint8 tag_info = 0;
9924 guint8 parsed_tag = 0;
9927 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
9928 offset = fError(tvb, pinfo, tree, offset);
9929 return offset + fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
9933 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9935 guint lastoffset = 0;
9936 guint8 tag_no = 0, tag_info = 0;
9938 proto_tree *subtree = tree;
9941 guint vendor_identifier = 0;
9942 guint service_number = 0;
9945 while (tvb_reported_length_remaining(tvb, offset) > 0) {
9946 /* exit loop if nothing happens inside */
9947 lastoffset = offset;
9948 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9950 case 0: /* errorType */
9951 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
9953 case 1: /* vendorID */
9954 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
9955 if (col_get_writable(pinfo->cinfo))
9956 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
9957 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
9959 case 2: /* serviceNumber */
9960 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
9961 if (col_get_writable(pinfo->cinfo))
9962 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
9963 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "service Number: ");
9965 case 3: /* errorParameters */
9966 if (tag_is_opening(tag_info)) {
9967 tt = proto_tree_add_text(subtree, tvb, offset, 1,
9968 "error Parameters");
9969 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9970 propertyIdentifier = -1;
9971 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9972 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
9973 } else if (tag_is_closing(tag_info)) {
9974 offset += fTagHeaderTree (tvb, pinfo, subtree, offset,
9975 &tag_no, &tag_info, &lvt);
9978 /* error condition: let caller handle */
9985 if (offset == lastoffset) break; /* nothing happened, exit loop */
9991 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9993 guint lastoffset = 0;
9995 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9996 lastoffset = offset;
9997 switch (fTagNo(tvb, offset)) {
9998 case 0: /* errorType */
9999 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10001 case 1: /* firstFailedElementNumber */
10002 offset = fUnsignedTag (tvb,pinfo,tree,offset,"first failed element number: ");
10007 if (offset == lastoffset) break; /* nothing happened, exit loop */
10013 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10015 /* Identical to CreateObjectError */
10016 return fCreateObjectError(tvb, pinfo, tree, offset);
10020 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10022 guint8 tag_no = 0, tag_info = 0;
10025 if (fTagNo(tvb, offset) == 0) {
10027 offset = fContextTaggedError(tvb, pinfo, tree,offset);
10028 if (fTagNo(tvb, offset) == 1) {
10029 /* listOfVTSessionIdentifiers [OPTIONAL] */
10030 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10031 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
10032 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10035 /* should report bad packet if initial tag wasn't 0 */
10040 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10042 guint lastoffset = 0;
10043 guint8 tag_no = 0, tag_info = 0;
10046 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10047 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10048 lastoffset = offset;
10049 switch (fTagNo(tvb, offset)) {
10050 case 0: /* errorType */
10051 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10053 case 1: /* firstFailedWriteAttempt */
10054 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10055 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
10056 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10061 if (offset == lastoffset) break; /* nothing happened, exit loop */
10067 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10069 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
10070 "error Class: ", BACnetErrorClass, 64);
10071 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
10072 "error Code: ", BACnetErrorCode, 256);
10076 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
10079 case 8: /* no break here !!!! */
10081 offset = fChangeListError (tvb, pinfo, tree, offset);
10084 offset = fCreateObjectError (tvb, pinfo, tree, offset);
10087 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
10090 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
10093 offset = fVTCloseError (tvb, pinfo, tree, offset);
10096 return fError (tvb, pinfo, tree, offset);
10102 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10103 { /* BACnet-Error-PDU */
10104 /* ASHRAE 135-2001 20.1.7 */
10107 proto_tree *bacapp_tree_control;
10110 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10111 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10113 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10114 offset++, 1, ENC_BIG_ENDIAN);
10115 tmp = tvb_get_guint8(tvb, offset);
10116 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
10117 offset++, 1, ENC_BIG_ENDIAN);
10118 /* Error Handling follows... */
10119 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
10123 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10124 { /* BACnet-Reject-PDU */
10125 /* ASHRAE 135-2001 20.1.8 */
10128 proto_tree *bacapp_tree_control;
10130 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10131 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10133 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10134 offset++, 1, ENC_BIG_ENDIAN);
10135 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
10136 offset++, 1, ENC_BIG_ENDIAN);
10141 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10142 { /* BACnet-Abort-PDU */
10143 /* ASHRAE 135-2001 20.1.9 */
10146 proto_tree *bacapp_tree_control;
10148 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10149 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10151 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10152 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10153 offset++, 1, ENC_BIG_ENDIAN);
10154 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
10155 offset++, 1, ENC_BIG_ENDIAN);
10160 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10162 guint8 flag, bacapp_type;
10165 flag = (gint) tvb_get_guint8(tvb, 0);
10166 bacapp_type = (flag >> 4) & 0x0f;
10172 /* ASHRAE 135-2001 20.1.1 */
10173 switch (bacapp_type) {
10174 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
10175 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
10177 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
10178 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
10180 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
10181 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
10183 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
10184 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
10186 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
10187 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
10189 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
10190 offset = fErrorPDU(tvb, pinfo, tree, offset);
10192 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
10193 offset = fRejectPDU(tvb, pinfo, tree, offset);
10195 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
10196 offset = fAbortPDU(tvb, pinfo, tree, offset);
10203 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10205 guint8 flag, bacapp_type;
10206 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
10207 tvbuff_t* new_tvb = NULL;
10209 guint8 bacapp_seqno = 0;
10210 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
10211 guint8 bacapp_invoke_id = 0;
10213 proto_tree *bacapp_tree = NULL;
10216 proto_item *tt = 0;
10219 /* Strings for BACnet Statistics */
10220 const gchar errstr[] = "ERROR: ";
10221 const gchar rejstr[] = "REJECTED: ";
10222 const gchar abortstr[] = "ABORTED: ";
10223 const gchar sackstr[] = " (SimpleAck)";
10224 const gchar cackstr[] = " (ComplexAck)";
10225 const gchar uconfsreqstr[] = " (Unconfirmed Service Request)";
10226 const gchar confsreqstr[] = " (Confirmed Service Request)";
10228 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
10229 col_clear (pinfo->cinfo, COL_INFO);
10231 flag = tvb_get_guint8(tvb, 0);
10232 bacapp_type = (flag >> 4) & 0x0f;
10234 /* show some descriptive text in the INFO column */
10235 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
10236 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
10238 bacinfo.service_type = NULL;
10239 bacinfo.invoke_id = NULL;
10240 bacinfo.instance_ident = NULL;
10241 bacinfo.object_ident = NULL;
10243 switch (bacapp_type) {
10244 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10245 /* segmented messages have 2 additional bytes */
10246 if (flag & BACAPP_SEGMENTED_REQUEST) {
10249 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
10250 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10251 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
10252 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
10253 bacapp_service = tvb_get_guint8(tvb, offset + 5);
10256 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10257 bacapp_service = tvb_get_guint8(tvb, offset + 3);
10259 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
10260 val_to_str(bacapp_service,
10261 BACnetConfirmedServiceChoice,
10262 bacapp_unknown_service_str),bacapp_invoke_id);
10264 updateBacnetInfoValue(BACINFO_INVOKEID,
10265 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10267 updateBacnetInfoValue(BACINFO_SERVICE,
10268 ep_strconcat(val_to_str(bacapp_service,
10269 BACnetConfirmedServiceChoice,
10270 bacapp_unknown_service_str),
10271 confsreqstr, NULL));
10273 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
10274 bacapp_service = tvb_get_guint8(tvb, offset + 1);
10275 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
10276 val_to_str(bacapp_service,
10277 BACnetUnconfirmedServiceChoice,
10278 bacapp_unknown_service_str));
10280 updateBacnetInfoValue(BACINFO_SERVICE,
10281 ep_strconcat(val_to_str(bacapp_service,
10282 BACnetUnconfirmedServiceChoice,
10283 bacapp_unknown_service_str),
10284 uconfsreqstr, NULL));
10286 case BACAPP_TYPE_SIMPLE_ACK:
10287 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10288 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10289 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10290 val_to_str(bacapp_service,
10291 BACnetConfirmedServiceChoice,
10292 bacapp_unknown_service_str), bacapp_invoke_id);
10294 updateBacnetInfoValue(BACINFO_INVOKEID,
10295 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10297 updateBacnetInfoValue(BACINFO_SERVICE,
10298 ep_strconcat(val_to_str(bacapp_service,
10299 BACnetConfirmedServiceChoice,
10300 bacapp_unknown_service_str),
10303 case BACAPP_TYPE_COMPLEX_ACK:
10304 /* segmented messages have 2 additional bytes */
10305 if (flag & BACAPP_SEGMENTED_REQUEST) {
10308 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
10309 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10310 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
10311 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
10312 bacapp_service = tvb_get_guint8(tvb, offset + 4);
10315 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10316 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10318 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10319 val_to_str(bacapp_service,
10320 BACnetConfirmedServiceChoice,
10321 bacapp_unknown_service_str), bacapp_invoke_id);
10323 updateBacnetInfoValue(BACINFO_INVOKEID,
10324 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10326 updateBacnetInfoValue(BACINFO_SERVICE,
10327 ep_strconcat(val_to_str(bacapp_service,
10328 BACnetConfirmedServiceChoice,
10329 bacapp_unknown_service_str),
10332 case BACAPP_TYPE_SEGMENT_ACK:
10333 /* nothing more to add */
10335 case BACAPP_TYPE_ERROR:
10336 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10337 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10338 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10339 val_to_str(bacapp_service,
10340 BACnetConfirmedServiceChoice,
10341 bacapp_unknown_service_str), bacapp_invoke_id);
10343 updateBacnetInfoValue(BACINFO_INVOKEID,
10344 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10346 updateBacnetInfoValue(BACINFO_SERVICE,
10347 ep_strconcat(errstr,
10348 val_to_str(bacapp_service,
10349 BACnetConfirmedServiceChoice,
10350 bacapp_unknown_service_str),
10353 case BACAPP_TYPE_REJECT:
10354 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10355 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10356 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10357 val_to_split_str(bacapp_reason,
10359 BACnetRejectReason,
10360 ASHRAE_Reserved_Fmt,
10361 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10363 updateBacnetInfoValue(BACINFO_INVOKEID,
10364 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10366 updateBacnetInfoValue(BACINFO_SERVICE,
10367 ep_strconcat(rejstr,
10368 val_to_split_str(bacapp_reason, 64,
10369 BACnetRejectReason,
10370 ASHRAE_Reserved_Fmt,
10371 Vendor_Proprietary_Fmt),
10374 case BACAPP_TYPE_ABORT:
10375 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10376 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10377 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10378 val_to_split_str(bacapp_reason,
10381 ASHRAE_Reserved_Fmt,
10382 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10384 updateBacnetInfoValue(BACINFO_INVOKEID,
10385 ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
10387 updateBacnetInfoValue(BACINFO_SERVICE,
10388 ep_strconcat(abortstr,
10389 val_to_split_str(bacapp_reason,
10392 ASHRAE_Reserved_Fmt,
10393 Vendor_Proprietary_Fmt),
10398 /* nothing more to add */
10402 save_fragmented = pinfo->fragmented;
10404 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA);
10405 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
10408 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
10410 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
10411 /* not resetting the offset so the remaining can be done */
10413 if (fragment) { /* fragmented */
10414 fragment_data *frag_msg = NULL;
10417 pinfo->fragmented = TRUE;
10419 frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
10420 bacapp_invoke_id, /* ID for fragments belonging together */
10421 msg_fragment_table, /* list of message fragments */
10422 msg_reassembled_table, /* list of reassembled messages */
10423 bacapp_seqno, /* fragment sequence number */
10424 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
10425 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
10426 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
10427 "Reassembled BACapp", frag_msg, &msg_frag_items,
10430 if (new_tvb) { /* Reassembled */
10431 col_append_str(pinfo->cinfo, COL_INFO,
10432 " (Message Reassembled)");
10433 } else { /* Not last packet of reassembled Short Message */
10434 col_append_fstr(pinfo->cinfo, COL_INFO,
10435 " (Message fragment %u)", bacapp_seqno);
10437 if (new_tvb) { /* take it all */
10438 switch (bacapp_type) {
10439 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10440 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10442 case BACAPP_TYPE_COMPLEX_ACK:
10443 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10452 pinfo->fragmented = save_fragmented;
10455 tap_queue_packet(bacapp_tap,pinfo,&bacinfo);
10459 bacapp_init_routine(void)
10461 fragment_table_init(&msg_fragment_table);
10462 reassembled_table_init(&msg_reassembled_table);
10466 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
10471 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
10472 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
10473 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
10476 g_iconv_close (icd);
10480 uni_to_string(in,*inbytesleft,out);
10481 out[*inbytesleft] = '\0';
10482 *outbytesleft -= *inbytesleft;
10489 uni_to_string(char * data, gsize str_length, char *dest_buf)
10493 gsize length_remaining = 0;
10495 length_remaining = str_length;
10496 dest_buf[0] = '\0';
10497 if(str_length == 0) {
10500 for ( i = 0; i < (gint) str_length; i++ ) {
10502 if (c_char<0x20 || c_char>0x7e) {
10503 if (c_char != 0x00) {
10505 dest_buf[i] = c_char & 0xff;
10511 dest_buf[i] = c_char & 0xff;
10513 length_remaining--;
10515 if(length_remaining==0) {
10516 dest_buf[i+1] = '\0';
10523 dest_buf[i] = '\0';
10528 proto_register_bacapp(void)
10530 static hf_register_info hf[] = {
10532 { "APDU Type", "bacapp.type",
10533 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
10535 { &hf_bacapp_pduflags,
10536 { "PDU Flags", "bacapp.pduflags",
10537 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
10540 { "Segmented Request", "bacapp.segmented_request",
10541 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
10544 { "More Segments", "bacapp.more_segments",
10545 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
10548 { "SA", "bacapp.SA",
10549 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
10551 { &hf_bacapp_max_adpu_size,
10552 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
10553 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
10555 { &hf_bacapp_response_segments,
10556 { "Max Response Segments accepted", "bacapp.response_segments",
10557 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
10559 { &hf_bacapp_objectType,
10560 { "Object Type", "bacapp.objectType",
10561 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
10563 { &hf_bacapp_instanceNumber,
10564 { "Instance Number", "bacapp.instance_number",
10565 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
10567 { &hf_BACnetPropertyIdentifier,
10568 { "Property Identifier", "bacapp.property_identifier",
10569 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
10571 { &hf_BACnetVendorIdentifier,
10572 { "Vendor Identifier", "bacapp.vendor_identifier",
10573 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
10575 { &hf_BACnetRestartReason,
10576 { "Restart Reason", "bacapp.restart_reason",
10577 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
10579 { &hf_bacapp_invoke_id,
10580 { "Invoke ID", "bacapp.invoke_id",
10581 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10583 { &hf_bacapp_sequence_number,
10584 { "Sequence Number", "bacapp.sequence_number",
10585 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10587 { &hf_bacapp_window_size,
10588 { "Proposed Window Size", "bacapp.window_size",
10589 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10591 { &hf_bacapp_service,
10592 { "Service Choice", "bacapp.confirmed_service",
10593 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
10595 { &hf_bacapp_uservice,
10596 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
10597 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
10600 { "NAK", "bacapp.NAK",
10601 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
10604 { "SRV", "bacapp.SRV",
10605 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
10607 { &hf_Device_Instance_Range_Low_Limit,
10608 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
10609 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
10611 { &hf_Device_Instance_Range_High_Limit,
10612 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
10613 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
10615 { &hf_BACnetRejectReason,
10616 { "Reject Reason", "bacapp.reject_reason",
10617 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
10619 { &hf_BACnetAbortReason,
10620 { "Abort Reason", "bacapp.abort_reason",
10621 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
10623 { &hf_BACnetApplicationTagNumber,
10624 { "Application Tag Number",
10625 "bacapp.application_tag_number",
10626 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
10629 { &hf_BACnetContextTagNumber,
10630 { "Context Tag Number",
10631 "bacapp.context_tag_number",
10632 FT_UINT8, BASE_DEC, NULL, 0xF0,
10635 { &hf_BACnetExtendedTagNumber,
10636 { "Extended Tag Number",
10637 "bacapp.extended_tag_number",
10638 FT_UINT8, BASE_DEC, NULL, 0,
10641 { &hf_BACnetNamedTag,
10643 "bacapp.named_tag",
10644 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
10647 { &hf_BACnetCharacterSet,
10648 { "String Character Set",
10649 "bacapp.string_character_set",
10650 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet),0,
10653 { &hf_BACnetTagClass,
10654 { "Tag Class", "bacapp.tag_class",
10655 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
10657 { &hf_bacapp_tag_lvt,
10658 { "Length Value Type",
10660 FT_UINT8, BASE_DEC, NULL, 0,
10663 { &hf_bacapp_tag_ProcessId,
10664 { "ProcessIdentifier", "bacapp.processId",
10665 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
10667 { &hf_bacapp_tag_IPV4,
10668 { "IPV4", "bacapp.IPV4",
10669 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
10671 { &hf_bacapp_tag_IPV6,
10672 { "IPV6", "bacapp.IPV6",
10673 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
10675 { &hf_bacapp_tag_PORT,
10676 { "Port", "bacapp.Port",
10677 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
10679 {&hf_msg_fragments,
10680 {"Message fragments", "bacapp.fragments",
10681 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10683 {"Message fragment", "bacapp.fragment",
10684 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10685 {&hf_msg_fragment_overlap,
10686 {"Message fragment overlap", "bacapp.fragment.overlap",
10687 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10688 {&hf_msg_fragment_overlap_conflicts,
10689 {"Message fragment overlapping with conflicting data",
10690 "bacapp.fragment.overlap.conflicts",
10691 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10692 {&hf_msg_fragment_multiple_tails,
10693 {"Message has multiple tail fragments",
10694 "bacapp.fragment.multiple_tails",
10695 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10696 {&hf_msg_fragment_too_long_fragment,
10697 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
10698 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10699 {&hf_msg_fragment_error,
10700 {"Message defragmentation error", "bacapp.fragment.error",
10701 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10702 {&hf_msg_fragment_count,
10703 {"Message fragment count", "bacapp.fragment.count",
10704 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
10705 {&hf_msg_reassembled_in,
10706 {"Reassembled in", "bacapp.reassembled.in",
10707 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
10708 {&hf_msg_reassembled_length,
10709 {"Reassembled BACapp length", "bacapp.reassembled.length",
10710 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
10712 static gint *ett[] = {
10714 &ett_bacapp_control,
10723 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
10724 "BACapp", "bacapp");
10726 proto_register_field_array(proto_bacapp, hf, array_length(hf));
10727 proto_register_subtree_array(ett, array_length(ett));
10728 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
10729 register_init_routine (&bacapp_init_routine);
10731 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
10732 "BACapp Vendor Identifier",
10733 FT_UINT8, BASE_HEX);
10735 /* Register BACnet Statistic trees */
10736 register_bacapp_stat_trees();
10737 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
10741 proto_reg_handoff_bacapp(void)
10743 data_handle = find_dissector("data");