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, packet_info *pinfo, 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);
1817 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1821 * BACnetSessionKey ::= SEQUENCE {
1822 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1823 * peerAddress BACnetAddress
1828 * @return modified offset
1829 * @todo check if checksum is displayed correctly
1832 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1836 * BACnetSpecialEvent ::= SEQUENCE {
1838 * calendarEntry [0] BACnetCalendarEntry,
1839 * calendarRefernce [1] BACnetObjectIdentifier
1841 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1842 * eventPriority [3] Unsigned (1..16)
1848 * @return modified offset
1851 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1854 * BACnetTimeStamp ::= CHOICE {
1856 * sequenceNumber [1] Unsigned (0..65535),
1857 * dateTime [2] BACnetDateTime
1863 * @return modified offset
1866 fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
1869 * BACnetTimeValue ::= SEQUENCE {
1871 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
1877 * @return modified offset
1880 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1884 * BACnetVTSession ::= SEQUENCE {
1885 * local-vtSessionID Unsigned8,
1886 * remote-vtSessionID Unsigned8,
1887 * remote-vtAddress BACnetAddress
1892 * @return modified offset
1895 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
1899 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
1900 * -- first octet month (1..12) January = 1, X'FF' = any month
1901 * -- second octet weekOfMonth where: 1 = days numbered 1-7
1902 * -- 2 = days numbered 8-14
1903 * -- 3 = days numbered 15-21
1904 * -- 4 = days numbered 22-28
1905 * -- 5 = days numbered 29-31
1906 * -- 6 = last 7 days of this month
1907 * -- X'FF' = any week of this month
1908 * -- third octet dayOfWeek (1..7) where 1 = Monday
1910 * -- X'FF' = any day of week
1914 * @return modified offset
1917 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
1920 * ReadAccessResult ::= SEQUENCE {
1921 * objectIdentifier [0] BACnetObjectIdentifier,
1922 * listOfResults [1] SEQUENCE OF SEQUENCE {
1923 * propertyIdentifier [2] BACnetPropertyIdentifier,
1924 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
1925 * readResult CHOICE {
1926 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1927 * propertyAccessError [5] Error
1935 * @return modified offset
1938 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1941 * ReadAccessSpecification ::= SEQUENCE {
1942 * objectIdentifier [0] BACnetObjectIdentifier,
1943 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
1949 * @return modified offset
1952 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1955 * WriteAccessSpecification ::= SEQUENCE {
1956 * objectIdentifier [0] BACnetObjectIdentifier,
1957 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
1963 * @return modified offset
1966 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
1969 /********************************************************* Helper functions *******************************************/
1972 * extracts the tag number from the tag header.
1973 * @param tvb "TestyVirtualBuffer"
1974 * @param offset in actual tvb
1975 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
1978 fTagNo (tvbuff_t *tvb, guint offset);
1981 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
1982 * @param tvb = "TestyVirtualBuffer"
1983 * @param offset = offset in actual tvb
1984 * @return tag_no BACnet 20.2.1.2 Tag Number
1985 * @return class_tag BACnet 20.2.1.1 Class
1986 * @return lvt BACnet 20.2.1.3 Length/Value/Type
1987 * @return offs = length of this header
1991 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
1995 * adds processID with max 32Bit unsigned Integer Value to tree
1999 * @return modified offset
2002 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
2005 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2009 * @return modified offset
2012 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2015 * BACnet Application PDUs chapter 21
2016 * BACnetPropertyIdentifier::= ENUMERATED {
2017 * @see bacapp_property_identifier
2023 * @param tt returnvalue of this item
2024 * @return modified offset
2027 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2030 * BACnet Application PDUs chapter 21
2031 * BACnetPropertyArrayIndex::= ENUMERATED {
2032 * @see bacapp_property_array_index
2037 * @param tt returnvalue of this item
2038 * @return modified offset
2041 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
2044 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2045 * objectIdentifier [0] BACnetObjectIdentifier,
2046 * eventState [1] BACnetEventState,
2047 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2048 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2049 * notifyType [4] BACnetNotifyType,
2050 * eventEnable [5] BACnetEventTransitionBits,
2051 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2057 * @return modified offset
2060 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2063 * SelectionCriteria ::= SEQUENCE {
2064 * propertyIdentifier [0] BACnetPropertyIdentifier,
2065 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2066 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2067 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2073 * @return modified offset
2076 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2079 * objectSelectionCriteria ::= SEQUENCE {
2080 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2081 * listOfSelectionCriteria [1] SelectionCriteria
2087 * @return modified offset
2090 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2093 * BACnet-Error ::= SEQUENCE {
2094 * error-class ENUMERATED {},
2095 * error-code ENUMERATED {}
2102 * @return modified offset
2105 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2108 * Generic handler for context tagged values. Mostly for handling
2109 * vendor-defined properties and services.
2113 * @return modified offset
2114 * @todo beautify this ugly construct
2117 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
2120 * realizes some ABSTRACT-SYNTAX.&Type
2125 * @return modified offset
2126 * @todo beautify this ugly construct
2129 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2133 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2134 const value_string *src);
2140 proto_register_bacapp(void);
2143 * proto_reg_handoff_bacapp
2146 proto_reg_handoff_bacapp(void);
2149 * converts XXX coded strings to UTF-8
2150 * else 'in' is copied to 'out'
2151 * @param in -- pointer to string
2152 * @param inbytesleft
2153 * @param out -- pointer to string
2154 * @param outbytesleft
2156 * @return count of modified characters of returned string, -1 for errors
2159 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2162 uni_to_string(char * data, gsize str_length, char *dest_buf);
2164 /* <<<< formerly bacapp.h */
2166 /* some hashes for segmented messages */
2167 static GHashTable *msg_fragment_table = NULL;
2168 static GHashTable *msg_reassembled_table = NULL;
2170 /* some necessary forward function prototypes */
2172 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2173 const gchar *label, const value_string *vs);
2175 static const char *bacapp_unknown_service_str = "unknown service";
2176 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2177 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2179 static const value_string
2180 BACnetTypeName[] = {
2181 {0, "Confirmed-REQ"},
2182 {1, "Unconfirmed-REQ"},
2192 static const true_false_string segments_follow = {
2193 "Segmented Request",
2194 "Unsegmented Request"
2197 static const true_false_string more_follow = {
2198 "More Segments Follow",
2199 "No More Segments Follow"
2202 static const true_false_string segmented_accept = {
2203 "Segmented Response accepted",
2204 "Segmented Response not accepted"
2207 static const true_false_string
2209 "Context Specific Tag",
2213 static const value_string
2214 BACnetMaxSegmentsAccepted [] = {
2222 {7,"Greater than 64 segments"},
2226 static const value_string
2227 BACnetMaxAPDULengthAccepted [] = {
2228 {0,"Up to MinimumMessageSize (50 octets)"},
2229 {1,"Up to 128 octets"},
2230 {2,"Up to 206 octets (fits in a LonTalk frame)"},
2231 {3,"Up to 480 octets (fits in an ARCNET frame)"},
2232 {4,"Up to 1024 octets"},
2233 {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2234 {6,"reserved by ASHRAE"},
2235 {7,"reserved by ASHRAE"},
2236 {8,"reserved by ASHRAE"},
2237 {9,"reserved by ASHRAE"},
2238 {10,"reserved by ASHRAE"},
2239 {11,"reserved by ASHRAE"},
2240 {12,"reserved by ASHRAE"},
2241 {13,"reserved by ASHRAE"},
2242 {14,"reserved by ASHRAE"},
2243 {15,"reserved by ASHRAE"},
2247 static const value_string
2248 BACnetRejectReason [] = {
2250 {1,"buffer-overflow"},
2251 {2,"inconsistent-parameters"},
2252 {3,"invalid-parameter-data-type"},
2254 {5,"missing-required-parameter"},
2255 {6,"parameter-out-of-range"},
2256 {7,"too-many-arguments"},
2257 {8,"undefined-enumeration"},
2258 {9,"unrecognized-service"},
2262 static const value_string
2263 BACnetRestartReason [] = {
2267 {3,"detected-power-lost"},
2268 {4,"detected-powered-off"},
2269 {5,"hardware-watchdog"},
2270 {6,"software-watchdog"},
2275 static const value_string
2276 BACnetApplicationTagNumber [] = {
2279 {2,"Unsigned Integer"},
2280 {3,"Signed Integer (2's complement notation)"},
2281 {4,"Real (ANSI/IEE-754 floating point)"},
2282 {5,"Double (ANSI/IEE-754 double precision floating point)"},
2284 {7,"Character String"},
2289 {12,"BACnetObjectIdentifier"},
2290 {13,"reserved by ASHRAE"},
2291 {14,"reserved by ASHRAE"},
2292 {15,"reserved by ASHRAE"},
2296 static const value_string
2303 static const value_string
2304 BACnetFileAccessMethod [] = {
2305 {0,"record-access"},
2306 {1,"stream-access"},
2310 /* For some reason, BACnet defines the choice parameter
2311 in the file read and write services backwards from the
2312 BACnetFileAccessMethod enumeration.
2314 static const value_string
2315 BACnetFileAccessOption [] = {
2316 {0,"stream access"},
2317 {1,"record access"},
2321 static const value_string
2322 BACnetFileStartOption [] = {
2323 {0, "File Start Position: "},
2324 {1, "File Start Record: "},
2328 static const value_string
2329 BACnetFileRequestCount [] = {
2330 {0, "Requested Octet Count: "},
2331 {1, "Requested Record Count: "},
2335 static const value_string
2336 BACnetFileWriteInfo [] = {
2338 {1, "Record Count: "},
2342 static const value_string
2343 BACnetAbortReason [] = {
2345 {1,"buffer-overflow"},
2346 {2,"invalid-apdu-in-this-state"},
2347 {3,"preempted-by-higher-priority-task"},
2348 {4,"segmentation-not-supported"},
2352 static const value_string
2353 BACnetLifeSafetyMode [] = {
2364 {10,"disconnected"},
2367 {13,"atomic-release-disabled"},
2370 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2371 Enumerated values 256-65535 may be used by others subject to
2372 procedures and constraints described in Clause 23. */
2375 static const value_string
2376 BACnetLifeSafetyOperation [] = {
2379 {2,"silence-audible"},
2380 {3,"silence-visual"},
2385 {8,"unsilence-audible"},
2386 {9,"unsilence-visual"},
2388 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2389 Enumerated values 64-65535 may be used by others subject to
2390 procedures and constraints described in Clause 23. */
2393 static const value_string
2394 BACnetLimitEnable [] = {
2395 {0,"lowLimitEnable"},
2396 {1,"highLimitEnable"},
2400 static const value_string
2401 BACnetLifeSafetyState [] = {
2406 {4,"fault-pre-alarm"},
2414 {12,"test-fault-alarm"},
2417 {15,"tamper-alarm"},
2419 {17,"emergency-power"},
2423 {21,"general-alarm"},
2425 {23,"test-supervisory"},
2427 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2428 Enumerated values 256-65535 may be used by others subject to
2429 procedures and constraints described in Clause 23. */
2432 static const value_string
2433 BACnetConfirmedServiceChoice [] = {
2434 {0,"acknowledgeAlarm"},
2435 {1,"confirmedCOVNotification"},
2436 {2,"confirmedEventNotification"},
2437 {3,"getAlarmSummary"},
2438 {4,"getEnrollmentSummary"},
2440 {6,"atomicReadFile"},
2441 {7,"atomicWriteFile"},
2442 {8,"addListElement"},
2443 {9,"removeListElement"},
2444 {10,"createObject"},
2445 {11,"deleteObject"},
2446 {12,"readProperty"},
2447 {13,"readPropertyConditional"},
2448 {14,"readPropertyMultiple"},
2449 {15,"writeProperty"},
2450 {16,"writePropertyMultiple"},
2451 {17,"deviceCommunicationControl"},
2452 {18,"confirmedPrivateTransfer"},
2453 {19,"confirmedTextMessage"},
2454 {20,"reinitializeDevice"},
2458 {24,"authenticate"},
2461 {27,"lifeSafetyOperation"},
2462 {28,"subscribeCOVProperty"},
2463 {29,"getEventInformation"},
2464 {30,"reserved by ASHRAE"},
2468 static const value_string
2469 BACnetReliability [] = {
2470 {0,"no-fault-detected"},
2477 {7,"unreliable-other"},
2478 {8,"process-error"},
2479 {9,"multi-state-fault"},
2483 static const value_string
2484 BACnetUnconfirmedServiceChoice [] = {
2487 {2,"unconfirmedCOVNotification"},
2488 {3,"unconfirmedEventNotification"},
2489 {4,"unconfirmedPrivateTransfer"},
2490 {5,"unconfirmedTextMessage"},
2491 {6,"timeSynchronization"},
2494 {9,"utcTimeSynchonization"},
2498 static const value_string
2499 BACnetUnconfirmedServiceRequest [] = {
2501 {1,"i-Have-Request"},
2502 {2,"unconfirmedCOVNotification-Request"},
2503 {3,"unconfirmedEventNotification-Request"},
2504 {4,"unconfirmedPrivateTransfer-Request"},
2505 {5,"unconfirmedTextMessage-Request"},
2506 {6,"timeSynchronization-Request"},
2507 {7,"who-Has-Request"},
2508 {8,"who-Is-Request"},
2509 {9,"utcTimeSynchonization-Request"},
2513 static const value_string
2514 BACnetObjectType [] = {
2516 {1,"analog-output"},
2519 {4,"binary-output"},
2524 {9,"event-enrollment"},
2528 {13,"multi-state-input"},
2529 {14,"multi-state-output"},
2530 {15,"notification-class"},
2534 {19,"multi-state-value"},
2536 {21,"life-safety-point"},
2537 {22,"life-safety-zone"},
2539 {24,"pulse-converter"},
2541 {26,"global-group"},
2542 {27,"trend-log-multiple"},
2543 {28,"load-control"},
2544 {29,"structured-view"},
2545 {30,"access-door"}, /* 30-37 added with addanda 135-2008j */
2546 {32,"access-credential"},
2547 {33,"access-point"},
2548 {34,"access-rights"},
2551 {37,"credential-data-input"},
2552 {39,"bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2553 {40,"characterstring-value"},
2554 {41,"date-pattern-value"},
2556 {43,"datetime-pattern-value"},
2557 {44,"datetime-value"},
2558 {45,"integer-value"},
2559 {46,"large-analog-value"},
2560 {47,"octetstring-value"},
2561 {48,"positive-Integer-value"},
2562 {49,"time-pattern-value"},
2565 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2566 Enumerated values 128-1023 may be used by others subject to
2567 the procedures and constraints described in Clause 23. */
2570 static const value_string
2571 BACnetEngineeringUnits [] = {
2581 {9,"Kilovolt Amperes"},
2582 {10,"Megavolt Amperes"},
2583 {11,"Volt Amperes Reactive"},
2584 {12,"Kilovolt Amperes Reactive"},
2585 {13,"Megavolt Amperes Reactive"},
2586 {14,"Degrees Phase"},
2587 {15,"Power Factor"},
2591 {19,"Kilowatt Hours"},
2595 {23,"Joules Per Kg Dry Air"},
2596 {24,"BTUs Per Pound Dry Air"},
2597 {25,"Cycles Per Hour"},
2598 {26,"Cycles Per Minute"},
2600 {28,"Grams Of Water Per Kilogram Dry Air"},
2601 {29,"Relative Humidity"},
2606 {34,"Watts Per Sq Foot"},
2607 {35,"Watts Per Sq meter"},
2610 {38,"Foot Candles"},
2614 {42,"Kgs per Second"},
2615 {43,"Kgs Per Minute"},
2616 {44,"Kgs Per Hour"},
2617 {45,"Pounds Mass Per Minute"},
2618 {46,"Pounds Mass Per Hour"},
2622 {50,"BTUs Per Hour"},
2624 {52,"Tons Refrigeration"},
2628 {56,"Pounds Force Per Square Inch"},
2629 {57,"Centimeters Of Water"},
2630 {58,"Inches Of Water"},
2631 {59,"Millimeters Of Mercury"},
2632 {60,"Centimeters Of Mercury"},
2633 {61,"Inches Of Mercury"},
2634 {62,"Degrees Celsius"},
2635 {63,"Degrees Kelvin"},
2636 {64,"Degrees Fahrenheit"},
2637 {65,"Degree Days Celsius"},
2638 {66,"Degree Days Fahrenheit"},
2646 {74,"Meters Per Second"},
2647 {75,"Kilometers Per Hour"},
2648 {76,"Feed Per Second"},
2649 {77,"Feet Per Minute"},
2650 {78,"Miles Per Hour"},
2652 {80,"Cubic Meters"},
2653 {81,"Imperial Gallons"},
2656 {84,"Cubic Feet Per Minute"},
2657 {85,"Cubic Meters Per Second"},
2658 {86,"Imperial Gallons Per Minute"},
2659 {87,"Liters Per Second"},
2660 {88,"Liters Per Minute"},
2661 {89,"US Gallons Per Minute"},
2662 {90,"Degrees Angular"},
2663 {91,"Degrees Celsius Per Hour"},
2664 {92,"Degrees Celsius Per Minute"},
2665 {93,"Degrees Fahrenheit Per Hour"},
2666 {94,"Degrees Fahrenheit Per Minute"},
2668 {96,"Parts Per Million"},
2669 {97,"Parts Per Billion"},
2671 {99,"Pecent Per Second"},
2674 {102,"Psi Per Degree Fahrenheit"},
2676 {104,"Revolutions Per Min"},
2688 {116,"Sq Centimeters"},
2689 {117,"BTUs Per Pound"},
2690 {118,"Centimeters"},
2691 {119,"Pounds Mass Per Second"},
2692 {120,"Delta Degrees Fahrenheit"},
2693 {121,"Delta Degrees Kelvin"},
2697 {125,"Kilojoules Per Kg"},
2699 {127,"Joules Per Degree Kelvin"},
2700 {128,"Joules Per Kg Degree Kelvin"},
2705 {133,"Hectopascals"},
2707 {135,"Cubic Meters Per Hour"},
2708 {136,"Liters Per Hour"},
2709 {137,"KWatt Hours Per Square Meter"},
2710 {138,"KWatt Hours Per Square Foot"},
2711 {139,"Megajoules Per Square Meter"},
2712 {140,"Megajoules Per Square Foot"},
2713 {141,"Watts Per Sq Meter Degree Kelvin"},
2714 {142,"Cubic Feet Per Second"},
2715 {143,"Percent Obstruction Per Foot"},
2716 {144,"Percent Obstruction Per Meter"},
2718 {146,"megawatt-hours"},
2721 {149,"kilojoules-per-kilogram-dry-air"},
2722 {150,"megajoules-per-kilogram-dry-air"},
2723 {151,"kilojoules-per-degree-Kelvin"},
2724 {152,"megajoules-per-degree-Kelvin"},
2726 {154,"grams-per-second"},
2727 {155,"grams-per-minute"},
2728 {156,"tons-per-hour"},
2729 {157,"kilo-btus-per-hour"},
2730 {158,"hundredths-seconds"},
2731 {159,"milliseconds"},
2732 {160,"newton-meters"},
2733 {161,"millimeters-per-second"},
2734 {162,"millimeters-per-minute"},
2735 {163,"meters-per-minute"},
2736 {164,"meters-per-hour"},
2737 {165,"cubic-meters-per-minute"},
2738 {166,"meters-per-second-per-second"},
2739 {167,"amperes-per-meter"},
2740 {168,"amperes-per-square-meter"},
2741 {169,"ampere-square-meters"},
2746 {174,"siemens-per-meter"},
2748 {176,"volts-per-degree-Kelvin"},
2749 {177,"volts-per-meter"},
2752 {180,"candelas-per-square-meter"},
2753 {181,"degrees-Kelvin-per-hour"},
2754 {182,"degrees-Kelvin-per-minute"},
2755 {183,"joule-seconds"},
2756 {184,"radians-per-second"},
2757 {185,"square-meters-per-Newton"},
2758 {186,"kilograms-per-cubic-meter"},
2759 {187,"newton-seconds"},
2760 {188,"newtons-per-meter"},
2761 {189,"watts-per-meter-per-degree-Kelvin"},
2763 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2764 Enumerated values 256-65535 may be used by others subject to
2765 the procedures and constraints described in Clause 23. */
2768 static const value_string
2769 BACnetErrorCode [] = {
2771 {1,"authentication-failed"},
2772 {2,"configuration-in-progress"},
2774 {4,"dynamic-creation-not-supported"},
2775 {5,"file-access-denied"},
2776 {6,"incompatible-security-levels"},
2777 {7,"inconsistent-parameters"},
2778 {8,"inconsistent-selection-criterion"},
2779 {9,"invalid-data-type"},
2780 {10,"invalid-file-access-method"},
2781 {11,"invalid-file-start-position"},
2782 {12,"invalid-operator-name"},
2783 {13,"invalid-parameter-data-type"},
2784 {14,"invalid-time-stamp"},
2785 {15,"key-generation-error"},
2786 {16,"missing-required-parameter"},
2787 {17,"no-objects-of-specified-type"},
2788 {18,"no-space-for-object"},
2789 {19,"no-space-to-add-list-element"},
2790 {20,"no-space-to-write-property"},
2791 {21,"no-vt-sessions-available"},
2792 {22,"property-is-not-a-list"},
2793 {23,"object-deletion-not-permitted"},
2794 {24,"object-identifier-already-exists"},
2795 {25,"operational-problem"},
2796 {26,"password-failure"},
2797 {27,"read-access-denied"},
2798 {28,"security-not-supported"},
2799 {29,"service-request-denied"},
2801 {31,"unknown-object"},
2802 {32,"unknown-property"},
2803 {33,"removed enumeration"},
2804 {34,"unknown-vt-class"},
2805 {35,"unknown-vt-session"},
2806 {36,"unsupported-object-type"},
2807 {37,"value-out-of-range"},
2808 {38,"vt-session-already-closed"},
2809 {39,"vt-session-termination-failure"},
2810 {40,"write-access-denied"},
2811 {41,"character-set-not-supported"},
2812 {42,"invalid-array-index"},
2813 {43,"cov-subscription-failed"},
2814 {44,"not-cov-property"},
2815 {45,"optional-functionality-not-supported"},
2816 {46,"invalid-configuration-data"},
2817 {47,"datatype-not-supported"},
2818 {48,"duplicate-name"},
2819 {49,"duplicate-object-id"},
2820 {50,"property-is-not-an-array"},
2821 {73,"invalid-event-state"},
2822 {74,"no-alarm-configured"},
2824 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2825 Enumerated values 256-65535 may be used by others subject to the
2826 procedures and constraints described in Clause 23. */
2829 static const value_string
2830 BACnetPropertyIdentifier [] = {
2831 {0,"acked-transition"},
2836 {5,"active-vt-session"},
2840 {9,"all-write-successful"},
2841 {10,"apdu-segment-timeout"},
2842 {11,"apdu-timeout"},
2843 {12,"application-software-version"},
2846 {15,"change-of-state-count"},
2847 {16,"change-of-state-time"},
2848 {17,"notification-class"},
2849 {18,"the property in this place was deleted"},
2850 {19,"controlled-variable-reference"},
2851 {20,"controlled-variable-units"},
2852 {21,"controlled-variable-value"},
2853 {22,"cov-increment"},
2855 {24,"daylights-savings-status"},
2857 {26,"derivative-constant"},
2858 {27,"derivative-constant-units"},
2860 {29,"description-of-halt"},
2861 {30,"device-address-binding"},
2863 {32,"effective-period"},
2864 {33,"elapsed-active-time"},
2866 {35,"event-enable"},
2869 {38,"exception-schedule"},
2870 {39,"fault-values"},
2871 {40,"feedback-value"},
2872 {41,"file-access-method"},
2875 {44,"firmware-revision"},
2877 {46,"inactive-text"},
2880 {49,"integral-constant"},
2881 {50,"integral-constant-units"},
2882 {51,"issue-confirmed-notifications"},
2883 {52,"limit-enable"},
2884 {53,"list-of-group-members"},
2885 {54,"list-of-object-property-references"},
2886 {55,"list-of-session-keys"},
2891 {60,"manipulated-variable-reference"},
2892 {61,"maximum-output"},
2893 {62,"max-apdu-length-accepted"},
2894 {63,"max-info-frames"},
2896 {65,"max-pres-value"},
2897 {66,"minimum-off-time"},
2898 {67,"minimum-on-time"},
2899 {68,"minimum-output"},
2900 {69,"min-pres-value"},
2902 {71,"modification-date"},
2904 {73,"number-of-APDU-retries"},
2905 {74,"number-of-states"},
2906 {75,"object-identifier"},
2909 {78,"object-property-reference"},
2912 {81,"out-of-service"},
2913 {82,"output-units"},
2914 {83,"event-parameters"},
2916 {85,"present-value"},
2918 {87,"priority-array"},
2919 {88,"priority-for-writing"},
2920 {89,"process-identifier"},
2921 {90,"program-change"},
2922 {91,"program-location"},
2923 {92,"program-state"},
2924 {93,"proportional-constant"},
2925 {94,"proportional-constant-units"},
2926 {95,"protocol-conformance-class"},
2927 {96,"protocol-object-types-supported"},
2928 {97,"protocol-services-supported"},
2929 {98,"protocol-version"},
2931 {100,"reason-for-halt"},
2933 {102,"recipient-list"},
2934 {103,"reliability"},
2935 {104,"relinquish-default"},
2938 {107,"segmentation-supported"},
2940 {109,"setpoint-reference"},
2942 {111,"status-flags"},
2943 {112,"system-status"},
2945 {114,"time-of-active-time-reset"},
2946 {115,"time-of-state-count-reset"},
2947 {116,"time-synchronization-recipients"},
2949 {118,"update-interval"},
2951 {120,"vendor-identifier"},
2952 {121,"vendor-name"},
2953 {122,"vt-class-supported"},
2954 {123,"weekly-schedule"},
2955 {124,"attempted-samples"},
2956 {125,"average-value"},
2957 {126,"buffer-size"},
2958 {127,"client-cov-increment"},
2959 {128,"cov-resubscription-interval"},
2960 {129,"current-notify-time"},
2961 {130,"event-time-stamp"},
2963 {132,"log-device-object-property"},
2964 {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
2965 {134,"log-interval"},
2966 {135,"maximum-value"},
2967 {136,"minimum-value"},
2968 {137,"notification-threshold"},
2969 {138,"previous-notify-time"},
2970 {139,"protocol-revision"},
2971 {140,"records-since-notification"},
2972 {141,"record-count"},
2975 {144,"stop-when-full"},
2976 {145,"total-record-count"},
2977 {146,"valid-samples"},
2978 {147,"window-interval"},
2979 {148,"window-samples"},
2980 {149,"maximum-value-time-stamp"},
2981 {150,"minimum-value-time-stamp"},
2982 {151,"variance-value"},
2983 {152,"active-cov-subscriptions"},
2984 {153,"backup-failure-timeout"},
2985 {154,"configuration-files"},
2986 {155,"database-revision"},
2987 {156,"direct-reading"},
2988 {157,"last-restore-time"},
2989 {158,"maintenance-required"},
2992 {161,"operation-expected"},
2995 {164,"tracking-value"},
2996 {165,"zone-members"},
2997 {166,"life-safety-alarm-values"},
2998 {167,"max-segments-accepted"},
2999 {168,"profile-name"},
3000 {169,"auto-slave-discovery"},
3001 {170,"manual-slave-address-binding"},
3002 {171,"slave-address-binding"},
3003 {172,"slave-proxy-enable"},
3004 {173,"last-notify-record"}, /* bug 4117 */
3005 {174,"schedule-default"},
3006 {175,"accepted-modes"},
3007 {176,"adjust-value"},
3009 {178,"count-before-change"},
3010 {179,"count-change-time"},
3012 {181,"input-reference"},
3013 {182,"limit-monitoring-interval"},
3014 {183,"logging-device"},
3015 {184,"logging-record"},
3019 {188,"scale-factor"},
3020 {189,"update-time"},
3021 {190,"value-before-change"},
3023 {192,"value-change-time"},
3024 {193,"align-intervals"},
3025 {194,"group-member-names"},
3026 {195,"interval-offset"},
3027 {196,"last-restart-reason"},
3028 {197,"logging-type"},
3029 {198,"member-status-flags"},
3030 {199,"notification-period"},
3031 {200,"previous-notify-record"},
3032 {201,"requested-update-interval"},
3033 {202,"restart-notification-recipients"},
3034 {203,"time-of-device-restart"},
3035 {204,"time-synchronization-recipients"},
3037 {206,"UTC-time-synchronization-recipients"},
3038 {207,"node-subtype"},
3040 {209,"structured-object-list"},
3041 {210,"subordinate-annotations"},
3042 {211,"subordinate-list"},
3043 {212,"actual-shed-level"},
3044 {213,"duty-window"},
3045 {214,"expected-shed-level"},
3046 {215,"full-duty-baseline"},
3047 {216,"node-subtype"},
3049 {218,"requested-shed-level"},
3050 {219,"shed-duration"},
3051 {220,"shed-level-descriptions"},
3052 {221,"shed-levels"},
3053 {222,"state-description"},
3054 {226,"door-alarm-state"},
3055 {227,"door-extended-pulse-time"},
3056 {228,"door-members"},
3057 {229,"door-open-too-long-time"},
3058 {230,"door-pulse-time"},
3059 {231,"door-status"},
3060 {232,"door-unlock-delay-time"},
3061 {233,"lock-status"},
3062 {234,"masked-alarm-values"},
3063 {235,"secured-status"},
3064 {244,"absentee-limit"}, /* added with addenda 135-2008j */
3065 {245,"access-alarm-events"},
3066 {246,"access-doors"},
3067 {247,"access-event"},
3068 {248,"access-event-authentication-factor"},
3069 {249,"access-event-credential"},
3070 {250,"access-event-time"},
3071 {251,"access-transaction-events"},
3072 {252,"accompaniment"},
3073 {253,"accompaniment-time"},
3074 {254,"activation-time"},
3075 {255,"active-authentication-policy"},
3076 {256,"assigned-access-rights"},
3077 {257,"authentication-factors"},
3078 {258,"authentication-policy-list"},
3079 {259,"authentication-policy-names"},
3080 {260,"authentication-status"},
3081 {261,"authorization-mode"},
3083 {263,"credential-disable"},
3084 {264,"credential-status"},
3085 {265,"credentials"},
3086 {266,"credentials-in-zone"},
3087 {267,"days-remaining"},
3088 {268,"entry-points"},
3089 {269,"exit-points"},
3090 {270,"expiry-time"},
3091 {271,"extended-time-enable"},
3092 {272,"failed-attempt-events"},
3093 {273,"failed-attempts"},
3094 {274,"failed-attempts-time"},
3095 {275,"last-access-event"},
3096 {276,"last-access-point"},
3097 {277,"last-credential-added"},
3098 {278,"last-credential-added-time"},
3099 {279,"last-credential-removed"},
3100 {280,"last-credential-removed-time"},
3101 {281,"last-use-time"},
3103 {283,"lockout-relinquish-time"},
3104 {284,"master-exemption"},
3105 {285,"max-failed-attempts"},
3107 {287,"muster-point"},
3108 {288,"negative-access-rules"},
3109 {289,"number-of-authentication-policies"},
3110 {290,"occupancy-count"},
3111 {291,"occupancy-count-adjust"},
3112 {292,"occupancy-count-enable"},
3113 {293,"occupancy-exemption"},
3114 {294,"occupancy-lower-limit"},
3115 {295,"occupancy-lower-limit-enforced"},
3116 {296,"occupancy-state"},
3117 {297,"occupancy-upper-limit"},
3118 {298,"occupancy-upper-limit-enforced"},
3119 {299,"passback-exemption"},
3120 {300,"passback-mode"},
3121 {301,"passback-timeout"},
3122 {302,"positive-access-rules"},
3123 {303,"reason-for-disable"},
3124 {304,"supported-formats"},
3125 {305,"supported-format-classes"},
3126 {306,"threat-authority"},
3127 {307,"threat-level"},
3129 {309,"transaction-notification-class"},
3130 {310,"user-external-identifier"},
3131 {311,"user-information-reference"},
3132 /* enumeration values 312-316 reserved for future addenda */
3135 {319,"uses-remaining"},
3138 {322,"access-event-tag"},
3139 {323,"global-identifier"},
3140 /* enumeration values 324-325 reserved for future addenda */
3141 {326,"verification-time"},
3142 {342,"bit-mask"}, /* addenda 135-2008w */
3146 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3147 Enumerated values 512-4194303 may be used by others subject to
3148 the procedures and constraints described in Clause 23. */
3151 static const value_string
3152 BACnetBinaryPV [] = {
3160 #define IBM_MS_DBCS 1
3161 #define JIS_C_6226 2
3162 #define ISO_10646_UCS4 3
3163 #define ISO_10646_UCS2 4
3164 #define ISO_18859_1 5
3165 static const value_string
3166 BACnetCharacterSet [] = {
3167 {ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3168 {IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3169 {JIS_C_6226, "JIS C 6226"},
3170 {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3171 {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3172 {ISO_18859_1, "ISO 18859-1"},
3176 static const value_string
3177 BACnetStatusFlags [] = {
3181 {3,"out-of-service"},
3185 static const value_string
3186 BACnetMessagePriority [] = {
3192 static const value_string
3193 BACnetAcknowledgementFilter [] = {
3200 static const value_string
3201 BACnetResultFlags [] = {
3208 static const value_string
3209 BACnetRelationSpecifier [] = {
3214 {4,"less-than-or-equal"},
3215 {5,"greater-than-or-equal"},
3219 static const value_string
3220 BACnetSelectionLogic [] = {
3227 static const value_string
3228 BACnetEventStateFilter [] = {
3237 static const value_string
3238 BACnetEventTransitionBits [] = {
3245 static const value_string
3246 BACnetSegmentation [] = {
3247 {0,"segmented-both"},
3248 {1,"segmented-transmit"},
3249 {2,"segmented-receive"},
3250 {3,"no-segmentation"},
3254 static const value_string
3255 BACnetSilencedState [] = {
3257 {1,"audible-silenced"},
3258 {2,"visible-silenced"},
3263 static const value_string
3264 BACnetDeviceStatus [] = {
3266 {1,"operational-read-only"},
3267 {2,"download-required"},
3268 {3,"download-in-progress"},
3269 {4,"non-operational"},
3270 {5,"backup-in-progress"},
3274 static const value_string
3275 BACnetEnableDisable [] = {
3278 {2,"disable-initiation"},
3282 static const value_string
3300 static const value_string
3302 {1,"days numbered 1-7" },
3303 {2,"days numbered 8-14" },
3304 {3,"days numbered 15-21" },
3305 {4,"days numbered 22-28" },
3306 {5,"days numbered 29-31" },
3307 {6,"last 7 days of this month" },
3308 {255,"any week of this month" },
3312 /* note: notification class object recipient-list uses
3313 different day-of-week enum */
3314 static const value_string
3323 {255,"any day of week" },
3327 static const value_string
3328 BACnetErrorClass [] = {
3337 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3338 Enumerated values64-65535 may be used by others subject to
3339 the procedures and constraints described in Clause 23. */
3342 static const value_string
3343 BACnetVTClass [] = {
3344 {0,"default-terminal" },
3354 static const value_string
3355 BACnetEventType [] = {
3356 {0,"change-of-bitstring" },
3357 {1,"change-of-state" },
3358 {2,"change-of-value" },
3359 {3,"command-failure" },
3360 {4,"floating-limit" },
3361 {5,"out-of-range" },
3362 {6,"complex-event-type" },
3363 {7,"buffer-ready" },
3364 {8,"change-of-life-safety" },
3366 {10,"buffer-ready" },
3367 {11,"unsigned-range" },
3368 {14,"double-out-of-range"}, /* added with addenda 135-2008w */
3369 {15,"signed-out-of-range"},
3370 {16,"unsigned-out-of-range"},
3371 {17,"change-of-characterstring"},
3373 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3374 Enumerated values 64-65535 may be used by others subject to
3375 the procedures and constraints described in Clause 23.
3376 It is expected that these enumerated values will correspond
3377 to the use of the complex-event-type CHOICE [6] of the
3378 BACnetNotificationParameters production. */
3381 static const value_string
3382 BACnetEventState [] = {
3388 {5,"life-safety-alarm" },
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 BACnetLogStatus [] = {
3397 {0,"log-disabled" },
3398 {1,"buffer-purged" },
3402 static const value_string
3403 BACnetMaintenance [] = {
3405 {1,"periodic-test" },
3406 {2,"need-service-operational" },
3407 {3,"need-service-inoperative" },
3411 static const value_string
3412 BACnetNotifyType [] = {
3415 {2,"ack-notification" },
3419 static const value_string
3420 BACnetServicesSupported [] = {
3421 {0,"acknowledgeAlarm"},
3422 {1,"confirmedCOVNotification"},
3423 {2,"confirmedEventNotification"},
3424 {3,"getAlarmSummary"},
3425 {4,"getEnrollmentSummary"},
3427 {6,"atomicReadFile"},
3428 {7,"atomicWriteFile"},
3429 {8,"addListElement"},
3430 {9,"removeListElement"},
3431 {10,"createObject"},
3432 {11,"deleteObject"},
3433 {12,"readProperty"},
3434 {13,"readPropertyConditional"},
3435 {14,"readPropertyMultiple"},
3436 {15,"writeProperty"},
3437 {16,"writePropertyMultiple"},
3438 {17,"deviceCommunicationControl"},
3439 {18,"confirmedPrivateTransfer"},
3440 {19,"confirmedTextMessage"},
3441 {20,"reinitializeDevice"},
3445 {24,"authenticate"},
3449 {28,"unconfirmedCOVNotification"},
3450 {29,"unconfirmedEventNotification"},
3451 {30,"unconfirmedPrivateTransfer"},
3452 {31,"unconfirmedTextMessage"},
3453 {32,"timeSynchronization"},
3457 {36,"utcTimeSynchronization"},
3458 {37,"lifeSafetyOperation"},
3459 {38,"subscribeCOVProperty"},
3460 {39,"getEventInformation"},
3464 static const value_string
3465 BACnetPropertyStates [] = {
3466 {0,"boolean-value"},
3470 {4,"program-change"},
3471 {5,"program-state"},
3472 {6,"reason-for-halt"},
3475 {9,"system-status"},
3477 {11,"unsigned-value"},
3478 {12,"life-safety-mode"},
3479 {13,"life-safety-state"},
3480 {14,"door-alarm-state"},
3482 /* Tag values 0-63 are reserved for definition by ASHRAE.
3483 Tag values of 64-254 may be used by others to accommodate
3484 vendor specific properties that have discrete or enumerated values,
3485 subject to the constraints described in Clause 23. */
3488 static const value_string
3489 BACnetProgramError [] = {
3496 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3497 Enumerated values 64-65535 may be used by others subject to
3498 the procedures and constraints described in Clause 23. */
3501 static const value_string
3502 BACnetProgramRequest [] = {
3512 static const value_string
3513 BACnetProgramState [] = {
3523 static const value_string
3524 BACnetReinitializedStateOfDevice [] = {
3535 static const value_string
3536 BACnetPolarity [] = {
3542 static const value_string
3543 BACnetTagNames[] = {
3544 { 5, "Extended Value" },
3545 { 6, "Opening Tag" },
3546 { 7, "Closing Tag" },
3550 static const value_string
3551 BACnetReadRangeOptions[] = {
3552 { 3, "range byPosition" },
3553 { 4, "range byTime" },
3554 { 5, "range timeRange" },
3555 { 6, "range bySequenceNumber" },
3556 { 7, "range byTime" },
3560 /* Present_Value for Load Control Object */
3561 static const value_string
3562 BACnetShedState[] = {
3563 { 0, "shed-inactive" },
3564 { 1, "shed-request-pending" },
3565 { 2, "shed-compliant" },
3566 { 3, "shed-non-compliant" },
3570 static const value_string
3571 BACnetVendorIdentifiers [] = {
3574 { 2, "The Trane Company" },
3575 { 3, "McQuay International" },
3577 { 5, "Johnson Controls, Inc." },
3578 { 6, "American Auto-Matrix" },
3579 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
3580 { 8, "Delta Controls" },
3581 { 9, "Siemens Building Technologies, Inc." },
3582 { 10, "Tour Andover Controls Corporation" },
3584 { 12, "Orion Analysis Corporation" },
3585 { 13, "Teletrol Systems Inc." },
3586 { 14, "Cimetrics Technology" },
3587 { 15, "Cornell University" },
3588 { 16, "United Technologies Carrier" },
3589 { 17, "Honeywell Inc." },
3590 { 18, "Alerton / Honeywell" },
3592 { 20, "Hewlett-Packard Company" },
3593 { 21, "Dorsette's Inc." },
3594 { 22, "Cerberus AG" },
3595 { 23, "York Controls Group" },
3596 { 24, "Automated Logic Corporation" },
3597 { 25, "CSI Control Systems International" },
3598 { 26, "Phoenix Controls Corporation" },
3599 { 27, "Innovex Technologies, Inc." },
3600 { 28, "KMC Controls, Inc." },
3601 { 29, "Xn Technologies, Inc." },
3602 { 30, "Hyundai Information Technology Co., Ltd." },
3603 { 31, "Tokimec Inc." },
3605 { 33, "North Communications Limited" },
3607 { 35, "Reliable Controls Corporation" },
3608 { 36, "Tridium Inc." },
3609 { 37, "Sierra Monitor Corp." },
3610 { 38, "Silicon Energy" },
3611 { 39, "Kieback & Peter GmbH & Co KG" },
3612 { 40, "Anacon Systems, Inc." },
3613 { 41, "Systems Controls & Instruments, LLC" },
3614 { 42, "Lithonia Lighting" },
3615 { 43, "Micropower Manufacturing" },
3616 { 44, "Matrix Controls" },
3617 { 45, "METALAIRE" },
3618 { 46, "ESS Engineering" },
3619 { 47, "Sphere Systems Pty Ltd." },
3620 { 48, "Walker Technologies Corporation" },
3621 { 49, "H I Solutions, Inc." },
3623 { 51, "SAMSON AG" },
3624 { 52, "Badger Meter Inc." },
3625 { 53, "DAIKIN Industries Ltd." },
3626 { 54, "NARA Controls Inc." },
3627 { 55, "Mammoth Inc." },
3628 { 56, "Liebert Corporation" },
3629 { 57, "SEMCO Incorporated" },
3630 { 58, "Air Monitor Corporation" },
3631 { 59, "TRIATEK, Inc." },
3633 { 61, "Multistack" },
3634 { 62, "TSI Incorporated" },
3635 { 63, "Weather-Rite, Inc." },
3636 { 64, "Dunham-Bush" },
3637 { 65, "Reliance Electric" },
3639 { 67, "Regulator Australia PTY Ltd." },
3640 { 68, "Touch-Plate Lighting Controls" },
3641 { 69, "Amann GmbH" },
3642 { 70, "RLE Technologies" },
3643 { 71, "Cardkey Systems" },
3644 { 72, "SECOM Co., Ltd." },
3645 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
3646 { 74, "KNX Association cvba" },
3647 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
3648 { 76, "Nohmi Bosai, Ltd." },
3649 { 77, "Carel S.p.A." },
3650 { 78, "AirSense Technology, Inc." },
3651 { 79, "Hochiki Corporation" },
3652 { 80, "Fr. Sauter AG" },
3653 { 81, "Matsushita Electric Works, Ltd." },
3654 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
3655 { 83, "Mitsubishi Heavy Industries, Ltd." },
3656 { 84, "ITT Bell & Gossett" },
3657 { 85, "Yamatake Building Systems Co., Ltd." },
3658 { 86, "The Watt Stopper, Inc." },
3659 { 87, "Aichi Tokei Denki Co., Ltd." },
3660 { 88, "Activation Technologies, LLC" },
3661 { 89, "Saia-Burgess Controls, Ltd." },
3662 { 90, "Hitachi, Ltd." },
3663 { 91, "Novar Corp./Trend Control Systems Ltd." },
3664 { 92, "Mitsubishi Electric Lighting Corporation" },
3665 { 93, "Argus Control Systems, Ltd." },
3666 { 94, "Kyuki Corporation" },
3667 { 95, "Richards-Zeta Building Intelligence, Inc." },
3668 { 96, "Scientech R&D, Inc." },
3669 { 97, "VCI Controls, Inc." },
3670 { 98, "Toshiba Corporation" },
3671 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
3672 { 100, "Custom Mechanical Equipment, LLC" },
3673 { 101, "ClimateMaster" },
3674 { 102, "ICP Panel-Tec, Inc." },
3675 { 103, "D-Tek Controls" },
3676 { 104, "NEC Engineering, Ltd." },
3677 { 105, "PRIVA BV" },
3678 { 106, "Meidensha Corporation" },
3679 { 107, "JCI Systems Integration Services" },
3680 { 108, "Freedom Corporation" },
3681 { 109, "Neuberger Gebaudeautomation GmbH" },
3682 { 110, "Sitronix" },
3683 { 111, "Leviton Manufacturing" },
3684 { 112, "Fujitsu Limited" },
3685 { 113, "Emerson Network Power" },
3686 { 114, "S. A. Armstrong, Ltd." },
3687 { 115, "Visonet AG" },
3688 { 116, "M&M Systems, Inc." },
3689 { 117, "Custom Software Engineering" },
3690 { 118, "Nittan Company, Limited" },
3691 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
3692 { 120, "Pacom Systems Pty., Ltd." },
3693 { 121, "Unico, Inc." },
3694 { 122, "Ebtron, Inc." },
3695 { 123, "Scada Engine" },
3696 { 124, "AC Technology Corporation" },
3697 { 125, "Eagle Technology" },
3698 { 126, "Data Aire, Inc." },
3699 { 127, "ABB, Inc." },
3700 { 128, "Transbit Sp. z o. o." },
3701 { 129, "Toshiba Carrier Corporation" },
3702 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
3703 { 131, "Tokai Soft" },
3705 { 133, "Veris Industries" },
3706 { 134, "Centaurus Prime" },
3707 { 135, "Sand Network Systems" },
3708 { 136, "Regulvar, Inc." },
3709 { 137, "Fastek International, Ltd." },
3710 { 138, "PowerCold Comfort Air Solutions, Inc." },
3711 { 139, "I Controls" },
3712 { 140, "Viconics Electronics, Inc." },
3713 { 141, "Yaskawa Electric America, Inc." },
3714 { 142, "Plueth Regelsysteme" },
3715 { 143, "Digitale Mess- und Steuersysteme AG" },
3716 { 144, "Fujitsu General Limited" },
3717 { 145, "Project Engineering S.r.l." },
3718 { 146, "Sanyo Electric Co., Ltd." },
3719 { 147, "Integrated Information Systems, Inc." },
3720 { 148, "Temco Controls, Ltd." },
3721 { 149, "Airtek Technologies, Inc." },
3722 { 150, "Advantech Corporation" },
3723 { 151, "Titan Products, Ltd." },
3724 { 152, "Regel Partners" },
3725 { 153, "National Environmental Product" },
3726 { 154, "Unitec Corporation" },
3727 { 155, "Kanden Engineering Company" },
3728 { 156, "Messner Gebaudetechnik GmbH" },
3729 { 157, "Integrated.CH" },
3730 { 158, "EH Price Limited" },
3731 { 159, "SE-Elektronic GmbH" },
3732 { 160, "Rockwell Automation" },
3733 { 161, "Enflex Corp." },
3734 { 162, "ASI Controls" },
3735 { 163, "SysMik GmbH Dresden" },
3736 { 164, "HSC Regelungstechnik GmbH" },
3737 { 165, "Smart Temp Australia Pty. Ltd." },
3738 { 166, "PCI Lighting Control Systems" },
3739 { 167, "Duksan Mecasys Co., Ltd." },
3740 { 168, "Fuji IT Co., Ltd." },
3741 { 169, "Vacon Plc" },
3742 { 170, "Leader Controls" },
3743 { 171, "Cylon Controls, Ltd." },
3745 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
3746 { 174, "Building Control Integrators" },
3747 { 175, "ITG Worldwide (M) Sdn Bhd" },
3748 { 176, "Lutron Electronics Co., Inc." },
3749 { 177, "Cooper-Atkins Corporation" },
3750 { 178, "LOYTEC Electronics GmbH" },
3752 { 180, "Mega Controls Limited" },
3753 { 181, "Micro Control Systems, Inc." },
3754 { 182, "Kiyon, Inc." },
3755 { 183, "Dust Networks" },
3756 { 184, "Advanced Building Automation Systems" },
3757 { 185, "Hermos AG" },
3760 { 188, "Lynxspring" },
3761 { 189, "Schneider Toshiba Inverter Europe" },
3762 { 190, "Danfoss Drives A/S" },
3763 { 191, "Eaton Corporation" },
3764 { 192, "Matyca S.A." },
3765 { 193, "Botech AB" },
3766 { 194, "Noveo, Inc." },
3768 { 196, "Yokogawa Electric Corporation" },
3769 { 197, "GFR Gesellschaft fur Regelungstechnik" },
3770 { 198, "Exact Logic" },
3771 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
3772 { 200, "Kandenko Co., Ltd." },
3773 { 201, "DTF, Daten-Technik Fries" },
3774 { 202, "Klimasoft, Ltd." },
3775 { 203, "Toshiba Schneider Inverter Corporation" },
3776 { 204, "Control Applications, Ltd." },
3777 { 205, "KDT Systems Co., Ltd." },
3778 { 206, "Onicon Incorporated" },
3779 { 207, "Automation Displays, Inc." },
3780 { 208, "Control Solutions, Inc." },
3781 { 209, "Remsdaq Limited" },
3782 { 210, "NTT Facilities, Inc." },
3783 { 211, "VIPA GmbH" },
3784 { 212, "TSC21 Association of Japan" },
3785 { 213, "BBP Energie Ltee" },
3786 { 214, "HRW Limited" },
3787 { 215, "Lighting Control & Design, Inc." },
3788 { 216, "Mercy Electronic and Electrical Industries" },
3789 { 217, "Samsung SDS Co., Ltd" },
3790 { 218, "Impact Facility Solutions, Inc." },
3791 { 219, "Aircuity" },
3792 { 220, "Control Techniques, Ltd." },
3793 { 221, "Evolve Control Systems, LLC" },
3794 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
3795 { 223, "Cerus Industrial" },
3796 { 224, "Chloride Power Protection Company" },
3797 { 225, "Computrols, Inc." },
3798 { 226, "Phoenix Contact GmbH & Co. KG" },
3799 { 227, "Grundfos Management A/S" },
3800 { 228, "Ridder Drive Systems" },
3801 { 229, "Soft Device SDN BHD" },
3802 { 230, "Integrated Control Technology Limited" },
3803 { 231, "AIRxpert Systems, Inc." },
3804 { 232, "Microtrol Limited" },
3805 { 233, "Red Lion Controls" },
3806 { 234, "Digital Electronics Corporation" },
3807 { 235, "Ennovatis GmbH" },
3808 { 236, "Serotonin Software Technologies, Inc." },
3809 { 237, "LS Industrial Systems Co., Ltd." },
3810 { 238, "Square D Company" },
3811 { 239, "S Squared Innovations, Inc." },
3812 { 240, "Aricent Ltd." },
3813 { 241, "EtherMetrics, LLC" },
3814 { 242, "Industrial Control Communications, Inc." },
3815 { 243, "Paragon Controls, Inc." },
3816 { 244, "A. O. Smith Corporation" },
3817 { 245, "Contemporary Control Systems, Inc." },
3818 { 246, "Intesis Software SL" },
3819 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
3820 { 248, "Heat-Timer Corporation" },
3821 { 249, "Ingrasys Technology, Inc." },
3822 { 250, "Costerm Building Automation" },
3824 { 252, "Embedia Technologies Corp." },
3825 { 253, "Technilog" },
3826 { 254, "HR Controls Ltd. & Co. KG" },
3827 { 255, "Lennox International, Inc." },
3828 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
3829 { 257, "Thermomax, Ltd." },
3830 { 258, "ELCON Electronic Control, Ltd." },
3831 { 259, "Larmia Control AB" },
3832 { 260, "BACnet Stack at SourceForge" },
3833 { 261, "G4S Security Services A/S" },
3834 { 262, "Sitek S.p.A." },
3835 { 263, "Cristal Controles" },
3836 { 264, "Regin AB" },
3837 { 265, "Dimension Software, Inc. " },
3838 { 266, "SynapSense Corporation" },
3839 { 267, "Beijing Nantree Electronic Co., Ltd." },
3840 { 268, "Camus Hydronics Ltd." },
3841 { 269, "Kawasaki Heavy Industries, Ltd. " },
3842 { 270, "Critical Environment Technologies" },
3843 { 271, "ILSHIN IBS Co., Ltd." },
3844 { 272, "ELESTA Energy Control AG" },
3845 { 273, "KROPMAN Installatietechniek" },
3846 { 274, "Baldor Electric Company" },
3847 { 275, "INGA mbH" },
3848 { 276, "GE Consumer & Industrial" },
3849 { 277, "Functional Devices, Inc." },
3851 { 279, "M-System Co., Ltd." },
3852 { 280, "Yokota Co., Ltd." },
3853 { 281, "Hitranse Technology Co., LTD" },
3854 { 282, "Federspiel Controls" },
3855 { 283, "Kele, Inc." },
3856 { 284, "Opera Electronics, Inc." },
3858 { 286, "Embedded Science Labs, LLC" },
3859 { 287, "Parker Hannifin Corporation" },
3860 { 288, "MaCaPS International Limited" },
3861 { 289, "Link4 Corporation" },
3862 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
3863 { 291, "Pribusin, Inc." },
3864 { 292, "Advantage Controls" },
3865 { 293, "Critical Room Control" },
3867 { 295, "Tongdy Control Technology Co., Ltd." },
3868 { 296, "ISSARO Integrierte Systemtechnik" },
3869 { 297, "Pro-Dev Industries" },
3870 { 298, "DRI-STEEM" },
3871 { 299, "Creative Electronic GmbH" },
3872 { 300, "Swegon AB" },
3873 { 301, "Jan Brachacek" },
3874 { 302, "Hitachi Appliances, Inc." },
3875 { 303, "Real Time Automation, Inc." },
3876 { 304, "ITEC Hankyu-Hanshin Co." },
3877 { 305, "Cyrus E&M Engineering Co., Ltd." },
3878 { 306, "Racine Federated, Inc." },
3879 { 307, "Verari Systems, Inc." },
3880 { 308, "Elesta GmbH Building Automation" },
3881 { 309, "Securiton" },
3882 { 310, "OSlsoft, Inc." },
3883 { 311, "Hanazeder Electronic GmbH" },
3884 { 312, "Honeywell Security Deutschland, Novar GmbH" },
3885 { 313, "Siemens Energy & Automation, Inc." },
3886 { 314, "ETM Professional Control GmbH" },
3887 { 315, "Meitav-tec, Ltd." },
3888 { 316, "Janitza Electronics GmbH" },
3889 { 317, "MKS Nordhausen" },
3890 { 318, "De Gier Drive Systems B.V." },
3891 { 319, "Cypress Envirosystems" },
3892 { 320, "SMARTron s.r.o." },
3893 { 321, "Verari Systems, Inc." },
3894 { 322, "K-W Electronic Service, Inc." },
3895 { 323, "ALFA-SMART Energy Management" },
3896 { 324, "Telkonet, Inc." },
3897 { 325, "Securiton GmbH" },
3898 { 326, "Cemtrex, Inc." },
3899 { 327, "Performance Technologies, Inc." },
3900 { 328, "Xtralis (Aust) Pty Ltd" },
3901 { 329, "TROX GmbH" },
3902 { 330, "Beijing Hysine Technology Co., Ltd" },
3903 { 331, "RCK Controls, Inc." },
3905 { 333, "Novar/Honeywell" },
3906 { 334, "The S4 Group, Inc." },
3907 { 335, "Schneider Electric" },
3908 { 336, "LHA Systems" },
3909 { 337, "GHM engineering Group, Inc." },
3910 { 338, "Cllimalux S.A." },
3911 { 339, "VAISALA Oyj" },
3912 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
3913 { 342, "POWERPEG NSI Limited" },
3914 { 343, "BACnet Interoperability Testing Services, Inc." },
3915 { 344, "Teco a.s." },
3919 static int proto_bacapp = -1;
3920 static int hf_bacapp_type = -1;
3921 static int hf_bacapp_pduflags = -1;
3922 static int hf_bacapp_SEG = -1;
3923 static int hf_bacapp_MOR = -1;
3924 static int hf_bacapp_SA = -1;
3925 static int hf_bacapp_response_segments = -1;
3926 static int hf_bacapp_max_adpu_size = -1;
3927 static int hf_bacapp_invoke_id = -1;
3928 static int hf_bacapp_objectType = -1;
3929 static int hf_bacapp_instanceNumber = -1;
3930 static int hf_bacapp_sequence_number = -1;
3931 static int hf_bacapp_window_size = -1;
3932 static int hf_bacapp_service = -1;
3933 static int hf_bacapp_NAK = -1;
3934 static int hf_bacapp_SRV = -1;
3935 static int hf_Device_Instance_Range_Low_Limit = -1;
3936 static int hf_Device_Instance_Range_High_Limit = -1;
3937 static int hf_BACnetRejectReason = -1;
3938 static int hf_BACnetAbortReason = -1;
3939 static int hf_BACnetApplicationTagNumber = -1;
3940 static int hf_BACnetContextTagNumber = -1;
3941 static int hf_BACnetExtendedTagNumber = -1;
3942 static int hf_BACnetNamedTag = -1;
3943 static int hf_BACnetTagClass = -1;
3944 static int hf_BACnetCharacterSet = -1;
3945 static int hf_bacapp_tag = -1;
3946 static int hf_bacapp_tag_lvt = -1;
3947 static int hf_bacapp_tag_value8 = -1;
3948 static int hf_bacapp_tag_value16 = -1;
3949 static int hf_bacapp_tag_value32 = -1;
3950 static int hf_bacapp_tag_ProcessId = -1;
3951 static int hf_bacapp_tag_initiatingObjectType = -1;
3952 static int hf_bacapp_vpart = -1;
3953 static int hf_bacapp_uservice = -1;
3954 static int hf_BACnetPropertyIdentifier = -1;
3955 static int hf_BACnetVendorIdentifier = -1;
3956 static int hf_BACnetRestartReason = -1;
3957 static int hf_bacapp_tag_IPV4 = -1;
3958 static int hf_bacapp_tag_IPV6 = -1;
3959 static int hf_bacapp_tag_PORT = -1;
3960 /* some more variables for segmented messages */
3961 static int hf_msg_fragments = -1;
3962 static int hf_msg_fragment = -1;
3963 static int hf_msg_fragment_overlap = -1;
3964 static int hf_msg_fragment_overlap_conflicts = -1;
3965 static int hf_msg_fragment_multiple_tails = -1;
3966 static int hf_msg_fragment_too_long_fragment = -1;
3967 static int hf_msg_fragment_error = -1;
3968 static int hf_msg_reassembled_in = -1;
3969 static int hf_msg_reassembled_length = -1;
3971 static gint ett_msg_fragment = -1;
3972 static gint ett_msg_fragments = -1;
3974 static gint ett_bacapp = -1;
3975 static gint ett_bacapp_control = -1;
3976 static gint ett_bacapp_tag = -1;
3977 static gint ett_bacapp_list = -1;
3978 static gint ett_bacapp_value = -1;
3980 static dissector_handle_t data_handle;
3981 static gint32 propertyIdentifier = -1;
3982 static gint32 propertyArrayIndex = -1;
3983 static guint32 object_type = 4096;
3985 static guint8 bacapp_flags = 0;
3986 static guint8 bacapp_seq = 0;
3988 /* Defined to allow vendor identifier registration of private transfer dissectors */
3989 static dissector_table_t bacapp_dissector_table;
3991 static const fragment_items msg_frag_items = {
3992 /* Fragment subtrees */
3995 /* Fragment fields */
3998 &hf_msg_fragment_overlap,
3999 &hf_msg_fragment_overlap_conflicts,
4000 &hf_msg_fragment_multiple_tails,
4001 &hf_msg_fragment_too_long_fragment,
4002 &hf_msg_fragment_error,
4003 /* Reassembled in field */
4004 &hf_msg_reassembled_in,
4005 /* Reassembled length field */
4006 &hf_msg_reassembled_length,
4011 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
4012 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
4015 fGetMaxAPDUSize(guint8 idx)
4017 /* only 16 values are defined, so use & 0x0f */
4018 /* check the size of the Array, deliver either the entry
4019 or the first entry if idx is outside of the array (bug 3736 comment#7) */
4020 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
4021 return MaxAPDUSize[0];
4023 return MaxAPDUSize[idx & 0x0f];
4026 /* Used when there are ranges of reserved and proprietary enumerations */
4028 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
4029 const char *fmt, const char *split_fmt)
4031 if (val < split_val)
4032 return val_to_str(val, vs, fmt);
4034 return val_to_str(val, vs, split_fmt);
4037 /* from clause 20.2.1.3.2 Constructed Data */
4038 /* returns true if the extended value is used */
4040 tag_is_extended_value(guint8 tag)
4042 return (tag & 0x07) == 5;
4046 tag_is_opening(guint8 tag)
4048 return (tag & 0x07) == 6;
4052 tag_is_closing(guint8 tag)
4054 return (tag & 0x07) == 7;
4057 /* from clause 20.2.1.1 Class
4058 class bit shall be one for context specific tags */
4059 /* returns true if the tag is context specific */
4061 tag_is_context_specific(guint8 tag)
4063 return (tag & 0x08) != 0;
4067 tag_is_extended_tag_number(guint8 tag)
4069 return ((tag & 0xF0) == 0xF0);
4073 object_id_type(guint32 object_identifier)
4075 return ((object_identifier >> 22) & 0x3FF);
4079 object_id_instance(guint32 object_identifier)
4081 return (object_identifier & 0x3FFFFF);
4085 fTagNo (tvbuff_t *tvb, guint offset)
4087 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
4091 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
4093 gboolean valid = TRUE;
4097 *val = tvb_get_guint8(tvb, offset);
4100 *val = tvb_get_ntohs(tvb, offset);
4103 *val = tvb_get_ntoh24(tvb, offset);
4106 *val = tvb_get_ntohl(tvb, offset);
4117 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4119 gboolean valid = FALSE;
4123 if (lvt && (lvt <= 8)) {
4125 data = tvb_get_guint8(tvb, offset);
4126 for (i = 0; i < lvt; i++) {
4127 data = tvb_get_guint8(tvb, offset+i);
4128 value = (value << 8) + data;
4136 /* BACnet Signed Value uses 2's complement notation, but with a twist:
4137 All signed integers shall be encoded in the smallest number of octets
4138 possible. That is, the first octet of any multi-octet encoded value
4139 shall not be X'00' if the most significant bit (bit 7) of the second
4140 octet is 0, and the first octet shall not be X'FF' if the most
4141 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
4143 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
4145 gboolean valid = FALSE;
4150 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
4151 if (lvt && (lvt <= 7)) {
4153 data = tvb_get_guint8(tvb, offset);
4154 if ((data & 0x80) != 0)
4155 value = (-1 << 8) | data;
4158 for (i = 1; i < lvt; i++) {
4159 data = tvb_get_guint8(tvb, offset+i);
4160 value = (value << 8) + data;
4169 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
4170 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
4175 guint lvt_len = 1; /* used for tree display of lvt */
4176 guint lvt_offset; /* used for tree display of lvt */
4178 proto_tree *subtree;
4180 lvt_offset = offset;
4181 tag = tvb_get_guint8(tvb, offset);
4184 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
4185 /* can mean open/close tag or length of 6/7 after the length is */
4186 /* computed below - store whole tag info, not just context bit. */
4187 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
4189 if (tag_is_extended_tag_number(tag)) {
4190 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
4192 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
4193 lvt_offset += tag_len;
4194 value = tvb_get_guint8(tvb, lvt_offset);
4196 if (value == 254) { /* length is encoded with 16 Bits */
4197 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
4200 } else if (value == 255) { /* length is encoded with 32 Bits */
4201 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
4209 if (tag_is_opening(tag))
4210 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
4211 else if (tag_is_closing(tag))
4212 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
4213 else if (tag_is_context_specific(tag)) {
4214 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4215 "Context Tag: %u, Length/Value/Type: %u",
4218 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
4219 "Application Tag: %s, Length/Value/Type: %u",
4221 BACnetApplicationTagNumber,
4222 ASHRAE_Reserved_Fmt),
4225 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4226 /* details if needed */
4227 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, FALSE);
4228 if (tag_is_extended_tag_number(tag)) {
4229 proto_tree_add_uint_format(subtree,
4230 hf_BACnetContextTagNumber,
4231 tvb, offset, 1, tag,
4232 "Extended Tag Number");
4233 proto_tree_add_item(subtree,
4234 hf_BACnetExtendedTagNumber,
4235 tvb, offset + 1, 1, FALSE);
4237 if (tag_is_context_specific(tag))
4238 proto_tree_add_item(subtree,
4239 hf_BACnetContextTagNumber,
4240 tvb, offset, 1, FALSE);
4242 proto_tree_add_item(subtree,
4243 hf_BACnetApplicationTagNumber,
4244 tvb, offset, 1, FALSE);
4246 if (tag_is_closing(tag) || tag_is_opening(tag))
4247 proto_tree_add_item(subtree,
4249 tvb, offset, 1, FALSE);
4250 else if (tag_is_extended_value(tag)) {
4251 proto_tree_add_item(subtree,
4253 tvb, offset, 1, FALSE);
4254 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4255 tvb, lvt_offset, lvt_len, *lvt);
4257 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
4258 tvb, lvt_offset, lvt_len, *lvt);
4265 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
4268 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
4272 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4274 guint8 tag_no, tag_info;
4277 proto_tree *subtree;
4279 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
4280 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4281 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4287 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4289 guint8 tag_no, tag_info;
4293 proto_tree *subtree;
4296 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4297 if (tag_info && lvt == 1)
4299 lvt = tvb_get_guint8(tvb, offset+1);
4303 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
4304 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
4305 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4306 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4308 return offset + bool_len;
4312 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4315 guint8 tag_no, tag_info;
4319 proto_tree *subtree;
4321 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4322 /* only support up to an 8 byte (64-bit) integer */
4323 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
4324 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4325 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
4327 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4328 "%s - %u octets (Unsigned)", label, lvt);
4329 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4330 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4332 return offset+tag_len+lvt;
4336 fDevice_Instance (tvbuff_t *tvb, proto_tree *tree, guint offset, int hf)
4338 guint8 tag_no, tag_info;
4342 proto_tree *subtree;
4344 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4345 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, lvt, TRUE);
4346 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4347 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4349 return offset+tag_len+lvt;
4352 /* set split_val to zero when not needed */
4354 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4355 const value_string *vs, guint32 split_val)
4358 guint8 tag_no, tag_info;
4362 proto_tree *subtree;
4364 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4365 /* only support up to a 4 byte (32-bit) enumeration */
4366 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
4368 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4369 "%s %s", label, val_to_split_str(val, split_val, vs,
4370 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
4372 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4373 "%s %u", label, val);
4375 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4376 "%s - %u octets (enumeration)", label, lvt);
4378 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4379 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4381 return offset+tag_len+lvt;
4385 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
4386 const value_string *vs)
4388 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
4392 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4395 guint8 tag_no, tag_info;
4399 proto_tree *subtree;
4401 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4402 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
4403 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4404 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
4406 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4407 "%s - %u octets (Signed)", label, lvt);
4408 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4409 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4411 return offset+tag_len+lvt;
4415 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4417 guint8 tag_no, tag_info;
4422 proto_tree *subtree;
4424 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4425 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
4426 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
4427 "%s%f (Real)", label, f_val);
4428 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4429 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4431 return offset+tag_len+4;
4435 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4437 guint8 tag_no, tag_info;
4442 proto_tree *subtree;
4444 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4445 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
4446 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
4447 "%s%f (Double)", label, d_val);
4448 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4449 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4451 return offset+tag_len+8;
4455 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
4457 guint32 val = 0, lvt;
4458 guint8 tag_no, tag_info;
4460 proto_tree *subtree;
4463 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4464 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4465 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
4466 tvb, offset, lvt+tag_len, val);
4468 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4469 "Process Identifier - %u octets (Signed)", lvt);
4470 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4471 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4472 offset += tag_len + lvt;
4478 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4480 guint32 val = 0, lvt;
4481 guint8 tag_no, tag_info;
4483 proto_tree *subtree;
4486 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4487 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
4488 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4489 "%s (hh.mm.ss): %d.%02d.%02d%s",
4491 (val / 3600), ((val % 3600) / 60), (val % 60),
4492 val == 0 ? " (indefinite)" : "");
4494 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4495 "%s - %u octets (Signed)", label, lvt);
4496 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4497 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4499 return offset+tag_len+lvt;
4503 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
4505 guint32 month, weekOfMonth, dayOfWeek;
4506 guint8 tag_no, tag_info;
4510 proto_tree *subtree;
4512 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4513 month = tvb_get_guint8(tvb, offset+tag_len);
4514 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
4515 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
4516 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
4517 val_to_str(month, months, "month (%d) not found"),
4518 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
4519 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
4520 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4521 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4523 return offset+tag_len+lvt;
4527 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4529 guint32 year, month, day, weekday;
4530 guint8 tag_no, tag_info;
4534 proto_tree *subtree;
4536 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4537 year = tvb_get_guint8(tvb, offset+tag_len);
4538 month = tvb_get_guint8(tvb, offset+tag_len+1);
4539 day = tvb_get_guint8(tvb, offset+tag_len+2);
4540 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
4541 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255))
4543 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4546 else if (year != 255)
4549 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4550 "%s%s %d, %d, (Day of Week = %s)",
4551 label, val_to_str(month,
4553 "month (%d) not found"),
4554 day, year, val_to_str(weekday,
4560 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4561 "%s%s %d, any year, (Day of Week = %s)",
4562 label, val_to_str(month, months, "month (%d) not found"),
4563 day, val_to_str(weekday, day_of_week, "(%d) not found"));
4565 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4566 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4568 return offset+tag_len+lvt;
4572 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4574 guint32 hour, minute, second, msec, lvt;
4575 guint8 tag_no, tag_info;
4578 proto_tree *subtree;
4580 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4581 hour = tvb_get_guint8(tvb, offset+tag_len);
4582 minute = tvb_get_guint8(tvb, offset+tag_len+1);
4583 second = tvb_get_guint8(tvb, offset+tag_len+2);
4584 msec = tvb_get_guint8(tvb, offset+tag_len+3);
4585 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
4586 ti = proto_tree_add_text(tree, tvb, offset,
4587 lvt+tag_len, "%sany", label);
4589 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
4590 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
4592 hour > 12 ? hour - 12 : hour,
4593 minute, second, msec,
4594 hour >= 12 ? "P.M." : "A.M.",
4595 hour, minute, second, msec);
4596 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4597 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4599 return offset+tag_len+lvt;
4603 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
4605 proto_tree *subtree = tree;
4608 if (label != NULL) {
4609 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
4610 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4612 offset = fDate (tvb,subtree,offset,"Date: ");
4613 return fTime (tvb,subtree,offset,"Time: ");
4617 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4619 guint lastoffset = 0;
4620 guint8 tag_no, tag_info;
4623 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4624 lastoffset = offset;
4625 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4626 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
4629 offset = fTime (tvb,tree,offset,"Time: ");
4630 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
4632 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
4638 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
4640 guint8 tag_no, tag_info;
4643 switch (fTagNo(tvb, offset)) {
4645 offset = fDate (tvb, tree, offset, "Date: ");
4647 case 1: /* dateRange */
4648 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4649 offset = fDateRange (tvb, tree, offset);
4650 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4652 case 2: /* BACnetWeekNDay */
4653 offset = fWeekNDay (tvb, tree, offset);
4662 static guint fTimeStamp (tvbuff_t *tvb, proto_tree *tree,
4663 guint offset, const gchar *label)
4665 guint8 tag_no = 0, tag_info = 0;
4668 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
4669 switch (fTagNo(tvb, offset)) {
4671 offset = fTime (tvb, tree, offset, label?label:"timestamp: ");
4673 case 1: /* sequenceNumber */
4674 offset = fUnsignedTag (tvb, tree, offset,
4675 label?label:"sequence Number: ");
4677 case 2: /* dateTime */
4678 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4679 offset = fDateTime (tvb, tree, offset, label?label:"timestamp: ");
4680 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4692 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4694 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4695 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
4700 static const value_string
4701 BACnetDaysOfWeek [] = {
4713 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4715 if (tvb_reported_length_remaining(tvb, offset) > 0) {
4716 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
4717 "valid Days: ", BACnetDaysOfWeek);
4718 offset = fTime (tvb,tree,offset,"from time: ");
4719 offset = fTime (tvb,tree,offset,"to time: ");
4720 offset = fRecipient (tvb,pinfo,tree,offset);
4721 offset = fProcessId (tvb,tree,offset);
4722 offset = fApplicationTypes (tvb,pinfo,tree,offset,
4723 "issue confirmed notifications: ");
4724 offset = fBitStringTagVS (tvb,tree,offset,
4725 "transitions: ", BACnetEventTransitionBits);
4732 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4735 guint start = offset;
4736 guint8 tag_no, tag_info;
4737 proto_tree* subtree = tree;
4740 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4744 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4745 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
4750 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4752 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4758 fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
4761 guint start = offset;
4762 guint8 tag_no, tag_info;
4763 proto_tree* subtree = tree;
4766 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4768 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
4772 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
4774 guint32 ip = tvb_get_ipv4(tvb, offset);
4775 guint16 port = tvb_get_ntohs(tvb, offset+4);
4777 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
4778 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
4781 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
4782 struct e_in6_addr addr;
4783 guint16 port = tvb_get_ntohs(tvb, offset+16);
4784 tvb_get_ipv6(tvb, offset, &addr);
4786 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
4787 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
4789 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
4790 tmp = tvb_bytes_to_str(tvb, offset, lvt);
4791 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
4798 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4800 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
4806 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
4808 guint8 tag_no, tag_info;
4812 offset = fUnsignedTag (tvb, tree, offset, "network-number");
4813 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4815 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
4818 offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
4824 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
4826 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
4827 return fAddress (tvb,tree,offset);
4831 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4833 guint8 tag_no, tag_info;
4837 proto_tree *subtree;
4840 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4841 object_id = tvb_get_ntohl(tvb,offset+tag_length);
4842 object_type = object_id_type(object_id);
4843 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
4844 "ObjectIdentifier: %s, %u",
4845 val_to_split_str(object_type,
4848 ASHRAE_Reserved_Fmt,
4849 Vendor_Proprietary_Fmt),
4850 object_id_instance(object_id));
4851 if (col_get_writable(pinfo->cinfo))
4852 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
4853 val_to_split_str(object_type,
4856 ASHRAE_Reserved_Fmt,
4857 Vendor_Proprietary_Fmt),
4858 object_id_instance(object_id));
4860 /* here are the details of how we arrived at the above text */
4861 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4862 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4863 offset += tag_length;
4864 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, FALSE);
4865 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, FALSE);
4872 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4874 guint8 tag_no, tag_info;
4877 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
4879 if (tag_no == 0) { /* device */
4880 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
4882 else { /* address */
4883 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4884 offset = fAddress (tvb, tree, offset);
4885 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4892 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4894 guint lastoffset = 0;
4895 guint8 tag_no, tag_info;
4897 proto_tree* orgtree = tree;
4899 proto_tree* subtree;
4901 /* beginning of new item - indent and label */
4902 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
4903 tree = proto_item_add_subtree(tt, ett_bacapp_value);
4905 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4906 lastoffset = offset;
4908 switch (fTagNo(tvb, offset)) {
4909 case 0: /* recipient */
4910 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
4911 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
4912 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4913 offset = fRecipient (tvb, pinfo, subtree, offset);
4914 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
4916 case 1: /* processId */
4917 offset = fProcessId (tvb, tree, offset);
4918 lastoffset = offset;
4923 if (offset == lastoffset) break; /* nothing happened, exit loop */
4929 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4931 guint lastoffset = 0, len;
4932 guint8 tag_no, tag_info;
4934 proto_tree* subtree;
4936 proto_tree* orgtree = tree;
4939 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
4940 lastoffset = offset;
4941 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4942 if (tag_is_closing(tag_info) ) {
4947 case 0: /* recipient */
4948 /* beginning of new item in list */
4949 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
4950 itemno = itemno + 1;
4951 tree = proto_item_add_subtree(tt, ett_bacapp_value);
4953 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
4954 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4955 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
4956 offset = fRecipientProcess (tvb, pinfo, subtree, offset);
4957 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
4958 subtree = tree; /* done with this level - return to previous tree */
4960 case 1: /* MonitoredPropertyReference */
4961 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
4962 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4963 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4964 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
4965 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4968 case 2: /* IssueConfirmedNotifications - boolean */
4969 offset = fBooleanTag (tvb, tree, offset, "Issue Confirmed Notifications: ");
4971 case 3: /* TimeRemaining */
4972 offset = fUnsignedTag (tvb, tree, offset, "Time Remaining: ");
4974 case 4: /* COVIncrement */
4975 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
4980 if (offset == lastoffset) break; /* nothing happened, exit loop */
4986 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
4988 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
4989 return fAddress (tvb, tree, offset);
4993 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
4995 guint lastoffset = 0, len;
4996 guint8 tag_no, tag_info;
4998 proto_tree *subtree = tree;
5000 /* set the optional global properties to indicate not-used */
5001 propertyArrayIndex = -1;
5002 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5003 lastoffset = offset;
5004 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5005 if (tag_is_closing(tag_info) ) {
5006 if (tag_no == tag_match) {
5015 case 0: /* deviceIdentifier */
5016 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5018 case 1: /* objectIdentifier */
5019 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5021 case 2: /* propertyIdentifier */
5022 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
5024 case 3: /* propertyArrayIndex */
5025 offset = fPropertyArrayIndex (tvb, subtree, offset);
5027 case 4: /* propertyValue */
5028 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
5030 case 5: /* priority */
5031 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
5033 case 6: /* postDelay */
5034 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
5036 case 7: /* quitOnFailure */
5037 offset = fBooleanTag(tvb, subtree, offset,
5038 "Quit On Failure: ");
5040 case 8: /* writeSuccessful */
5041 offset = fBooleanTag(tvb, subtree, offset,
5042 "Write Successful: ");
5047 if (offset == lastoffset) break; /* nothing happened, exit loop */
5052 /* BACnetActionList ::= SEQUENCE{
5053 action [0] SEQUENCE OF BACnetActionCommand
5057 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5059 guint lastoffset = 0, len;
5060 guint8 tag_no, tag_info;
5062 proto_tree *subtree = tree;
5065 while (tvb_reported_length_remaining(tvb, offset)) {
5066 lastoffset = offset;
5067 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5068 if (tag_is_closing(tag_info)) {
5073 if (tag_is_opening(tag_info)) {
5074 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
5075 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5076 offset += fTagHeaderTree (tvb, subtree, offset,
5077 &tag_no, &tag_info, &lvt);
5080 case 0: /* BACnetActionCommand */
5081 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
5086 if (offset == lastoffset) break; /* nothing happened, exit loop */
5092 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5094 guint8 tag_no, tag_info;
5098 proto_tree *subtree;
5099 const gchar *label = "Property Identifier";
5101 propertyIdentifier = 0; /* global Variable */
5102 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5103 /* can we decode this value? */
5104 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
5105 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5106 "%s: %s (%u)", label,
5107 val_to_split_str(propertyIdentifier, 512,
5108 BACnetPropertyIdentifier,
5109 ASHRAE_Reserved_Fmt,
5110 Vendor_Proprietary_Fmt), propertyIdentifier);
5111 if (col_get_writable(pinfo->cinfo))
5112 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
5113 val_to_split_str(propertyIdentifier, 512,
5114 BACnetPropertyIdentifier,
5115 ASHRAE_Reserved_Fmt,
5116 Vendor_Proprietary_Fmt));
5118 /* property identifiers cannot be larger than 22-bits */
5121 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5122 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5123 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
5124 offset+tag_len, lvt, FALSE);
5126 return offset+tag_len+lvt;
5130 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
5132 guint8 tag_no, tag_info;
5136 proto_tree *subtree;
5138 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5139 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
5140 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5141 "property Array Index (Unsigned) %u", propertyArrayIndex);
5143 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5144 "property Array Index - %u octets (Unsigned)", lvt);
5145 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5146 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5148 return offset+tag_len+lvt;
5152 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5154 guint8 tag_no, tag_info, character_set;
5156 gsize inbytesleft, outbytesleft = 512;
5157 guint offs, extra = 1;
5160 guint8 bf_arr[512], *out = &bf_arr[0];
5162 proto_tree *subtree;
5163 guint start = offset;
5165 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5167 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5169 character_set = tvb_get_guint8(tvb, offset+offs);
5170 /* Account for code page if DBCS */
5171 if (character_set == 1)
5175 offset += (offs+extra);
5179 inbytesleft = l = MIN(lvt, 255);
5181 * XXX - are we guaranteed that these encoding
5182 * names correspond, on *all* platforms with
5183 * iconv(), to the encodings we want?
5184 * If not (and perhaps even if so), we should
5185 * perhaps have our own iconv() implementation,
5186 * with a different name, so that we control the
5187 * encodings it supports and the names of those
5190 * We should also handle that in the general
5191 * string handling code, rather than making it
5192 * specific to the BACAPP dissector, as many
5193 * other dissectors need to handle various
5194 * character encodings.
5196 str_val = tvb_get_ephemeral_string(tvb, offset, l);
5197 /** this decoding may be not correct for multi-byte characters, Lka */
5198 switch (character_set) {
5200 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ANSI_X3.4");
5201 coding = "ANSI X3.4";
5205 coding = "IBM MS DBCS";
5209 coding = "JIS C 6226";
5211 case ISO_10646_UCS4:
5212 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
5213 coding = "ISO 10646 UCS-4";
5215 case ISO_10646_UCS2:
5216 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
5217 coding = "ISO 10646 UCS-2";
5220 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
5221 coding = "ISO 8859-1";
5228 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s'%s'", label, coding, out);
5233 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5235 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
5236 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, FALSE);
5238 if (character_set == 1)
5240 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
5247 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
5248 const value_string *src)
5250 guint8 tag_no, tag_info, tmp;
5251 gint j, unused, skip;
5252 guint start = offset;
5254 guint32 lvt, i, numberOfBytes;
5256 proto_tree* subtree = tree;
5259 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5260 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
5262 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
5263 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
5267 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5269 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
5270 proto_tree_add_text(subtree, tvb, offset, 1,
5274 for (i = 0; i < numberOfBytes; i++) {
5275 tmp = tvb_get_guint8(tvb, (offset)+i+1);
5276 if (i == numberOfBytes-1) { skip = unused; }
5277 for (j = 0; j < 8-skip; j++) {
5279 if (tmp & (1 << (7 - j)))
5280 proto_tree_add_text(subtree, tvb,
5283 val_to_str((guint) (i*8 +j),
5285 ASHRAE_Reserved_Fmt));
5287 proto_tree_add_text(subtree, tvb,
5290 val_to_str((guint) (i*8 +j),
5292 ASHRAE_Reserved_Fmt));
5294 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
5301 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
5302 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
5311 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5313 return fBitStringTagVS (tvb, tree, offset, label, NULL);
5316 /* handles generic application types, as well as enumerated and enumerations
5317 with reserved and proprietarty ranges (split) */
5319 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5320 const gchar *label, const value_string *src, guint32 split_val)
5322 guint8 tag_no, tag_info;
5326 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5328 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5329 if (!tag_is_context_specific(tag_info))
5332 case 0: /** NULL 20.2.2 */
5333 offset = fNullTag(tvb, tree, offset, label);
5335 case 1: /** BOOLEAN 20.2.3 */
5336 offset = fBooleanTag(tvb, tree, offset, label);
5338 case 2: /** Unsigned Integer 20.2.4 */
5339 offset = fUnsignedTag(tvb, tree, offset, label);
5341 case 3: /** Signed Integer 20.2.5 */
5342 offset = fSignedTag(tvb, tree, offset, label);
5344 case 4: /** Real 20.2.6 */
5345 offset = fRealTag(tvb, tree, offset, label);
5347 case 5: /** Double 20.2.7 */
5348 offset = fDoubleTag(tvb, tree, offset, label);
5350 case 6: /** Octet String 20.2.8 */
5351 offset = fOctetString (tvb, tree, offset, label, lvt);
5353 case 7: /** Character String 20.2.9 */
5354 offset = fCharacterString (tvb,tree,offset,label);
5356 case 8: /** Bit String 20.2.10 */
5357 offset = fBitStringTagVS (tvb, tree, offset, label, src);
5359 case 9: /** Enumerated 20.2.11 */
5360 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
5362 case 10: /** Date 20.2.12 */
5363 offset = fDate (tvb, tree, offset, label);
5365 case 11: /** Time 20.2.13 */
5366 offset = fTime (tvb, tree, offset, label);
5368 case 12: /** BACnetObjectIdentifier 20.2.14 */
5369 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5371 case 13: /* reserved for ASHRAE */
5374 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
5375 offset+=lvt+tag_len;
5387 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
5389 guint lastoffset = 0;
5391 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5392 lastoffset = offset;
5394 switch (fTagNo(tvb,offset)) {
5395 case 0: /* percent */
5396 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
5399 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
5401 case 2: /* amount */
5402 offset = fRealTag(tvb, tree, offset, "shed amount: ");
5407 if (offset == lastoffset) break; /* nothing happened, exit loop */
5413 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5414 const gchar *label, const value_string *vs)
5416 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
5420 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
5423 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
5427 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
5429 guint8 tag_no, tag_info;
5433 proto_tree *subtree;
5437 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
5438 /* cap the the suggested length in case of bad data */
5439 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
5440 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt))
5444 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
5445 "Context Value (as %u DATA octets)", lvt);
5447 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5448 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5450 return offset + tag_len + lvt;
5454 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5456 guint8 tag_no, tag_info;
5458 guint lastoffset = 0, depth = 0;
5461 if (propertyIdentifier >= 0)
5463 g_snprintf (ar, sizeof(ar), "%s: ",
5464 val_to_split_str(propertyIdentifier, 512,
5465 BACnetPropertyIdentifier,
5466 ASHRAE_Reserved_Fmt,
5467 Vendor_Proprietary_Fmt));
5471 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
5473 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5474 lastoffset = offset;
5475 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5476 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
5477 if (depth <= 0) return offset;
5480 /* Application Tags */
5481 switch (propertyIdentifier) {
5482 case 2: /* action */
5483 /* loop object is application tagged,
5484 command object is context tagged */
5485 if (tag_is_context_specific(tag_info)) {
5486 /* BACnetActionList */
5487 offset = fActionList (tvb, pinfo, tree,offset);
5490 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5494 case 30: /* BACnetAddressBinding */
5495 offset = fAddressBinding (tvb,pinfo,tree,offset);
5497 case 54: /* list of object property reference */
5498 offset = fLOPR (tvb, pinfo, tree,offset);
5500 case 55: /* list-of-session-keys */
5501 fSessionKey (tvb, tree, offset);
5503 case 79: /* object-type */
5504 case 96: /* protocol-object-types-supported */
5505 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
5506 BACnetObjectType, 128);
5508 case 97: /* Protocol-Services-Supported */
5509 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5510 BACnetServicesSupported);
5512 case 102: /* recipient-list */
5513 offset = fDestination (tvb, pinfo, tree, offset);
5515 case 107: /* segmentation-supported */
5516 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5517 BACnetSegmentation);
5519 case 111: /* Status-Flags */
5520 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5523 case 112: /* System-Status */
5524 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5525 BACnetDeviceStatus);
5527 case 117: /* units */
5528 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
5529 BACnetEngineeringUnits);
5531 case 87: /* priority-array -- accessed as a BACnetARRAY */
5532 if (propertyArrayIndex == 0) {
5533 /* BACnetARRAY index 0 refers to the length
5534 of the array, not the elements of the array */
5535 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5537 offset = fPriorityArray (tvb, pinfo, tree, offset);
5540 case 38: /* exception-schedule */
5541 if (object_type < 128)
5543 if (propertyArrayIndex == 0) {
5544 /* BACnetARRAY index 0 refers to the length
5545 of the array, not the elements of the array */
5546 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5548 offset = fSpecialEvent (tvb,pinfo,tree,offset);
5552 case 19: /* controlled-variable-reference */
5553 case 60: /* manipulated-variable-reference */
5554 case 109: /* Setpoint-Reference */
5555 case 132: /* log-device-object-property */
5556 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
5558 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
5559 if (object_type < 128)
5561 if (propertyArrayIndex == 0) {
5562 /* BACnetARRAY index 0 refers to the length
5563 of the array, not the elements of the array */
5564 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5566 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
5570 case 127: /* client COV increment */
5571 offset = fClientCOV (tvb, pinfo, tree, offset);
5573 case 131: /* log-buffer */
5574 offset = fLogRecord (tvb, pinfo, tree, offset);
5576 case 159: /* member-of */
5577 case 165: /* zone-members */
5578 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
5580 case 196: /* last-restart-reason */
5581 offset = fRestartReason (tvb, pinfo, tree, offset);
5583 case 212: /* actual-shed-level */
5584 case 214: /* expected-shed-level */
5585 case 218: /* requested-shed-level */
5586 offset = fShedLevel (tvb, tree, offset);
5588 case 152: /* active-cov-subscriptions */
5589 offset = fCOVSubscription (tvb, pinfo, tree, offset);
5594 if (tag_is_opening(tag_info))
5597 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5599 else if (tag_is_closing(tag_info))
5602 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
5606 offset = fContextTaggedValue(tvb, tree, offset, ar);
5611 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
5615 if (offset == lastoffset) break; /* nothing happened, exit loop */
5622 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
5627 if (tag_is_opening(tag_info)) {
5628 offset += fTagHeaderTree(tvb, tree, offset,
5629 &tag_no, &tag_info, &lvt);
5630 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
5631 if (tvb_length_remaining(tvb, offset) > 0) {
5632 offset += fTagHeaderTree(tvb, tree, offset,
5633 &tag_no, &tag_info, &lvt);
5636 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
5637 "expected Opening Tag!"); \
5638 offset = tvb_length(tvb);
5646 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
5648 guint lastoffset = offset;
5649 guint8 tag_no, tag_info;
5652 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
5653 if (offset > lastoffset)
5655 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5656 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
5657 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
5664 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5666 guint lastoffset = 0;
5667 guint8 tag_no, tag_info;
5670 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5671 lastoffset = offset;
5672 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
5673 if (offset > lastoffset)
5675 /* detect optional priority
5676 by looking to see if the next tag is context tag number 3 */
5677 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5678 if (tag_is_context_specific(tag_info) && (tag_no == 3))
5679 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
5681 if (offset == lastoffset) break; /* nothing happened, exit loop */
5687 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5689 guint lastoffset = 0, len;
5690 guint8 tag_no, tag_info;
5692 proto_tree *subtree = tree;
5695 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5696 lastoffset = offset;
5697 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5698 if (tag_is_closing(tag_info)) {
5705 case 0: /* ProcessId */
5706 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
5708 case 1: /* monitored ObjectId */
5709 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5711 case 2: /* issueConfirmedNotifications */
5712 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
5714 case 3: /* life time */
5715 offset = fTimeSpan (tvb,tree,offset,"life time");
5717 case 4: /* monitoredPropertyIdentifier */
5718 if (tag_is_opening(tag_info)) {
5719 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
5721 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5723 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5724 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
5729 case 5: /* covIncrement */
5730 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
5735 if (offset == lastoffset) break; /* nothing happened, exit loop */
5741 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5743 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
5747 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5749 guint lastoffset = 0;
5751 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5752 lastoffset = offset;
5754 switch (fTagNo(tvb, offset)) {
5755 case 0: /* deviceInstanceLowLimit */
5756 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
5758 case 1: /* deviceInstanceHighLimit */
5759 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
5761 case 2: /* BACnetObjectId */
5762 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5764 case 3: /* messageText */
5765 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
5770 if (offset == lastoffset) break; /* nothing happened, exit loop */
5777 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
5779 guint lastoffset = 0;
5780 guint8 tag_no, tag_info;
5783 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5784 if (tag_is_opening(tag_info) && tag_no == 0)
5786 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
5787 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5788 lastoffset = offset;
5789 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5790 if (tag_is_closing(tag_info)) {
5791 /* should be closing context tag 0 */
5792 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5796 offset = fTimeValue (tvb, pinfo, subtree, offset);
5797 if (offset == lastoffset) break; /* nothing happened, exit loop */
5800 else if (tag_no == 0 && lvt == 0)
5802 /* not sure null (empty array element) is legal */
5803 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5809 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5811 guint lastoffset = 0;
5812 guint8 tag_no, tag_info;
5814 guint i = 1; /* day of week array index */
5815 proto_tree *subtree = tree;
5818 if (propertyArrayIndex > 0) {
5819 /* BACnetARRAY index 0 refers to the length
5820 of the array, not the elements of the array.
5821 BACnetARRAY index -1 is our internal flag that
5822 the optional index was not used.
5823 BACnetARRAY refers to this as all elements of the array.
5824 If the optional index is specified for a BACnetARRAY,
5825 then that specific array element is referenced. */
5826 i = propertyArrayIndex;
5828 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5829 lastoffset = offset;
5830 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5831 if (tag_is_closing(tag_info)) {
5832 return offset; /* outer encoding will print out closing tag */
5834 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
5835 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5836 offset = fDailySchedule (tvb, pinfo, subtree, offset);
5837 if (offset == lastoffset) break; /* nothing happened, exit loop */
5844 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5846 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5849 return fDateTime (tvb, tree, offset, "UTC-Time: ");
5853 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5855 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5858 return fDateTime (tvb, tree, offset, NULL);
5862 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
5864 if (tvb_reported_length_remaining(tvb, offset) <= 0)
5866 offset = fDate (tvb,tree,offset,"Start Date: ");
5867 return fDate (tvb, tree, offset, "End Date: ");
5871 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5874 guint8 tag_no, tag_info;
5878 proto_tree *subtree;
5879 const gchar *label = "Vendor ID";
5881 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5882 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
5883 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5884 "%s: %s (%u)", label,
5885 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
5887 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5888 "%s - %u octets (Unsigned)", label, lvt);
5889 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5890 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5892 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
5893 proto_item *expert_item;
5894 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
5895 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
5896 PROTO_ITEM_SET_GENERATED(expert_item);
5897 return offset+tag_len+lvt;
5900 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
5901 offset+tag_len, lvt, FALSE);
5903 return offset+tag_len+lvt;
5907 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5910 guint8 tag_no, tag_info;
5914 proto_tree *subtree;
5915 const gchar *label = "Restart Reason";
5917 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5918 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
5919 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5920 "%s: %s (%u)", label,
5921 val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
5923 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5924 "%s - %u octets (Unsigned)", label, lvt);
5925 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5926 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5929 proto_item *expert_item;
5930 expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
5931 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
5932 PROTO_ITEM_SET_GENERATED(expert_item);
5933 return offset+tag_len+lvt;
5936 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
5937 offset+tag_len, lvt, FALSE);
5939 return offset+tag_len+lvt;
5943 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5945 guint lastoffset = 0;
5947 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
5948 lastoffset = offset;
5949 switch (fTagNo(tvb, offset)) {
5951 case 0: /* textMessageSourceDevice */
5952 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5954 case 1: /* messageClass */
5955 switch (fTagNo(tvb, offset)) {
5956 case 0: /* numeric */
5957 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
5959 case 1: /* character */
5960 offset = fCharacterString (tvb, tree, offset, "message Class: ");
5964 case 2: /* messagePriority */
5965 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
5966 BACnetMessagePriority);
5968 case 3: /* message */
5969 offset = fCharacterString (tvb, tree, offset, "message: ");
5974 if (offset == lastoffset) break; /* nothing happened, exit loop */
5980 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5982 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
5986 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5988 guint lastoffset = 0, len;
5989 guint8 tag_no, tag_info;
5991 proto_tree *subtree = tree;
5994 guint vendor_identifier = 0;
5995 guint service_number = 0;
5997 lastoffset = offset;
5998 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5999 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
6000 if (col_get_writable(pinfo->cinfo))
6001 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
6002 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6004 next_tvb = tvb_new_subset_remaining(tvb,offset);
6005 if (dissector_try_uint(bacapp_dissector_table,
6006 vendor_identifier, next_tvb, pinfo, tree))
6008 /* we parsed it so skip over length and we are done */
6009 offset += tvb_length(next_tvb);
6013 /* Not handled by vendor dissector */
6015 /* exit loop if nothing happens inside */
6016 while (tvb_reported_length_remaining(tvb, offset)) {
6017 lastoffset = offset;
6018 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6019 if (tag_is_closing(tag_info)) {
6020 if (tag_no == 2) /* Make sure it's the expected tag */
6028 break; /* End loop if incorrect closing tag */
6033 /* vendorID is now parsed above */
6034 case 1: /* serviceNumber */
6035 fUnsigned32(tvb, offset+len, lvt, &service_number);
6036 if (col_get_writable(pinfo->cinfo))
6037 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
6038 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
6040 case 2: /*serviceParameters */
6041 if (tag_is_opening(tag_info)) {
6042 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
6043 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6044 propertyIdentifier = -1;
6045 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6053 if (offset == lastoffset) break; /* nothing happened, exit loop */
6060 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6062 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
6066 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6068 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
6072 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6074 guint lastoffset = 0;
6075 guint8 tag_no, tag_info;
6077 proto_tree *subtree = tree;
6080 if (label != NULL) {
6081 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
6082 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6085 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6086 lastoffset = offset;
6087 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6090 case 0: /* subscriberProcessId */
6091 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
6093 case 1: /* requestingSource */
6094 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
6096 case 2: /* request */
6097 offset = fEnumeratedTagSplit (tvb, tree, offset,
6098 "request: ", BACnetLifeSafetyOperation, 64);
6100 case 3: /* objectId */
6101 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6106 if (offset == lastoffset) break; /* nothing happened, exit loop */
6112 fBACnetPropertyStates(tvbuff_t *tvb, proto_tree *tree, guint offset)
6114 switch (fTagNo(tvb, offset))
6117 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6120 offset = fEnumeratedTagSplit (tvb, tree, offset,
6121 "binary-value: ", BACnetBinaryPV, 2);
6124 offset = fEnumeratedTagSplit (tvb, tree, offset,
6125 "event-type: ", BACnetEventType, 12);
6128 offset = fEnumeratedTagSplit (tvb, tree, offset,
6129 "polarity: ", BACnetPolarity, 2);
6132 offset = fEnumeratedTagSplit (tvb, tree, offset,
6133 "program-change: ", BACnetProgramRequest, 5);
6136 offset = fEnumeratedTagSplit (tvb, tree, offset,
6137 "program-state: ", BACnetProgramState, 5);
6140 offset = fEnumeratedTagSplit (tvb, tree, offset,
6141 "reason-for-halt: ", BACnetProgramError, 5);
6144 offset = fEnumeratedTagSplit (tvb, tree, offset,
6145 "reliability: ", BACnetReliability, 10);
6148 offset = fEnumeratedTagSplit (tvb, tree, offset,
6149 "state: ", BACnetEventState, 64);
6152 offset = fEnumeratedTagSplit (tvb, tree, offset,
6153 "system-status: ", BACnetDeviceStatus, 64);
6156 offset = fEnumeratedTagSplit (tvb, tree, offset,
6157 "units: ", BACnetEngineeringUnits, 2);
6160 offset = fUnsignedTag(tvb, tree, offset, "unsigned-value: ");
6163 offset = fEnumeratedTagSplit (tvb, tree, offset,
6164 "life-safety-mode: ", BACnetLifeSafetyMode, 64);
6167 offset = fEnumeratedTagSplit (tvb, tree, offset,
6168 "life-safety-state: ", BACnetLifeSafetyState, 64);
6178 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
6179 deviceIdentifier [0] BACnetObjectIdentifier,
6180 objectIdentifier [1] BACnetObjectIdentifier,
6181 propertyIdentifier [2] BACnetPropertyIdentifier,
6182 arrayIndex [3] Unsigned OPTIONAL,
6183 value [4] ABSTRACT-SYNTAX.&Type
6187 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6189 guint lastoffset = 0;
6190 guint8 tag_no, tag_info;
6193 while (tvb_reported_length_remaining(tvb, offset)) {
6194 lastoffset = offset;
6195 /* check the tag. A closing tag means we are done */
6196 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6197 if (tag_is_closing(tag_info)) {
6201 case 0: /* deviceIdentifier */
6202 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6204 case 1: /* objectIdentifier */
6205 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6207 case 2: /* propertyIdentifier */
6208 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6210 case 3: /* arrayIndex - OPTIONAL */
6211 offset = fUnsignedTag (tvb, tree, offset,
6215 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6216 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6217 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6222 if (offset == lastoffset) break; /* nothing happened, exit loop */
6229 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
6230 objectIdentifier [0] BACnetObjectIdentifier,
6231 propertyIdentifier [1] BACnetPropertyIdentifier,
6232 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
6233 -- if omitted with an array then
6234 -- the entire array is referenced
6235 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
6239 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6241 guint lastoffset = 0;
6242 guint8 tag_no, tag_info;
6245 while (tvb_reported_length_remaining(tvb, offset)) {
6246 lastoffset = offset;
6247 /* check the tag. A closing tag means we are done */
6248 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6249 if (tag_is_closing(tag_info)) {
6253 case 0: /* objectIdentifier */
6254 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6256 case 1: /* propertyIdentifier */
6257 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
6259 case 2: /* arrayIndex - OPTIONAL */
6260 offset = fUnsignedTag (tvb, tree, offset,
6263 case 3: /* deviceIdentifier - OPTIONAL */
6264 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6269 if (offset == lastoffset) break; /* nothing happened, exit loop */
6275 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6277 guint lastoffset = offset;
6278 guint8 tag_no, tag_info;
6280 proto_tree *subtree = tree;
6283 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6284 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
6285 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
6286 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6287 /* Opening tag for parameter choice */
6288 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6291 case 0: /* change-of-bitstring */
6292 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6293 lastoffset = offset;
6294 switch (fTagNo(tvb, offset)) {
6296 offset = fBitStringTag (tvb, subtree, offset,
6297 "referenced-bitstring: ");
6300 offset = fBitStringTagVS (tvb, subtree, offset,
6301 "status-flags: ", BACnetStatusFlags);
6302 lastoffset = offset;
6307 if (offset == lastoffset) break; /* nothing happened, exit loop */
6310 case 1: /* change-of-state */
6311 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6312 lastoffset = offset;
6313 switch (fTagNo(tvb, offset)) {
6315 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6316 offset = fBACnetPropertyStates(tvb, subtree, offset);
6317 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6320 offset = fBitStringTagVS (tvb, subtree, offset,
6321 "status-flags: ", BACnetStatusFlags);
6322 lastoffset = offset;
6327 if (offset == lastoffset) break; /* nothing happened, exit loop */
6330 case 2: /* change-of-value */
6331 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6332 lastoffset = offset;
6333 switch (fTagNo(tvb, offset)) {
6335 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6336 switch (fTagNo(tvb, offset)) {
6338 offset = fBitStringTag (tvb, subtree, offset,
6342 offset = fRealTag (tvb, subtree, offset,
6348 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6351 offset = fBitStringTagVS (tvb, subtree, offset,
6352 "status-flags: ", BACnetStatusFlags);
6353 lastoffset = offset;
6358 if (offset == lastoffset) break; /* nothing happened, exit loop */
6361 case 3: /* command-failure */
6362 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6363 lastoffset = offset;
6364 switch (fTagNo(tvb, offset)) {
6365 case 0: /* "command-value: " */
6366 /* from BACnet Table 13-3,
6367 Standard Object Property Values Returned in Notifications */
6368 propertyIdentifier = 85; /* PRESENT_VALUE */
6369 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6370 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6371 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6374 offset = fBitStringTagVS (tvb, subtree, offset,
6375 "status-flags: ", BACnetStatusFlags);
6377 case 2: /* "feedback-value: " */
6378 propertyIdentifier = 40; /* FEEDBACK_VALUE */
6379 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6380 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
6381 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6382 lastoffset = offset;
6387 if (offset == lastoffset) break; /* nothing happened, exit loop */
6390 case 4: /* floating-limit */
6391 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6392 lastoffset = offset;
6393 switch (fTagNo(tvb, offset)) {
6395 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
6398 offset = fBitStringTagVS (tvb, subtree, offset,
6399 "status-flags: ", BACnetStatusFlags);
6402 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
6405 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
6406 lastoffset = offset;
6411 if (offset == lastoffset) break; /* nothing happened, exit loop */
6414 case 5: /* out-of-range */
6415 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6416 lastoffset = offset;
6417 switch (fTagNo(tvb, offset)) {
6419 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
6422 offset = fBitStringTagVS (tvb, subtree, offset,
6423 "status-flags: ", BACnetStatusFlags);
6426 offset = fRealTag (tvb, subtree, offset, "deadband: ");
6429 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
6430 lastoffset = offset;
6435 if (offset == lastoffset) break; /* nothing happened, exit loop */
6439 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6440 lastoffset = offset;
6441 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
6442 if (offset == lastoffset) break; /* nothing happened, exit loop */
6445 case 7: /* buffer-ready */
6446 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6447 lastoffset = offset;
6448 switch (fTagNo(tvb, offset)) {
6450 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
6453 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
6456 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6457 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
6458 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6461 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6462 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
6463 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6464 lastoffset = offset;
6469 if (offset == lastoffset) break; /* nothing happened, exit loop */
6472 case 8: /* change-of-life-safety */
6473 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6474 lastoffset = offset;
6475 switch (fTagNo(tvb, offset)) {
6477 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6478 "new-state: ", BACnetLifeSafetyState, 256);
6481 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6482 "new-mode: ", BACnetLifeSafetyMode, 256);
6485 offset = fBitStringTagVS (tvb, subtree, offset,
6486 "status-flags: ", BACnetStatusFlags);
6489 offset = fEnumeratedTagSplit (tvb, subtree, offset,
6490 "operation-expected: ", BACnetLifeSafetyOperation, 64);
6491 lastoffset = offset;
6496 if (offset == lastoffset) break; /* nothing happened, exit loop */
6499 case 9: /* extended */
6500 while (tvb_reported_length_remaining(tvb, offset)) {
6501 lastoffset = offset;
6502 switch (fTagNo(tvb, offset)) {
6504 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
6507 offset = fUnsignedTag (tvb, subtree, offset,
6508 "extended-event-type: ");
6510 case 2: /* parameters */
6511 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6512 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
6513 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
6514 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6515 lastoffset = offset;
6520 if (offset == lastoffset) break; /* nothing happened, exit loop */
6523 case 10: /* buffer ready */
6524 while (tvb_reported_length_remaining(tvb, offset)) {
6525 lastoffset = offset;
6526 switch (fTagNo(tvb, offset)) {
6527 case 0: /* buffer-property */
6528 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6529 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
6530 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6533 offset = fUnsignedTag (tvb, subtree, offset,
6534 "previous-notification: ");
6537 offset = fUnsignedTag (tvb, subtree, offset,
6538 "current-notification: ");
6539 lastoffset = offset;
6544 if (offset == lastoffset) break; /* nothing happened, exit loop */
6547 case 11: /* unsigned range */
6548 while (tvb_reported_length_remaining(tvb, offset)) {
6549 lastoffset = offset;
6550 switch (fTagNo(tvb, offset)) {
6552 offset = fUnsignedTag (tvb, subtree, offset,
6553 "exceeding-value: ");
6556 offset = fBitStringTagVS (tvb, subtree, offset,
6557 "status-flags: ", BACnetStatusFlags);
6560 offset = fUnsignedTag (tvb, subtree, offset,
6561 "exceeded-limit: ");
6562 lastoffset = offset;
6567 if (offset == lastoffset) break; /* nothing happened, exit loop */
6574 /* Closing tag for parameter choice */
6575 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6582 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset)
6584 guint lastoffset = 0;
6586 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6587 lastoffset = offset;
6588 switch (fTagNo(tvb, offset)) {
6589 case 0: /* change-of-bitstring */
6590 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6591 lastoffset = offset;
6592 switch (fTagNo(tvb, offset)) {
6594 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6597 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6599 case 2: /* SEQUENCE OF BIT STRING */
6600 offset = fBitStringTagVS (tvb, tree, offset,
6601 "bitstring value: ", BACnetEventTransitionBits);
6608 case 1: /* change-of-state */
6609 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6610 lastoffset = offset;
6611 switch (fTagNo(tvb, offset)) {
6613 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6615 case 1: /* SEQUENCE OF BACnetPropertyStates */
6616 offset = fEnumeratedTagSplit (tvb, tree, offset,
6617 "value: ", BACnetPropertyStates, 64);
6624 case 2: /* change-of-value */
6625 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6626 lastoffset = offset;
6627 switch (fTagNo(tvb, offset)) {
6629 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6631 case 1: /* don't loop it, it's a CHOICE */
6632 switch (fTagNo(tvb, offset)) {
6634 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
6637 offset = fRealTag (tvb, tree, offset,
6638 "referenced Property Increment: ");
6648 case 3: /* command-failure */
6649 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6650 lastoffset = offset;
6651 switch (fTagNo(tvb, offset)) {
6653 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6656 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6662 case 4: /* floating-limit */
6663 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6664 lastoffset = offset;
6665 switch (fTagNo(tvb, offset)) {
6667 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6670 offset = fDeviceObjectPropertyReference (tvb,pinfo,tree,offset);
6673 offset = fRealTag (tvb, tree, offset, "low diff limit: ");
6676 offset = fRealTag (tvb, tree, offset, "high diff limit: ");
6679 offset = fRealTag (tvb, tree, offset, "deadband: ");
6686 case 5: /* out-of-range */
6687 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6688 lastoffset = offset;
6689 switch (fTagNo(tvb, offset)) {
6691 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6694 offset = fRealTag (tvb, tree, offset, "low limit: ");
6697 offset = fRealTag (tvb, tree, offset, "high limit: ");
6700 offset = fRealTag (tvb, tree, offset, "deadband: ");
6708 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
6710 case 7: /* buffer-ready */
6711 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6712 lastoffset = offset;
6713 switch (fTagNo(tvb, offset)) {
6715 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
6718 offset = fUnsignedTag (tvb,tree,offset,
6719 "previous notification count: ");
6726 case 8: /* change-of-life-safety */
6727 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6728 lastoffset = offset;
6729 switch (fTagNo(tvb, offset)) {
6731 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
6734 offset = fEnumeratedTagSplit (tvb, tree, offset,
6735 "life safety alarm value: ", BACnetLifeSafetyState, 256);
6738 offset = fEnumeratedTagSplit (tvb, tree, offset,
6739 "alarm value: ", BACnetLifeSafetyState, 256);
6742 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6758 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6760 guint lastoffset = 0;
6761 guint8 tag_no, tag_info;
6764 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6765 lastoffset = offset;
6766 switch (fTagNo(tvb, offset)) {
6767 case 0: /* timestamp */
6768 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6769 offset = fDate (tvb,tree,offset,"Date: ");
6770 offset = fTime (tvb,tree,offset,"Time: ");
6771 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6773 case 1: /* logDatum: don't loop, it's a CHOICE */
6774 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6775 switch (fTagNo(tvb, offset)) {
6776 case 0: /* logStatus */
6777 offset = fEnumeratedTag (tvb, tree, offset,
6778 "log status: ", BACnetLogStatus);
6781 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
6784 offset = fRealTag (tvb, tree, offset, "real value: ");
6787 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
6790 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
6793 offset = fSignedTag (tvb, tree, offset, "signed value: ");
6796 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
6799 offset = fNullTag(tvb, tree, offset, "null value: ");
6802 offset = fError (tvb, pinfo, tree, offset);
6805 offset = fRealTag (tvb, tree, offset, "time change: ");
6807 case 10: /* any Value */
6808 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6809 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6810 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6815 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6818 offset = fEnumeratedTag (tvb, tree, offset,
6819 "Status Flags: ", BACnetStatusFlags);
6824 if (offset == lastoffset) break; /* nothing happened, exit loop */
6831 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6833 guint lastoffset = 0;
6834 guint8 tag_no, tag_info;
6837 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6838 lastoffset = offset;
6840 switch (fTagNo(tvb,offset)) {
6841 case 0: /* ProcessId */
6842 offset = fProcessId (tvb,tree,offset);
6844 case 1: /* initiating ObjectId */
6845 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6847 case 2: /* event ObjectId */
6848 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6850 case 3: /* time stamp */
6851 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6852 offset = fTimeStamp (tvb, tree, offset, NULL);
6853 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6855 case 4: /* notificationClass */
6856 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
6858 case 5: /* Priority */
6859 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
6861 case 6: /* EventType */
6862 offset = fEnumeratedTagSplit (tvb, tree, offset,
6863 "Event Type: ", BACnetEventType, 64);
6865 case 7: /* messageText */
6866 offset = fCharacterString (tvb, tree, offset, "message Text: ");
6868 case 8: /* NotifyType */
6869 offset = fEnumeratedTag (tvb, tree, offset,
6870 "Notify Type: ", BACnetNotifyType);
6872 case 9: /* ackRequired */
6873 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
6875 case 10: /* fromState */
6876 offset = fEnumeratedTagSplit (tvb, tree, offset,
6877 "from State: ", BACnetEventState, 64);
6879 case 11: /* toState */
6880 offset = fEnumeratedTagSplit (tvb, tree, offset,
6881 "to State: ", BACnetEventState, 64);
6883 case 12: /* NotificationParameters */
6884 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6885 offset = fNotificationParameters (tvb, pinfo, tree, offset);
6886 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
6891 if (offset == lastoffset) break; /* nothing happened, exit loop */
6897 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6899 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
6903 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6905 guint lastoffset = 0, len;
6906 guint8 tag_no, tag_info;
6908 proto_tree *subtree = tree;
6911 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6912 lastoffset = offset;
6913 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
6914 if (tag_is_closing(tag_info)) {
6921 case 0: /* ProcessId */
6922 offset = fProcessId (tvb,tree,offset);
6924 case 1: /* initiating DeviceId */
6925 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6927 case 2: /* monitored ObjectId */
6928 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
6930 case 3: /* time remaining */
6931 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
6933 case 4: /* List of Values */
6934 if (tag_is_opening(tag_info)) {
6935 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
6936 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6937 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
6938 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
6946 if (offset == lastoffset) break; /* nothing happened, exit loop */
6952 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6954 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
6958 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6960 guint lastoffset = 0;
6961 guint8 tag_no = 0, tag_info = 0;
6964 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
6965 lastoffset = offset;
6966 switch (fTagNo(tvb, offset)) {
6967 case 0: /* acknowledgingProcessId */
6968 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
6970 case 1: /* eventObjectId */
6971 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6973 case 2: /* eventStateAcknowledged */
6974 offset = fEnumeratedTagSplit (tvb, tree, offset,
6975 "event State Acknowledged: ", BACnetEventState, 64);
6977 case 3: /* timeStamp */
6978 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6979 offset = fTimeStamp(tvb, tree, offset, NULL);
6980 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6982 case 4: /* acknowledgementSource */
6983 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
6985 case 5: /* timeOfAcknowledgement */
6986 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6987 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
6988 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6993 if (offset == lastoffset) break; /* nothing happened, exit loop */
6999 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7001 guint lastoffset = 0;
7003 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7004 lastoffset = offset;
7005 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
7006 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
7007 "alarm State: ", BACnetEventState, 64);
7008 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7009 "acknowledged Transitions: ", BACnetEventTransitionBits);
7010 if (offset == lastoffset) break; /* nothing happened, exit loop */
7016 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7018 guint lastoffset = 0;
7019 guint8 tag_no, tag_info;
7022 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7023 lastoffset = offset;
7024 switch (fTagNo(tvb, offset)) {
7025 case 0: /* acknowledgmentFilter */
7026 offset = fEnumeratedTag (tvb, tree, offset,
7027 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
7029 case 1: /* eventObjectId - OPTIONAL */
7030 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7031 offset = fRecipientProcess (tvb, pinfo, tree, offset);
7032 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7034 case 2: /* eventStateFilter */
7035 offset = fEnumeratedTag (tvb, tree, offset,
7036 "event State Filter: ", BACnetEventStateFilter);
7038 case 3: /* eventTypeFilter - OPTIONAL */
7039 offset = fEnumeratedTag (tvb, tree, offset,
7040 "event Type Filter: ", BACnetEventType);
7042 case 4: /* priorityFilter */
7043 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7044 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
7045 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
7046 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7048 case 5: /* notificationClassFilter - OPTIONAL */
7049 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
7054 if (offset == lastoffset) break; /* nothing happened, exit loop */
7060 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7062 guint lastoffset = 0;
7064 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7065 lastoffset = offset;
7066 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
7067 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
7068 "event Type: ", BACnetEventType, 64);
7069 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7070 "event State: ", BACnetEventState);
7071 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
7072 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
7073 if (offset == lastoffset) break; /* nothing happened, exit loop */
7080 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7082 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7083 if (fTagNo(tvb, offset) == 0) {
7084 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7091 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7093 guint lastoffset = 0;
7094 guint8 tag_no, tag_info;
7096 proto_tree* subtree = tree;
7099 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7100 lastoffset = offset;
7101 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7102 /* we are finished here if we spot a closing tag */
7103 if (tag_is_closing(tag_info)) {
7107 case 0: /* ObjectId */
7108 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7110 case 1: /* eventState */
7111 offset = fEnumeratedTag (tvb, tree, offset,
7112 "event State: ", BACnetEventState);
7114 case 2: /* acknowledgedTransitions */
7115 offset = fBitStringTagVS (tvb, tree, offset,
7116 "acknowledged Transitions: ", BACnetEventTransitionBits);
7118 case 3: /* eventTimeStamps */
7119 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
7121 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7123 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7124 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
7125 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
7126 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
7127 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7129 case 4: /* notifyType */
7130 offset = fEnumeratedTag (tvb, tree, offset,
7131 "Notify Type: ", BACnetNotifyType);
7133 case 5: /* eventEnable */
7134 offset = fBitStringTagVS (tvb, tree, offset,
7135 "event Enable: ", BACnetEventTransitionBits);
7137 case 6: /* eventPriorities */
7138 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
7140 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7142 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7143 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
7144 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
7145 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
7146 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7151 if (offset == lastoffset) break; /* nothing happened, exit loop */
7157 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7159 guint lastoffset = 0;
7160 guint8 tag_no, tag_info;
7163 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7164 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7165 lastoffset = offset;
7166 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7167 /* we are finished here if we spot a closing tag */
7168 if (tag_is_closing(tag_info)) {
7171 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7172 if (offset == lastoffset) break; /* nothing happened, exit loop */
7178 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7180 guint lastoffset = 0;
7181 guint8 tag_no, tag_info;
7184 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7185 lastoffset = offset;
7186 switch (fTagNo(tvb, offset)) {
7187 case 0: /* listOfEventSummaries */
7188 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7189 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
7190 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7192 case 1: /* moreEvents */
7193 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
7198 if (offset == lastoffset) break; /* nothing happened, exit loop */
7204 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7206 guint lastoffset = 0, len;
7207 guint8 tag_no, tag_info;
7209 proto_tree *subtree = tree;
7212 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7214 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7215 lastoffset = offset;
7216 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7217 if (tag_is_closing(tag_info)) {
7224 case 0: /* ObjectId */
7225 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
7227 case 3: /* listOfElements */
7228 if (tag_is_opening(tag_info)) {
7229 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
7230 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7231 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7232 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7240 if (offset == lastoffset) break; /* nothing happened, exit loop */
7246 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7248 return fObjectIdentifier (tvb, pinfo, tree, offset);
7252 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7254 guint lastoffset = 0;
7256 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7257 lastoffset = offset;
7259 switch (fTagNo(tvb, offset)) {
7260 case 0: /* timeDuration */
7261 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
7263 case 1: /* enable-disable */
7264 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
7265 BACnetEnableDisable);
7267 case 2: /* password - OPTIONAL */
7268 offset = fCharacterString (tvb, tree, offset, "Password: ");
7273 if (offset == lastoffset) break; /* nothing happened, exit loop */
7279 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
7281 guint lastoffset = 0;
7283 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7284 lastoffset = offset;
7286 switch (fTagNo(tvb, offset)) {
7287 case 0: /* reinitializedStateOfDevice */
7288 offset = fEnumeratedTag (tvb, tree, offset,
7289 "reinitialized State Of Device: ",
7290 BACnetReinitializedStateOfDevice);
7292 case 1: /* password - OPTIONAL */
7293 offset = fCharacterString (tvb, tree, offset, "Password: ");
7298 if (offset == lastoffset) break; /* nothing happened, exit loop */
7304 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7306 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
7307 "vtClass: ", BACnetVTClass);
7308 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
7312 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7314 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7318 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7320 guint lastoffset = 0;
7322 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7323 lastoffset = offset;
7324 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
7325 if (offset == lastoffset) break; /* nothing happened, exit loop */
7331 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7333 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
7334 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
7335 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
7339 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
7341 guint lastoffset = 0;
7343 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7344 lastoffset = offset;
7346 switch (fTagNo(tvb,offset)) {
7347 case 0: /* BOOLEAN */
7348 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
7350 case 1: /* Unsigned OPTIONAL */
7351 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
7356 if (offset == lastoffset) break; /* nothing happened, exit loop */
7362 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
7364 guint lastoffset = 0;
7366 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7367 lastoffset = offset;
7369 switch (fTagNo(tvb,offset)) {
7370 case 0: /* Unsigned32 */
7371 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
7373 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
7374 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
7376 case 2: /* Chararacter String OPTIONAL */
7377 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
7379 case 3: /* Chararacter String OPTIONAL */
7380 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
7382 case 4: /* Boolean OPTIONAL */
7383 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
7388 if (offset == lastoffset) break; /* nothing happened, exit loop */
7394 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7396 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
7400 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7402 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
7403 offset = fAddress (tvb, tree, offset);
7404 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
7405 return fAddress (tvb, tree, offset);
7409 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7411 /* Same as AddListElement request after service choice */
7412 return fAddListElementRequest(tvb, pinfo, tree, offset);
7416 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7418 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
7422 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7424 guint lastoffset = 0, len;
7425 guint8 tag_no, tag_info;
7427 proto_tree *subtree = tree;
7429 /* set the optional global properties to indicate not-used */
7430 propertyArrayIndex = -1;
7431 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7432 lastoffset = offset;
7433 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7434 if (tag_is_closing(tag_info)) {
7440 case 0: /* objectIdentifier */
7441 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7443 case 1: /* propertyIdentifier */
7444 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7446 case 2: /* propertyArrayIndex */
7447 offset = fPropertyArrayIndex (tvb, subtree, offset);
7449 case 3: /* propertyValue */
7450 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7455 if (offset == lastoffset) break; /* nothing happened, exit loop */
7461 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7463 guint lastoffset = 0;
7464 guint8 tag_no, tag_info;
7466 proto_tree *subtree = tree;
7468 /* set the optional global properties to indicate not-used */
7469 propertyArrayIndex = -1;
7470 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7471 lastoffset = offset;
7472 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7473 /* quit loop if we spot a closing tag */
7474 if (tag_is_closing(tag_info)) {
7480 case 0: /* objectIdentifier */
7481 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7483 case 1: /* propertyIdentifier */
7484 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7486 case 2: /* propertyArrayIndex */
7487 offset = fPropertyArrayIndex (tvb, subtree, offset);
7489 case 3: /* propertyValue */
7490 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
7492 case 4: /* Priority (only used for write) */
7493 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7498 if (offset == lastoffset) break; /* nothing happened, exit loop */
7504 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7506 guint lastoffset = 0, len;
7507 guint8 tag_no, tag_info;
7510 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7511 lastoffset = offset;
7512 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7513 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
7514 if (tag_is_closing(tag_info)) {
7520 case 0: /* objectIdentifier */
7521 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7523 case 1: /* listOfPropertyValues */
7524 if (tag_is_opening(tag_info)) {
7525 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7526 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
7534 if (offset == lastoffset) break; /* nothing happened, exit loop */
7540 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7542 if (offset >= tvb_reported_length(tvb))
7545 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7546 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
7550 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
7552 guint lastoffset = 0;
7553 guint8 tag_no, tag_info;
7556 /* set the optional global properties to indicate not-used */
7557 propertyArrayIndex = -1;
7558 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7559 lastoffset = offset;
7560 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7561 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
7563 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
7566 switch (tag_no-tagoffset) {
7567 case 0: /* PropertyIdentifier */
7568 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7570 case 1: /* propertyArrayIndex */
7571 offset = fPropertyArrayIndex (tvb, tree, offset);
7572 if (list != 0) break; /* Continue decoding if this may be a list */
7574 lastoffset = offset; /* Set loop end condition */
7577 if (offset == lastoffset) break; /* nothing happened, exit loop */
7583 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
7585 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7586 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
7590 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7592 guint lastoffset = 0;
7594 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7595 lastoffset = offset;
7597 switch (fTagNo(tvb,offset)) {
7598 case 0: /* ObjectIdentifier */
7599 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7601 case 1: /* PropertyIdentifier and propertyArrayIndex */
7602 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
7603 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
7605 lastoffset = offset; /* Set loop end condition */
7608 if (offset == lastoffset) break; /* nothing happened, exit loop */
7615 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
7617 guint lastoffset = 0;
7618 guint8 tag_no, tag_info;
7620 proto_tree* subtree = tree;
7623 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7624 lastoffset = offset;
7625 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7626 if (tag_is_closing(tag_info)) {
7627 offset += fTagHeaderTree (tvb, subtree, offset,
7628 &tag_no, &tag_info, &lvt);
7632 case 0: /* ObjectIdentifier */
7633 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7635 case 1: /* PropertyIdentifier */
7636 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
7638 case 2: /* propertyArrayIndex */
7639 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
7642 offset = fPropertyValue (tvb, subtree, offset, tag_info);
7644 case 4: /* Priority */
7645 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
7656 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7658 char i = 1, ar[256];
7659 guint lastoffset = 0;
7661 if (propertyArrayIndex > 0) {
7662 /* BACnetARRAY index 0 refers to the length
7663 of the array, not the elements of the array.
7664 BACnetARRAY index -1 is our internal flag that
7665 the optional index was not used.
7666 BACnetARRAY refers to this as all elements of the array.
7667 If the optional index is specified for a BACnetARRAY,
7668 then that specific array element is referenced. */
7669 i = propertyArrayIndex;
7671 while (tvb_reported_length_remaining(tvb, offset)) {
7672 /* exit loop if nothing happens inside */
7673 lastoffset = offset;
7674 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
7675 val_to_split_str(87 , 512,
7676 BACnetPropertyIdentifier,
7677 ASHRAE_Reserved_Fmt,
7678 Vendor_Proprietary_Fmt),
7680 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
7681 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
7682 /* there are only 16 priority array elements */
7686 if (offset == lastoffset) break; /* nothing happened, exit loop */
7693 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7695 guint lastoffset = 0;
7697 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7698 lastoffset = offset;
7700 switch (fTagNo(tvb,offset)) {
7701 case 0: /* deviceIdentifier - OPTIONAL */
7702 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7704 case 1: /* ObjectIdentifier */
7705 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7710 if (offset == lastoffset) break; /* nothing happened, exit loop */
7716 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7718 guint8 tag_no, tag_info;
7720 guint lastoffset = 0, len;
7722 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7723 lastoffset = offset;
7724 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7725 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
7726 if (tag_is_closing(tag_info)) {
7732 case 0: /* calendaryEntry */
7733 if (tag_is_opening(tag_info))
7735 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7736 offset = fCalendaryEntry (tvb, subtree, offset);
7737 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7740 case 1: /* calendarReference */
7741 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7743 case 2: /* list of BACnetTimeValue */
7744 if (tag_is_opening(tag_info)) {
7745 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7746 offset = fTimeValue (tvb, pinfo, subtree, offset);
7747 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7752 case 3: /* eventPriority */
7753 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
7758 if (offset == lastoffset) break; /* nothing happened, exit loop */
7764 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7766 guint lastoffset = 0, len;
7767 guint8 tag_no, tag_info;
7770 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7771 lastoffset = offset;
7772 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7773 /* maybe a listOfSelectionCriteria if we spot a closing tag */
7774 if (tag_is_closing(tag_info)) {
7779 switch (fTagNo(tvb,offset)) {
7780 case 0: /* propertyIdentifier */
7781 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7783 case 1: /* propertyArrayIndex */
7784 offset = fPropertyArrayIndex (tvb, tree, offset);
7786 case 2: /* relationSpecifier */
7787 offset = fEnumeratedTag (tvb, tree, offset,
7788 "relation Specifier: ", BACnetRelationSpecifier);
7790 case 3: /* comparisonValue */
7791 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7792 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7793 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
7798 if (offset == lastoffset) break; /* nothing happened, exit loop */
7804 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7806 guint lastoffset = 0;
7807 guint8 tag_no, tag_info;
7810 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7811 lastoffset = offset;
7812 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7813 /* quit loop if we spot a closing tag */
7814 if (tag_is_closing(tag_info)) {
7819 case 0: /* selectionLogic */
7820 offset = fEnumeratedTag (tvb, subtree, offset,
7821 "selection Logic: ", BACnetSelectionLogic);
7823 case 1: /* listOfSelectionCriteria */
7824 if (tag_is_opening(tag_info)) {
7825 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7826 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
7827 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7835 if (offset == lastoffset) break; /* nothing happened, exit loop */
7842 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
7844 guint lastoffset = 0;
7845 guint8 tag_no, tag_info;
7848 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7849 lastoffset = offset;
7850 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7852 if (tag_is_opening(tag_info) && tag_no < 2) {
7853 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7855 case 0: /* objectSelectionCriteria */
7856 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
7858 case 1: /* listOfPropertyReferences */
7859 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
7864 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7866 if (offset == lastoffset) break; /* nothing happened, exit loop */
7872 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7874 guint lastoffset = 0;
7875 guint8 tag_no, tag_info;
7878 proto_tree *subtree = tree;
7880 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7881 lastoffset = offset;
7882 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7884 case 0: /* objectIdentifier */
7885 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7887 case 1: /* listOfPropertyReferences */
7888 if (tag_is_opening(tag_info)) {
7889 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
7890 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7891 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7892 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
7893 } else if (tag_is_closing(tag_info)) {
7894 offset += fTagHeaderTree (tvb, subtree, offset,
7895 &tag_no, &tag_info, &lvt);
7898 /* error condition: let caller handle */
7905 if (offset == lastoffset) break; /* nothing happened, exit loop */
7911 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7913 guint lastoffset = 0, len;
7917 proto_tree *subtree = tree;
7920 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7921 lastoffset = offset;
7922 len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7923 /* maybe a listOfReadAccessResults if we spot a closing tag here */
7924 if (tag_is_closing(tag_info)) {
7926 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
7931 case 0: /* objectSpecifier */
7932 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7934 case 1: /* list of Results */
7935 if (tag_is_opening(tag_info)) {
7936 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
7937 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7938 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7943 case 2: /* propertyIdentifier */
7944 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
7946 case 5: /* propertyAccessError */
7947 if (tag_is_opening(tag_info)) {
7948 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
7949 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7950 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7951 /* Error Code follows */
7952 offset = fError(tvb, pinfo, subtree, offset);
7960 if (offset == lastoffset) break; /* nothing happened, exit loop */
7967 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7969 /* listOfReadAccessResults */
7970 return fReadAccessResult (tvb, pinfo, tree, offset);
7975 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7977 guint lastoffset = 0;
7978 guint8 tag_no, tag_info;
7981 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
7982 lastoffset = offset;
7983 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
7987 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
7989 case 0: /* objectSpecifier */
7990 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
7991 case 0: /* objectType */
7992 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
7994 case 1: /* objectIdentifier */
7995 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8001 case 1: /* propertyValue */
8002 if (tag_is_opening(tag_info)) {
8003 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8011 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8013 if (offset == lastoffset) break; /* nothing happened, exit loop */
8019 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8021 return fObjectIdentifier (tvb, pinfo, tree, offset);
8025 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8027 guint8 tag_no, tag_info;
8029 proto_tree *subtree = tree;
8032 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
8034 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8035 /* optional range choice */
8036 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8037 if (tag_is_opening(tag_info)) {
8038 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
8039 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8040 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8042 case 3: /* range byPosition */
8043 case 6: /* range bySequenceNumber, 2004 spec */
8044 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
8045 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
8047 case 4: /* range byTime - deprecated in 2004 */
8048 case 7: /* 2004 spec */
8049 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
8050 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
8052 case 5: /* range timeRange - deprecated in 2004 */
8053 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
8054 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
8059 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8066 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8068 guint8 tag_no, tag_info;
8070 proto_tree *subtree = tree;
8073 /* set the optional global properties to indicate not-used */
8074 propertyArrayIndex = -1;
8075 /* objectIdentifier, propertyIdentifier, and
8076 OPTIONAL propertyArrayIndex */
8077 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
8078 /* resultFlags => BACnetResultFlags ::= BIT STRING */
8079 offset = fBitStringTagVS (tvb, tree, offset,
8083 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
8085 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8086 if (tag_is_opening(tag_info)) {
8087 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8088 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
8089 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8090 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8091 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8092 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8094 /* firstSequenceNumber - OPTIONAL */
8095 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8096 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
8103 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8105 guint lastoffset = 0;
8107 guint8 tag_no, tag_info;
8109 proto_tree* subtree = NULL;
8111 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8113 if (tag_is_opening(tag_info))
8115 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
8116 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8117 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8118 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
8119 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
8123 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset))
8124 { /* exit loop if nothing happens inside */
8125 lastoffset = offset;
8126 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
8130 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0)
8132 /* More Flag is not set, so we can look for closing tag in this segment */
8133 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8134 if (tag_is_closing(tag_info)) {
8135 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8143 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8145 guint8 tag_no, tag_info;
8147 proto_tree *subtree = tree;
8150 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8152 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8154 if (tag_is_opening(tag_info))
8156 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
8157 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8158 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8159 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
8160 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
8161 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8167 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8170 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
8171 offset = fAccessMethod(tvb, pinfo, tree, offset);
8177 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
8179 guint tag_no = fTagNo(tvb, offset);
8180 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
8184 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8186 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
8187 offset = fAccessMethod(tvb,pinfo, tree, offset);
8193 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
8195 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8196 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
8200 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8202 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8203 return fReadAccessResult (tvb,pinfo,tree,offset);
8207 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8209 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8212 switch (service_choice) {
8213 case 0: /* acknowledgeAlarm */
8214 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
8216 case 1: /* confirmedCOVNotification */
8217 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8219 case 2: /* confirmedEventNotification */
8220 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8222 case 3: /* confirmedGetAlarmSummary conveys no parameters */
8224 case 4: /* getEnrollmentSummaryRequest */
8225 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
8227 case 5: /* subscribeCOVRequest */
8228 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
8230 case 6: /* atomicReadFile-Request */
8231 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
8233 case 7: /* atomicWriteFile-Request */
8234 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
8236 case 8: /* AddListElement-Request */
8237 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
8239 case 9: /* removeListElement-Request */
8240 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
8242 case 10: /* createObjectRequest */
8243 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
8245 case 11: /* deleteObject */
8246 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
8249 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
8252 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
8255 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
8258 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
8261 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
8264 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
8267 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8270 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8273 offset = fReinitializeDeviceRequest(tvb, tree, offset);
8276 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
8279 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8282 offset = fVtDataRequest (tvb, pinfo, tree, offset);
8285 offset = fAuthenticateRequest (tvb, tree, offset);
8288 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
8291 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
8294 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
8297 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
8300 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
8309 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8311 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8314 switch (service_choice) {
8315 case 3: /* confirmedEventNotificationAck */
8316 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
8318 case 4: /* getEnrollmentSummaryAck */
8319 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
8321 case 6: /* atomicReadFile */
8322 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
8324 case 7: /* atomicReadFileAck */
8325 offset = fAtomicWriteFileAck (tvb, tree, offset);
8327 case 10: /* createObject */
8328 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
8331 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
8334 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
8337 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
8340 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
8343 offset = fVtOpenAck (tvb, pinfo, tree, offset);
8346 offset = fVtDataAck (tvb, tree, offset);
8349 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
8352 offset = fReadRangeAck (tvb, pinfo, tree, offset);
8355 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
8364 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8366 /* BACnetObjectIdentifier */
8367 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
8369 /* MaxAPDULengthAccepted */
8370 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
8372 /* segmentationSupported */
8373 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8374 "Segmentation Supported: ", BACnetSegmentation);
8377 return fVendorIdentifier (tvb, pinfo, tree, offset);
8381 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8383 /* BACnetDeviceIdentifier */
8384 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
8386 /* BACnetObjectIdentifier */
8387 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8390 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
8395 fWhoIsRequest (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
8397 guint lastoffset = 0;
8401 guint8 tag_no, tag_info;
8404 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8405 lastoffset = offset;
8407 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8411 /* DeviceInstanceRangeLowLimit Optional */
8412 fUnsigned32(tvb, offset+tag_len, lvt, &val);
8413 if (col_get_writable(pinfo->cinfo))
8414 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
8415 offset = fDevice_Instance (tvb, tree, offset,
8416 hf_Device_Instance_Range_Low_Limit);
8419 /* DeviceInstanceRangeHighLimit Optional but
8420 required if DeviceInstanceRangeLowLimit is there */
8421 fUnsigned32(tvb, offset+tag_len, lvt, &val);
8422 if (col_get_writable(pinfo->cinfo))
8423 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
8424 offset = fDevice_Instance (tvb, tree, offset,
8425 hf_Device_Instance_Range_High_Limit);
8430 if (offset == lastoffset) break; /* nothing happened, exit loop */
8436 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
8438 if (tvb_reported_length_remaining(tvb,offset) <= 0)
8441 switch (service_choice) {
8442 case 0: /* I-Am-Request */
8443 offset = fIAmRequest (tvb, pinfo, tree, offset);
8445 case 1: /* i-Have Request */
8446 offset = fIHaveRequest (tvb, pinfo, tree, offset);
8448 case 2: /* unconfirmedCOVNotification */
8449 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8451 case 3: /* unconfirmedEventNotification */
8452 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8454 case 4: /* unconfirmedPrivateTransfer */
8455 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
8457 case 5: /* unconfirmedTextMessage */
8458 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
8460 case 6: /* timeSynchronization */
8461 offset = fTimeSynchronizationRequest (tvb, tree, offset);
8463 case 7: /* who-Has */
8464 offset = fWhoHas (tvb, pinfo, tree, offset);
8466 case 8: /* who-Is */
8467 offset = fWhoIsRequest (tvb, pinfo, tree, offset);
8469 case 9: /* utcTimeSynchronization */
8470 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
8479 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
8480 gint *svc, proto_item **tt)
8483 proto_tree *bacapp_tree_control;
8484 gint tmp, bacapp_type;
8488 tmp = (gint) tvb_get_guint8(tvb, offset);
8489 bacapp_type = (tmp >> 4) & 0x0f;
8490 bacapp_flags = tmp & 0x0f;
8495 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
8496 if (bacapp_flags & 0x08)
8497 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
8499 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8500 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, TRUE);
8501 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
8503 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, TRUE);
8504 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, TRUE);
8505 if (ack == 0) /* The following are for ConfirmedRequest, not Complex ack */
8507 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, TRUE);
8508 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
8510 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
8514 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
8515 if (bacapp_flags & 0x08) {
8516 bacapp_seq = tvb_get_guint8(tvb, offset);
8517 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
8519 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
8522 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8528 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
8529 { /* BACnet-Confirmed-Request */
8530 /* ASHRAE 135-2001 20.1.2 */
8532 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
8536 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8537 { /* BACnet-Confirmed-Request */
8538 /* ASHRAE 135-2001 20.1.2 */
8542 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
8543 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
8547 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8548 { /* BACnet-Unconfirmed-Request-PDU */
8549 /* ASHRAE 135-2001 20.1.3 */
8553 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8555 tmp = tvb_get_guint8(tvb, offset);
8556 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
8558 /* Service Request follows... Variable Encoding 20.2ff */
8559 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
8563 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8564 { /* BACnet-Simple-Ack-PDU */
8565 /* ASHRAE 135-2001 20.1.4 */
8569 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8571 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8573 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8580 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
8581 { /* BACnet-Complex-Ack-PDU */
8582 /* ASHRAE 135-2001 20.1.5 */
8584 /* Service ACK follows... */
8585 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
8589 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8590 { /* BACnet-Complex-Ack-PDU */
8591 /* ASHRAE 135-2001 20.1.5 */
8595 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
8596 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
8600 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8601 { /* BACnet-SegmentAck-PDU */
8602 /* ASHRAE 135-2001 20.1.6 */
8605 proto_tree *bacapp_tree_control;
8607 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8608 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8610 proto_tree_add_item(bacapp_tree, hf_bacapp_NAK, tvb, offset, 1, TRUE);
8611 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8612 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8614 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
8616 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
8622 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8624 guint8 tag_info = 0;
8625 guint8 parsed_tag = 0;
8627 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8628 offset = fError(tvb, pinfo, tree, offset);
8629 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
8633 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8635 guint lastoffset = 0;
8636 guint8 tag_no = 0, tag_info = 0;
8638 proto_tree *subtree = tree;
8641 guint vendor_identifier = 0;
8642 guint service_number = 0;
8645 while (tvb_reported_length_remaining(tvb, offset)) {
8646 /* exit loop if nothing happens inside */
8647 lastoffset = offset;
8648 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
8650 case 0: /* errorType */
8651 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
8653 case 1: /* vendorID */
8654 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
8655 if (col_get_writable(pinfo->cinfo))
8656 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
8657 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
8659 case 2: /* serviceNumber */
8660 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
8661 if (col_get_writable(pinfo->cinfo))
8662 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
8663 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
8665 case 3: /* errorParameters */
8666 if (tag_is_opening(tag_info)) {
8667 tt = proto_tree_add_text(subtree, tvb, offset, 1,
8668 "error Parameters");
8669 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8670 propertyIdentifier = -1;
8671 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
8672 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8673 } else if (tag_is_closing(tag_info)) {
8674 offset += fTagHeaderTree (tvb, subtree, offset,
8675 &tag_no, &tag_info, &lvt);
8678 /* error condition: let caller handle */
8685 if (offset == lastoffset) break; /* nothing happened, exit loop */
8691 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8693 guint lastoffset = 0;
8695 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8696 lastoffset = offset;
8697 switch (fTagNo(tvb, offset)) {
8698 case 0: /* errorType */
8699 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8701 case 1: /* firstFailedElementNumber */
8702 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
8707 if (offset == lastoffset) break; /* nothing happened, exit loop */
8713 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8715 /* Identical to CreateObjectError */
8716 return fCreateObjectError(tvb, pinfo, tree, offset);
8720 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8722 guint8 tag_no = 0, tag_info = 0;
8725 if (fTagNo(tvb, offset) == 0)
8728 offset = fContextTaggedError(tvb, pinfo, tree,offset);
8729 if (fTagNo(tvb, offset) == 1)
8731 /* listOfVTSessionIdentifiers [OPTIONAL] */
8732 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8733 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
8734 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8737 /* should report bad packet if initial tag wasn't 0 */
8742 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8744 guint lastoffset = 0;
8745 guint8 tag_no = 0, tag_info = 0;
8748 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8749 while (tvb_reported_length_remaining(tvb, offset)) { /* exit loop if nothing happens inside */
8750 lastoffset = offset;
8751 switch (fTagNo(tvb, offset)) {
8752 case 0: /* errorType */
8753 offset = fContextTaggedError(tvb, pinfo, tree, offset);
8755 case 1: /* firstFailedWriteAttempt */
8756 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8757 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
8758 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
8763 if (offset == lastoffset) break; /* nothing happened, exit loop */
8769 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8771 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8772 "error Class: ", BACnetErrorClass, 64);
8773 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8774 "error Code: ", BACnetErrorCode, 256);
8778 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
8781 case 8: /* no break here !!!! */
8783 offset = fChangeListError (tvb, pinfo, tree, offset);
8786 offset = fCreateObjectError (tvb, pinfo, tree, offset);
8789 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
8792 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
8795 offset = fVTCloseError (tvb, pinfo, tree, offset);
8798 return fError (tvb, pinfo, tree, offset);
8804 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
8805 { /* BACnet-Error-PDU */
8806 /* ASHRAE 135-2001 20.1.7 */
8808 proto_item *tc, *tt;
8809 proto_tree *bacapp_tree_control;
8812 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8813 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8815 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8817 tmp = tvb_get_guint8(tvb, offset);
8818 tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
8820 /* Error Handling follows... */
8821 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
8825 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8826 { /* BACnet-Reject-PDU */
8827 /* ASHRAE 135-2001 20.1.8 */
8830 proto_tree *bacapp_tree_control;
8832 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
8833 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8835 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8837 proto_tree_add_item(bacapp_tree, hf_BACnetRejectReason, tvb,
8843 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
8844 { /* BACnet-Abort-PDU */
8845 /* ASHRAE 135-2001 20.1.9 */
8848 proto_tree *bacapp_tree_control;
8850 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
8851 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
8853 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
8854 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
8856 proto_tree_add_item(bacapp_tree, hf_BACnetAbortReason, tvb,
8862 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8864 guint8 flag, bacapp_type;
8867 flag = (gint) tvb_get_guint8(tvb, 0);
8868 bacapp_type = (flag >> 4) & 0x0f;
8870 if (tvb == NULL || tree == NULL) {
8874 /* ASHRAE 135-2001 20.1.1 */
8875 switch (bacapp_type) {
8876 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
8877 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
8879 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
8880 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
8882 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
8883 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
8885 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
8886 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
8888 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
8889 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
8891 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
8892 offset = fErrorPDU(tvb, pinfo, tree, offset);
8894 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
8895 offset = fRejectPDU(tvb, pinfo, tree, offset);
8897 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
8898 offset = fAbortPDU(tvb, pinfo, tree, offset);
8905 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8907 guint8 flag, bacapp_type;
8908 guint save_fragmented = FALSE, data_offset = 0, bacapp_apdu_size = fGetMaxAPDUSize(0), fragment = FALSE;
8909 tvbuff_t* new_tvb = NULL;
8911 guint8 bacapp_seqno = 0;
8912 guint8 bacapp_service, bacapp_reason, bacapp_prop_win_size;
8913 guint8 bacapp_invoke_id = 0;
8915 proto_tree *bacapp_tree = NULL;
8921 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
8922 col_clear (pinfo->cinfo, COL_INFO);
8924 flag = tvb_get_guint8(tvb, 0);
8925 bacapp_type = (flag >> 4) & 0x0f;
8927 /* show some descriptive text in the INFO column */
8928 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
8929 val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
8931 switch (bacapp_type)
8933 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
8934 /* segmented messages have 2 additional bytes */
8935 if (flag & BACAPP_SEGMENTED_REQUEST)
8939 bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); /* has 16 values, reserved are 50 Bytes */
8940 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
8941 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
8942 bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4);
8943 bacapp_service = tvb_get_guint8(tvb, offset + 5);
8948 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
8949 bacapp_service = tvb_get_guint8(tvb, offset + 3);
8951 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
8952 val_to_str(bacapp_service,
8953 BACnetConfirmedServiceChoice,
8954 bacapp_unknown_service_str),bacapp_invoke_id);
8956 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
8957 bacapp_service = tvb_get_guint8(tvb, offset + 1);
8958 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
8959 val_to_str(bacapp_service,
8960 BACnetUnconfirmedServiceChoice,
8961 bacapp_unknown_service_str));
8963 case BACAPP_TYPE_SIMPLE_ACK:
8964 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8965 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8966 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8967 val_to_str(bacapp_service,
8968 BACnetConfirmedServiceChoice,
8969 bacapp_unknown_service_str), bacapp_invoke_id);
8971 case BACAPP_TYPE_COMPLEX_ACK:
8972 /* segmented messages have 2 additional bytes */
8973 if (flag & BACAPP_SEGMENTED_REQUEST)
8977 bacapp_apdu_size = fGetMaxAPDUSize(0); /* has minimum of 50 Bytes */
8978 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8979 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
8980 bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3);
8981 bacapp_service = tvb_get_guint8(tvb, offset + 4);
8986 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8987 bacapp_service = tvb_get_guint8(tvb, offset + 2);
8989 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
8990 val_to_str(bacapp_service,
8991 BACnetConfirmedServiceChoice,
8992 bacapp_unknown_service_str), bacapp_invoke_id);
8994 case BACAPP_TYPE_SEGMENT_ACK:
8995 /* nothing more to add */
8997 case BACAPP_TYPE_ERROR:
8998 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
8999 bacapp_service = tvb_get_guint8(tvb, offset + 2);
9000 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9001 val_to_str(bacapp_service,
9002 BACnetConfirmedServiceChoice,
9003 bacapp_unknown_service_str), bacapp_invoke_id);
9005 case BACAPP_TYPE_REJECT:
9006 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9007 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
9008 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9009 val_to_split_str(bacapp_reason,
9012 ASHRAE_Reserved_Fmt,
9013 Vendor_Proprietary_Fmt), bacapp_invoke_id);
9015 case BACAPP_TYPE_ABORT:
9016 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
9017 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
9018 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
9019 val_to_split_str(bacapp_reason,
9022 ASHRAE_Reserved_Fmt,
9023 Vendor_Proprietary_Fmt), bacapp_invoke_id);
9027 /* nothing more to add */
9031 save_fragmented = pinfo->fragmented;
9035 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, FALSE);
9036 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
9039 offset = do_the_dissection(tvb,pinfo,bacapp_tree);
9041 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
9042 /* not resetting the offset so the remaining can be done */
9045 if (fragment) { /* fragmented */
9046 fragment_data *frag_msg = NULL;
9049 pinfo->fragmented = TRUE;
9051 frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
9052 bacapp_invoke_id, /* ID for fragments belonging together */
9053 msg_fragment_table, /* list of message fragments */
9054 msg_reassembled_table, /* list of reassembled messages */
9055 bacapp_seqno, /* fragment sequence number */
9056 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
9057 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
9058 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
9059 "Reassembled BACapp", frag_msg, &msg_frag_items,
9062 if (new_tvb) { /* Reassembled */
9063 col_append_str(pinfo->cinfo, COL_INFO,
9064 " (Message Reassembled)");
9065 } else { /* Not last packet of reassembled Short Message */
9066 col_append_fstr(pinfo->cinfo, COL_INFO,
9067 " (Message fragment %u)", bacapp_seqno);
9069 if (new_tvb) { /* take it all */
9070 switch (bacapp_type)
9072 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
9073 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
9075 case BACAPP_TYPE_COMPLEX_ACK:
9076 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
9086 pinfo->fragmented = save_fragmented;
9091 bacapp_init_routine(void)
9093 fragment_table_init(&msg_fragment_table);
9094 reassembled_table_init(&msg_reassembled_table);
9098 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
9103 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
9104 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
9105 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
9108 g_iconv_close (icd);
9112 uni_to_string(in,*inbytesleft,out);
9113 out[*inbytesleft] = '\0';
9114 *outbytesleft -= *inbytesleft;
9121 uni_to_string(char * data, gsize str_length, char *dest_buf)
9125 gsize length_remaining = 0;
9127 length_remaining = str_length;
9133 for ( i = 0; i < (gint) str_length; i++ )
9136 if (c_char<0x20 || c_char>0x7e)
9141 dest_buf[i] = c_char & 0xff;
9151 dest_buf[i] = c_char & 0xff;
9155 if(length_remaining==0)
9157 dest_buf[i+1] = '\0';
9169 proto_register_bacapp(void)
9171 static hf_register_info hf[] = {
9173 { "APDU Type", "bacapp.type",
9174 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
9176 { &hf_bacapp_pduflags,
9177 { "PDU Flags", "bacapp.pduflags",
9178 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
9181 { "Segmented Request", "bacapp.segmented_request",
9182 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
9185 { "More Segments", "bacapp.more_segments",
9186 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
9189 { "SA", "bacapp.SA",
9190 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
9192 { &hf_bacapp_max_adpu_size,
9193 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
9194 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
9196 { &hf_bacapp_response_segments,
9197 { "Max Response Segments accepted", "bacapp.response_segments",
9198 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
9200 { &hf_bacapp_objectType,
9201 { "Object Type", "bacapp.objectType",
9202 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
9204 { &hf_bacapp_instanceNumber,
9205 { "Instance Number", "bacapp.instance_number",
9206 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
9208 { &hf_BACnetPropertyIdentifier,
9209 { "Property Identifier", "bacapp.property_identifier",
9210 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
9212 { &hf_BACnetVendorIdentifier,
9213 { "Vendor Identifier", "bacapp.vendor_identifier",
9214 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
9216 { &hf_BACnetRestartReason,
9217 { "Restart Reason", "bacapp.restart_reason",
9218 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
9220 { &hf_bacapp_invoke_id,
9221 { "Invoke ID", "bacapp.invoke_id",
9222 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9224 { &hf_bacapp_sequence_number,
9225 { "Sequence Number", "bacapp.sequence_number",
9226 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9228 { &hf_bacapp_window_size,
9229 { "Proposed Window Size", "bacapp.window_size",
9230 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
9232 { &hf_bacapp_service,
9233 { "Service Choice", "bacapp.confirmed_service",
9234 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
9236 { &hf_bacapp_uservice,
9237 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
9238 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
9241 { "NAK", "bacapp.NAK",
9242 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
9245 { "SRV", "bacapp.SRV",
9246 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
9248 { &hf_Device_Instance_Range_Low_Limit,
9249 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
9250 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
9252 { &hf_Device_Instance_Range_High_Limit,
9253 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
9254 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
9256 { &hf_BACnetRejectReason,
9257 { "Reject Reason", "bacapp.reject_reason",
9258 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
9260 { &hf_BACnetAbortReason,
9261 { "Abort Reason", "bacapp.abort_reason",
9262 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
9265 { "BACnet APDU variable part:", "bacapp.variable_part",
9266 FT_NONE, BASE_NONE, NULL, 0, "BACnet APDU variable part", HFILL }
9271 FT_BYTES, BASE_NONE, NULL, 0,
9274 { &hf_BACnetApplicationTagNumber,
9275 { "Application Tag Number",
9276 "bacapp.application_tag_number",
9277 FT_UINT8, BASE_DEC, VALS(&BACnetApplicationTagNumber), 0xF0,
9280 { &hf_BACnetContextTagNumber,
9281 { "Context Tag Number",
9282 "bacapp.context_tag_number",
9283 FT_UINT8, BASE_DEC, NULL, 0xF0,
9286 { &hf_BACnetExtendedTagNumber,
9287 { "Extended Tag Number",
9288 "bacapp.extended_tag_number",
9289 FT_UINT8, BASE_DEC, NULL, 0,
9292 { &hf_BACnetNamedTag,
9295 FT_UINT8, BASE_DEC, VALS(&BACnetTagNames), 0x07,
9298 { &hf_BACnetCharacterSet,
9299 { "String Character Set",
9300 "bacapp.string_character_set",
9301 FT_UINT8, BASE_DEC, VALS(&BACnetCharacterSet),0,
9304 { &hf_BACnetTagClass,
9305 { "Tag Class", "bacapp.tag_class",
9306 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
9308 { &hf_bacapp_tag_lvt,
9309 { "Length Value Type",
9311 FT_UINT8, BASE_DEC, NULL, 0,
9314 { &hf_bacapp_tag_value8,
9316 "bacapp.tag_value8",
9317 FT_UINT8, BASE_DEC, NULL, 0,
9320 { &hf_bacapp_tag_value16,
9321 { "Tag Value 16-bit",
9322 "bacapp.tag_value16",
9323 FT_UINT16, BASE_DEC, NULL, 0,
9326 { &hf_bacapp_tag_value32,
9327 { "Tag Value 32-bit",
9328 "bacapp.tag_value32",
9329 FT_UINT32, BASE_DEC, NULL, 0,
9332 { &hf_bacapp_tag_ProcessId,
9333 { "ProcessIdentifier", "bacapp.processId",
9334 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
9336 { &hf_bacapp_tag_IPV4,
9337 { "IPV4", "bacapp.IPV4",
9338 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
9340 { &hf_bacapp_tag_IPV6,
9341 { "IPV6", "bacapp.IPV6",
9342 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
9344 { &hf_bacapp_tag_PORT,
9345 { "Port", "bacapp.Port",
9346 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
9348 { &hf_bacapp_tag_initiatingObjectType,
9349 { "ObjectType", "bacapp.objectType",
9350 FT_UINT16, BASE_DEC, VALS(BACnetObjectType), 0x00, "Object Type", HFILL }
9353 {"Message fragments", "bacapp.fragments",
9354 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9356 {"Message fragment", "bacapp.fragment",
9357 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9358 {&hf_msg_fragment_overlap,
9359 {"Message fragment overlap", "bacapp.fragment.overlap",
9360 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9361 {&hf_msg_fragment_overlap_conflicts,
9362 {"Message fragment overlapping with conflicting data",
9363 "bacapp.fragment.overlap.conflicts",
9364 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9365 {&hf_msg_fragment_multiple_tails,
9366 {"Message has multiple tail fragments",
9367 "bacapp.fragment.multiple_tails",
9368 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9369 {&hf_msg_fragment_too_long_fragment,
9370 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
9371 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9372 {&hf_msg_fragment_error,
9373 {"Message defragmentation error", "bacapp.fragment.error",
9374 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9375 {&hf_msg_reassembled_in,
9376 {"Reassembled in", "bacapp.reassembled.in",
9377 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
9378 {&hf_msg_reassembled_length,
9379 {"Reassembled BACapp length", "bacapp.reassembled.length",
9380 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
9382 static gint *ett[] = {
9384 &ett_bacapp_control,
9393 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
9394 "BACapp", "bacapp");
9396 proto_register_field_array(proto_bacapp, hf, array_length(hf));
9397 proto_register_subtree_array(ett, array_length(ett));
9398 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
9399 register_init_routine (&bacapp_init_routine);
9401 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
9402 "BACapp Vendor Identifier",
9403 FT_UINT8, BASE_HEX);
9408 proto_reg_handoff_bacapp(void)
9410 data_handle = find_dissector("data");