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
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald[AT]wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * Copied from README.developer,v 1.23
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.
39 #include <epan/packet.h>
40 #include <epan/reassemble.h>
41 #include <epan/expert.h>
43 /* formerly bacapp.h contains definitions and forward declarations */
46 #define FAULT proto_tree_add_text(subtree, tvb, offset, tvb_length(tvb) - offset, "something is going wrong here !!"); \
47 offset = tvb_length(tvb);
50 /* BACnet PDU Types */
51 #define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0
52 #define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1
53 #define BACAPP_TYPE_SIMPLE_ACK 2
54 #define BACAPP_TYPE_COMPLEX_ACK 3
55 #define BACAPP_TYPE_SEGMENT_ACK 4
56 #define BACAPP_TYPE_ERROR 5
57 #define BACAPP_TYPE_REJECT 6
58 #define BACAPP_TYPE_ABORT 7
59 #define MAX_BACAPP_TYPE 8
61 #define BACAPP_SEGMENTED_REQUEST 0x08
62 #define BACAPP_MORE_SEGMENTS 0x04
63 #define BACAPP_SEGMENTED_RESPONSE 0x02
64 #define BACAPP_SEGMENT_NAK 0x02
65 #define BACAPP_SENT_BY 0x01
69 * dissect_bacapp ::= CHOICE {
70 * confirmed-request-PDU [0] BACnet-Confirmed-Request-PDU,
71 * unconfirmed-request-PDU [1] BACnet-Unconfirmed-Request-PDU,
72 * simpleACK-PDU [2] BACnet-SimpleACK-PDU,
73 * complexACK-PDU [3] BACnet-ComplexACK-PDU,
74 * segmentACK-PDU [4] BACnet-SegmentACK-PDU,
75 * error-PDU [5] BACnet-Error-PDU,
76 * reject-PDU [6] BACnet-Reject-PDU,
77 * abort-PDU [7] BACnet-Abort-PDU
84 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
87 * ConfirmedRequest-PDU ::= SEQUENCE {
88 * pdu-type [0] Unsigned (0..15), -- 0 for this PDU Type
89 * segmentedMessage [1] BOOLEAN,
90 * moreFollows [2] BOOLEAN,
91 * segmented-response-accepted [3] BOOLEAN,
92 * reserved [4] Unsigned (0..3), -- must be set zero
93 * max-segments-accepted [5] Unsigned (0..7), -- as per 20.1.2.4
94 * max-APDU-length-accepted [5] Unsigned (0..15), -- as per 20.1.2.5
95 * invokeID [6] Unsigned (0..255),
96 * sequence-number [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
97 * proposed-window-size [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
98 * service-choice [9] BACnetConfirmedServiceChoice,
99 * service-request [10] BACnet-Confirmed-Service-Request OPTIONAL
105 * @return modified offset
108 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
115 * @param ack - indocates whether working on request or ack
116 * @param svc - output variable to return service choice
117 * @param tt - output varable to return service choice item
118 * @return modified offset
121 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 ack,
122 gint *svc, proto_item **tt);
125 * Unconfirmed-Request-PDU ::= SEQUENCE {
126 * pdu-type [0] Unsigned (0..15), -- 1 for this PDU type
127 * reserved [1] Unsigned (0..15), -- must be set zero
128 * service-choice [2] BACnetUnconfirmedServiceChoice,
129 * service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
135 * @return modified offset
138 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
141 * SimpleACK-PDU ::= SEQUENCE {
142 * pdu-type [0] Unsigned (0..15), -- 2 for this PDU type
143 * reserved [1] Unsigned (0..15), -- must be set zero
144 * invokeID [2] Unsigned (0..255),
145 * service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
151 * @return modified offset
154 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
157 * ComplexACK-PDU ::= SEQUENCE {
158 * pdu-type [0] Unsigned (0..15), -- 3 for this PDU Type
159 * segmentedMessage [1] BOOLEAN,
160 * moreFollows [2] BOOLEAN,
161 * reserved [3] Unsigned (0..3), -- must be set zero
162 * invokeID [4] Unsigned (0..255),
163 * sequence-number [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
164 * proposed-window-size [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
165 * service-ACK-choice [7] BACnetConfirmedServiceChoice,
166 * service-ACK [8] BACnet-Confirmed-Service-Request -- Context-specific tags 0..8 are NOT used in header encoding
172 * @return modified offset
175 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
178 * SegmentACK-PDU ::= SEQUENCE {
179 * pdu-type [0] Unsigned (0..15), -- 4 for this PDU Type
180 * reserved [1] Unsigned (0..3), -- must be set zero
181 * negative-ACK [2] BOOLEAN,
182 * server [3] BOOLEAN,
183 * original-invokeID [4] Unsigned (0..255),
184 * sequence-number [5] Unsigned (0..255),
185 * actual-window-size [6] Unsigned (0..127)
191 * @return modified offset
194 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
197 * Error-PDU ::= SEQUENCE {
198 * pdu-type [0] Unsigned (0..15), -- 5 for this PDU Type
199 * reserved [1] Unsigned (0..3), -- must be set zero
200 * original-invokeID [2] Unsigned (0..255),
201 * error-choice [3] BACnetConfirmedServiceChoice,
202 * error [4] BACnet-Error
208 * @return modified offset
211 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
214 * Reject-PDU ::= SEQUENCE {
215 * pdu-type [0] Unsigned (0..15), -- 6 for this PDU Type
216 * reserved [1] Unsigned (0..3), -- must be set zero
217 * original-invokeID [2] Unsigned (0..255),
218 * reject-reason [3] BACnetRejectReason
224 * @return modified offset
227 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
230 * Abort-PDU ::= SEQUENCE {
231 * pdu-type [0] Unsigned (0..15), -- 7 for this PDU Type
232 * reserved [1] Unsigned (0..3), -- must be set zero
233 * server [2] BOOLEAN,
234 * original-invokeID [3] Unsigned (0..255),
235 * abort-reason [4] BACnetAbortReason
241 * @return modified offset
244 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
247 * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree
252 * @return modified offset
255 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
258 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
263 * @return modified offset
266 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
269 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
274 * @param lvt length of String
275 * @return modified offset
278 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
281 * 20.2.12, adds the label with Date Value to tree
286 * @return modified offset
289 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
292 * 20.2.13, adds the label with Time Value to tree
297 * @return modified offset
300 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
303 * 20.2.14, adds Object Identifier to tree
304 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
309 * @return modified offset
312 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
315 * BACnet-Confirmed-Service-Request ::= CHOICE {
321 * @param service_choice
325 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
328 * BACnet-Confirmed-Service-ACK ::= CHOICE {
334 * @param service_choice
338 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
341 * AcknowledgeAlarm-Request ::= SEQUENCE {
342 * acknowledgingProcessIdentifier [0] Unsigned32,
343 * eventObjectIdentifier [1] BACnetObjectIdentifer,
344 * eventStateAcknowledge [2] BACnetEventState,
345 * timeStamp [3] BACnetTimeStamp,
346 * acknowledgementSource [4] Character String,
347 * timeOfAcknowledgement [5] BACnetTimeStamp
353 * @return modified offset
356 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
359 * ConfirmedCOVNotification-Request ::= SEQUENCE {
360 * subscriberProcessIdentifier [0] Unsigned32,
361 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
362 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
363 * timeRemaining [3] unsigned,
364 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
370 * @return modified offset
373 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
376 * ConfirmedEventNotification-Request ::= SEQUENCE {
377 * ProcessIdentifier [0] Unsigned32,
378 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
379 * eventObjectIdentifier [2] BACnetObjectIdentifer,
380 * timeStamp [3] BACnetTimeStamp,
381 * notificationClass [4] unsigned,
382 * priority [5] unsigned8,
383 * eventType [6] BACnetEventType,
384 * messageText [7] CharacterString OPTIONAL,
385 * notifyType [8] BACnetNotifyType,
386 * ackRequired [9] BOOLEAN OPTIONAL,
387 * fromState [10] BACnetEventState OPTIONAL,
388 * toState [11] BACnetEventState,
389 * eventValues [12] BACnetNotificationParameters OPTIONAL
395 * @return modified offset
398 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
401 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
402 * objectIdentifier BACnetObjectIdentifer,
403 * alarmState BACnetEventState,
404 * acknowledgedTransitions BACnetEventTransitionBits
410 * @return modified offset
413 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
416 * GetEnrollmentSummary-Request ::= SEQUENCE {
417 * acknowledgmentFilter [0] ENUMERATED {
422 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
423 * eventStateFilter [2] ENUMERATED {
430 * eventTypeFilter [3] BACnetEventType OPTIONAL,
431 * priorityFilter [4] SEQUENCE {
432 * minPriority [0] Unsigned8,
433 * maxPriority [1] Unsigned8
435 * notificationClassFilter [5] Unsigned OPTIONAL
441 * @return modified offset
444 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
447 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
448 * objectIdentifier BACnetObjectIdentifer,
449 * eventType BACnetEventType,
450 * eventState BACnetEventState,
451 * priority Unsigned8,
452 * notificationClass Unsigned OPTIONAL
458 * @return modified offset
461 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
464 * GetEventInformation-Request ::= SEQUENCE {
465 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
471 * @return modified offset
474 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
477 * GetEventInformation-ACK ::= SEQUENCE {
478 * listOfEventSummaries [0] listOfEventSummaries,
479 * moreEvents [1] BOOLEAN
485 * @return modified offset
488 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
491 * LifeSafetyOperation-Request ::= SEQUENCE {
492 * requestingProcessIdentifier [0] Unsigned32
493 * requestingSource [1] CharacterString
494 * request [2] BACnetLifeSafetyOperation
495 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
501 * @return modified offset
504 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
507 * SubscribeCOV-Request ::= SEQUENCE {
508 * subscriberProcessIdentifier [0] Unsigned32
509 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
510 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
511 * lifetime [3] Unsigned OPTIONAL
519 * @return modified offset
522 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
525 * SubscribeCOVProperty-Request ::= SEQUENCE {
526 * subscriberProcessIdentifier [0] Unsigned32
527 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
528 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
529 * lifetime [3] Unsigned OPTIONAL
530 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
531 * covIncrement [5] Unsigned OPTIONAL
537 * @return modified offset
540 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
543 * AtomicReadFile-Request ::= SEQUENCE {
544 * fileIdentifier BACnetObjectIdentifier,
545 * accessMethod CHOICE {
546 * streamAccess [0] SEQUENCE {
547 * fileStartPosition INTEGER,
548 * requestedOctetCount Unsigned
550 * recordAccess [1] SEQUENCE {
551 * fileStartRecord INTEGER,
552 * requestedRecordCount Unsigned
560 * @return modified offset
563 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
566 * AtomicWriteFile-ACK ::= SEQUENCE {
568 * accessMethod CHOICE {
569 * streamAccess [0] SEQUENCE {
570 * fileStartPosition INTEGER,
571 * fileData OCTET STRING
573 * recordAccess [1] SEQUENCE {
574 * fileStartRecord INTEGER,
575 * returnedRecordCount Unsigned,
576 * fileRecordData SEQUENCE OF OCTET STRING
584 * @return modified offset
587 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
590 * AtomicWriteFile-Request ::= SEQUENCE {
591 * fileIdentifier BACnetObjectIdentifier,
592 * accessMethod CHOICE {
593 * streamAccess [0] SEQUENCE {
594 * fileStartPosition INTEGER,
595 * fileData OCTET STRING
597 * recordAccess [1] SEQUENCE {
598 * fileStartRecord INTEGER,
599 * recordCount Unsigned,
600 * fileRecordData SEQUENCE OF OCTET STRING
608 * @return modified offset
611 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
614 * AtomicWriteFile-ACK ::= SEQUENCE {
615 * fileStartPosition [0] INTEGER,
616 * fileStartRecord [1] INTEGER,
621 * @return modified offset
624 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
627 * AddListElement-Request ::= SEQUENCE {
628 * objectIdentifier [0] BACnetObjectIdentifier,
629 * propertyIdentifier [1] BACnetPropertyIdentifier,
630 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
631 * listOfElements [3] ABSTRACT-SYNTAX.&Type
637 * @return modified offset
640 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
643 * CreateObject-Request ::= SEQUENCE {
644 * objectSpecifier [0] ObjectSpecifier,
645 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
651 * @return modified offset
654 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
657 * CreateObject-Request ::= BACnetObjectIdentifier
662 * @return modified offset
665 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
668 * DeleteObject-Request ::= SEQUENCE {
669 * ObjectIdentifier BACnetObjectIdentifer
675 * @return modified offset
678 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
681 * ReadProperty-Request ::= SEQUENCE {
682 * objectIdentifier [0] BACnetObjectIdentifier,
683 * propertyIdentifier [1] BACnetPropertyIdentifier,
684 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
690 * @return modified offset
693 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
696 * ReadProperty-ACK ::= SEQUENCE {
697 * objectIdentifier [0] BACnetObjectIdentifier,
698 * propertyIdentifier [1] BACnetPropertyIdentifier,
699 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
700 * propertyValue [3] ABSTRACT-SYNTAX.&Type
706 * @return modified offset
709 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
712 * ReadPropertyConditional-Request ::= SEQUENCE {
713 * objectSelectionCriteria [0] objectSelectionCriteria,
714 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
720 * @return modified offset
723 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
726 * ReadPropertyConditional-ACK ::= SEQUENCE {
727 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
733 * @return modified offset
736 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
739 * ReadPropertyMultiple-Request ::= SEQUENCE {
740 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
746 * @return offset modified
749 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
752 * ReadPropertyMultiple-Ack ::= SEQUENCE {
753 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
759 * @return offset modified
762 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
765 * ReadRange-Request ::= SEQUENCE {
766 * objectIdentifier [0] BACnetObjectIdentifier,
767 * propertyIdentifier [1] BACnetPropertyIdentifier,
768 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
770 * byPosition [3] SEQUENCE {
771 * referencedIndex Unsigned,
774 * byTime [4] SEQUENCE {
775 * referenceTime BACnetDateTime,
778 * timeRange [5] SEQUENCE {
779 * beginningTime BACnetDateTime,
780 * endingTime BACnetDateTime
788 * @return modified offset
791 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
794 * ReadRange-ACK ::= SEQUENCE {
795 * objectIdentifier [0] BACnetObjectIdentifier,
796 * propertyIdentifier [1] BACnetPropertyIdentifier,
797 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
798 * resultFlags [3] BACnetResultFlags,
799 * itemCount [4] Unsigned,
800 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
806 * @return modified offset
809 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
812 * RemoveListElement-Request ::= SEQUENCE {
813 * objectIdentifier [0] BACnetObjectIdentifier,
814 * propertyIdentifier [1] BACnetPropertyIdentifier,
815 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
816 * listOfElements [3] ABSTRACT-SYNTAX.&Type
822 * @return modified offset
825 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
828 * WriteProperty-Request ::= SEQUENCE {
829 * objectIdentifier [0] BACnetObjectIdentifier,
830 * propertyIdentifier [1] BACnetPropertyIdentifier,
831 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
832 * propertyValue [3] ABSTRACT-SYNTAX.&Type
833 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
839 * @return modified offset
842 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
845 * WritePropertyMultiple-Request ::= SEQUENCE {
846 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
852 * @return modified offset
855 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
858 * DeviceCommunicationControl-Request ::= SEQUENCE {
859 * timeDuration [0] Unsigned16 OPTIONAL,
860 * enable-disable [1] ENUMERATED {
864 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
869 * @return modified offset
872 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
875 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
876 * vendorID [0] Unsigned,
877 * serviceNumber [1] Unsigned,
878 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
884 * @return modified offset
887 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
890 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
891 * vendorID [0] Unsigned,
892 * serviceNumber [1] Unsigned,
893 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
899 * @return modified offset
902 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
905 * ConfirmedTextMessage-Request ::= SEQUENCE {
906 * textMessageSourceDevice [0] BACnetObjectIdentifier,
907 * messageClass [1] CHOICE {
908 * numeric [0] Unsigned,
909 * character [1] CharacterString
911 * messagePriority [2] ENUMERATED {
915 * message [3] CharacterString
921 * @return modified offset
924 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
927 * ReinitializeDevice-Request ::= SEQUENCE {
928 * reinitializedStateOfDevice [0] ENUMERATED {
937 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
942 * @return modified offset
945 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
948 * VTOpen-Request ::= SEQUENCE {
949 * vtClass BACnetVTClass,
950 * localVTSessionIdentifier Unsigned8
956 * @return modified offset
959 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
962 * VTOpen-ACK ::= SEQUENCE {
963 * remoteVTSessionIdentifier Unsigned8
969 * @return modified offset
972 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
975 * VTClose-Request ::= SEQUENCE {
976 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
982 * @return modified offset
985 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
988 * VTData-Request ::= SEQUENCE {
989 * vtSessionIdentifier Unsigned8,
990 * vtNewData OCTET STRING,
991 * vtDataFlag Unsigned (0..1)
997 * @return modified offset
1000 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1003 * VTData-ACK ::= SEQUENCE {
1004 * allNewDataAccepted [0] BOOLEAN,
1005 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1010 * @return modified offset
1013 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
1016 * Authenticate-Request ::= SEQUENCE {
1017 * pseudoRandomNumber [0] Unsigned32,
1018 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1019 * operatorName [2] CharacterString OPTIONAL,
1020 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1021 * startEncypheredSession [4] BOOLEAN OPTIONAL
1026 * @return modified offset
1029 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1032 * Authenticate-ACK ::= SEQUENCE {
1033 * modifiedRandomNumber Unsigned32,
1039 * @return modified offset
1042 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1045 * RequestKey-Request ::= SEQUENCE {
1046 * requestingDeviceIdentifier BACnetObjectIdentifier,
1047 * requestingDeviceAddress BACnetAddress,
1048 * remoteDeviceIdentifier BACnetObjectIdentifier,
1049 * remoteDeviceAddress BACnetAddress
1055 * @return modified offset
1058 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1061 * Unconfirmed-Service-Request ::= CHOICE {
1067 * @param service_choice
1068 * @return modified offset
1071 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1074 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1075 * subscriberProcessIdentifier [0] Unsigned32,
1076 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1077 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1078 * timeRemaining [3] unsigned,
1079 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1085 * @return modified offset
1088 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1091 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1092 * ProcessIdentifier [0] Unsigned32,
1093 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1094 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1095 * timeStamp [3] BACnetTimeStamp,
1096 * notificationClass [4] unsigned,
1097 * priority [5] unsigned8,
1098 * eventType [6] BACnetEventType,
1099 * messageText [7] CharacterString OPTIONAL,
1100 * notifyType [8] BACnetNotifyType,
1101 * ackRequired [9] BOOLEAN OPTIONAL,
1102 * fromState [10] BACnetEventState OPTIONAL,
1103 * toState [11] BACnetEventState,
1104 * eventValues [12] BACnetNotificationParameters OPTIONAL
1110 * @return modified offset
1113 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1116 * I-Am-Request ::= SEQUENCE {
1117 * aAmDeviceIdentifier BACnetObjectIdentifier,
1118 * maxAPDULengthAccepted Unsigned,
1119 * segmentationSupported BACnetSegmentation,
1126 * @return modified offset
1129 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1133 * I-Have-Request ::= SEQUENCE {
1134 * deviceIdentifier BACnetObjectIdentifier,
1135 * objectIdentifier BACnetObjectIdentifier,
1136 * objectName CharacterString
1142 * @return modified offset
1145 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1148 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1149 * vendorID [0] Unsigned,
1150 * serviceNumber [1] Unsigned,
1151 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1157 * @return modified offset
1160 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1163 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1164 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1165 * messageClass [1] CHOICE {
1166 * numeric [0] Unsigned,
1167 * character [1] CharacterString
1169 * messagePriority [2] ENUMERATED {
1173 * message [3] CharacterString
1179 * @return modified offset
1182 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1185 * TimeSynchronization-Request ::= SEQUENCE {
1191 * @return modified offset
1194 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1197 * UTCTimeSynchronization-Request ::= SEQUENCE {
1203 * @return modified offset
1206 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1209 * Who-Has-Request ::= SEQUENCE {
1211 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1212 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1215 * objectIdentifier [2] BACnetObjectIdentifier,
1216 * objectName [3] CharacterString
1223 * @return modified offset
1226 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1229 * Who-Is-Request ::= SEQUENCE {
1230 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1231 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1236 * @return modified offset
1239 fWhoIsRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
1242 * BACnet-Error ::= CHOICE {
1243 * addListElement [8] ChangeList-Error,
1244 * removeListElement [9] ChangeList-Error,
1245 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1246 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1247 * vtClose [22] VTClose-Error,
1248 * readRange [26] ObjectAccessService-Error
1256 * @return modified offset
1259 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1262 * Dissect a BACnetError in a context tag
1268 * @return modified offset
1270 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1273 * ChangeList-Error ::= SEQUENCE {
1274 * errorType [0] Error,
1275 * firstFailedElementNumber [1] Unsigned
1282 * @return modified offset
1285 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1288 * CreateObject-Error ::= SEQUENCE {
1289 * errorType [0] Error,
1290 * firstFailedElementNumber [1] Unsigned
1297 * @return modified offset
1300 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1303 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1304 * errorType [0] Error,
1305 * vendorID [1] Unsigned,
1306 * serviceNumber [2] Unsigned,
1307 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1314 * @return modified offset
1317 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1320 * WritePropertyMultiple-Error ::= SEQUENCE {
1321 * errorType [0] Error,
1322 * firstFailedWriteAttempt [1] Unsigned
1329 * @return modified offset
1332 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1335 * VTClose-Error ::= SEQUENCE {
1336 * errorType [0] Error,
1337 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1344 * @return modified offset
1347 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1350 * BACnet Application Types chapter 20.2.1
1356 * @return modified offset
1359 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1362 * BACnetActionCommand ::= SEQUENCE {
1363 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1364 * objectIdentifier [1] BACnetObjectIdentifier,
1365 * propertyIdentifier [2] BACnetPropertyIdentifier,
1366 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1367 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1368 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1369 * postDelay [6] Unsigned OPTIONAL,
1370 * quitOnFailure [7] BOOLEAN,
1371 * writeSuccessful [8] BOOLEAN
1377 * @param matching tag number
1378 * @return modified offset
1381 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1384 * BACnetActionList ::= SEQUENCE {
1385 * action [0] SEQUENCE of BACnetActionCommand
1391 * @return modified offset
1394 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1396 /** BACnetAddress ::= SEQUENCE {
1397 * network-number Unsigned16, -- A value 0 indicates the local network
1398 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1403 * @return modified offset
1406 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset);
1409 * BACnetAddressBinding ::= SEQUENCE {
1410 * deviceObjectID BACnetObjectIdentifier
1411 * deviceAddress BacnetAddress
1417 * @return modified offset
1420 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1423 * BACnetCalendaryEntry ::= CHOICE {
1425 * dateRange [1] BACnetDateRange,
1426 * weekNDay [2] BacnetWeekNday
1431 * @return modified offset
1434 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset);
1437 * BACnetClientCOV ::= CHOICE {
1438 * real-increment REAL,
1439 * default-increment NULL
1444 * @return modified offset
1447 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1451 * BACnetDailySchedule ::= SEQUENCE {
1452 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1458 * @return modified offset
1461 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1464 * BACnetWeeklySchedule ::= SEQUENCE {
1465 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1471 * @return modified offset
1474 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1477 * BACnetDateRange ::= SEQUENCE {
1484 * @return modified offset
1487 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset);
1490 * BACnetDateTime ::= SEQUENCE {
1498 * @return modified offset
1501 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1504 * BACnetDestination ::= SEQUENCE {
1505 * validDays BACnetDaysOfWeek,
1508 * recipient BACnetRecipient,
1509 * processIdentifier Unsigned32,
1510 * issueConfirmedNotifications BOOLEAN,
1511 * transitions BACnetEventTransitionBits
1517 * @return modified offset
1520 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1523 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1524 * objectIdentifier [0] BACnetObjectIdentifier,
1525 * propertyIdentifier [1] BACnetPropertyIdentifier,
1526 * propertyArrayIndex [2] Unsigend OPTIONAL,
1527 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1533 * @return modified offset
1536 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1539 * BACnetDeviceObjectReference ::= SEQUENCE {
1540 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1541 * objectIdentifier [1] BACnetObjectIdentifier
1547 * @return modified offset
1550 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1554 * BACnetEventParameter ::= CHOICE {
1555 * change-of-bitstring [0] SEQUENCE {
1556 * time-delay [0] Unsigned,
1557 * bitmask [1] BIT STRING,
1558 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1560 * change-of-state [1] SEQUENCE {
1561 * time-delay [0] Unsigned,
1562 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1564 * change-of-value [2] SEQUENCE {
1565 * time-delay [0] Unsigned,
1566 * cov-criteria [1] CHOICE {
1567 * bitmask [0] BIT STRING,
1568 * referenced-property-increment [1] REAL
1571 * command-failure [3] SEQUENCE {
1572 * time-delay [0] Unsigned,
1573 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1575 * floating-limit [4] SEQUENCE {
1576 * time-delay [0] Unsigned,
1577 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1578 * low-diff-limit [2] REAL,
1579 * high-diff-limit [3] REAL,
1582 * out-of-range [5] SEQUENCE {
1583 * time-delay [0] Unsigned,
1584 * low-limit [1] REAL,
1585 * high-limit [2] REAL,
1588 * buffer-ready [7] SEQUENCE {
1589 * notification-threshold [0] Unsigned,
1590 * previous-notification-count [1] Unsigned32
1592 * change-of-life-safety [8] SEQUENCE {
1593 * time-delay [0] Unsigned,
1594 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1595 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1596 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1602 * @return modified offset
1605 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset);
1611 * BACnetLogRecord ::= SEQUENCE {
1612 * timestamp [0] BACnetDateTime,
1613 * logDatum [1] CHOICE {
1614 * log-status [0] BACnetLogStatus,
1615 * boolean-value [1] BOOLEAN,
1616 * real-value [2] REAL,
1617 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1618 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1619 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1620 * bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
1621 * null-value [7] NULL,
1622 * failure [8] Error,
1623 * time-change [9] REAL,
1624 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1626 * statusFlags [2] BACnetStatusFlags OPTIONAL
1632 * @return modified offset
1635 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1639 * BACnetNotificationParameters ::= CHOICE {
1640 * change-of-bitstring [0] SEQUENCE {
1641 * referenced-bitstring [0] BIT STRING,
1642 * status-flags [1] BACnetStatusFlags
1644 * change-of-state [1] SEQUENCE {
1645 * new-state [0] BACnetPropertyStatus,
1646 * status-flags [1] BACnetStatusFlags
1648 * change-of-value [2] SEQUENCE {
1649 * new-value [0] CHOICE {
1650 * changed-bits [0] BIT STRING,
1651 * changed-value [1] REAL
1653 * status-flags [1] BACnetStatusFlags
1655 * command-failure [3] SEQUENCE {
1656 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1657 * status-flags [1] BACnetStatusFlags
1658 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1660 * floating-limit [4] SEQUENCE {
1661 * reference-value [0] REAL,
1662 * status-flags [1] BACnetStatusFlags
1663 * setpoint-value [2] REAL,
1664 * error-limit [3] REAL
1666 * out-of-range [5] SEQUENCE {
1667 * exceeding-value [0] REAL,
1668 * status-flags [1] BACnetStatusFlags
1669 * deadband [2] REAL,
1670 * exceeded-limit [0] REAL
1672 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1673 * buffer-ready [7] SEQUENCE {
1674 * buffer-device [0] BACnetObjectIdentifier,
1675 * buffer-object [1] BACnetObjectIdentifier
1676 * previous-notification [2] BACnetDateTime,
1677 * current-notification [3] BACnetDateTime
1679 * change-of-life-safety [8] SEQUENCE {
1680 * new-state [0] BACnetLifeSafetyState,
1681 * new-mode [1] BACnetLifeSafetyState
1682 * status-flags [2] BACnetStatusFlags,
1683 * operation-expected [3] BACnetLifeSafetyOperation
1690 * @return modified offset
1693 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1696 * BACnetObjectPropertyReference ::= SEQUENCE {
1697 * objectIdentifier [0] BACnetObjectIdentifier,
1698 * propertyIdentifier [1] BACnetPropertyIdentifier,
1699 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1705 * @return modified offset
1708 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1712 * BACnetObjectPropertyValue ::= SEQUENCE {
1713 * objectIdentifier [0] BACnetObjectIdentifier,
1714 * propertyIdentifier [1] BACnetPropertyIdentifier,
1715 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1716 * -- if omitted with an array the entire array is referenced
1717 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1718 * priority [4] Unsigned (1..16) OPTIONAL
1723 * @return modified offset
1726 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
1730 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1735 * @return modified offset
1738 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1741 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1744 * BACnetPropertyReference ::= SEQUENCE {
1745 * propertyIdentifier [0] BACnetPropertyIdentifier,
1746 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1752 * @return modified offset
1755 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1758 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1761 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1764 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1767 * BACnetPropertyValue ::= SEQUENCE {
1768 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1769 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1770 * -- if omitted with an array the entire array is referenced
1771 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1772 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1778 * @return modified offset
1781 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1784 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1787 * BACnet Application PDUs chapter 21
1788 * BACnetRecipient::= CHOICE {
1789 * device [0] BACnetObjectIdentifier
1790 * address [1] BACnetAddress
1796 * @return modified offset
1799 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1802 * BACnet Application PDUs chapter 21
1803 * BACnetRecipientProcess::= SEQUENCE {
1804 * recipient [0] BACnetRecipient
1805 * processID [1] Unsigned32
1811 * @return modified offset
1814 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1818 * BACnetSessionKey ::= SEQUENCE {
1819 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1820 * peerAddress BACnetAddress
1825 * @return modified offset
1826 * @todo check if checksum is displayed correctly
1829 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1833 * BACnetSpecialEvent ::= SEQUENCE {
1835 * calendarEntry [0] BACnetCalendarEntry,
1836 * calendarRefernce [1] BACnetObjectIdentifier
1838 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1839 * eventPriority [3] Unsigned (1..16)
1845 * @return modified offset
1848 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1851 * BACnetTimeStamp ::= CHOICE {
1853 * sequenceNumber [1] Unsigned (0..65535),
1854 * dateTime [2] BACnetDateTime
1860 * @return modified offset
1863 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1866 * BACnetTimeValue ::= SEQUENCE {
1868 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1874 * @return modified offset
1877 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1881 * BACnetVTSession ::= SEQUENCE {
1882 * local-vtSessionID Unsigned8,
1883 * remote-vtSessionID Unsigned8,
1884 * remote-vtAddress BACnetAddress
1889 * @return modified offset
1892 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1896 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1897 * -- first octet month (1..12) January = 1, X'FF' = any month
1898 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1899 * -- 2 = days numbered 8-14
1900 * -- 3 = days numbered 15-21
1901 * -- 4 = days numbered 22-28
1902 * -- 5 = days numbered 29-31
1903 * -- 6 = last 7 days of this month
1904 * -- X'FF' = any week of this month
1905 * -- third octet dayOfWeek (1..7) where 1 = Monday
1907 * -- X'FF' = any day of week
1911 * @return modified offset
1914 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
1917 * ReadAccessResult ::= SEQUENCE {
1918 * objectIdentifier [0] BACnetObjectIdentifier,
1919 * listOfResults [1] SEQUENCE OF SEQUENCE {
1920 * propertyIdentifier [2] BACnetPropertyIdentifier,
1921 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1922 * readResult CHOICE {
1923 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1924 * propertyAccessError [5] Error
1932 * @return modified offset
1935 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1938 * ReadAccessSpecification ::= SEQUENCE {
1939 * objectIdentifier [0] BACnetObjectIdentifier,
1940 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
1946 * @return modified offset
1949 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1952 * WriteAccessSpecification ::= SEQUENCE {
1953 * objectIdentifier [0] BACnetObjectIdentifier,
1954 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
1960 * @return modified offset
1963 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1966 /********************************************************* Helper functions *******************************************/
1969 * extracts the tag number from the tag header.
1970 * @param tvb "TestyVirtualBuffer"
1971 * @param offset in actual tvb
1972 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
1975 fTagNo (tvbuff_t *tvb, guint offset);
1978 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
1979 * @param tvb = "TestyVirtualBuffer"
1980 * @param offset = offset in actual tvb
1981 * @return tag_no BACnet 20.2.1.2 Tag Number
1982 * @return class_tag BACnet 20.2.1.1 Class
1983 * @return lvt BACnet 20.2.1.3 Length/Value/Type
1984 * @return offs = length of this header
1988 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
1992 * adds processID with max 32Bit unsigned Integer Value to tree
1996 * @return modified offset
1999 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
2002 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2006 * @return modified offset
2009 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2012 * BACnet Application PDUs chapter 21
2013 * BACnetPropertyIdentifier::= ENUMERATED {
2014 * @see bacapp_property_identifier
2020 * @param tt returnvalue of this item
2021 * @return modified offset
2024 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2027 * BACnet Application PDUs chapter 21
2028 * BACnetPropertyArrayIndex::= ENUMERATED {
2029 * @see bacapp_property_array_index
2034 * @param tt returnvalue of this item
2035 * @return modified offset
2038 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
2041 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2042 * objectIdentifier [0] BACnetObjectIdentifier,
2043 * eventState [1] BACnetEventState,
2044 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2045 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2046 * notifyType [4] BACnetNotifyType,
2047 * eventEnable [5] BACnetEventTransitionBits,
2048 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2054 * @return modified offset
2057 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2060 * SelectionCriteria ::= SEQUENCE {
2061 * propertyIdentifier [0] BACnetPropertyIdentifier,
2062 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2063 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2064 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2070 * @return modified offset
2073 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2076 * objectSelectionCriteria ::= SEQUENCE {
2077 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2078 * listOfSelectionCriteria [1] SelectionCriteria
2084 * @return modified offset
2087 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2090 * BACnet-Error ::= SEQUENCE {
2091 * error-class ENUMERATED {},
2092 * error-code ENUMERATED {}
2099 * @return modified offset
2102 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2105 * Generic handler for context tagged values. Mostly for handling
2106 * vendor-defined properties and services.
2110 * @return modified offset
2111 * @todo beautify this ugly construct
2114 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2117 * realizes some ABSTRACT-SYNTAX.&Type
2122 * @return modified offset
2123 * @todo beautify this ugly construct
2126 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2130 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2131 const value_string *src);
2137 proto_register_bacapp(void);
2140 * proto_reg_handoff_bacapp
2143 proto_reg_handoff_bacapp(void);
2146 * converts XXX coded strings to UTF-8
2147 * else 'in' is copied to 'out'
2148 * @param in -- pointer to string
2149 * @param inbytesleft
2150 * @param out -- pointer to string
2151 * @param outbytesleft
2153 * @return count of modified characters of returned string, -1 for errors
2156 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2159 uni_to_string(char * data, gsize str_length, char *dest_buf);
2161 /* <<<< formerly bacapp.h */
2163 /* some hashes for segmented messages */
2164 static GHashTable *msg_fragment_table = NULL;
2165 static GHashTable *msg_reassembled_table = NULL;
2167 /* some necessary forward function prototypes */
2169 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2170 const gchar *label, const value_string *vs);
2172 static const char *bacapp_unknown_service_str = "unknown service";
2173 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2174 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2176 static const value_string
2177 BACnetTypeName[] = {
2178 {0, "Confirmed-REQ"},
2179 {1, "Unconfirmed-REQ"},
2189 static const true_false_string segments_follow = {
2190 "Segmented Request",
2191 "Unsegmented Request"
2194 static const true_false_string more_follow = {
2195 "More Segments Follow",
2196 "No More Segments Follow"
2199 static const true_false_string segmented_accept = {
2200 "Segmented Response accepted",
2201 "Segmented Response not accepted"
2204 static const true_false_string
2206 "Context Specific Tag",
2210 static const value_string
2211 BACnetMaxSegmentsAccepted [] = {
2219 {7,"Greater than 64 segments"},
2223 static const value_string
2224 BACnetMaxAPDULengthAccepted [] = {
2225 {0,"Up to MinimumMessageSize (50 octets)"},
2226 {1,"Up to 128 octets"},
2227 {2,"Up to 206 octets (fits in a LonTalk frame)"},
2228 {3,"Up to 480 octets (fits in an ARCNET frame)"},
2229 {4,"Up to 1024 octets"},
2230 {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2231 {6,"reserved by ASHRAE"},
2232 {7,"reserved by ASHRAE"},
2233 {8,"reserved by ASHRAE"},
2234 {9,"reserved by ASHRAE"},
2235 {10,"reserved by ASHRAE"},
2236 {11,"reserved by ASHRAE"},
2237 {12,"reserved by ASHRAE"},
2238 {13,"reserved by ASHRAE"},
2239 {14,"reserved by ASHRAE"},
2240 {15,"reserved by ASHRAE"},
2244 static const value_string
2245 BACnetRejectReason [] = {
2247 {1,"buffer-overflow"},
2248 {2,"inconsistent-parameters"},
2249 {3,"invalid-parameter-data-type"},
2251 {5,"missing-required-parameter"},
2252 {6,"parameter-out-of-range"},
2253 {7,"too-many-arguments"},
2254 {8,"undefined-enumeration"},
2255 {9,"unrecognized-service"},
2259 static const value_string
2260 BACnetRestartReason [] = {
2264 {3,"detected-power-lost"},
2265 {4,"detected-powered-off"},
2266 {5,"hardware-watchdog"},
2267 {6,"software-watchdog"},
2272 static const value_string
2273 BACnetApplicationTagNumber [] = {
2276 {2,"Unsigned Integer"},
2277 {3,"Signed Integer (2's complement notation)"},
2278 {4,"Real (ANSI/IEE-754 floating point)"},
2279 {5,"Double (ANSI/IEE-754 double precision floating point)"},
2281 {7,"Character String"},
2286 {12,"BACnetObjectIdentifier"},
2287 {13,"reserved by ASHRAE"},
2288 {14,"reserved by ASHRAE"},
2289 {15,"reserved by ASHRAE"},
2293 static const value_string
2300 static const value_string
2301 BACnetFileAccessMethod [] = {
2302 {0,"record-access"},
2303 {1,"stream-access"},
2307 /* For some reason, BACnet defines the choice parameter
2308 in the file read and write services backwards from the
2309 BACnetFileAccessMethod enumeration.
2311 static const value_string
2312 BACnetFileAccessOption [] = {
2313 {0,"stream access"},
2314 {1,"record access"},
2318 static const value_string
2319 BACnetFileStartOption [] = {
2320 {0, "File Start Position: "},
2321 {1, "File Start Record: "},
2325 static const value_string
2326 BACnetFileRequestCount [] = {
2327 {0, "Requested Octet Count: "},
2328 {1, "Requested Record Count: "},
2332 static const value_string
2333 BACnetFileWriteInfo [] = {
2335 {1, "Record Count: "},
2339 static const value_string
2340 BACnetAbortReason [] = {
2342 {1,"buffer-overflow"},
2343 {2,"invalid-apdu-in-this-state"},
2344 {3,"preempted-by-higher-priority-task"},
2345 {4,"segmentation-not-supported"},
2349 static const value_string
2350 BACnetLifeSafetyMode [] = {
2361 {10,"disconnected"},
2364 {13,"atomic-release-disabled"},
2367 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2368 Enumerated values 256-65535 may be used by others subject to
2369 procedures and constraints described in Clause 23. */
2372 static const value_string
2373 BACnetLifeSafetyOperation [] = {
2376 {2,"silence-audible"},
2377 {3,"silence-visual"},
2382 {8,"unsilence-audible"},
2383 {9,"unsilence-visual"},
2385 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2386 Enumerated values 64-65535 may be used by others subject to
2387 procedures and constraints described in Clause 23. */
2390 static const value_string
2391 BACnetLimitEnable [] = {
2392 {0,"lowLimitEnable"},
2393 {1,"highLimitEnable"},
2397 static const value_string
2398 BACnetLifeSafetyState [] = {
2403 {4,"fault-pre-alarm"},
2411 {12,"test-fault-alarm"},
2414 {15,"tamper-alarm"},
2416 {17,"emergency-power"},
2420 {21,"general-alarm"},
2422 {23,"test-supervisory"},
2424 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2425 Enumerated values 256-65535 may be used by others subject to
2426 procedures and constraints described in Clause 23. */
2429 static const value_string
2430 BACnetConfirmedServiceChoice [] = {
2431 {0,"acknowledgeAlarm"},
2432 {1,"confirmedCOVNotification"},
2433 {2,"confirmedEventNotification"},
2434 {3,"getAlarmSummary"},
2435 {4,"getEnrollmentSummary"},
2437 {6,"atomicReadFile"},
2438 {7,"atomicWriteFile"},
2439 {8,"addListElement"},
2440 {9,"removeListElement"},
2441 {10,"createObject"},
2442 {11,"deleteObject"},
2443 {12,"readProperty"},
2444 {13,"readPropertyConditional"},
2445 {14,"readPropertyMultiple"},
2446 {15,"writeProperty"},
2447 {16,"writePropertyMultiple"},
2448 {17,"deviceCommunicationControl"},
2449 {18,"confirmedPrivateTransfer"},
2450 {19,"confirmedTextMessage"},
2451 {20,"reinitializeDevice"},
2455 {24,"authenticate"},
2458 {27,"lifeSafetyOperation"},
2459 {28,"subscribeCOVProperty"},
2460 {29,"getEventInformation"},
2461 {30,"reserved by ASHRAE"},
2465 static const value_string
2466 BACnetReliability [] = {
2467 {0,"no-fault-detected"},
2474 {7,"unreliable-other"},
2475 {8,"process-error"},
2476 {9,"multi-state-fault"},
2480 static const value_string
2481 BACnetUnconfirmedServiceChoice [] = {
2484 {2,"unconfirmedCOVNotification"},
2485 {3,"unconfirmedEventNotification"},
2486 {4,"unconfirmedPrivateTransfer"},
2487 {5,"unconfirmedTextMessage"},
2488 {6,"timeSynchronization"},
2491 {9,"utcTimeSynchonization"},
2495 static const value_string
2496 BACnetUnconfirmedServiceRequest [] = {
2498 {1,"i-Have-Request"},
2499 {2,"unconfirmedCOVNotification-Request"},
2500 {3,"unconfirmedEventNotification-Request"},
2501 {4,"unconfirmedPrivateTransfer-Request"},
2502 {5,"unconfirmedTextMessage-Request"},
2503 {6,"timeSynchronization-Request"},
2504 {7,"who-Has-Request"},
2505 {8,"who-Is-Request"},
2506 {9,"utcTimeSynchonization-Request"},
2510 static const value_string
2511 BACnetObjectType [] = {
2513 {1,"analog-output"},
2516 {4,"binary-output"},
2521 {9,"event-enrollment"},
2525 {13,"multi-state-input"},
2526 {14,"multi-state-output"},
2527 {15,"notification-class"},
2531 {19,"multi-state-value"},
2533 {21,"life-safety-point"},
2534 {22,"life-safety-zone"},
2536 {24,"pulse-converter"},
2538 {26,"global-group"},
2539 {27,"trend-log-multiple"},
2540 {28,"load-control"},
2541 {29,"structured-view"},
2544 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2545 Enumerated values 128-1023 may be used by others subject to
2546 the procedures and constraints described in Clause 23. */
2549 static const value_string
2550 BACnetEngineeringUnits [] = {
2560 {9,"Kilovolt Amperes"},
2561 {10,"Megavolt Amperes"},
2562 {11,"Volt Amperes Reactive"},
2563 {12,"Kilovolt Amperes Reactive"},
2564 {13,"Megavolt Amperes Reactive"},
2565 {14,"Degrees Phase"},
2566 {15,"Power Factor"},
2570 {19,"Kilowatt Hours"},
2574 {23,"Joules Per Kg Dry Air"},
2575 {24,"BTUs Per Pound Dry Air"},
2576 {25,"Cycles Per Hour"},
2577 {26,"Cycles Per Minute"},
2579 {28,"Grams Of Water Per Kilogram Dry Air"},
2580 {29,"Relative Humidity"},
2585 {34,"Watts Per Sq Foot"},
2586 {35,"Watts Per Sq meter"},
2589 {38,"Foot Candles"},
2593 {42,"Kgs per Second"},
2594 {43,"Kgs Per Minute"},
2595 {44,"Kgs Per Hour"},
2596 {45,"Pounds Mass Per Minute"},
2597 {46,"Pounds Mass Per Hour"},
2601 {50,"BTUs Per Hour"},
2603 {52,"Tons Refrigeration"},
2607 {56,"Pounds Force Per Square Inch"},
2608 {57,"Centimeters Of Water"},
2609 {58,"Inches Of Water"},
2610 {59,"Millimeters Of Mercury"},
2611 {60,"Centimeters Of Mercury"},
2612 {61,"Inches Of Mercury"},
2613 {62,"Degrees Celsius"},
2614 {63,"Degrees Kelvin"},
2615 {64,"Degrees Fahrenheit"},
2616 {65,"Degree Days Celsius"},
2617 {66,"Degree Days Fahrenheit"},
2625 {74,"Meters Per Second"},
2626 {75,"Kilometers Per Hour"},
2627 {76,"Feed Per Second"},
2628 {77,"Feet Per Minute"},
2629 {78,"Miles Per Hour"},
2631 {80,"Cubic Meters"},
2632 {81,"Imperial Gallons"},
2635 {84,"Cubic Feet Per Minute"},
2636 {85,"Cubic Meters Per Second"},
2637 {86,"Imperial Gallons Per Minute"},
2638 {87,"Liters Per Second"},
2639 {88,"Liters Per Minute"},
2640 {89,"US Gallons Per Minute"},
2641 {90,"Degrees Angular"},
2642 {91,"Degrees Celsius Per Hour"},
2643 {92,"Degrees Celsius Per Minute"},
2644 {93,"Degrees Fahrenheit Per Hour"},
2645 {94,"Degrees Fahrenheit Per Minute"},
2647 {96,"Parts Per Million"},
2648 {97,"Parts Per Billion"},
2650 {99,"Pecent Per Second"},
2653 {102,"Psi Per Degree Fahrenheit"},
2655 {104,"Revolutions Per Min"},
2667 {116,"Sq Centimeters"},
2668 {117,"BTUs Per Pound"},
2669 {118,"Centimeters"},
2670 {119,"Pounds Mass Per Second"},
2671 {120,"Delta Degrees Fahrenheit"},
2672 {121,"Delta Degrees Kelvin"},
2676 {125,"Kilojoules Per Kg"},
2678 {127,"Joules Per Degree Kelvin"},
2679 {128,"Joules Per Kg Degree Kelvin"},
2684 {133,"Hectopascals"},
2686 {135,"Cubic Meters Per Hour"},
2687 {136,"Liters Per Hour"},
2688 {137,"KWatt Hours Per Square Meter"},
2689 {138,"KWatt Hours Per Square Foot"},
2690 {139,"Megajoules Per Square Meter"},
2691 {140,"Megajoules Per Square Foot"},
2692 {141,"Watts Per Sq Meter Degree Kelvin"},
2693 {142,"Cubic Feet Per Second"},
2694 {143,"Percent Obstruction Per Foot"},
2695 {144,"Percent Obstruction Per Meter"},
2697 {146,"megawatt-hours"},
2700 {149,"kilojoules-per-kilogram-dry-air"},
2701 {150,"megajoules-per-kilogram-dry-air"},
2702 {151,"kilojoules-per-degree-Kelvin"},
2703 {152,"megajoules-per-degree-Kelvin"},
2705 {154,"grams-per-second"},
2706 {155,"grams-per-minute"},
2707 {156,"tons-per-hour"},
2708 {157,"kilo-btus-per-hour"},
2709 {158,"hundredths-seconds"},
2710 {159,"milliseconds"},
2711 {160,"newton-meters"},
2712 {161,"millimeters-per-second"},
2713 {162,"millimeters-per-minute"},
2714 {163,"meters-per-minute"},
2715 {164,"meters-per-hour"},
2716 {165,"cubic-meters-per-minute"},
2717 {166,"meters-per-second-per-second"},
2718 {167,"amperes-per-meter"},
2719 {168,"amperes-per-square-meter"},
2720 {169,"ampere-square-meters"},
2725 {174,"siemens-per-meter"},
2727 {176,"volts-per-degree-Kelvin"},
2728 {177,"volts-per-meter"},
2731 {180,"candelas-per-square-meter"},
2732 {181,"degrees-Kelvin-per-hour"},
2733 {182,"degrees-Kelvin-per-minute"},
2734 {183,"joule-seconds"},
2735 {184,"radians-per-second"},
2736 {185,"square-meters-per-Newton"},
2737 {186,"kilograms-per-cubic-meter"},
2738 {187,"newton-seconds"},
2739 {188,"newtons-per-meter"},
2740 {189,"watts-per-meter-per-degree-Kelvin"},
2742 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2743 Enumerated values 256-65535 may be used by others subject to
2744 the procedures and constraints described in Clause 23. */
2747 static const value_string
2748 BACnetErrorCode [] = {
2750 {1,"authentication-failed"},
2751 {2,"configuration-in-progress"},
2753 {4,"dynamic-creation-not-supported"},
2754 {5,"file-access-denied"},
2755 {6,"incompatible-security-levels"},
2756 {7,"inconsistent-parameters"},
2757 {8,"inconsistent-selection-criterion"},
2758 {9,"invalid-data-type"},
2759 {10,"invalid-file-access-method"},
2760 {11,"invalid-file-start-position"},
2761 {12,"invalid-operator-name"},
2762 {13,"invalid-parameter-data-type"},
2763 {14,"invalid-time-stamp"},
2764 {15,"key-generation-error"},
2765 {16,"missing-required-parameter"},
2766 {17,"no-objects-of-specified-type"},
2767 {18,"no-space-for-object"},
2768 {19,"no-space-to-add-list-element"},
2769 {20,"no-space-to-write-property"},
2770 {21,"no-vt-sessions-available"},
2771 {22,"property-is-not-a-list"},
2772 {23,"object-deletion-not-permitted"},
2773 {24,"object-identifier-already-exists"},
2774 {25,"operational-problem"},
2775 {26,"password-failure"},
2776 {27,"read-access-denied"},
2777 {28,"security-not-supported"},
2778 {29,"service-request-denied"},
2780 {31,"unknown-object"},
2781 {32,"unknown-property"},
2782 {33,"removed enumeration"},
2783 {34,"unknown-vt-class"},
2784 {35,"unknown-vt-session"},
2785 {36,"unsupported-object-type"},
2786 {37,"value-out-of-range"},
2787 {38,"vt-session-already-closed"},
2788 {39,"vt-session-termination-failure"},
2789 {40,"write-access-denied"},
2790 {41,"character-set-not-supported"},
2791 {42,"invalid-array-index"},
2792 {43,"cov-subscription-failed"},
2793 {44,"not-cov-property"},
2794 {45,"optional-functionality-not-supported"},
2795 {46,"invalid-configuration-data"},
2796 {47,"datatype-not-supported"},
2797 {48,"duplicate-name"},
2798 {49,"duplicate-object-id"},
2799 {50,"property-is-not-an-array"},
2800 {73,"invalid-event-state"},
2801 {74,"no-alarm-configured"},
2803 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2804 Enumerated values 256-65535 may be used by others subject to the
2805 procedures and constraints described in Clause 23. */
2808 static const value_string
2809 BACnetPropertyIdentifier [] = {
2810 {0,"acked-transition"},
2815 {5,"active-vt-session"},
2819 {9,"all-write-successful"},
2820 {10,"apdu-segment-timeout"},
2821 {11,"apdu-timeout"},
2822 {12,"application-software-version"},
2825 {15,"change-of-state-count"},
2826 {16,"change-of-state-time"},
2827 {17,"notification-class"},
2828 {18,"the property in this place was deleted"},
2829 {19,"controlled-variable-reference"},
2830 {20,"controlled-variable-units"},
2831 {21,"controlled-variable-value"},
2832 {22,"cov-increment"},
2834 {24,"daylights-savings-status"},
2836 {26,"derivative-constant"},
2837 {27,"derivative-constant-units"},
2839 {29,"description-of-halt"},
2840 {30,"device-address-binding"},
2842 {32,"effective-period"},
2843 {33,"elapsed-active-time"},
2845 {35,"event-enable"},
2848 {38,"exception-schedule"},
2849 {39,"fault-values"},
2850 {40,"feedback-value"},
2851 {41,"file-access-method"},
2854 {44,"firmware-revision"},
2856 {46,"inactive-text"},
2859 {49,"integral-constant"},
2860 {50,"integral-constant-units"},
2861 {51,"issue-confirmed-notifications"},
2862 {52,"limit-enable"},
2863 {53,"list-of-group-members"},
2864 {54,"list-of-object-property-references"},
2865 {55,"list-of-session-keys"},
2870 {60,"manipulated-variable-reference"},
2871 {61,"maximum-output"},
2872 {62,"max-apdu-length-accepted"},
2873 {63,"max-info-frames"},
2875 {65,"max-pres-value"},
2876 {66,"minimum-off-time"},
2877 {67,"minimum-on-time"},
2878 {68,"minimum-output"},
2879 {69,"min-pres-value"},
2881 {71,"modification-date"},
2883 {73,"number-of-APDU-retries"},
2884 {74,"number-of-states"},
2885 {75,"object-identifier"},
2888 {78,"object-property-reference"},
2891 {81,"out-of-service"},
2892 {82,"output-units"},
2893 {83,"event-parameters"},
2895 {85,"present-value"},
2897 {87,"priority-array"},
2898 {88,"priority-for-writing"},
2899 {89,"process-identifier"},
2900 {90,"program-change"},
2901 {91,"program-location"},
2902 {92,"program-state"},
2903 {93,"proportional-constant"},
2904 {94,"proportional-constant-units"},
2905 {95,"protocol-conformance-class"},
2906 {96,"protocol-object-types-supported"},
2907 {97,"protocol-services-supported"},
2908 {98,"protocol-version"},
2910 {100,"reason-for-halt"},
2912 {102,"recipient-list"},
2913 {103,"reliability"},
2914 {104,"relinquish-default"},
2917 {107,"segmentation-supported"},
2919 {109,"setpoint-reference"},
2921 {111,"status-flags"},
2922 {112,"system-status"},
2924 {114,"time-of-active-time-reset"},
2925 {115,"time-of-state-count-reset"},
2926 {116,"time-synchronization-recipients"},
2928 {118,"update-interval"},
2930 {120,"vendor-identifier"},
2931 {121,"vendor-name"},
2932 {122,"vt-class-supported"},
2933 {123,"weekly-schedule"},
2934 {124,"attempted-samples"},
2935 {125,"average-value"},
2936 {126,"buffer-size"},
2937 {127,"client-cov-increment"},
2938 {128,"cov-resubscription-interval"},
2939 {129,"current-notify-time"},
2940 {130,"event-time-stamp"},
2942 {132,"log-device-object-property"},
2943 {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
2944 {134,"log-interval"},
2945 {135,"maximum-value"},
2946 {136,"minimum-value"},
2947 {137,"notification-threshold"},
2948 {138,"previous-notify-time"},
2949 {139,"protocol-revision"},
2950 {140,"records-since-notification"},
2951 {141,"record-count"},
2954 {144,"stop-when-full"},
2955 {145,"total-record-count"},
2956 {146,"valid-samples"},
2957 {147,"window-interval"},
2958 {148,"window-samples"},
2959 {149,"maximum-value-time-stamp"},
2960 {150,"minimum-value-time-stamp"},
2961 {151,"variance-value"},
2962 {152,"active-cov-subscriptions"},
2963 {153,"backup-failure-timeout"},
2964 {154,"configuration-files"},
2965 {155,"database-revision"},
2966 {156,"direct-reading"},
2967 {157,"last-restore-time"},
2968 {158,"maintenance-required"},
2971 {161,"operation-expected"},
2974 {164,"tracking-value"},
2975 {165,"zone-members"},
2976 {166,"life-safety-alarm-values"},
2977 {167,"max-segments-accepted"},
2978 {168,"profile-name"},
2979 {169,"auto-slave-discovery"},
2980 {170,"manual-slave-address-binding"},
2981 {171,"slave-address-binding"},
2982 {172,"slave-proxy-enable"},
2983 {173,"last-notify-record"}, /* bug 4117 */
2984 {174,"schedule-default"},
2985 {175,"accepted-modes"},
2986 {176,"adjust-value"},
2988 {178,"count-before-change"},
2989 {179,"count-change-time"},
2991 {181,"input-reference"},
2992 {182,"limit-monitoring-interval"},
2993 {183,"logging-device"},
2994 {184,"logging-record"},
2998 {188,"scale-factor"},
2999 {189,"update-time"},
3000 {190,"value-before-change"},
3002 {192,"value-change-time"},
3003 {193,"align-intervals"},
3004 {194,"group-member-names"},
3005 {195,"interval-offset"},
3006 {196,"last-restart-reason"},
3007 {197,"logging-type"},
3008 {198,"member-status-flags"},
3009 {199,"notification-period"},
3010 {200,"previous-notify-record"},
3011 {201,"requested-update-interval"},
3012 {202,"restart-notification-recipients"},
3013 {203,"time-of-device-restart"},
3014 {204,"time-synchronization-recipients"},
3016 {206,"UTC-time-synchronization-recipients"},
3017 {207,"node-subtype"},
3019 {209,"structured-object-list"},
3020 {210,"subordinate-annotations"},
3021 {211,"subordinate-list"},
3022 {212,"actual-shed-level"},
3023 {213,"duty-window"},
3024 {214,"expected-shed-level"},
3025 {215,"full-duty-baseline"},
3026 {216,"node-subtype"},
3028 {218,"requested-shed-level"},
3029 {219,"shed-duration"},
3030 {220,"shed-level-descriptions"},
3031 {221,"shed-levels"},
3032 {222,"state-description"},
3033 {226,"door-alarm-state"},
3034 {227,"door-extended-pulse-time"},
3035 {228,"door-members"},
3036 {229,"door-open-too-long-time"},
3037 {230,"door-pulse-time"},
3038 {231,"door-status"},
3039 {232,"door-unlock-delay-time"},
3040 {233,"lock-status"},
3041 {234,"masked-alarm-values"},
3042 {235,"secured-status"},
3044 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3045 Enumerated values 512-4194303 may be used by others subject to
3046 the procedures and constraints described in Clause 23. */
3049 static const value_string
3050 BACnetBinaryPV [] = {
3058 #define IBM_MS_DBCS 1
3059 #define JIS_C_6226 2
3060 #define ISO_10646_UCS4 3
3061 #define ISO_10646_UCS2 4
3062 #define ISO_18859_1 5
3063 static const value_string
3064 BACnetCharacterSet [] = {
3065 {ANSI_X34, "ANSI X3.4"},
3066 {IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3067 {JIS_C_6226, "JIS C 6226"},
3068 {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3069 {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3070 {ISO_18859_1, "ISO 18859-1"},
3074 static const value_string
3075 BACnetStatusFlags [] = {
3079 {3,"out-of-service"},
3083 static const value_string
3084 BACnetMessagePriority [] = {
3090 static const value_string
3091 BACnetAcknowledgementFilter [] = {
3098 static const value_string
3099 BACnetResultFlags [] = {
3106 static const value_string
3107 BACnetRelationSpecifier [] = {
3112 {4,"less-than-or-equal"},
3113 {5,"greater-than-or-equal"},
3117 static const value_string
3118 BACnetSelectionLogic [] = {
3125 static const value_string
3126 BACnetEventStateFilter [] = {
3135 static const value_string
3136 BACnetEventTransitionBits [] = {
3143 static const value_string
3144 BACnetSegmentation [] = {
3145 {0,"segmented-both"},
3146 {1,"segmented-transmit"},
3147 {2,"segmented-receive"},
3148 {3,"no-segmentation"},
3152 static const value_string
3153 BACnetSilencedState [] = {
3155 {1,"audible-silenced"},
3156 {2,"visible-silenced"},
3161 static const value_string
3162 BACnetDeviceStatus [] = {
3164 {1,"operational-read-only"},
3165 {2,"download-required"},
3166 {3,"download-in-progress"},
3167 {4,"non-operational"},
3168 {5,"backup-in-progress"},
3172 static const value_string
3173 BACnetEnableDisable [] = {
3176 {2,"disable-initiation"},
3180 static const value_string
3198 static const value_string
3200 {1,"days numbered 1-7" },
3201 {2,"days numbered 8-14" },
3202 {3,"days numbered 15-21" },
3203 {4,"days numbered 22-28" },
3204 {5,"days numbered 29-31" },
3205 {6,"last 7 days of this month" },
3206 {255,"any week of this month" },
3210 /* note: notification class object recipient-list uses
3211 different day-of-week enum */
3212 static const value_string
3221 {255,"any day of week" },
3225 static const value_string
3226 BACnetErrorClass [] = {
3235 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3236 Enumerated values64-65535 may be used by others subject to
3237 the procedures and constraints described in Clause 23. */
3240 static const value_string
3241 BACnetVTClass [] = {
3242 {0,"default-terminal" },
3252 static const value_string
3253 BACnetEventType [] = {
3254 {0,"change-of-bitstring" },
3255 {1,"change-of-state" },
3256 {2,"change-of-value" },
3257 {3,"command-failure" },
3258 {4,"floating-limit" },
3259 {5,"out-of-range" },
3260 {6,"complex-event-type" },
3261 {7,"buffer-ready" },
3262 {8,"change-of-life-safety" },
3264 {10,"buffer-ready" },
3265 {11,"unsigned-range" },
3267 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3268 Enumerated values 64-65535 may be used by others subject to
3269 the procedures and constraints described in Clause 23.
3270 It is expected that these enumerated values will correspond
3271 to the use of the complex-event-type CHOICE [6] of the
3272 BACnetNotificationParameters production. */
3275 static const value_string
3276 BACnetEventState [] = {
3282 {5,"life-safety-alarm" },
3284 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3285 Enumerated values 64-65535 may be used by others subject to
3286 the procedures and constraints described in Clause 23. */
3289 static const value_string
3290 BACnetLogStatus [] = {
3291 {0,"log-disabled" },
3292 {1,"buffer-purged" },
3296 static const value_string
3297 BACnetMaintenance [] = {
3299 {1,"periodic-test" },
3300 {2,"need-service-operational" },
3301 {3,"need-service-inoperative" },
3305 static const value_string
3306 BACnetNotifyType [] = {
3309 {2,"ack-notification" },
3313 static const value_string
3314 BACnetServicesSupported [] = {
3315 {0,"acknowledgeAlarm"},
3316 {1,"confirmedCOVNotification"},
3317 {2,"confirmedEventNotification"},
3318 {3,"getAlarmSummary"},
3319 {4,"getEnrollmentSummary"},
3321 {6,"atomicReadFile"},
3322 {7,"atomicWriteFile"},
3323 {8,"addListElement"},
3324 {9,"removeListElement"},
3325 {10,"createObject"},
3326 {11,"deleteObject"},
3327 {12,"readProperty"},
3328 {13,"readPropertyConditional"},
3329 {14,"readPropertyMultiple"},
3330 {15,"writeProperty"},
3331 {16,"writePropertyMultiple"},
3332 {17,"deviceCommunicationControl"},
3333 {18,"confirmedPrivateTransfer"},
3334 {19,"confirmedTextMessage"},
3335 {20,"reinitializeDevice"},
3339 {24,"authenticate"},
3343 {28,"unconfirmedCOVNotification"},
3344 {29,"unconfirmedEventNotification"},
3345 {30,"unconfirmedPrivateTransfer"},
3346 {31,"unconfirmedTextMessage"},
3347 {32,"timeSynchronization"},
3351 {36,"utcTimeSynchronization"},
3352 {37,"lifeSafetyOperation"},
3353 {38,"subscribeCOVProperty"},
3354 {39,"getEventInformation"},
3358 static const value_string
3359 BACnetPropertyStates [] = {
3360 {0,"boolean-value"},
3364 {4,"program-change"},
3365 {5,"program-state"},
3366 {6,"reason-for-halt"},
3369 {9,"system-status"},
3371 {11,"unsigned-value"},
3372 {12,"life-safety-mode"},
3373 {13,"life-safety-state"},
3374 {14,"door-alarm-state"},
3376 /* Tag values 0-63 are reserved for definition by ASHRAE.
3377 Tag values of 64-254 may be used by others to accommodate
3378 vendor specific properties that have discrete or enumerated values,
3379 subject to the constraints described in Clause 23. */
3382 static const value_string
3383 BACnetProgramError [] = {
3390 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3391 Enumerated values 64-65535 may be used by others subject to
3392 the procedures and constraints described in Clause 23. */
3395 static const value_string
3396 BACnetProgramRequest [] = {
3406 static const value_string
3407 BACnetProgramState [] = {
3417 static const value_string
3418 BACnetReinitializedStateOfDevice [] = {
3429 static const value_string
3430 BACnetPolarity [] = {
3436 static const value_string
3437 BACnetTagNames[] = {
3438 { 5, "Extended Value" },
3439 { 6, "Opening Tag" },
3440 { 7, "Closing Tag" },
3444 static const value_string
3445 BACnetReadRangeOptions[] = {
3446 { 3, "range byPosition" },
3447 { 4, "range byTime" },
3448 { 5, "range timeRange" },
3449 { 6, "range bySequenceNumber" },
3450 { 7, "range byTime" },
3454 /* Present_Value for Load Control Object */
3455 static const value_string
3456 BACnetShedState[] = {
3457 { 0, "shed-inactive" },
3458 { 1, "shed-request-pending" },
3459 { 2, "shed-compliant" },
3460 { 3, "shed-non-compliant" },
3464 static const value_string
3465 BACnetVendorIdentifiers [] = {
3468 { 2, "The Trane Company" },
3469 { 3, "McQuay International" },
3471 { 5, "Johnson Controls, Inc." },
3472 { 6, "American Auto-Matrix" },
3473 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3474 { 8, "Delta Controls" },
3475 { 9, "Siemens Building Technologies, Inc." },
3476 { 10, "Tour Andover Controls Corporation" },
3478 { 12, "Orion Analysis Corporation" },
3479 { 13, "Teletrol Systems Inc." },
3480 { 14, "Cimetrics Technology" },
3481 { 15, "Cornell University" },
3482 { 16, "United Technologies Carrier" },
3483 { 17, "Honeywell Inc." },
3484 { 18, "Alerton / Honeywell" },
3486 { 20, "Hewlett-Packard Company" },
3487 { 21, "Dorsette's Inc." },
3488 { 22, "Cerberus AG" },
3489 { 23, "York Controls Group" },
3490 { 24, "Automated Logic Corporation" },
3491 { 25, "CSI Control Systems International" },
3492 { 26, "Phoenix Controls Corporation" },
3493 { 27, "Innovex Technologies, Inc." },
3494 { 28, "KMC Controls, Inc." },
3495 { 29, "Xn Technologies, Inc." },
3496 { 30, "Hyundai Information Technology Co., Ltd." },
3497 { 31, "Tokimec Inc." },
3499 { 33, "North Communications Limited" },
3501 { 35, "Reliable Controls Corporation" },
3502 { 36, "Tridium Inc." },
3503 { 37, "Sierra Monitor Corp." },
3504 { 38, "Silicon Energy" },
3505 { 39, "Kieback & Peter GmbH & Co KG" },
3506 { 40, "Anacon Systems, Inc." },
3507 { 41, "Systems Controls & Instruments, LLC" },
3508 { 42, "Lithonia Lighting" },
3509 { 43, "Micropower Manufacturing" },
3510 { 44, "Matrix Controls" },
3511 { 45, "METALAIRE" },
3512 { 46, "ESS Engineering" },
3513 { 47, "Sphere Systems Pty Ltd." },
3514 { 48, "Walker Technologies Corporation" },
3515 { 49, "H I Solutions, Inc." },
3517 { 51, "SAMSON AG" },
3518 { 52, "Badger Meter Inc." },
3519 { 53, "DAIKIN Industries Ltd." },
3520 { 54, "NARA Controls Inc." },
3521 { 55, "Mammoth Inc." },
3522 { 56, "Liebert Corporation" },
3523 { 57, "SEMCO Incorporated" },
3524 { 58, "Air Monitor Corporation" },
3525 { 59, "TRIATEK, Inc." },
3527 { 61, "Multistack" },
3528 { 62, "TSI Incorporated" },
3529 { 63, "Weather-Rite, Inc." },
3530 { 64, "Dunham-Bush" },
3531 { 65, "Reliance Electric" },
3533 { 67, "Regulator Australia PTY Ltd." },
3534 { 68, "Touch-Plate Lighting Controls" },
3535 { 69, "Amann GmbH" },
3536 { 70, "RLE Technologies" },
3537 { 71, "Cardkey Systems" },
3538 { 72, "SECOM Co., Ltd." },
3539 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3540 { 74, "KNX Association cvba" },
3541 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3542 { 76, "Nohmi Bosai, Ltd." },
3543 { 77, "Carel S.p.A." },
3544 { 78, "AirSense Technology, Inc." },
3545 { 79, "Hochiki Corporation" },
3546 { 80, "Fr. Sauter AG" },
3547 { 81, "Matsushita Electric Works, Ltd." },
3548 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3549 { 83, "Mitsubishi Heavy Industries, Ltd." },
3550 { 84, "ITT Bell & Gossett" },
3551 { 85, "Yamatake Building Systems Co., Ltd." },
3552 { 86, "The Watt Stopper, Inc." },
3553 { 87, "Aichi Tokei Denki Co., Ltd." },
3554 { 88, "Activation Technologies, LLC" },
3555 { 89, "Saia-Burgess Controls, Ltd." },
3556 { 90, "Hitachi, Ltd." },
3557 { 91, "Novar Corp./Trend Control Systems Ltd." },
3558 { 92, "Mitsubishi Electric Lighting Corporation" },
3559 { 93, "Argus Control Systems, Ltd." },
3560 { 94, "Kyuki Corporation" },
3561 { 95, "Richards-Zeta Building Intelligence, Inc." },
3562 { 96, "Scientech R&D, Inc." },
3563 { 97, "VCI Controls, Inc." },
3564 { 98, "Toshiba Corporation" },
3565 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3566 { 100, "Custom Mechanical Equipment, LLC" },
3567 { 101, "ClimateMaster" },
3568 { 102, "ICP Panel-Tec, Inc." },
3569 { 103, "D-Tek Controls" },
3570 { 104, "NEC Engineering, Ltd." },
3571 { 105, "PRIVA BV" },
3572 { 106, "Meidensha Corporation" },
3573 { 107, "JCI Systems Integration Services" },
3574 { 108, "Freedom Corporation" },
3575 { 109, "Neuberger Gebaudeautomation GmbH" },
3576 { 110, "Sitronix" },
3577 { 111, "Leviton Manufacturing" },
3578 { 112, "Fujitsu Limited" },
3579 { 113, "Emerson Network Power" },
3580 { 114, "S. A. Armstrong, Ltd." },
3581 { 115, "Visonet AG" },
3582 { 116, "M&M Systems, Inc." },
3583 { 117, "Custom Software Engineering" },
3584 { 118, "Nittan Company, Limited" },
3585 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3586 { 120, "Pacom Systems Pty., Ltd." },
3587 { 121, "Unico, Inc." },
3588 { 122, "Ebtron, Inc." },
3589 { 123, "Scada Engine" },
3590 { 124, "AC Technology Corporation" },
3591 { 125, "Eagle Technology" },
3592 { 126, "Data Aire, Inc." },
3593 { 127, "ABB, Inc." },
3594 { 128, "Transbit Sp. z o. o." },
3595 { 129, "Toshiba Carrier Corporation" },
3596 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
3597 { 131, "Tokai Soft" },
3599 { 133, "Veris Industries" },
3600 { 134, "Centaurus Prime" },
3601 { 135, "Sand Network Systems" },
3602 { 136, "Regulvar, Inc." },
3603 { 137, "Fastek International, Ltd." },
3604 { 138, "PowerCold Comfort Air Solutions, Inc." },
3605 { 139, "I Controls" },
3606 { 140, "Viconics Electronics, Inc." },
3607 { 141, "Yaskawa Electric America, Inc." },
3608 { 142, "Plueth Regelsysteme" },
3609 { 143, "Digitale Mess- und Steuersysteme AG" },
3610 { 144, "Fujitsu General Limited" },
3611 { 145, "Project Engineering S.r.l." },
3612 { 146, "Sanyo Electric Co., Ltd." },
3613 { 147, "Integrated Information Systems, Inc." },
3614 { 148, "Temco Controls, Ltd." },
3615 { 149, "Airtek Technologies, Inc." },
3616 { 150, "Advantech Corporation" },
3617 { 151, "Titan Products, Ltd." },
3618 { 152, "Regel Partners" },
3619 { 153, "National Environmental Product" },
3620 { 154, "Unitec Corporation" },
3621 { 155, "Kanden Engineering Company" },
3622 { 156, "Messner Gebaudetechnik GmbH" },
3623 { 157, "Integrated.CH" },
3624 { 158, "EH Price Limited" },
3625 { 159, "SE-Elektronic GmbH" },
3626 { 160, "Rockwell Automation" },
3627 { 161, "Enflex Corp." },
3628 { 162, "ASI Controls" },
3629 { 163, "SysMik GmbH Dresden" },
3630 { 164, "HSC Regelungstechnik GmbH" },
3631 { 165, "Smart Temp Australia Pty. Ltd." },
3632 { 166, "PCI Lighting Control Systems" },
3633 { 167, "Duksan Mecasys Co., Ltd." },
3634 { 168, "Fuji IT Co., Ltd." },
3635 { 169, "Vacon Plc" },
3636 { 170, "Leader Controls" },
3637 { 171, "Cylon Controls, Ltd." },
3639 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
3640 { 174, "Building Control Integrators" },
3641 { 175, "ITG Worldwide (M) Sdn Bhd" },
3642 { 176, "Lutron Electronics Co., Inc." },
3643 { 177, "Cooper-Atkins Corporation" },
3644 { 178, "LOYTEC Electronics GmbH" },
3646 { 180, "Mega Controls Limited" },
3647 { 181, "Micro Control Systems, Inc." },
3648 { 182, "Kiyon, Inc." },
3649 { 183, "Dust Networks" },
3650 { 184, "Advanced Building Automation Systems" },
3651 { 185, "Hermos AG" },
3654 { 188, "Lynxspring" },
3655 { 189, "Schneider Toshiba Inverter Europe" },
3656 { 190, "Danfoss Drives A/S" },
3657 { 191, "Eaton Corporation" },
3658 { 192, "Matyca S.A." },
3659 { 193, "Botech AB" },
3660 { 194, "Noveo, Inc." },
3662 { 196, "Yokogawa Electric Corporation" },
3663 { 197, "GFR Gesellschaft fur Regelungstechnik" },
3664 { 198, "Exact Logic" },
3665 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
3666 { 200, "Kandenko Co., Ltd." },
3667 { 201, "DTF, Daten-Technik Fries" },
3668 { 202, "Klimasoft, Ltd." },
3669 { 203, "Toshiba Schneider Inverter Corporation" },
3670 { 204, "Control Applications, Ltd." },
3671 { 205, "KDT Systems Co., Ltd." },
3672 { 206, "Onicon Incorporated" },
3673 { 207, "Automation Displays, Inc." },
3674 { 208, "Control Solutions, Inc." },
3675 { 209, "Remsdaq Limited" },
3676 { 210, "NTT Facilities, Inc." },
3677 { 211, "VIPA GmbH" },
3678 { 212, "TSC21 Association of Japan" },
3679 { 213, "BBP Energie Ltee" },
3680 { 214, "HRW Limited" },
3681 { 215, "Lighting Control & Design, Inc." },
3682 { 216, "Mercy Electronic and Electrical Industries" },
3683 { 217, "Samsung SDS Co., Ltd" },
3684 { 218, "Impact Facility Solutions, Inc." },
3685 { 219, "Aircuity" },
3686 { 220, "Control Techniques, Ltd." },
3687 { 221, "Evolve Control Systems, LLC" },
3688 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
3689 { 223, "Cerus Industrial" },
3690 { 224, "Chloride Power Protection Company" },
3691 { 225, "Computrols, Inc." },
3692 { 226, "Phoenix Contact GmbH & Co. KG" },
3693 { 227, "Grundfos Management A/S" },
3694 { 228, "Ridder Drive Systems" },
3695 { 229, "Soft Device SDN BHD" },
3696 { 230, "Integrated Control Technology Limited" },
3697 { 231, "AIRxpert Systems, Inc." },
3698 { 232, "Microtrol Limited" },
3699 { 233, "Red Lion Controls" },
3700 { 234, "Digital Electronics Corporation" },
3701 { 235, "Ennovatis GmbH" },
3702 { 236, "Serotonin Software Technologies, Inc." },
3703 { 237, "LS Industrial Systems Co., Ltd." },
3704 { 238, "Square D Company" },
3705 { 239, "S Squared Innovations, Inc." },
3706 { 240, "Aricent Ltd." },
3707 { 241, "EtherMetrics, LLC" },
3708 { 242, "Industrial Control Communications, Inc." },
3709 { 243, "Paragon Controls, Inc." },
3710 { 244, "A. O. Smith Corporation" },
3711 { 245, "Contemporary Control Systems, Inc." },
3712 { 246, "Intesis Software SL" },
3713 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
3714 { 248, "Heat-Timer Corporation" },
3715 { 249, "Ingrasys Technology, Inc." },
3716 { 250, "Costerm Building Automation" },
3718 { 252, "Embedia Technologies Corp." },
3719 { 253, "Technilog" },
3720 { 254, "HR Controls Ltd. & Co. KG" },
3721 { 255, "Lennox International, Inc." },
3722 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
3723 { 257, "Thermomax, Ltd." },
3724 { 258, "ELCON Electronic Control, Ltd." },
3725 { 259, "Larmia Control AB" },
3726 { 260, "BACnet Stack at SourceForge" },
3727 { 261, "G4S Security Services A/S" },
3728 { 262, "Sitek S.p.A." },
3729 { 263, "Cristal Controles" },
3730 { 264, "Regin AB" },
3731 { 265, "Dimension Software, Inc. " },
3732 { 266, "SynapSense Corporation" },
3733 { 267, "Beijing Nantree Electronic Co., Ltd." },
3734 { 268, "Camus Hydronics Ltd." },
3735 { 269, "Kawasaki Heavy Industries, Ltd. " },
3736 { 270, "Critical Environment Technologies" },
3737 { 271, "ILSHIN IBS Co., Ltd." },
3738 { 272, "ELESTA Energy Control AG" },
3739 { 273, "KROPMAN Installatietechniek" },
3740 { 274, "Baldor Electric Company" },
3741 { 275, "INGA mbH" },
3742 { 276, "GE Consumer & Industrial" },
3743 { 277, "Functional Devices, Inc." },
3745 { 279, "M-System Co., Ltd." },
3746 { 280, "Yokota Co., Ltd." },
3747 { 281, "Hitranse Technology Co., LTD" },
3748 { 282, "Federspiel Controls" },
3749 { 283, "Kele, Inc." },
3750 { 284, "Opera Electronics, Inc." },
3752 { 286, "Embedded Science Labs, LLC" },
3753 { 287, "Parker Hannifin Corporation" },
3754 { 288, "MaCaPS International Limited" },
3755 { 289, "Link4 Corporation" },
3756 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
3757 { 291, "Pribusin, Inc." },
3758 { 292, "Advantage Controls" },
3759 { 293, "Critical Room Control" },
3761 { 295, "Tongdy Control Technology Co., Ltd." },
3762 { 296, "ISSARO Integrierte Systemtechnik" },
3763 { 297, "Pro-Dev Industries" },
3764 { 298, "DRI-STEEM" },
3765 { 299, "Creative Electronic GmbH" },
3766 { 300, "Swegon AB" },
3767 { 301, "Jan Brachacek" },
3768 { 302, "Hitachi Appliances, Inc." },
3769 { 303, "Real Time Automation, Inc." },
3770 { 304, "ITEC Hankyu-Hanshin Co." },
3771 { 305, "Cyrus E&M Engineering Co., Ltd." },
3772 { 306, "Racine Federated, Inc." },
3773 { 307, "Verari Systems, Inc." },
3774 { 308, "Elesta GmbH Building Automation" },
3775 { 309, "Securiton" },
3776 { 310, "OSlsoft, Inc." },
3777 { 311, "Hanazeder Electronic GmbH" },
3778 { 312, "Honeywell Security Deutschland, Novar GmbH" },
3779 { 313, "Siemens Energy & Automation, Inc." },
3780 { 314, "ETM Professional Control GmbH" },
3781 { 315, "Meitav-tec, Ltd." },
3782 { 316, "Janitza Electronics GmbH" },
3783 { 317, "MKS Nordhausen" },
3784 { 318, "De Gier Drive Systems B.V." },
3785 { 319, "Cypress Envirosystems" },
3786 { 320, "SMARTron s.r.o." },
3787 { 321, "Verari Systems, Inc." },
3788 { 322, "K-W Electronic Service, Inc." },
3789 { 323, "ALFA-SMART Energy Management" },
3790 { 324, "Telkonet, Inc." },
3791 { 325, "Securiton GmbH" },
3792 { 326, "Cemtrex, Inc." },
3793 { 327, "Performance Technologies, Inc." },
3794 { 328, "Xtralis (Aust) Pty Ltd" },
3795 { 329, "TROX GmbH" },
3796 { 330, "Beijing Hysine Technology Co., Ltd" },
3797 { 331, "RCK Controls, Inc." },
3799 { 333, "Novar/Honeywell" },
3800 { 334, "The S4 Group, Inc." },
3801 { 335, "Schneider Electric" },
3802 { 336, "LHA Systems" },
3803 { 337, "GHM engineering Group, Inc." },
3804 { 338, "Cllimalux S.A." },
3805 { 339, "VAISALA Oyj" },
3806 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
3807 { 342, "POWERPEG NSI Limited" },
3808 { 343, "BACnet Interoperability Testing Services, Inc." },
3809 { 344, "Teco a.s." },
3813 static int proto_bacapp = -1;
3814 static int hf_bacapp_type = -1;
3815 static int hf_bacapp_pduflags = -1;
3816 static int hf_bacapp_SEG = -1;
3817 static int hf_bacapp_MOR = -1;
3818 static int hf_bacapp_SA = -1;
3819 static int hf_bacapp_response_segments = -1;
3820 static int hf_bacapp_max_adpu_size = -1;
3821 static int hf_bacapp_invoke_id = -1;
3822 static int hf_bacapp_objectType = -1;
3823 static int hf_bacapp_instanceNumber = -1;
3824 static int hf_bacapp_sequence_number = -1;
3825 static int hf_bacapp_window_size = -1;
3826 static int hf_bacapp_service = -1;
3827 static int hf_bacapp_NAK = -1;
3828 static int hf_bacapp_SRV = -1;
3829 static int hf_BACnetRejectReason = -1;
3830 static int hf_BACnetAbortReason = -1;
3831 static int hf_BACnetApplicationTagNumber = -1;
3832 static int hf_BACnetContextTagNumber = -1;
3833 static int hf_BACnetExtendedTagNumber = -1;
3834 static int hf_BACnetNamedTag = -1;
3835 static int hf_BACnetTagClass = -1;
3836 static int hf_BACnetCharacterSet = -1;
3837 static int hf_bacapp_tag = -1;
3838 static int hf_bacapp_tag_lvt = -1;
3839 static int hf_bacapp_tag_value8 = -1;
3840 static int hf_bacapp_tag_value16 = -1;
3841 static int hf_bacapp_tag_value32 = -1;
3842 static int hf_bacapp_tag_ProcessId = -1;
3843 static int hf_bacapp_tag_initiatingObjectType = -1;
3844 static int hf_bacapp_vpart = -1;
3845 static int hf_bacapp_uservice = -1;
3846 static int hf_BACnetPropertyIdentifier = -1;
3847 static int hf_BACnetVendorIdentifier = -1;
3848 static int hf_BACnetRestartReason = -1;
3849 static int hf_bacapp_tag_IPV4 = -1;
3850 static int hf_bacapp_tag_IPV6 = -1;
3851 static int hf_bacapp_tag_PORT = -1;
3852 /* some more variables for segmented messages */
3853 static int hf_msg_fragments = -1;
3854 static int hf_msg_fragment = -1;
3855 static int hf_msg_fragment_overlap = -1;
3856 static int hf_msg_fragment_overlap_conflicts = -1;
3857 static int hf_msg_fragment_multiple_tails = -1;
3858 static int hf_msg_fragment_too_long_fragment = -1;
3859 static int hf_msg_fragment_error = -1;
3860 static int hf_msg_reassembled_in = -1;
3861 static int hf_msg_reassembled_length = -1;
3863 static gint ett_msg_fragment = -1;
3864 static gint ett_msg_fragments = -1;
3866 static gint ett_bacapp = -1;
3867 static gint ett_bacapp_control = -1;
3868 static gint ett_bacapp_tag = -1;
3869 static gint ett_bacapp_list = -1;
3870 static gint ett_bacapp_value = -1;
3872 static dissector_handle_t data_handle;
3873 static gint32 propertyIdentifier = -1;
3874 static gint32 propertyArrayIndex = -1;
3875 static guint32 object_type = 4096;
3877 static guint8 bacapp_flags = 0;
3878 static guint8 bacapp_seq = 0;
3880 static const fragment_items msg_frag_items = {
3881 /* Fragment subtrees */
3884 /* Fragment fields */
3887 &hf_msg_fragment_overlap,
3888 &hf_msg_fragment_overlap_conflicts,
3889 &hf_msg_fragment_multiple_tails,
3890 &hf_msg_fragment_too_long_fragment,
3891 &hf_msg_fragment_error,
3892 /* Reassembled in field */
3893 &hf_msg_reassembled_in,
3894 /* Reassembled length field */
3895 &hf_msg_reassembled_length,
3900 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
3901 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
3904 fGetMaxAPDUSize(guint8 idx)
3906 /* only 16 values are defined, so use & 0x0f */
3907 /* check the size of the Array, deliver either the entry
3908 or the first entry if idx is outside of the array (bug 3736 comment#7) */
3909 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
3910 return MaxAPDUSize[0];
3912 return MaxAPDUSize[idx & 0x0f];
3915 /* Used when there are ranges of reserved and proprietary enumerations */
3917 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
3918 const char *fmt, const char *split_fmt)
3920 if (val < split_val)
3921 return val_to_str(val, vs, fmt);
3923 return val_to_str(val, vs, split_fmt);
3926 /* from clause 20.2.1.3.2 Constructed Data */
3927 /* returns true if the extended value is used */
3928 static gboolean tag_is_extended_value(guint8 tag)
3930 return (tag & 0x07) == 5;
3933 static gboolean tag_is_opening(guint8 tag)
3935 return (tag & 0x07) == 6;
3938 static gboolean tag_is_closing(guint8 tag)
3940 return (tag & 0x07) == 7;
3943 /* from clause 20.2.1.1 Class
3944 class bit shall be one for context specific tags */
3945 /* returns true if the tag is context specific */
3946 static gboolean tag_is_context_specific(guint8 tag)
3948 return (tag & 0x08) != 0;
3951 static gboolean tag_is_extended_tag_number(guint8 tag)
3953 return ((tag & 0xF0) == 0xF0);
3956 static guint32 object_id_type(guint32 object_identifier)
3958 return ((object_identifier >> 22) & 0x3FF);
3961 static guint32 object_id_instance(guint32 object_identifier)
3963 return (object_identifier & 0x3FFFFF);
3967 fTagNo (tvbuff_t *tvb, guint offset)
3969 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
3973 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
3975 gboolean valid = TRUE;
3979 *val = tvb_get_guint8(tvb, offset);
3982 *val = tvb_get_ntohs(tvb, offset);
3985 *val = tvb_get_ntoh24(tvb, offset);
3988 *val = tvb_get_ntohl(tvb, offset);
3999 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4001 gboolean valid = FALSE;
4005 if (lvt && (lvt <= 8)) {
4007 data = tvb_get_guint8(tvb, offset);
4008 for (i = 0; i < lvt; i++) {
4009 data = tvb_get_guint8(tvb, offset+i);
4010 value = (value << 8) + data;
4018 /* BACnet Signed Value uses 2's compliment notation, but with a twist:
4019 All signed integers shall be encoded in the smallest number of octets
4020 possible. That is, the first octet of any multi-octet encoded value
4021 shall not be X'00' if the most significant bit (bit 7) of the second
4022 octet is 0, and the first octet shall not be X'FF' if the most
4023 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4025 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4027 gboolean valid = FALSE;
4031 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4032 if (lvt && (lvt <= 7)) {
4034 data = tvb_get_guint8(tvb, offset);
4035 if ((data & 0x80) != 0)
4036 value = (-1 << 8) | data;
4039 for (i = 1; i < lvt; i++) {
4040 data = tvb_get_guint8(tvb, offset+i);
4041 value = (value << 8) + data;
4050 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
4051 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4056 guint lvt_len = 1; /* used for tree display of lvt */
4057 guint lvt_offset; /* used for tree display of lvt */
4059 proto_tree *subtree;
4061 lvt_offset = offset;
4062 tag = tvb_get_guint8(tvb, offset);
4065 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4066 /* can mean open/close tag or length of 6/7 after the length is */
4067 /* computed below - store whole tag info, not just context bit. */
4068 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4070 if (tag_is_extended_tag_number(tag)) {
4071 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4073 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4074 lvt_offset += tag_len;
4075 value = tvb_get_guint8(tvb, lvt_offset);
4077 if (value == 254) { /* length is encoded with 16 Bits */
4078 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4081 } else if (value == 255) { /* length is encoded with 32 Bits */
4082 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4090 if (tag_is_opening(tag))
4091 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4092 else if (tag_is_closing(tag))
4093 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4094 /* this is mostly too much information
4095 if (tag_is_closing(tag) || tag_is_opening(tag))
4096 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4097 "%s: %u", val_to_str(
4098 tag & 0x07, BACnetTagNames, "Unknown (%d)"),
4101 else if (tag_is_context_specific(tag)) {
4102 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4103 "Context Tag: %u, Length/Value/Type: %u",
4106 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4107 "Application Tag: %s, Length/Value/Type: %u",
4109 BACnetApplicationTagNumber,
4110 ASHRAE_Reserved_Fmt),
4113 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4114 /* details if needed */
4115 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, FALSE);
4116 if (tag_is_extended_tag_number(tag)) {
4117 proto_tree_add_uint_format(subtree,
4118 hf_BACnetContextTagNumber,
4119 tvb, offset, 1, tag,
4120 "Extended Tag Number");
4121 proto_tree_add_item(subtree,
4122 hf_BACnetExtendedTagNumber,
4123 tvb, offset + 1, 1, FALSE);
4125 if (tag_is_context_specific(tag))
4126 proto_tree_add_item(subtree,
4127 hf_BACnetContextTagNumber,
4128 tvb, offset, 1, FALSE);
4130 proto_tree_add_item(subtree,
4131 hf_BACnetApplicationTagNumber,
4132 tvb, offset, 1, FALSE);
4134 if (tag_is_closing(tag) || tag_is_opening(tag))
4135 proto_tree_add_item(subtree,
4137 tvb, offset, 1, FALSE);
4138 else if (tag_is_extended_value(tag)) {
4139 proto_tree_add_item(subtree,
4141 tvb, offset, 1, FALSE);
4142 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4143 tvb, lvt_offset, lvt_len, *lvt);
4145 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4146 tvb, lvt_offset, lvt_len, *lvt);
4153 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
4156 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
4160 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4162 guint8 tag_no, tag_info;
4165 proto_tree *subtree;
4167 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4168 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4169 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4175 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4177 guint8 tag_no, tag_info;
4181 proto_tree *subtree;
4184 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4185 if (tag_info && lvt == 1)
4187 lvt = tvb_get_guint8(tvb, offset+1);
4191 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
4192 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
4193 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4194 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4196 return offset + bool_len;
4200 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4203 guint8 tag_no, tag_info;
4207 proto_tree *subtree;
4209 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4210 /* only support up to an 8 byte (64-bit) integer */
4211 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
4212 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4213 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
4215 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4216 "%s - %u octets (Unsigned)", label, lvt);
4217 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4218 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4220 return offset+tag_len+lvt;
4223 /* set split_val to zero when not needed */
4225 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4226 const value_string *vs, guint32 split_val)
4229 guint8 tag_no, tag_info;
4233 proto_tree *subtree;
4235 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4236 /* only support up to a 4 byte (32-bit) enumeration */
4237 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
4239 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4240 "%s %s", label, val_to_split_str(val, split_val, vs,
4241 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
4243 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4244 "%s %u", label, val);
4246 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4247 "%s - %u octets (enumeration)", label, lvt);
4249 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4250 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4252 return offset+tag_len+lvt;
4256 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4257 const value_string *vs)
4259 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
4263 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4266 guint8 tag_no, tag_info;
4270 proto_tree *subtree;
4272 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4273 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
4274 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4275 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
4277 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4278 "%s - %u octets (Signed)", label, lvt);
4279 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4280 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4282 return offset+tag_len+lvt;
4286 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4288 guint8 tag_no, tag_info;
4293 proto_tree *subtree;
4295 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4296 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
4297 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
4298 "%s%f (Real)", label, f_val);
4299 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4300 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4302 return offset+tag_len+4;
4306 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4308 guint8 tag_no, tag_info;
4313 proto_tree *subtree;
4315 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4316 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
4317 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
4318 "%s%f (Double)", label, d_val);
4319 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4320 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4322 return offset+tag_len+8;
4326 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
4328 guint32 val = 0, lvt;
4329 guint8 tag_no, tag_info;
4331 proto_tree *subtree;
4334 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4335 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4336 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
4337 tvb, offset, lvt+tag_len, val);
4339 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4340 "Process Identifier - %u octets (Signed)", lvt);
4341 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4342 offset += tag_len + lvt;
4348 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4350 guint32 val = 0, lvt;
4351 guint8 tag_no, tag_info;
4353 proto_tree *subtree;
4356 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4357 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4358 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4359 "%s (hh.mm.ss): %d.%02d.%02d%s",
4361 (val / 3600), ((val % 3600) / 60), (val % 60),
4362 val == 0 ? " (indefinite)" : "");
4364 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4365 "%s - %u octets (Signed)", label, lvt);
4366 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4367 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4369 return offset+tag_len+lvt;
4373 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
4375 guint32 month, weekOfMonth, dayOfWeek;
4376 guint8 tag_no, tag_info;
4380 proto_tree *subtree;
4382 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4383 month = tvb_get_guint8(tvb, offset+tag_len);
4384 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
4385 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
4386 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
4387 val_to_str(month, months, "month (%d) not found"),
4388 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
4389 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
4390 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4391 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4393 return offset+tag_len+lvt;
4397 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4399 guint32 year, month, day, weekday;
4400 guint8 tag_no, tag_info;
4404 proto_tree *subtree;
4406 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4407 year = tvb_get_guint8(tvb, offset+tag_len);
4408 month = tvb_get_guint8(tvb, offset+tag_len+1);
4409 day = tvb_get_guint8(tvb, offset+tag_len+2);
4410 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
4411 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255))
4413 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4416 else if (year != 255)
4419 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4420 "%s%s %d, %d, (Day of Week = %s)",
4421 label, val_to_str(month,
4423 "month (%d) not found"),
4424 day, year, val_to_str(weekday,
4430 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4431 "%s%s %d, any year, (Day of Week = %s)",
4432 label, val_to_str(month, months, "month (%d) not found"),
4433 day, val_to_str(weekday, day_of_week, "(%d) not found"));
4435 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4436 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4438 return offset+tag_len+lvt;
4442 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4444 guint32 hour, minute, second, msec, lvt;
4445 guint8 tag_no, tag_info;
4448 proto_tree *subtree;
4450 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4451 hour = tvb_get_guint8(tvb, offset+tag_len);
4452 minute = tvb_get_guint8(tvb, offset+tag_len+1);
4453 second = tvb_get_guint8(tvb, offset+tag_len+2);
4454 msec = tvb_get_guint8(tvb, offset+tag_len+3);
4455 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
4456 ti = proto_tree_add_text(tree, tvb, offset,
4457 lvt+tag_len, "%sany", label);
4459 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4460 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
4462 hour > 12 ? hour - 12 : hour,
4463 minute, second, msec,
4464 hour >= 12 ? "P.M." : "A.M.",
4465 hour, minute, second, msec);
4466 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4467 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4469 return offset+tag_len+lvt;
4473 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4475 proto_tree *subtree = tree;
4478 if (label != NULL) {
4479 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
4480 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4482 offset = fDate (tvb,subtree,offset,"Date: ");
4483 return fTime (tvb,subtree,offset,"Time: ");
4487 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4489 guint lastoffset = 0;
4490 guint8 tag_no, tag_info;
4493 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4494 lastoffset = offset;
4495 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4496 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
4499 offset = fTime (tvb,tree,offset,"Time: ");
4500 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
4506 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
4508 guint8 tag_no, tag_info;
4511 switch (fTagNo(tvb, offset)) {
4513 offset = fDate (tvb, tree, offset, "Date: ");
4515 case 1: /* dateRange */
4516 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4517 offset = fDateRange (tvb, tree, offset);
4518 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4520 case 2: /* BACnetWeekNDay */
4521 offset = fWeekNDay (tvb, tree, offset);
4530 static guint fTimeStamp (tvbuff_t *tvb, proto_tree *tree,
4531 guint offset, const gchar *label)
4533 guint8 tag_no = 0, tag_info = 0;
4536 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
4537 switch (fTagNo(tvb, offset)) {
4539 offset = fTime (tvb, tree, offset, label?label:"timestamp: ");
4541 case 1: /* sequenceNumber */
4542 offset = fUnsignedTag (tvb, tree, offset,
4543 label?label:"sequence Number: ");
4545 case 2: /* dateTime */
4546 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4547 offset = fDateTime (tvb, tree, offset, label?label:"timestamp: ");
4548 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4560 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4562 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4563 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
4568 static const value_string
4569 BACnetDaysOfWeek [] = {
4581 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4583 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4584 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
4585 "valid Days: ", BACnetDaysOfWeek);
4586 offset = fTime (tvb,tree,offset,"from time: ");
4587 offset = fTime (tvb,tree,offset,"to time: ");
4588 offset = fRecipient (tvb,pinfo,tree,offset);
4589 offset = fProcessId (tvb,tree,offset);
4590 offset = fApplicationTypes (tvb,pinfo,tree,offset,
4591 "issue confirmed notifications: ");
4592 offset = fBitStringTagVS (tvb,tree,offset,
4593 "transitions: ", BACnetEventTransitionBits);
4600 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4603 guint start = offset;
4604 guint8 tag_no, tag_info;
4605 proto_tree* subtree = tree;
4608 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4612 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4613 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
4618 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4620 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4626 fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4629 guint start = offset;
4630 guint8 tag_no, tag_info;
4631 proto_tree* subtree = tree;
4634 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4636 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
4640 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
4642 guint32 ip = tvb_get_ipv4(tvb, offset);
4643 guint16 port = tvb_get_ntohs(tvb, offset+4);
4645 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
4646 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
4649 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
4650 struct e_in6_addr addr;
4651 guint16 port = tvb_get_ntohs(tvb, offset+16);
4652 tvb_get_ipv6(tvb, offset, &addr);
4654 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
4655 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
4657 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
4658 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4659 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
4666 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4668 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4674 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
4676 guint8 tag_no, tag_info;
4680 offset = fUnsignedTag (tvb, tree, offset, "network-number");
4681 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4683 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
4686 offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
4692 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
4694 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
4695 return fAddress (tvb,tree,offset);
4699 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4701 guint8 tag_no, tag_info;
4705 proto_tree *subtree;
4708 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4709 object_id = tvb_get_ntohl(tvb,offset+tag_length);
4710 object_type = object_id_type(object_id);
4711 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
4712 "ObjectIdentifier: %s, %u",
4713 val_to_split_str(object_type,
4716 ASHRAE_Reserved_Fmt,
4717 Vendor_Proprietary_Fmt),
4718 object_id_instance(object_id));
4719 if (col_get_writable(pinfo->cinfo))
4720 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
4721 val_to_split_str(object_type,
4724 ASHRAE_Reserved_Fmt,
4725 Vendor_Proprietary_Fmt),
4726 object_id_instance(object_id));
4728 /* here are the details of how we arrived at the above text */
4729 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4730 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4731 offset += tag_length;
4732 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, FALSE);
4733 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, FALSE);
4740 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4742 guint8 tag_no, tag_info;
4745 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4747 if (tag_no == 0) { /* device */
4748 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
4750 else { /* address */
4751 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4752 offset = fAddress (tvb, tree, offset);
4753 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4760 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4762 guint lastoffset = 0;
4763 guint8 tag_no, tag_info;
4766 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4767 lastoffset = offset;
4769 switch (fTagNo(tvb, offset)) {
4770 case 0: /* recipient */
4771 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4772 offset = fRecipient (tvb, pinfo, tree, offset);
4773 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4775 case 1: /* processId */
4776 offset = fProcessId (tvb, tree, offset);
4777 lastoffset = offset;
4787 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4789 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
4790 return fAddress (tvb, tree, offset);
4794 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
4796 guint lastoffset = 0;
4797 guint8 tag_no, tag_info;
4799 proto_tree *subtree = tree;
4801 /* set the optional global properties to indicate not-used */
4802 propertyArrayIndex = -1;
4803 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4804 lastoffset = offset;
4805 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4806 if (tag_is_closing(tag_info) ) {
4807 if (tag_no == tag_match) {
4810 offset += fTagHeaderTree (tvb, subtree, offset,
4811 &tag_no, &tag_info, &lvt);
4817 case 0: /* deviceIdentifier */
4818 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
4820 case 1: /* objectIdentifier */
4821 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
4823 case 2: /* propertyIdentifier */
4824 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
4826 case 3: /* propertyArrayIndex */
4827 offset = fPropertyArrayIndex (tvb, subtree, offset);
4829 case 4: /* propertyValue */
4830 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
4832 case 5: /* priority */
4833 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
4835 case 6: /* postDelay */
4836 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
4838 case 7: /* quitOnFailure */
4839 offset = fBooleanTag(tvb, subtree, offset,
4840 "Quit On Failure: ");
4842 case 8: /* writeSuccessful */
4843 offset = fBooleanTag(tvb, subtree, offset,
4844 "Write Successful: ");
4853 /* BACnetActionList ::= SEQUENCE{
4854 action [0] SEQUENCE OF BACnetActionCommand
4858 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4860 guint lastoffset = 0;
4861 guint8 tag_no, tag_info;
4863 proto_tree *subtree = tree;
4866 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
4867 lastoffset = offset;
4868 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4869 if (tag_is_closing(tag_info)) {
4870 offset += fTagHeaderTree (tvb, subtree, offset,
4871 &tag_no, &tag_info, &lvt);
4875 if (tag_is_opening(tag_info)) {
4876 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
4877 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4878 offset += fTagHeaderTree (tvb, subtree, offset,
4879 &tag_no, &tag_info, &lvt);
4882 case 0: /* BACnetActionCommand */
4883 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
4893 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4895 guint8 tag_no, tag_info;
4899 proto_tree *subtree;
4900 const gchar *label = "Property Identifier";
4902 propertyIdentifier = 0; /* global Variable */
4903 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4904 /* can we decode this value? */
4905 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
4906 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4907 "%s: %s (%u)", label,
4908 val_to_split_str(propertyIdentifier, 512,
4909 BACnetPropertyIdentifier,
4910 ASHRAE_Reserved_Fmt,
4911 Vendor_Proprietary_Fmt), propertyIdentifier);
4912 if (col_get_writable(pinfo->cinfo))
4913 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
4914 val_to_split_str(propertyIdentifier, 512,
4915 BACnetPropertyIdentifier,
4916 ASHRAE_Reserved_Fmt,
4917 Vendor_Proprietary_Fmt));
4919 /* property identifiers cannot be larger than 22-bits */
4922 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4923 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4924 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
4925 offset+tag_len, lvt, FALSE);
4927 return offset+tag_len+lvt;
4931 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
4933 guint8 tag_no, tag_info;
4937 proto_tree *subtree;
4939 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4940 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
4941 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4942 "property Array Index (Unsigned) %u", propertyArrayIndex);
4944 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4945 "property Array Index - %u octets (Unsigned)", lvt);
4946 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4947 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4949 return offset+tag_len+lvt;
4953 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4955 guint8 tag_no, tag_info, character_set;
4957 gsize inbytesleft, outbytesleft = 512;
4958 guint offs, extra = 1;
4961 guint8 bf_arr[512], *out = &bf_arr[0];
4963 proto_tree *subtree;
4964 guint start = offset;
4966 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4968 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4970 character_set = tvb_get_guint8(tvb, offset+offs);
4971 /* Account for code page if DBCS */
4972 if (character_set == 1)
4976 offset += (offs+extra);
4980 inbytesleft = l = MIN(lvt, 255);
4982 * XXX - are we guaranteed that these encoding
4983 * names correspond, on *all* platforms with
4984 * iconv(), to the encodings we want?
4985 * If not (and perhaps even if so), we should
4986 * perhaps have our own iconv() implementation,
4987 * with a different name, so that we control the
4988 * encodings it supports and the names of those
4991 * We should also handle that in the general
4992 * string handling code, rather than making it
4993 * specific to the BACAPP dissector, as many
4994 * other dissectors need to handle various
4995 * character encodings.
4997 str_val = tvb_get_ephemeral_string(tvb, offset, l);
4998 /** this decoding may be not correct for multi-byte characters, Lka */
4999 switch (character_set) {
5001 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ANSI_X3.4");
5002 coding = "ANSI X3.4";
5006 coding = "IBM MS DBCS";
5010 coding = "JIS C 6226";
5012 case ISO_10646_UCS4:
5013 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5014 coding = "ISO 10646 UCS-4";
5016 case ISO_10646_UCS2:
5017 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5018 coding = "ISO 10646 UCS-2";
5021 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5022 coding = "ISO 8859-1";
5029 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s'%s'", label, coding, out);
5034 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5036 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
5037 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, FALSE);
5039 if (character_set == 1)
5041 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5048 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5049 const value_string *src)
5051 guint8 tag_no, tag_info, tmp;
5052 gint j, unused, skip;
5053 guint start = offset;
5055 guint32 lvt, i, numberOfBytes;
5057 proto_tree* subtree = tree;
5060 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5061 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
5063 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
5064 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
5068 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5070 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5071 proto_tree_add_text(subtree, tvb, offset, 1,
5075 for (i = 0; i < numberOfBytes; i++) {
5076 tmp = tvb_get_guint8(tvb, (offset)+i+1);
5077 if (i == numberOfBytes-1) { skip = unused; }
5078 for (j = 0; j < 8-skip; j++) {
5080 if (tmp & (1 << (7 - j)))
5081 proto_tree_add_text(subtree, tvb,
5084 val_to_str((guint) (i*8 +j),
5086 ASHRAE_Reserved_Fmt));
5088 proto_tree_add_text(subtree, tvb,
5091 val_to_str((guint) (i*8 +j),
5093 ASHRAE_Reserved_Fmt));
5095 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
5102 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
5103 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
5112 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5114 return fBitStringTagVS (tvb, tree, offset, label, NULL);
5117 /* handles generic application types, as well as enumerated and enumerations
5118 with reserved and proprietarty ranges (split) */
5120 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5121 const gchar *label, const value_string *src, guint32 split_val)
5123 guint8 tag_no, tag_info;
5127 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5129 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5130 if (!tag_is_context_specific(tag_info))
5133 case 0: /** NULL 20.2.2 */
5134 offset = fNullTag(tvb, tree, offset, label);
5136 case 1: /** BOOLEAN 20.2.3 */
5137 offset = fBooleanTag(tvb, tree, offset, label);
5139 case 2: /** Unsigned Integer 20.2.4 */
5140 offset = fUnsignedTag(tvb, tree, offset, label);
5142 case 3: /** Signed Integer 20.2.5 */
5143 offset = fSignedTag(tvb, tree, offset, label);
5145 case 4: /** Real 20.2.6 */
5146 offset = fRealTag(tvb, tree, offset, label);
5148 case 5: /** Double 20.2.7 */
5149 offset = fDoubleTag(tvb, tree, offset, label);
5151 case 6: /** Octet String 20.2.8 */
5152 offset = fOctetString (tvb, tree, offset, label, lvt);
5154 case 7: /** Character String 20.2.9 */
5155 offset = fCharacterString (tvb,tree,offset,label);
5157 case 8: /** Bit String 20.2.10 */
5158 offset = fBitStringTagVS (tvb, tree, offset, label, src);
5160 case 9: /** Enumerated 20.2.11 */
5161 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
5163 case 10: /** Date 20.2.12 */
5164 offset = fDate (tvb, tree, offset, label);
5166 case 11: /** Time 20.2.13 */
5167 offset = fTime (tvb, tree, offset, label);
5169 case 12: /** BACnetObjectIdentifier 20.2.14 */
5170 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5172 case 13: /* reserved for ASHRAE */
5175 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
5176 offset+=lvt+tag_len;
5188 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
5190 guint lastoffset = 0;
5192 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5193 lastoffset = offset;
5195 switch (fTagNo(tvb,offset)) {
5196 case 0: /* percent */
5197 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
5200 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
5202 case 2: /* amount */
5203 offset = fRealTag(tvb, tree, offset, "shed amount: ");
5213 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5214 const gchar *label, const value_string *vs)
5216 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
5220 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5223 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
5227 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5229 guint8 tag_no, tag_info;
5233 proto_tree *subtree;
5237 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5238 /* cap the the suggested length in case of bad data */
5239 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
5240 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt))
5244 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
5245 "Context Value (as %u DATA octets)", lvt);
5247 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5248 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5250 return offset + tag_len + lvt;
5254 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5256 guint8 tag_no, tag_info;
5258 guint lastoffset = 0, depth = 0;
5261 if (propertyIdentifier >= 0)
5263 g_snprintf (ar, sizeof(ar), "%s: ",
5264 val_to_split_str(propertyIdentifier, 512,
5265 BACnetPropertyIdentifier,
5266 ASHRAE_Reserved_Fmt,
5267 Vendor_Proprietary_Fmt));
5271 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
5273 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5274 lastoffset = offset;
5275 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5276 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
5277 if (depth <= 0) return offset;
5280 /* Application Tags */
5281 switch (propertyIdentifier) {
5282 case 2: /* action */
5283 /* loop object is application tagged,
5284 command object is context tagged */
5285 if (tag_is_context_specific(tag_info)) {
5286 /* BACnetActionList */
5287 offset = fActionList (tvb, pinfo, tree,offset);
5290 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5294 case 30: /* BACnetAddressBinding */
5295 offset = fAddressBinding (tvb,pinfo,tree,offset);
5297 case 54: /* list of object property reference */
5298 offset = fLOPR (tvb, pinfo, tree,offset);
5300 case 55: /* list-of-session-keys */
5301 fSessionKey (tvb, tree, offset);
5303 case 79: /* object-type */
5304 case 96: /* protocol-object-types-supported */
5305 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
5306 BACnetObjectType, 128);
5308 case 97: /* Protocol-Services-Supported */
5309 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5310 BACnetServicesSupported);
5312 case 102: /* recipient-list */
5313 offset = fDestination (tvb, pinfo, tree, offset);
5315 case 107: /* segmentation-supported */
5316 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5317 BACnetSegmentation);
5319 case 111: /* Status-Flags */
5320 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5323 case 112: /* System-Status */
5324 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5325 BACnetDeviceStatus);
5327 case 117: /* units */
5328 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5329 BACnetEngineeringUnits);
5331 case 87: /* priority-array -- accessed as a BACnetARRAY */
5332 if (propertyArrayIndex == 0) {
5333 /* BACnetARRAY index 0 refers to the length
5334 of the array, not the elements of the array */
5335 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5337 offset = fPriorityArray (tvb, pinfo, tree, offset);
5340 case 38: /* exception-schedule */
5341 if (object_type < 128)
5343 if (propertyArrayIndex == 0) {
5344 /* BACnetARRAY index 0 refers to the length
5345 of the array, not the elements of the array */
5346 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5348 offset = fSpecialEvent (tvb,pinfo,tree,offset);
5352 case 19: /* controlled-variable-reference */
5353 case 60: /* manipulated-variable-reference */
5354 case 109: /* Setpoint-Reference */
5355 case 132: /* log-device-object-property */
5356 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
5358 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
5359 if (object_type < 128)
5361 if (propertyArrayIndex == 0) {
5362 /* BACnetARRAY index 0 refers to the length
5363 of the array, not the elements of the array */
5364 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5366 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
5370 case 127: /* client COV increment */
5371 offset = fClientCOV (tvb, pinfo, tree, offset);
5373 case 131: /* log-buffer */
5374 offset = fLogRecord (tvb, pinfo, tree, offset);
5376 case 159: /* member-of */
5377 case 165: /* zone-members */
5378 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
5380 case 196: /* last-restart-reason */
5381 offset = fRestartReason (tvb, pinfo, tree, offset);
5383 case 212: /* actual-shed-level */
5384 case 214: /* expected-shed-level */
5385 case 218: /* requested-shed-level */
5386 offset = fShedLevel (tvb, tree, offset);
5391 if (tag_is_opening(tag_info))
5394 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5396 else if (tag_is_closing(tag_info))
5399 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5403 offset = fContextTaggedValue(tvb, tree, offset, ar);
5408 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5418 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
5423 if (tag_is_opening(tag_info)) {
5424 offset += fTagHeaderTree(tvb, tree, offset,
5425 &tag_no, &tag_info, &lvt);
5426 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
5427 if (tvb_length_remaining(tvb, offset) > 0) {
5428 offset += fTagHeaderTree(tvb, tree, offset,
5429 &tag_no, &tag_info, &lvt);
5432 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
5433 "expected Opening Tag!"); \
5434 offset = tvb_length(tvb);
5442 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
5444 guint lastoffset = offset;
5445 guint8 tag_no, tag_info;
5448 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
5449 if (offset > lastoffset)
5451 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5452 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
5453 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
5460 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5462 guint lastoffset = 0;
5463 guint8 tag_no, tag_info;
5466 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5467 lastoffset = offset;
5468 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
5469 if (offset > lastoffset)
5471 /* detect optional priority
5472 by looking to see if the next tag is context tag number 3 */
5473 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5474 if (tag_is_context_specific(tag_info) && (tag_no == 3))
5475 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
5482 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5484 guint lastoffset = 0;
5485 guint8 tag_no, tag_info;
5487 proto_tree *subtree = tree;
5490 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5491 lastoffset = offset;
5492 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5493 if (tag_is_closing(tag_info)) {
5494 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5500 case 0: /* ProcessId */
5501 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
5503 case 1: /* monitored ObjectId */
5504 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5506 case 2: /* issueConfirmedNotifications */
5507 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
5509 case 3: /* life time */
5510 offset = fTimeSpan (tvb,tree,offset,"life time");
5512 case 4: /* monitoredPropertyIdentifier */
5513 if (tag_is_opening(tag_info)) {
5514 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
5516 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5518 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5519 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
5524 case 5: /* covIncrement */
5525 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5535 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5537 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
5541 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5543 guint lastoffset = 0;
5545 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5546 lastoffset = offset;
5548 switch (fTagNo(tvb, offset)) {
5549 case 0: /* deviceInstanceLowLimit */
5550 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
5552 case 1: /* deviceInstanceHighLimit */
5553 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
5555 case 2: /* BACnetObjectId */
5556 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5558 case 3: /* messageText */
5559 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
5570 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
5572 guint lastoffset = 0;
5573 guint8 tag_no, tag_info;
5576 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5577 if (tag_is_opening(tag_info) && tag_no == 0)
5579 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
5580 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5581 lastoffset = offset;
5582 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5583 if (tag_is_closing(tag_info)) {
5584 /* should be closing context tag 0 */
5585 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5589 offset = fTimeValue (tvb, pinfo, subtree, offset);
5592 else if (tag_no == 0 && lvt == 0)
5594 /* not sure null (empty array element) is legal */
5595 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5601 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5603 guint lastoffset = 0;
5604 guint8 tag_no, tag_info;
5606 guint i = 1; /* day of week array index */
5607 proto_tree *subtree = tree;
5610 if (propertyArrayIndex > 0) {
5611 /* BACnetARRAY index 0 refers to the length
5612 of the array, not the elements of the array.
5613 BACnetARRAY index -1 is our internal flag that
5614 the optional index was not used.
5615 BACnetARRAY refers to this as all elements of the array.
5616 If the optional index is specified for a BACnetARRAY,
5617 then that specific array element is referenced. */
5618 i = propertyArrayIndex;
5620 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5621 lastoffset = offset;
5622 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5623 if (tag_is_closing(tag_info)) {
5624 return offset; /* outer encoding will print out closing tag */
5626 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
5627 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5628 offset = fDailySchedule (tvb, pinfo, subtree, offset);
5635 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5637 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5640 return fDateTime (tvb, tree, offset, "UTC-Time: ");
5644 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5646 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5649 return fDateTime (tvb, tree, offset, NULL);
5653 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
5655 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5657 offset = fDate (tvb,tree,offset,"Start Date: ");
5658 return fDate (tvb, tree, offset, "End Date: ");
5662 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5665 guint8 tag_no, tag_info;
5669 proto_tree *subtree;
5670 const gchar *label = "Vendor ID";
5672 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5673 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
5674 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5675 "%s: %s (%u)", label,
5676 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
5678 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5679 "%s - %u octets (Unsigned)", label, lvt);
5680 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5681 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5684 proto_item *expert_item;
5685 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
5686 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
5687 PROTO_ITEM_SET_GENERATED(expert_item);
5688 return offset+tag_len+lvt;
5691 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
5692 offset+tag_len, lvt, FALSE);
5694 return offset+tag_len+lvt;
5698 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5701 guint8 tag_no, tag_info;
5705 proto_tree *subtree;
5706 const gchar *label = "Restart Reason";
5708 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5709 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
5710 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5711 "%s: %s (%u)", label,
5712 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
5714 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5715 "%s - %u octets (Unsigned)", label, lvt);
5716 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5717 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5720 proto_item *expert_item;
5721 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
5722 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
5723 PROTO_ITEM_SET_GENERATED(expert_item);
5724 return offset+tag_len+lvt;
5727 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
5728 offset+tag_len, lvt, FALSE);
5730 return offset+tag_len+lvt;
5734 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5736 guint lastoffset = 0;
5738 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5739 lastoffset = offset;
5740 switch (fTagNo(tvb, offset)) {
5742 case 0: /* textMessageSourceDevice */
5743 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5745 case 1: /* messageClass */
5746 switch (fTagNo(tvb, offset)) {
5747 case 0: /* numeric */
5748 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
5750 case 1: /* character */
5751 offset = fCharacterString (tvb, tree, offset, "message Class: ");
5755 case 2: /* messagePriority */
5756 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
5757 BACnetMessagePriority);
5759 case 3: /* message */
5760 offset = fCharacterString (tvb, tree, offset, "message: ");
5770 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5772 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
5776 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5778 guint lastoffset = 0;
5779 guint8 tag_no, tag_info;
5781 proto_tree *subtree = tree;
5784 /* exit loop if nothing happens inside */
5785 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
5786 lastoffset = offset;
5787 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5788 if (tag_is_closing(tag_info)) {
5789 if (tag_no == 2) /* Make sure it's the expected tag */
5791 offset += fTagHeaderTree (tvb, subtree, offset,
5792 &tag_no, &tag_info, &lvt);
5798 break; /* End loop if incorrect closing tag */
5803 case 0: /* vendorID */
5804 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
5806 case 1: /* serviceNumber */
5807 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
5809 case 2: /*serviceParameters */
5810 if (tag_is_opening(tag_info)) {
5811 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
5812 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5813 propertyIdentifier = -1;
5814 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
5827 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5829 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
5833 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5835 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
5839 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5841 guint lastoffset = 0;
5842 guint8 tag_no, tag_info;
5844 proto_tree *subtree = tree;
5847 if (label != NULL) {
5848 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
5849 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5852 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5853 lastoffset = offset;
5854 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5857 case 0: /* subscriberProcessId */
5858 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
5860 case 1: /* requestingSource */
5861 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
5863 case 2: /* request */
5864 offset = fEnumeratedTagSplit (tvb, tree, offset,
5865 "request: ", BACnetLifeSafetyOperation, 64);
5867 case 3: /* objectId */
5868 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5877 static guint fBACnetPropertyStates(tvbuff_t *tvb, proto_tree *tree, guint offset)
5879 switch (fTagNo(tvb, offset))
5882 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
5885 offset = fEnumeratedTagSplit (tvb, tree, offset,
5886 "binary-value: ", BACnetBinaryPV, 2);
5889 offset = fEnumeratedTagSplit (tvb, tree, offset,
5890 "event-type: ", BACnetEventType, 12);
5893 offset = fEnumeratedTagSplit (tvb, tree, offset,
5894 "polarity: ", BACnetPolarity, 2);
5897 offset = fEnumeratedTagSplit (tvb, tree, offset,
5898 "program-change: ", BACnetProgramRequest, 5);
5901 offset = fEnumeratedTagSplit (tvb, tree, offset,
5902 "program-state: ", BACnetProgramState, 5);
5905 offset = fEnumeratedTagSplit (tvb, tree, offset,
5906 "reason-for-halt: ", BACnetProgramError, 5);
5909 offset = fEnumeratedTagSplit (tvb, tree, offset,
5910 "reliability: ", BACnetReliability, 10);
5913 offset = fEnumeratedTagSplit (tvb, tree, offset,
5914 "state: ", BACnetEventState, 64);
5917 offset = fEnumeratedTagSplit (tvb, tree, offset,
5918 "system-status: ", BACnetDeviceStatus, 64);
5921 offset = fEnumeratedTagSplit (tvb, tree, offset,
5922 "units: ", BACnetEngineeringUnits, 2);
5925 offset = fUnsignedTag(tvb, tree, offset, "unsigned-value: ");
5928 offset = fEnumeratedTagSplit (tvb, tree, offset,
5929 "life-safety-mode: ", BACnetLifeSafetyMode, 64);
5932 offset = fEnumeratedTagSplit (tvb, tree, offset,
5933 "life-safety-state: ", BACnetLifeSafetyState, 64);
5943 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
5944 deviceIdentifier [0] BACnetObjectIdentifier,
5945 objectIdentifier [1] BACnetObjectIdentifier,
5946 propertyIdentifier [2] BACnetPropertyIdentifier,
5947 arrayIndex [3] Unsigned OPTIONAL,
5948 value [4] ABSTRACT-SYNTAX.&Type
5952 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5954 guint lastoffset = 0;
5955 guint8 tag_no, tag_info;
5958 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
5959 lastoffset = offset;
5960 /* check the tag. A closing tag means we are done */
5961 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5962 if (tag_is_closing(tag_info)) {
5966 case 0: /* deviceIdentifier */
5967 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5969 case 1: /* objectIdentifier */
5970 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5972 case 2: /* propertyIdentifier */
5973 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
5975 case 3: /* arrayIndex - OPTIONAL */
5976 offset = fUnsignedTag (tvb, tree, offset,
5980 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5981 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
5982 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5993 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
5994 objectIdentifier [0] BACnetObjectIdentifier,
5995 propertyIdentifier [1] BACnetPropertyIdentifier,
5996 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
5997 -- if omitted with an array then
5998 -- the entire array is referenced
5999 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
6003 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6005 guint lastoffset = 0;
6006 guint8 tag_no, tag_info;
6009 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
6010 lastoffset = offset;
6011 /* check the tag. A closing tag means we are done */
6012 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6013 if (tag_is_closing(tag_info)) {
6017 case 0: /* objectIdentifier */
6018 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6020 case 1: /* propertyIdentifier */
6021 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6023 case 2: /* arrayIndex - OPTIONAL */
6024 offset = fUnsignedTag (tvb, tree, offset,
6027 case 3: /* deviceIdentifier - OPTIONAL */
6028 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6038 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6040 guint lastoffset = offset;
6041 guint8 tag_no, tag_info;
6043 proto_tree *subtree = tree;
6046 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6047 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
6048 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
6049 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6050 /* Opening tag for parameter choice */
6051 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6054 case 0: /* change-of-bitstring */
6055 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6056 lastoffset = offset;
6057 switch (fTagNo(tvb, offset)) {
6059 offset = fBitStringTag (tvb, subtree, offset,
6060 "referenced-bitstring: ");
6063 offset = fBitStringTagVS (tvb, subtree, offset,
6064 "status-flags: ", BACnetStatusFlags);
6065 lastoffset = offset;
6072 case 1: /* change-of-state */
6073 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6074 lastoffset = offset;
6075 switch (fTagNo(tvb, offset)) {
6077 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6078 offset = fBACnetPropertyStates(tvb, subtree, offset);
6079 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6082 offset = fBitStringTagVS (tvb, subtree, offset,
6083 "status-flags: ", BACnetStatusFlags);
6084 lastoffset = offset;
6091 case 2: /* change-of-value */
6092 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6093 lastoffset = offset;
6094 switch (fTagNo(tvb, offset)) {
6096 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6097 switch (fTagNo(tvb, offset)) {
6099 offset = fBitStringTag (tvb, subtree, offset,
6103 offset = fRealTag (tvb, subtree, offset,
6109 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6112 offset = fBitStringTagVS (tvb, subtree, offset,
6113 "status-flags: ", BACnetStatusFlags);
6114 lastoffset = offset;
6121 case 3: /* command-failure */
6122 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6123 lastoffset = offset;
6124 switch (fTagNo(tvb, offset)) {
6125 case 0: /* "command-value: " */
6126 /* from BACnet Table 13-3,
6127 Standard Object Property Values Returned in Notifications */
6128 propertyIdentifier = 85; /* PRESENT_VALUE */
6129 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6130 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6131 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6134 offset = fBitStringTagVS (tvb, subtree, offset,
6135 "status-flags: ", BACnetStatusFlags);
6137 case 2: /* "feedback-value: " */
6138 propertyIdentifier = 40; /* FEEDBACK_VALUE */
6139 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6140 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6141 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6142 lastoffset = offset;
6149 case 4: /* floating-limit */
6150 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6151 lastoffset = offset;
6152 switch (fTagNo(tvb, offset)) {
6154 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
6157 offset = fBitStringTagVS (tvb, subtree, offset,
6158 "status-flags: ", BACnetStatusFlags);
6161 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
6164 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
6165 lastoffset = offset;
6172 case 5: /* out-of-range */
6173 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6174 lastoffset = offset;
6175 switch (fTagNo(tvb, offset)) {
6177 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
6180 offset = fBitStringTagVS (tvb, subtree, offset,
6181 "status-flags: ", BACnetStatusFlags);
6184 offset = fRealTag (tvb, subtree, offset, "deadband: ");
6187 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
6188 lastoffset = offset;
6196 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6197 lastoffset = offset;
6198 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
6201 case 7: /* buffer-ready */
6202 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6203 lastoffset = offset;
6204 switch (fTagNo(tvb, offset)) {
6206 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
6209 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
6212 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6213 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
6214 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6217 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6218 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
6219 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6220 lastoffset = offset;
6227 case 8: /* change-of-life-safety */
6228 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6229 lastoffset = offset;
6230 switch (fTagNo(tvb, offset)) {
6232 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6233 "new-state: ", BACnetLifeSafetyState, 256);
6236 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6237 "new-mode: ", BACnetLifeSafetyMode, 256);
6240 offset = fBitStringTagVS (tvb, subtree, offset,
6241 "status-flags: ", BACnetStatusFlags);
6244 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6245 "operation-expected: ", BACnetLifeSafetyOperation, 64);
6246 lastoffset = offset;
6253 case 9: /* extended */
6254 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
6255 lastoffset = offset;
6256 switch (fTagNo(tvb, offset)) {
6258 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6261 offset = fUnsignedTag (tvb, subtree, offset,
6262 "extended-event-type: ");
6264 case 2: /* parameters */
6265 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6266 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
6267 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
6268 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6269 lastoffset = offset;
6276 case 10: /* buffer ready */
6277 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
6278 lastoffset = offset;
6279 switch (fTagNo(tvb, offset)) {
6280 case 0: /* buffer-property */
6281 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6282 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
6283 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6286 offset = fUnsignedTag (tvb, subtree, offset,
6287 "previous-notification: ");
6290 offset = fUnsignedTag (tvb, subtree, offset,
6291 "current-notification: ");
6292 lastoffset = offset;
6299 case 11: /* unsigned range */
6300 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
6301 lastoffset = offset;
6302 switch (fTagNo(tvb, offset)) {
6304 offset = fUnsignedTag (tvb, subtree, offset,
6305 "exceeding-value: ");
6308 offset = fBitStringTagVS (tvb, subtree, offset,
6309 "status-flags: ", BACnetStatusFlags);
6312 offset = fUnsignedTag (tvb, subtree, offset,
6313 "exceeded-limit: ");
6314 lastoffset = offset;
6325 /* Closing tag for parameter choice */
6326 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6333 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset)
6335 guint lastoffset = 0;
6337 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6338 lastoffset = offset;
6339 switch (fTagNo(tvb, offset)) {
6340 case 0: /* change-of-bitstring */
6341 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6342 lastoffset = offset;
6343 switch (fTagNo(tvb, offset)) {
6345 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6348 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6350 case 2: /* SEQUENCE OF BIT STRING */
6351 offset = fBitStringTagVS (tvb, tree, offset,
6352 "bitstring value: ", BACnetEventTransitionBits);
6359 case 1: /* change-of-state */
6360 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6361 lastoffset = offset;
6362 switch (fTagNo(tvb, offset)) {
6364 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6366 case 1: /* SEQUENCE OF BACnetPropertyStates */
6367 offset = fEnumeratedTagSplit (tvb, tree, offset,
6368 "value: ", BACnetPropertyStates, 64);
6375 case 2: /* change-of-value */
6376 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6377 lastoffset = offset;
6378 switch (fTagNo(tvb, offset)) {
6380 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6382 case 1: /* don't loop it, it's a CHOICE */
6383 switch (fTagNo(tvb, offset)) {
6385 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6388 offset = fRealTag (tvb, tree, offset,
6389 "referenced Property Increment: ");
6399 case 3: /* command-failure */
6400 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6401 lastoffset = offset;
6402 switch (fTagNo(tvb, offset)) {
6404 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6407 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6413 case 4: /* floating-limit */
6414 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6415 lastoffset = offset;
6416 switch (fTagNo(tvb, offset)) {
6418 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6421 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6424 offset = fRealTag (tvb, tree, offset, "low diff limit: ");
6427 offset = fRealTag (tvb, tree, offset, "high diff limit: ");
6430 offset = fRealTag (tvb, tree, offset, "deadband: ");
6437 case 5: /* out-of-range */
6438 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6439 lastoffset = offset;
6440 switch (fTagNo(tvb, offset)) {
6442 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6445 offset = fRealTag (tvb, tree, offset, "low limit: ");
6448 offset = fRealTag (tvb, tree, offset, "high limit: ");
6451 offset = fRealTag (tvb, tree, offset, "deadband: ");
6459 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
6461 case 7: /* buffer-ready */
6462 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6463 lastoffset = offset;
6464 switch (fTagNo(tvb, offset)) {
6466 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
6469 offset = fUnsignedTag (tvb,tree,offset,
6470 "previous notification count: ");
6477 case 8: /* change-of-life-safety */
6478 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6479 lastoffset = offset;
6480 switch (fTagNo(tvb, offset)) {
6482 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6485 offset = fEnumeratedTagSplit (tvb, tree, offset,
6486 "life safety alarm value: ", BACnetLifeSafetyState, 256);
6489 offset = fEnumeratedTagSplit (tvb, tree, offset,
6490 "alarm value: ", BACnetLifeSafetyState, 256);
6493 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6509 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6511 guint lastoffset = 0;
6512 guint8 tag_no, tag_info;
6515 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6516 lastoffset = offset;
6517 switch (fTagNo(tvb, offset)) {
6518 case 0: /* timestamp */
6519 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6520 offset = fDate (tvb,tree,offset,"Date: ");
6521 offset = fTime (tvb,tree,offset,"Time: ");
6522 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6524 case 1: /* logDatum: don't loop, it's a CHOICE */
6525 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6526 switch (fTagNo(tvb, offset)) {
6527 case 0: /* logStatus */
6528 offset = fEnumeratedTag (tvb, tree, offset,
6529 "log status: ", BACnetLogStatus);
6532 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6535 offset = fRealTag (tvb, tree, offset, "real value: ");
6538 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
6541 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
6544 offset = fSignedTag (tvb, tree, offset, "signed value: ");
6547 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
6550 offset = fNullTag(tvb, tree, offset, "null value: ");
6553 offset = fError (tvb, pinfo, tree, offset);
6556 offset = fRealTag (tvb, tree, offset, "time change: ");
6558 case 10: /* any Value */
6559 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6560 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6561 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6566 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6569 offset = fEnumeratedTag (tvb, tree, offset,
6570 "Status Flags: ", BACnetStatusFlags);
6581 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6583 guint lastoffset = 0;
6584 guint8 tag_no, tag_info;
6587 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6588 lastoffset = offset;
6590 switch (fTagNo(tvb,offset)) {
6591 case 0: /* ProcessId */
6592 offset = fProcessId (tvb,tree,offset);
6594 case 1: /* initiating ObjectId */
6595 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6597 case 2: /* event ObjectId */
6598 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6600 case 3: /* time stamp */
6601 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6602 offset = fTimeStamp (tvb, tree, offset, NULL);
6603 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6605 case 4: /* notificationClass */
6606 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
6608 case 5: /* Priority */
6609 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
6611 case 6: /* EventType */
6612 offset = fEnumeratedTagSplit (tvb, tree, offset,
6613 "Event Type: ", BACnetEventType, 64);
6615 case 7: /* messageText */
6616 offset = fCharacterString (tvb, tree, offset, "message Text: ");
6618 case 8: /* NotifyType */
6619 offset = fEnumeratedTag (tvb, tree, offset,
6620 "Notify Type: ", BACnetNotifyType);
6622 case 9: /* ackRequired */
6623 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
6625 case 10: /* fromState */
6626 offset = fEnumeratedTagSplit (tvb, tree, offset,
6627 "from State: ", BACnetEventState, 64);
6629 case 11: /* toState */
6630 offset = fEnumeratedTagSplit (tvb, tree, offset,
6631 "to State: ", BACnetEventState, 64);
6633 case 12: /* NotificationParameters */
6634 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6635 offset = fNotificationParameters (tvb, pinfo, tree, offset);
6636 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6646 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6648 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
6652 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6654 guint lastoffset = 0;
6655 guint8 tag_no, tag_info;
6657 proto_tree *subtree = tree;
6660 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6661 lastoffset = offset;
6662 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6663 if (tag_is_closing(tag_info)) {
6664 offset += fTagHeaderTree (tvb, subtree, offset,
6665 &tag_no, &tag_info, &lvt);
6666 lastoffset = offset;
6672 case 0: /* ProcessId */
6673 offset = fProcessId (tvb,tree,offset);
6675 case 1: /* initiating DeviceId */
6676 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6678 case 2: /* monitored ObjectId */
6679 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6681 case 3: /* time remaining */
6682 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
6684 case 4: /* List of Values */
6685 if (tag_is_opening(tag_info)) {
6686 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
6687 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6688 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6689 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
6702 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6704 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
6708 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6710 guint lastoffset = 0;
6711 guint8 tag_no = 0, tag_info = 0;
6714 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6715 lastoffset = offset;
6716 switch (fTagNo(tvb, offset)) {
6717 case 0: /* acknowledgingProcessId */
6718 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
6720 case 1: /* eventObjectId */
6721 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6723 case 2: /* eventStateAcknowledged */
6724 offset = fEnumeratedTagSplit (tvb, tree, offset,
6725 "event State Acknowledged: ", BACnetEventState, 64);
6727 case 3: /* timeStamp */
6728 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6729 offset = fTimeStamp(tvb, tree, offset, NULL);
6730 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6732 case 4: /* acknowledgementSource */
6733 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
6735 case 5: /* timeOfAcknowledgement */
6736 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6737 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
6738 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6748 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6750 guint lastoffset = 0;
6752 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6753 lastoffset = offset;
6754 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
6755 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
6756 "alarm State: ", BACnetEventState, 64);
6757 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
6758 "acknowledged Transitions: ", BACnetEventTransitionBits);
6764 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6766 guint lastoffset = 0;
6767 guint8 tag_no, tag_info;
6770 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6771 lastoffset = offset;
6772 switch (fTagNo(tvb, offset)) {
6773 case 0: /* acknowledgmentFilter */
6774 offset = fEnumeratedTag (tvb, tree, offset,
6775 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
6777 case 1: /* eventObjectId - OPTIONAL */
6778 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6779 offset = fRecipientProcess (tvb, pinfo, tree, offset);
6780 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6782 case 2: /* eventStateFilter */
6783 offset = fEnumeratedTag (tvb, tree, offset,
6784 "event State Filter: ", BACnetEventStateFilter);
6786 case 3: /* eventTypeFilter - OPTIONAL */
6787 offset = fEnumeratedTag (tvb, tree, offset,
6788 "event Type Filter: ", BACnetEventType);
6790 case 4: /* priorityFilter */
6791 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6792 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
6793 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
6794 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6796 case 5: /* notificationClassFilter - OPTIONAL */
6797 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
6807 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6809 guint lastoffset = 0;
6811 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6812 lastoffset = offset;
6813 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
6814 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
6815 "event Type: ", BACnetEventType, 64);
6816 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
6817 "event State: ", BACnetEventState);
6818 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
6819 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
6826 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6828 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6829 if (fTagNo(tvb, offset) == 0) {
6830 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6837 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6839 guint lastoffset = 0;
6840 guint8 tag_no, tag_info;
6842 proto_tree* subtree = tree;
6845 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6846 lastoffset = offset;
6847 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6848 /* we are finished here if we spot a closing tag */
6849 if (tag_is_closing(tag_info)) {
6853 case 0: /* ObjectId */
6854 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6856 case 1: /* eventState */
6857 offset = fEnumeratedTag (tvb, tree, offset,
6858 "event State: ", BACnetEventState);
6860 case 2: /* acknowledgedTransitions */
6861 offset = fBitStringTagVS (tvb, tree, offset,
6862 "acknowledged Transitions: ", BACnetEventTransitionBits);
6864 case 3: /* eventTimeStamps */
6865 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
6867 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6869 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6870 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
6871 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
6872 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
6873 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6875 case 4: /* notifyType */
6876 offset = fEnumeratedTag (tvb, tree, offset,
6877 "Notify Type: ", BACnetNotifyType);
6879 case 5: /* eventEnable */
6880 offset = fBitStringTagVS (tvb, tree, offset,
6881 "event Enable: ", BACnetEventTransitionBits);
6883 case 6: /* eventPriorities */
6884 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
6886 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6888 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6889 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
6890 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
6891 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
6892 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6902 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6904 guint lastoffset = 0;
6905 guint8 tag_no, tag_info;
6908 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
6909 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6910 lastoffset = offset;
6911 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6912 /* we are finished here if we spot a closing tag */
6913 if (tag_is_closing(tag_info)) {
6916 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
6922 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6924 guint lastoffset = 0;
6925 guint8 tag_no, tag_info;
6928 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6929 lastoffset = offset;
6930 switch (fTagNo(tvb, offset)) {
6931 case 0: /* listOfEventSummaries */
6932 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6933 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
6934 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6936 case 1: /* moreEvents */
6937 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
6947 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6949 guint lastoffset = 0;
6950 guint8 tag_no, tag_info;
6952 proto_tree *subtree = tree;
6955 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
6957 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6958 lastoffset = offset;
6959 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6960 if (tag_is_closing(tag_info)) {
6961 offset += fTagHeaderTree (tvb, subtree, offset,
6962 &tag_no, &tag_info, &lvt);
6968 case 0: /* ObjectId */
6969 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
6971 case 3: /* listOfElements */
6972 if (tag_is_opening(tag_info)) {
6973 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
6974 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6975 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6976 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6989 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6991 return fObjectIdentifier (tvb, pinfo, tree, offset);
6995 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
6997 guint lastoffset = 0;
6999 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7000 lastoffset = offset;
7002 switch (fTagNo(tvb, offset)) {
7003 case 0: /* timeDuration */
7004 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
7006 case 1: /* enable-disable */
7007 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
7008 BACnetEnableDisable);
7010 case 2: /* password - OPTIONAL */
7011 offset = fCharacterString (tvb, tree, offset, "Password: ");
7021 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7023 guint lastoffset = 0;
7025 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7026 lastoffset = offset;
7028 switch (fTagNo(tvb, offset)) {
7029 case 0: /* reinitializedStateOfDevice */
7030 offset = fEnumeratedTag (tvb, tree, offset,
7031 "reinitialized State Of Device: ",
7032 BACnetReinitializedStateOfDevice);
7034 case 1: /* password - OPTIONAL */
7035 offset = fCharacterString (tvb, tree, offset, "Password: ");
7045 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7047 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7048 "vtClass: ", BACnetVTClass);
7049 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
7053 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7055 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7059 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7061 guint lastoffset = 0;
7063 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7064 lastoffset = offset;
7065 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7071 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7073 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
7074 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
7075 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
7079 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
7081 guint lastoffset = 0;
7083 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7084 lastoffset = offset;
7086 switch (fTagNo(tvb,offset)) {
7087 case 0: /* BOOLEAN */
7088 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
7090 case 1: /* Unsigned OPTIONAL */
7091 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
7101 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
7103 guint lastoffset = 0;
7105 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7106 lastoffset = offset;
7108 switch (fTagNo(tvb,offset)) {
7109 case 0: /* Unsigned32 */
7110 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
7112 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
7113 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
7115 case 2: /* Chararacter String OPTIONAL */
7116 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
7118 case 3: /* Chararacter String OPTIONAL */
7119 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
7121 case 4: /* Boolean OPTIONAL */
7122 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
7132 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7134 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
7138 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7140 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
7141 offset = fAddress (tvb, tree, offset);
7142 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
7143 return fAddress (tvb, tree, offset);
7147 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7149 /* Same as AddListElement request after service choice */
7150 return fAddListElementRequest(tvb, pinfo, tree, offset);
7154 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7156 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
7160 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7162 guint lastoffset = 0;
7163 guint8 tag_no, tag_info;
7165 proto_tree *subtree = tree;
7167 /* set the optional global properties to indicate not-used */
7168 propertyArrayIndex = -1;
7169 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7170 lastoffset = offset;
7171 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7172 if (tag_is_closing(tag_info)) {
7173 offset += fTagHeaderTree (tvb, tree, offset,
7174 &tag_no, &tag_info, &lvt);
7179 case 0: /* objectIdentifier */
7180 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7182 case 1: /* propertyIdentifier */
7183 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7185 case 2: /* propertyArrayIndex */
7186 offset = fPropertyArrayIndex (tvb, subtree, offset);
7188 case 3: /* propertyValue */
7189 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7199 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7201 guint lastoffset = 0;
7202 guint8 tag_no, tag_info;
7204 proto_tree *subtree = tree;
7206 /* set the optional global properties to indicate not-used */
7207 propertyArrayIndex = -1;
7208 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7209 lastoffset = offset;
7210 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7211 if (tag_is_closing(tag_info)) {
7212 offset += fTagHeaderTree (tvb, subtree, offset,
7213 &tag_no, &tag_info, &lvt);
7219 case 0: /* objectIdentifier */
7220 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7222 case 1: /* propertyIdentifier */
7223 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7225 case 2: /* propertyArrayIndex */
7226 offset = fPropertyArrayIndex (tvb, subtree, offset);
7228 case 3: /* propertyValue */
7229 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7231 case 4: /* Priority (only used for write) */
7232 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7242 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7244 guint lastoffset = 0;
7245 guint8 tag_no, tag_info;
7248 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7249 lastoffset = offset;
7250 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7251 if (tag_is_closing(tag_info)) {
7252 offset += fTagHeaderTree (tvb, subtree, offset,
7253 &tag_no, &tag_info, &lvt);
7258 case 0: /* objectIdentifier */
7259 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7261 case 1: /* listOfPropertyValues */
7262 if (tag_is_opening(tag_info)) {
7263 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7264 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7277 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7279 if (offset >= tvb_reported_length(tvb))
7282 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7283 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
7287 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
7289 guint lastoffset = 0;
7290 guint8 tag_no, tag_info;
7293 /* set the optional global properties to indicate not-used */
7294 propertyArrayIndex = -1;
7295 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7296 lastoffset = offset;
7297 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7298 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
7300 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
7303 switch (tag_no-tagoffset) {
7304 case 0: /* PropertyIdentifier */
7305 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7307 case 1: /* propertyArrayIndex */
7308 offset = fPropertyArrayIndex (tvb, tree, offset);
7309 if (list != 0) break; /* Continue decoding if this may be a list */
7311 lastoffset = offset; /* Set loop end condition */
7319 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
7321 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7322 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
7326 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7328 guint lastoffset = 0;
7330 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7331 lastoffset = offset;
7333 switch (fTagNo(tvb,offset)) {
7334 case 0: /* ObjectIdentifier */
7335 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7337 case 1: /* PropertyIdentifier and propertyArrayIndex */
7338 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
7339 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7341 lastoffset = offset; /* Set loop end condition */
7350 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
7352 guint lastoffset = 0;
7353 guint8 tag_no, tag_info;
7355 proto_tree* subtree = tree;
7358 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7359 lastoffset = offset;
7360 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7361 if (tag_is_closing(tag_info)) {
7362 offset += fTagHeaderTree (tvb, subtree, offset,
7363 &tag_no, &tag_info, &lvt);
7367 case 0: /* ObjectIdentifier */
7368 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7370 case 1: /* PropertyIdentifier */
7371 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7373 case 2: /* propertyArrayIndex */
7374 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
7377 offset = fPropertyValue (tvb, subtree, offset, tag_info);
7379 case 4: /* Priority */
7380 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7391 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7393 char i = 1, ar[256];
7394 guint lastoffset = 0;
7396 if (propertyArrayIndex > 0) {
7397 /* BACnetARRAY index 0 refers to the length
7398 of the array, not the elements of the array.
7399 BACnetARRAY index -1 is our internal flag that
7400 the optional index was not used.
7401 BACnetARRAY refers to this as all elements of the array.
7402 If the optional index is specified for a BACnetARRAY,
7403 then that specific array element is referenced. */
7404 i = propertyArrayIndex;
7406 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
7407 /* exit loop if nothing happens inside */
7408 lastoffset = offset;
7409 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
7410 val_to_split_str(87 , 512,
7411 BACnetPropertyIdentifier,
7412 ASHRAE_Reserved_Fmt,
7413 Vendor_Proprietary_Fmt),
7415 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
7416 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
7417 /* there are only 16 priority array elements */
7427 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7429 guint lastoffset = 0;
7431 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7432 lastoffset = offset;
7434 switch (fTagNo(tvb,offset)) {
7435 case 0: /* deviceIdentifier - OPTIONAL */
7436 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7438 case 1: /* ObjectIdentifier */
7439 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7449 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7451 guint8 tag_no, tag_info;
7453 guint lastoffset = 0;
7455 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7456 lastoffset = offset;
7457 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7458 if (tag_is_closing(tag_info)) {
7463 case 0: /* calendaryEntry */
7464 if (tag_is_opening(tag_info))
7466 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7467 offset = fCalendaryEntry (tvb, subtree, offset);
7468 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7471 case 1: /* calendarReference */
7472 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7474 case 2: /* list of BACnetTimeValue */
7475 if (tag_is_opening(tag_info)) {
7476 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7477 offset = fTimeValue (tvb, pinfo, subtree, offset);
7478 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7483 case 3: /* eventPriority */
7484 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
7494 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7496 guint lastoffset = 0;
7497 guint8 tag_no, tag_info;
7500 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7501 lastoffset = offset;
7502 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7503 if (tag_is_closing(tag_info)) { /* stop when we hit outer closing tag */
7507 switch (fTagNo(tvb,offset)) {
7508 case 0: /* propertyIdentifier */
7509 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7511 case 1: /* propertyArrayIndex */
7512 offset = fPropertyArrayIndex (tvb, tree, offset);
7514 case 2: /* relationSpecifier */
7515 offset = fEnumeratedTag (tvb, tree, offset,
7516 "relation Specifier: ", BACnetRelationSpecifier);
7518 case 3: /* comparisonValue */
7519 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7520 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7521 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7531 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7533 guint lastoffset = 0;
7534 guint8 tag_no, tag_info;
7537 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7538 lastoffset = offset;
7539 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7540 if (tag_is_closing(tag_info)) { /* stop when we hit outer closing tag */
7545 case 0: /* selectionLogic */
7546 offset = fEnumeratedTag (tvb, subtree, offset,
7547 "selection Logic: ", BACnetSelectionLogic);
7549 case 1: /* listOfSelectionCriteria */
7550 if (tag_is_opening(tag_info)) {
7551 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7552 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
7553 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7567 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
7569 guint lastoffset = 0;
7570 guint8 tag_no, tag_info;
7573 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7574 lastoffset = offset;
7575 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7577 if (tag_is_opening(tag_info) && tag_no < 2) {
7578 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7580 case 0: /* objectSelectionCriteria */
7581 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
7583 case 1: /* listOfPropertyReferences */
7584 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
7589 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7596 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7598 guint lastoffset = 0;
7599 guint8 tag_no, tag_info;
7602 proto_tree *subtree = tree;
7604 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7605 lastoffset = offset;
7606 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7608 case 0: /* objectIdentifier */
7609 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7611 case 1: /* listOfPropertyReferences */
7612 if (tag_is_opening(tag_info)) {
7613 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
7614 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7615 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7616 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
7617 } else if (tag_is_closing(tag_info)) {
7618 offset += fTagHeaderTree (tvb, subtree, offset,
7619 &tag_no, &tag_info, &lvt);
7622 /* error condition: let caller handle */
7634 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7636 guint lastoffset = 0;
7640 proto_tree *subtree = tree;
7643 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7644 lastoffset = offset;
7645 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7646 if (tag_is_closing(tag_info)) {
7647 offset += fTagHeaderTree (tvb, subtree, offset,
7648 &tag_no, &tag_info, &lvt);
7649 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
7654 case 0: /* objectSpecifier */
7655 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7657 case 1: /* list of Results */
7658 if (tag_is_opening(tag_info)) {
7659 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
7660 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7661 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7666 case 2: /* propertyIdentifier */
7667 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
7669 case 5: /* propertyAccessError */
7670 if (tag_is_opening(tag_info)) {
7671 tt = proto_tree_add_text(tree, tvb, offset, 1, "propertyAccessError");
7672 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7673 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7674 /* Error Code follows */
7675 offset = fError(tvb, pinfo, subtree, offset);
7689 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7691 /* listOfReadAccessResults */
7692 return fReadAccessResult (tvb, pinfo, tree, offset);
7697 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7699 guint lastoffset = 0;
7700 guint8 tag_no, tag_info;
7703 while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset > lastoffset)) { /* exit loop if nothing happens inside */
7704 lastoffset = offset;
7705 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7709 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7711 case 0: /* objectSpecifier */
7712 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
7713 case 0: /* objectType */
7714 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
7716 case 1: /* objectIdentifier */
7717 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7723 case 1: /* propertyValue */
7724 if (tag_is_opening(tag_info)) {
7725 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7733 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7740 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7742 return fObjectIdentifier (tvb, pinfo, tree, offset);
7746 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7748 guint8 tag_no, tag_info;
7750 proto_tree *subtree = tree;
7753 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
7755 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7756 /* optional range choice */
7757 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7758 if (tag_is_opening(tag_info)) {
7759 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
7760 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7761 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7763 case 3: /* range byPosition */
7764 case 6: /* range bySequenceNumber, 2004 spec */
7765 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
7766 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
7768 case 4: /* range byTime - deprecated in 2004 */
7769 case 7: /* 2004 spec */
7770 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
7771 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
7773 case 5: /* range timeRange - deprecated in 2004 */
7774 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
7775 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
7780 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7787 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7789 guint8 tag_no, tag_info;
7791 proto_tree *subtree = tree;
7794 /* set the optional global properties to indicate not-used */
7795 propertyArrayIndex = -1;
7796 /* objectIdentifier, propertyIdentifier, and
7797 OPTIONAL propertyArrayIndex */
7798 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
7799 /* resultFlags => BACnetResultFlags ::= BIT STRING */
7800 offset = fBitStringTagVS (tvb, tree, offset,
7804 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
7806 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7807 if (tag_is_opening(tag_info)) {
7808 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7809 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
7810 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7811 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7812 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7813 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7815 /* firstSequenceNumber - OPTIONAL */
7816 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7817 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
7823 static guint fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7825 guint lastoffset = 0;
7827 guint8 tag_no, tag_info;
7829 proto_tree* subtree = NULL;
7831 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7833 if (tag_is_opening(tag_info))
7835 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
7836 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7837 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7838 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
7839 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
7843 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset))
7844 { /* exit loop if nothing happens inside */
7845 lastoffset = offset;
7846 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
7850 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0)
7852 /* More Flag is not set, so we can look for closing tag in this segment */
7853 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7854 if (tag_is_closing(tag_info)) {
7855 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7863 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7865 guint8 tag_no, tag_info;
7867 proto_tree *subtree = tree;
7870 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7872 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7874 if (tag_is_opening(tag_info))
7876 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
7877 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7878 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7879 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
7880 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
7881 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7887 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7890 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
7891 offset = fAccessMethod(tvb, pinfo, tree, offset);
7897 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
7899 guint tag_no = fTagNo(tvb, offset);
7900 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
7904 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7906 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
7907 offset = fAccessMethod(tvb,pinfo, tree, offset);
7913 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7915 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7916 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
7920 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7922 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7923 return fReadAccessResult (tvb,pinfo,tree,offset);
7927 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
7929 if (tvb_reported_length_remaining(tvb,offset) <= 0)
7932 switch (service_choice) {
7933 case 0: /* acknowledgeAlarm */
7934 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
7936 case 1: /* confirmedCOVNotification */
7937 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
7939 case 2: /* confirmedEventNotification */
7940 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
7942 case 3: /* confirmedGetAlarmSummary conveys no parameters */
7944 case 4: /* getEnrollmentSummaryRequest */
7945 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
7947 case 5: /* subscribeCOVRequest */
7948 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
7950 case 6: /* atomicReadFile-Request */
7951 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
7953 case 7: /* atomicWriteFile-Request */
7954 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
7956 case 8: /* AddListElement-Request */
7957 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
7959 case 9: /* removeListElement-Request */
7960 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
7962 case 10: /* createObjectRequest */
7963 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
7965 case 11: /* deleteObject */
7966 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
7969 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
7972 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
7975 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
7978 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
7981 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
7984 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
7987 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7990 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
7993 offset = fReinitializeDeviceRequest(tvb, tree, offset);
7996 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
7999 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8002 offset = fVtDataRequest (tvb, pinfo, tree, offset);
8005 offset = fAuthenticateRequest (tvb, tree, offset);
8008 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
8011 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
8014 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
8017 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
8020 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
8029 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8031 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8034 switch (service_choice) {
8035 case 3: /* confirmedEventNotificationAck */
8036 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
8038 case 4: /* getEnrollmentSummaryAck */
8039 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
8041 case 6: /* atomicReadFile */
8042 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
8044 case 7: /* atomicReadFileAck */
8045 offset = fAtomicWriteFileAck (tvb, tree, offset);
8047 case 10: /* createObject */
8048 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
8051 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
8054 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
8057 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
8060 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
8063 offset = fVtOpenAck (tvb, pinfo, tree, offset);
8066 offset = fVtDataAck (tvb, tree, offset);
8069 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
8072 offset = fReadRangeAck (tvb, pinfo, tree, offset);
8075 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
8084 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8086 /* BACnetObjectIdentifier */
8087 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
8089 /* MaxAPDULengthAccepted */
8090 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
8092 /* segmentationSupported */
8093 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8094 "Segmentation Supported: ", BACnetSegmentation);
8097 return fVendorIdentifier (tvb, pinfo, tree, offset);
8101 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8103 /* BACnetDeviceIdentifier */
8104 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
8106 /* BACnetObjectIdentifier */
8107 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8110 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
8115 fWhoIsRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
8117 guint lastoffset = 0;
8119 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8120 lastoffset = offset;
8121 switch (fTagNo(tvb, offset)) {
8122 case 0: /* DeviceInstanceRangeLowLimit Optional */
8123 offset = fUnsignedTag (tvb, tree, offset, "Device Instance Range Low Limit: ");
8125 case 1: /* DeviceInstanceRangeHighLimit Optional but required if DeviceInstanceRangeLowLimit is there */
8126 offset = fUnsignedTag (tvb, tree, offset, "Device Instance Range High Limit: ");
8136 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8138 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8141 switch (service_choice) {
8142 case 0: /* I-Am-Request */
8143 offset = fIAmRequest (tvb, pinfo, tree, offset);
8145 case 1: /* i-Have Request */
8146 offset = fIHaveRequest (tvb, pinfo, tree, offset);
8148 case 2: /* unconfirmedCOVNotification */
8149 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8151 case 3: /* unconfirmedEventNotification */
8152 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8154 case 4: /* unconfirmedPrivateTransfer */
8155 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8157 case 5: /* unconfirmedTextMessage */
8158 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8160 case 6: /* timeSynchronization */
8161 offset = fTimeSynchronizationRequest (tvb, tree, offset);
8163 case 7: /* who-Has */
8164 offset = fWhoHas (tvb, pinfo, tree, offset);
8166 case 8: /* who-Is */
8167 offset = fWhoIsRequest (tvb, tree, offset);
8169 case 9: /* utcTimeSynchronization */
8170 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
8179 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
8180 gint *svc, proto_item **tt)
8183 proto_tree *bacapp_tree_control;
8184 gint tmp, bacapp_type;
8188 tmp = (gint) tvb_get_guint8(tvb, offset);
8189 bacapp_type = (tmp >> 4) & 0x0f;
8190 bacapp_flags = tmp & 0x0f;
8195 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
8196 if (bacapp_flags & 0x08)
8197 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
8199 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8200 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, TRUE);
8201 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
8203 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, TRUE);
8204 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, TRUE);
8205 if (ack == 0) /* The following are for ConfirmedRequest, not Complex ack */
8207 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, TRUE);
8208 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
8210 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
8214 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
8215 if (bacapp_flags & 0x08) {
8216 bacapp_seq = tvb_get_guint8(tvb, offset);
8217 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
8219 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
8222 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8228 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8229 { /* BACnet-Confirmed-Request */
8230 /* ASHRAE 135-2001 20.1.2 */
8234 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
8235 if (bacapp_seq > 0) /* Can't handle continuation segments, so just treat as data */
8237 proto_tree_add_text(bacapp_tree, tvb, offset, 0, "(continuation)");
8242 /* Service Request follows... Variable Encoding 20.2ff */
8243 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
8248 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8249 { /* BACnet-Unconfirmed-Request-PDU */
8250 /* ASHRAE 135-2001 20.1.3 */
8254 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8256 tmp = tvb_get_guint8(tvb, offset);
8257 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
8259 /* Service Request follows... Variable Encoding 20.2ff */
8260 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
8264 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8265 { /* BACnet-Simple-Ack-PDU */
8266 /* ASHRAE 135-2001 20.1.4 */
8270 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8272 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8274 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8281 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8282 { /* BACnet-Complex-Ack-PDU */
8283 /* ASHRAE 135-2001 20.1.5 */
8287 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
8289 if (bacapp_seq > 0) /* Can't handle continuation segments, so just treat as data */
8291 proto_tree_add_text(bacapp_tree, tvb, offset, 0, "(continuation)");
8296 /* Service ACK follows... */
8297 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
8303 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8304 { /* BACnet-SegmentAck-PDU */
8305 /* ASHRAE 135-2001 20.1.6 */
8308 proto_tree *bacapp_tree_control;
8310 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8311 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8313 proto_tree_add_item(bacapp_tree, hf_bacapp_NAK, tvb, offset, 1, TRUE);
8314 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8315 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8317 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
8319 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
8324 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8326 guint8 tag_info = 0;
8327 guint8 parsed_tag = 0;
8329 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8330 offset = fError(tvb, pinfo, tree, offset);
8331 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8335 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8337 guint lastoffset = 0;
8338 guint8 tag_no = 0, tag_info = 0;
8340 proto_tree *subtree = tree;
8343 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
8344 /* exit loop if nothing happens inside */
8345 lastoffset = offset;
8346 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8348 case 0: /* errorType */
8349 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
8351 case 1: /* vendorID */
8352 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
8354 case 2: /* serviceNumber */
8355 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
8357 case 3: /* errorParameters */
8358 if (tag_is_opening(tag_info)) {
8359 tt = proto_tree_add_text(subtree, tvb, offset, 1,
8360 "error Parameters");
8361 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8362 propertyIdentifier = -1;
8363 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8364 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8365 } else if (tag_is_closing(tag_info)) {
8366 offset += fTagHeaderTree (tvb, subtree, offset,
8367 &tag_no, &tag_info, &lvt);
8370 /* error condition: let caller handle */
8382 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8384 guint lastoffset = 0;
8386 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8387 lastoffset = offset;
8388 switch (fTagNo(tvb, offset)) {
8389 case 0: /* errorType */
8390 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8392 case 1: /* firstFailedElementNumber */
8393 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
8403 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8405 /* Identical to CreateObjectError */
8406 return fCreateObjectError(tvb, pinfo, tree, offset);
8410 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8412 guint8 tag_no = 0, tag_info = 0;
8415 if (fTagNo(tvb, offset) == 0)
8418 offset = fContextTaggedError(tvb, pinfo, tree,offset);
8419 if (fTagNo(tvb, offset) == 1)
8421 /* listOfVTSessionIdentifiers [OPTIONAL] */
8422 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8423 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8424 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8427 /* should report bad packet if initial tag wasn't 0 */
8432 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8434 guint lastoffset = 0;
8435 guint8 tag_no = 0, tag_info = 0;
8438 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8439 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8440 lastoffset = offset;
8441 switch (fTagNo(tvb, offset)) {
8442 case 0: /* errorType */
8443 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8445 case 1: /* firstFailedWriteAttempt */
8446 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8447 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8448 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8458 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8460 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8461 "error Class: ", BACnetErrorClass, 64);
8462 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8463 "error Code: ", BACnetErrorCode, 256);
8467 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
8470 case 8: /* no break here !!!! */
8472 offset = fChangeListError (tvb, pinfo, tree, offset);
8475 offset = fCreateObjectError (tvb, pinfo, tree, offset);
8478 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
8481 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
8484 offset = fVTCloseError (tvb, pinfo, tree, offset);
8487 return fError (tvb, pinfo, tree, offset);
8493 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8494 { /* BACnet-Error-PDU */
8495 /* ASHRAE 135-2001 20.1.7 */
8497 proto_item *tc, *tt;
8498 proto_tree *bacapp_tree_control;
8501 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8502 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8504 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8506 tmp = tvb_get_guint8(tvb, offset);
8507 tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8509 /* Error Handling follows... */
8510 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
8514 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8515 { /* BACnet-Reject-PDU */
8516 /* ASHRAE 135-2001 20.1.8 */
8519 proto_tree *bacapp_tree_control;
8521 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8522 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8524 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8526 proto_tree_add_item(bacapp_tree, hf_BACnetRejectReason, tvb,
8532 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8533 { /* BACnet-Abort-PDU */
8534 /* ASHRAE 135-2001 20.1.9 */
8537 proto_tree *bacapp_tree_control;
8539 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8540 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8542 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8543 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8545 proto_tree_add_item(bacapp_tree, hf_BACnetAbortReason, tvb,
8551 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8553 guint8 flag, bacapp_type;
8556 flag = (gint) tvb_get_guint8(tvb, 0);
8557 bacapp_type = (flag >> 4) & 0x0f;
8559 if (tvb == NULL || tree == NULL) {
8563 /* ASHRAE 135-2001 20.1.1 */
8564 switch (bacapp_type) {
8565 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
8566 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
8568 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
8569 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
8571 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
8572 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
8574 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
8575 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
8577 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
8578 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
8580 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
8581 offset = fErrorPDU(tvb, pinfo, tree, offset);
8583 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
8584 offset = fRejectPDU(tvb, pinfo, tree, offset);
8586 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
8587 offset = fAbortPDU(tvb, pinfo, tree, offset);
8594 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8596 guint8 flag, bacapp_type;
8597 guint save_fragmented = FALSE, data_offset = 0, bacapp_apdu_size = fGetMaxAPDUSize(0), fragment = FALSE;
8598 tvbuff_t* new_tvb = NULL;
8600 gint8 bacapp_seqno = -1;
8601 guint8 bacapp_service, bacapp_reason, bacapp_prop_win_size;
8602 guint8 bacapp_invoke_id = 0;
8604 proto_tree *bacapp_tree = NULL;
8606 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
8607 col_clear (pinfo->cinfo, COL_INFO);
8609 flag = tvb_get_guint8(tvb, 0);
8610 bacapp_type = (flag >> 4) & 0x0f;
8612 /* show some descriptive text in the INFO column */
8613 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
8614 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
8616 switch (bacapp_type)
8618 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
8619 /* segmented messages have 2 additional bytes */
8620 if (flag & BACAPP_SEGMENTED_REQUEST)
8623 bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); /* has 16 values, reserved are 50 Bytes */
8624 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
8625 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
8626 bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4);
8627 bacapp_service = tvb_get_guint8(tvb, offset + 5);
8632 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
8633 bacapp_service = tvb_get_guint8(tvb, offset + 3);
8635 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
8636 val_to_str(bacapp_service,
8637 BACnetConfirmedServiceChoice,
8638 bacapp_unknown_service_str),bacapp_invoke_id);
8640 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
8641 bacapp_service = tvb_get_guint8(tvb, offset + 1);
8642 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
8643 val_to_str(bacapp_service,
8644 BACnetUnconfirmedServiceChoice,
8645 bacapp_unknown_service_str));
8647 case BACAPP_TYPE_SIMPLE_ACK:
8648 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8649 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8650 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8651 val_to_str(bacapp_service,
8652 BACnetConfirmedServiceChoice,
8653 bacapp_unknown_service_str), bacapp_invoke_id);
8655 case BACAPP_TYPE_COMPLEX_ACK:
8656 /* segmented messages have 2 additional bytes */
8657 if (flag & BACAPP_SEGMENTED_REQUEST)
8660 bacapp_apdu_size = fGetMaxAPDUSize(0); /* has minimum of 50 Bytes */
8661 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8662 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
8663 bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3);
8664 bacapp_service = tvb_get_guint8(tvb, offset + 4);
8669 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8670 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8672 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8673 val_to_str(bacapp_service,
8674 BACnetConfirmedServiceChoice,
8675 bacapp_unknown_service_str), bacapp_invoke_id);
8677 case BACAPP_TYPE_SEGMENT_ACK:
8678 /* nothing more to add */
8680 case BACAPP_TYPE_ERROR:
8681 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8682 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8683 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8684 val_to_str(bacapp_service,
8685 BACnetConfirmedServiceChoice,
8686 bacapp_unknown_service_str), bacapp_invoke_id);
8688 case BACAPP_TYPE_REJECT:
8689 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8690 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
8691 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8692 val_to_split_str(bacapp_reason,
8695 ASHRAE_Reserved_Fmt,
8696 Vendor_Proprietary_Fmt), bacapp_invoke_id);
8698 case BACAPP_TYPE_ABORT:
8699 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8700 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
8701 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8702 val_to_split_str(bacapp_reason,
8705 ASHRAE_Reserved_Fmt,
8706 Vendor_Proprietary_Fmt), bacapp_invoke_id);
8710 /* nothing more to add */
8714 save_fragmented = pinfo->fragmented;
8718 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, FALSE);
8719 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
8722 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
8725 if (fragment) { /* fragmented */
8726 fragment_data *frag_msg = NULL;
8727 guint real_size = 0;
8729 pinfo->fragmented = TRUE;
8730 frag_msg = fragment_add_seq_check(tvb, bacapp_seqno == 0 ? 0 : data_offset, pinfo,
8731 bacapp_invoke_id, /* ID for fragments belonging together */
8732 msg_fragment_table, /* list of message fragments */
8733 msg_reassembled_table, /* list of reassembled messages */
8734 bacapp_seqno, /* fragment sequence number */
8735 tvb_reported_length_remaining(tvb, bacapp_seqno == 0 ? 0 : data_offset), /* fragment length - to the end */
8736 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
8737 new_tvb = process_reassembled_data(tvb, bacapp_seqno == 0 ? 0 : data_offset, pinfo,
8738 "Reassembled BACapp", frag_msg, &msg_frag_items,
8741 if (frag_msg) { /* Reassembled */
8742 col_append_str(pinfo->cinfo, COL_INFO,
8743 " (Message Reassembled)");
8744 } else { /* Not last packet of reassembled Short Message */
8745 col_append_fstr(pinfo->cinfo, COL_INFO,
8746 " (Message fragment %u)", bacapp_seqno);
8748 if (new_tvb) { /* take it all */
8749 real_size = tvb_reported_length_remaining(new_tvb, 0);
8750 if (real_size > bacapp_apdu_size) { /* enter this, if we really have more than one chunk */
8751 offset = do_the_dissection(new_tvb,pinfo,bacapp_tree);
8756 /* next_tvb = tvb_new_subset(tvb,offset,-1,tvb_reported_length_remaining(tvb,offset));
8757 call_dissector(data_handle,next_tvb, pinfo, tree); */
8759 pinfo->fragmented = save_fragmented;
8764 bacapp_init_routine(void)
8766 fragment_table_init(&msg_fragment_table);
8767 reassembled_table_init(&msg_reassembled_table);
8771 proto_register_bacapp(void)
8773 static hf_register_info hf[] = {
8775 { "APDU Type", "bacapp.type",
8776 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
8778 { &hf_bacapp_pduflags,
8779 { "PDU Flags", "bacapp.pduflags",
8780 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
8783 { "Segmented Request", "bacapp.segmented_request",
8784 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
8787 { "More Segments", "bacapp.more_segments",
8788 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
8791 { "SA", "bacapp.SA",
8792 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
8794 { &hf_bacapp_max_adpu_size,
8795 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
8796 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
8798 { &hf_bacapp_response_segments,
8799 { "Max Response Segments accepted", "bacapp.response_segments",
8800 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
8802 { &hf_bacapp_objectType,
8803 { "Object Type", "bacapp.objectType",
8804 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
8806 { &hf_bacapp_instanceNumber,
8807 { "Instance Number", "bacapp.instance_number",
8808 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
8810 { &hf_BACnetPropertyIdentifier,
8811 { "Property Identifier", "bacapp.property_identifier",
8812 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
8814 { &hf_BACnetVendorIdentifier,
8815 { "Vendor Identifier", "bacapp.vendor_identifier",
8816 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
8818 { &hf_BACnetRestartReason,
8819 { "Restart Reason", "bacapp.restart_reason",
8820 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
8822 { &hf_bacapp_invoke_id,
8823 { "Invoke ID", "bacapp.invoke_id",
8824 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
8826 { &hf_bacapp_sequence_number,
8827 { "Sequence Number", "bacapp.sequence_number",
8828 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
8830 { &hf_bacapp_window_size,
8831 { "Proposed Window Size", "bacapp.window_size",
8832 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
8834 { &hf_bacapp_service,
8835 { "Service Choice", "bacapp.confirmed_service",
8836 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
8838 { &hf_bacapp_uservice,
8839 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
8840 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
8843 { "NAK", "bacapp.NAK",
8844 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
8847 { "SRV", "bacapp.SRV",
8848 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
8850 { &hf_BACnetRejectReason,
8851 { "Reject Reason", "bacapp.reject_reason",
8852 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
8854 { &hf_BACnetAbortReason,
8855 { "Abort Reason", "bacapp.abort_reason",
8856 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
8859 { "BACnet APDU variable part:", "bacapp.variable_part",
8860 FT_NONE, BASE_NONE, NULL, 0, "BACnet APDU variable part", HFILL }
8865 FT_BYTES, BASE_NONE, NULL, 0,
8868 { &hf_BACnetApplicationTagNumber,
8869 { "Application Tag Number",
8870 "bacapp.application_tag_number",
8871 FT_UINT8, BASE_DEC, VALS(&BACnetApplicationTagNumber), 0xF0,
8874 { &hf_BACnetContextTagNumber,
8875 { "Context Tag Number",
8876 "bacapp.context_tag_number",
8877 FT_UINT8, BASE_DEC, NULL, 0xF0,
8880 { &hf_BACnetExtendedTagNumber,
8881 { "Extended Tag Number",
8882 "bacapp.extended_tag_number",
8883 FT_UINT8, BASE_DEC, NULL, 0,
8886 { &hf_BACnetNamedTag,
8889 FT_UINT8, BASE_DEC, VALS(&BACnetTagNames), 0x07,
8892 { &hf_BACnetCharacterSet,
8893 { "String Character Set",
8894 "bacapp.string_character_set",
8895 FT_UINT8, BASE_DEC, VALS(&BACnetCharacterSet),0,
8898 { &hf_BACnetTagClass,
8899 { "Tag Class", "bacapp.tag_class",
8900 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
8902 { &hf_bacapp_tag_lvt,
8903 { "Length Value Type",
8905 FT_UINT8, BASE_DEC, NULL, 0,
8908 { &hf_bacapp_tag_value8,
8910 "bacapp.tag_value8",
8911 FT_UINT8, BASE_DEC, NULL, 0,
8914 { &hf_bacapp_tag_value16,
8915 { "Tag Value 16-bit",
8916 "bacapp.tag_value16",
8917 FT_UINT16, BASE_DEC, NULL, 0,
8920 { &hf_bacapp_tag_value32,
8921 { "Tag Value 32-bit",
8922 "bacapp.tag_value32",
8923 FT_UINT32, BASE_DEC, NULL, 0,
8926 { &hf_bacapp_tag_ProcessId,
8927 { "ProcessIdentifier", "bacapp.processId",
8928 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
8930 { &hf_bacapp_tag_IPV4,
8931 { "IPV4", "bacapp.IPV4",
8932 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
8934 { &hf_bacapp_tag_IPV6,
8935 { "IPV6", "bacapp.IPV6",
8936 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
8938 { &hf_bacapp_tag_PORT,
8939 { "Port", "bacapp.Port",
8940 FT_UINT16, BASE_DEC, NULL, 0, "Port", HFILL }
8942 { &hf_bacapp_tag_initiatingObjectType,
8943 { "ObjectType", "bacapp.objectType",
8944 FT_UINT16, BASE_DEC, VALS(BACnetObjectType), 0x00, "Object Type", HFILL }
8947 {"Message fragments", "bacapp.fragments",
8948 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
8950 {"Message fragment", "bacapp.fragment",
8951 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
8952 {&hf_msg_fragment_overlap,
8953 {"Message fragment overlap", "bacapp.fragment.overlap",
8954 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
8955 {&hf_msg_fragment_overlap_conflicts,
8956 {"Message fragment overlapping with conflicting data",
8957 "bacapp.fragment.overlap.conflicts",
8958 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
8959 {&hf_msg_fragment_multiple_tails,
8960 {"Message has multiple tail fragments",
8961 "bacapp.fragment.multiple_tails",
8962 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
8963 {&hf_msg_fragment_too_long_fragment,
8964 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
8965 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
8966 {&hf_msg_fragment_error,
8967 {"Message defragmentation error", "bacapp.fragment.error",
8968 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
8969 {&hf_msg_reassembled_in,
8970 {"Reassembled in", "bacapp.reassembled.in",
8971 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
8972 {&hf_msg_reassembled_length,
8973 {"Reassembled BACapp length", "bacapp.reassembled.length",
8974 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
8976 static gint *ett[] = {
8978 &ett_bacapp_control,
8987 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
8988 "BACapp", "bacapp");
8990 proto_register_field_array(proto_bacapp, hf, array_length(hf));
8991 proto_register_subtree_array(ett, array_length(ett));
8992 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
8993 register_init_routine (&bacapp_init_routine);
8998 proto_reg_handoff_bacapp(void)
9000 data_handle = find_dissector("data");
9004 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
9009 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
9010 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
9011 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
9014 g_iconv_close (icd);
9018 uni_to_string(in,*inbytesleft,out);
9019 /* memcpy (out, in, *inbytesleft); */
9020 out[*inbytesleft] = '\0';
9021 *outbytesleft -= *inbytesleft;
9028 uni_to_string(char * data, gsize str_length, char *dest_buf)
9032 gsize length_remaining = 0;
9034 length_remaining = str_length;
9040 for ( i = 0; i < (gint) str_length; i++ )
9043 if (c_char<0x20 || c_char>0x7e)
9048 dest_buf[i] = c_char & 0xff;
9058 dest_buf[i] = c_char & 0xff;
9062 if(length_remaining==0)
9064 dest_buf[i+1] = '\0';