2 * Routines for BACnet (APDU) dissection
3 * Copyright 2001, Hartmut Mueller <hartmut[AT]abmlinux.org>, FH Dortmund
4 * Enhanced by Steve Karg, 2005, <skarg[AT]users.sourceforge.net>, Atlanta
5 * Enhanced by Herbert Lischka, 2005, <lischka[AT]kieback-peter.de>, Berlin
6 * Enhanced by Felix Kraemer, 2010, <sauter-cumulus[AT]de.sauter-bc.com>,
7 * Sauter-Cumulus GmbH, Freiburg
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald[AT]wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include <epan/packet.h>
35 #include <epan/wmem/wmem.h>
36 #include <epan/reassemble.h>
37 #include <epan/expert.h>
38 #include <epan/stats_tree.h>
39 #include "packet-bacapp.h"
41 static int bacapp_tap = -1;
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
79 * @param tvb the tv buffer of the current data
80 * @param pinfo the packet info of the current data
81 * @param tree the tree to append this item to
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
101 * @param tvb the tv buffer of the current data
102 * @param pinfo the packet info of the current data
103 * @param tree the tree to append this item to
104 * @param offset the offset in the tvb
105 * @return modified offset
108 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
111 * @param tvb the tv buffer of the current data
112 * @param pinfo the packet info of the current data
113 * @param tree the tree to append this item to
114 * @param offset the offset in the tvb
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
131 * @param tvb the tv buffer of the current data
132 * @param pinfo the packet info of the current data
133 * @param tree the tree to append this item to
134 * @param offset the offset in the tvb
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
147 * @param tvb the tv buffer of the current data
148 * @param pinfo the packet info of the current data
149 * @param tree the tree to append this item to
150 * @param offset the offset in the tvb
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
168 * @param tvb the tv buffer of the current data
169 * @param pinfo the packet info of the current data
170 * @param tree the tree to append this item to
171 * @param offset the offset in the tvb
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)
187 * @param tvb the tv buffer of the current data
188 * @param pinfo the packet info of the current data
189 * @param tree the tree to append this item to
190 * @param offset the offset in the tvb
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
204 * @param tvb the tv buffer of the current data
205 * @param pinfo the packet info of the current data
206 * @param tree the tree to append this item to
207 * @param offset the offset in the tvb
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
220 * @param tvb the tv buffer of the current data
221 * @param pinfo the packet info of the current data
222 * @param tree the tree to append this item to
223 * @param offset the offset in the tvb
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
237 * @param tvb the tv buffer of the current data
238 * @param pinfo the packet info of the current data
239 * @param tree the tree to append this item to
240 * @param offset the offset in the tvb
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
248 * @param tvb the tv buffer of the current data
249 * @param pinfo the packet info of the current data
250 * @param tree the tree to append this item to
251 * @param offset the offset in the tvb
252 * @param label the label of this item
253 * @return modified offset
256 fUnsignedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
259 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
260 * @param tvb the tv buffer of the current data
261 * @param pinfo the packet info of the current data
262 * @param tree the tree to append this item to
263 * @param offset the offset in the tvb
264 * @param label the label of this item
265 * @return modified offset
268 fSignedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
271 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
272 * @param tvb the tv buffer of the current data
273 * @param pinfo the packet info of the current data
274 * @param tree the tree to append this item to
275 * @param offset the offset in the tvb
276 * @param label the label of this item
277 * @param lvt length of String
278 * @return modified offset
281 fOctetString (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
284 * 20.2.12, adds the label with Date Value to tree
285 * @param tvb the tv buffer of the current data
286 * @param pinfo the packet info of the current data
287 * @param tree the tree to append this item to
288 * @param offset the offset in the tvb
289 * @param label the label of this item
290 * @return modified offset
293 fDate (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
296 * 20.2.13, adds the label with Time Value to tree
297 * @param tvb the tv buffer of the current data
298 * @param pinfo the packet info of the current data
299 * @param tree the tree to append this item to
300 * @param offset the offset in the tvb
301 * @param label the label of this item
302 * @return modified offset
305 fTime (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
308 * 20.2.14, adds Object Identifier to tree
309 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
310 * @param tvb the tv buffer of the current data
311 * @param pinfo the packet info of the current data
312 * @param tree the tree to append this item to
313 * @param offset the offset in the tvb
314 * @return modified offset
317 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
320 * BACnet-Confirmed-Service-Request ::= CHOICE {
322 * @param tvb the tv buffer of the current data
323 * @param pinfo the packet info of the current data
324 * @param tree the tree to append this item to
325 * @param offset the offset in the tvb
326 * @param service_choice the service choice
330 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
333 * BACnet-Confirmed-Service-ACK ::= CHOICE {
335 * @param tvb the tv buffer of the current data
336 * @param pinfo the packet info of the current data
337 * @param tree the tree to append this item to
338 * @param offset the offset in the tvb
339 * @param service_choice the service choice
343 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
346 * AcknowledgeAlarm-Request ::= SEQUENCE {
347 * acknowledgingProcessIdentifier [0] Unsigned32,
348 * eventObjectIdentifier [1] BACnetObjectIdentifer,
349 * eventStateAcknowledge [2] BACnetEventState,
350 * timeStamp [3] BACnetTimeStamp,
351 * acknowledgementSource [4] Character String,
352 * timeOfAcknowledgement [5] BACnetTimeStamp
354 * @param tvb the tv buffer of the current data
355 * @param pinfo the packet info of the current data
356 * @param tree the tree to append this item to
357 * @param offset the offset in the tvb
358 * @return modified offset
361 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
364 * ConfirmedCOVNotification-Request ::= SEQUENCE {
365 * subscriberProcessIdentifier [0] Unsigned32,
366 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
367 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
368 * timeRemaining [3] unsigned,
369 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
371 * @param tvb the tv buffer of the current data
372 * @param pinfo the packet info of the current data
373 * @param tree the tree to append this item to
374 * @param offset the offset in the tvb
375 * @return modified offset
378 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
381 * ConfirmedEventNotification-Request ::= SEQUENCE {
382 * ProcessIdentifier [0] Unsigned32,
383 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
384 * eventObjectIdentifier [2] BACnetObjectIdentifer,
385 * timeStamp [3] BACnetTimeStamp,
386 * notificationClass [4] unsigned,
387 * priority [5] unsigned8,
388 * eventType [6] BACnetEventType,
389 * messageText [7] CharacterString OPTIONAL,
390 * notifyType [8] BACnetNotifyType,
391 * ackRequired [9] BOOLEAN OPTIONAL,
392 * fromState [10] BACnetEventState OPTIONAL,
393 * toState [11] BACnetEventState,
394 * eventValues [12] BACnetNotificationParameters OPTIONAL
396 * @param tvb the tv buffer of the current data
397 * @param pinfo the packet info of the current data
398 * @param tree the tree to append this item to
399 * @param offset the offset in the tvb
400 * @return modified offset
403 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
406 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
407 * objectIdentifier BACnetObjectIdentifer,
408 * alarmState BACnetEventState,
409 * acknowledgedTransitions BACnetEventTransitionBits
411 * @param tvb the tv buffer of the current data
412 * @param pinfo the packet info of the current data
413 * @param tree the tree to append this item to
414 * @param offset the offset in the tvb
415 * @return modified offset
418 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
421 * GetEnrollmentSummary-Request ::= SEQUENCE {
422 * acknowledgmentFilter [0] ENUMERATED {
427 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
428 * eventStateFilter [2] ENUMERATED {
435 * eventTypeFilter [3] BACnetEventType OPTIONAL,
436 * priorityFilter [4] SEQUENCE {
437 * minPriority [0] Unsigned8,
438 * maxPriority [1] Unsigned8
440 * notificationClassFilter [5] Unsigned OPTIONAL
442 * @param tvb the tv buffer of the current data
443 * @param pinfo the packet info of the current data
444 * @param tree the tree to append this item to
445 * @param offset the offset in the tvb
446 * @return modified offset
449 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
452 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
453 * objectIdentifier BACnetObjectIdentifer,
454 * eventType BACnetEventType,
455 * eventState BACnetEventState,
456 * priority Unsigned8,
457 * notificationClass Unsigned OPTIONAL
459 * @param tvb the tv buffer of the current data
460 * @param pinfo the packet info of the current data
461 * @param tree the tree to append this item to
462 * @param offset the offset in the tvb
463 * @return modified offset
466 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
469 * GetEventInformation-Request ::= SEQUENCE {
470 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
472 * @param tvb the tv buffer of the current data
473 * @param pinfo the packet info of the current data
474 * @param tree the tree to append this item to
475 * @param offset the offset in the tvb
476 * @return modified offset
479 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
482 * GetEventInformation-ACK ::= SEQUENCE {
483 * listOfEventSummaries [0] listOfEventSummaries,
484 * moreEvents [1] BOOLEAN
486 * @param tvb the tv buffer of the current data
487 * @param pinfo the packet info of the current data
488 * @param tree the tree to append this item to
489 * @param offset the offset in the tvb
490 * @return modified offset
493 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
496 * LifeSafetyOperation-Request ::= SEQUENCE {
497 * requestingProcessIdentifier [0] Unsigned32
498 * requestingSource [1] CharacterString
499 * request [2] BACnetLifeSafetyOperation
500 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
502 * @param tvb the tv buffer of the current data
503 * @param pinfo the packet info of the current data
504 * @param tree the tree to append this item to
505 * @param offset the offset in the tvb
506 * @return modified offset
509 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
512 * SubscribeCOV-Request ::= SEQUENCE {
513 * subscriberProcessIdentifier [0] Unsigned32
514 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
515 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
516 * lifetime [3] Unsigned OPTIONAL
518 * @param tvb the tv buffer of the current data
519 * @param pinfo the packet info of the current data
520 * @param tree the tree to append this item to
521 * @param offset the offset in the tvb
522 * @return modified offset
525 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
528 * SubscribeCOVProperty-Request ::= SEQUENCE {
529 * subscriberProcessIdentifier [0] Unsigned32
530 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
531 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
532 * lifetime [3] Unsigned OPTIONAL
533 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
534 * covIncrement [5] Unsigned OPTIONAL
536 * @param tvb the tv buffer of the current data
537 * @param pinfo the packet info of the current data
538 * @param tree the tree to append this item to
539 * @param offset the offset in the tvb
540 * @return modified offset
543 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
546 * AtomicReadFile-Request ::= SEQUENCE {
547 * fileIdentifier BACnetObjectIdentifier,
548 * accessMethod CHOICE {
549 * streamAccess [0] SEQUENCE {
550 * fileStartPosition INTEGER,
551 * requestedOctetCount Unsigned
553 * recordAccess [1] SEQUENCE {
554 * fileStartRecord INTEGER,
555 * requestedRecordCount Unsigned
559 * @param tvb the tv buffer of the current data
560 * @param pinfo the packet info of the current data
561 * @param tree the tree to append this item to
562 * @param offset the offset in the tvb
563 * @return modified offset
566 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
569 * AtomicWriteFile-ACK ::= SEQUENCE {
571 * accessMethod CHOICE {
572 * streamAccess [0] SEQUENCE {
573 * fileStartPosition INTEGER,
574 * fileData OCTET STRING
576 * recordAccess [1] SEQUENCE {
577 * fileStartRecord INTEGER,
578 * returnedRecordCount Unsigned,
579 * fileRecordData SEQUENCE OF OCTET STRING
583 * @param tvb the tv buffer of the current data
584 * @param pinfo the packet info of the current data
585 * @param tree the tree to append this item to
586 * @param offset the offset in the tvb
587 * @return modified offset
590 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
593 * AtomicWriteFile-Request ::= SEQUENCE {
594 * fileIdentifier BACnetObjectIdentifier,
595 * accessMethod CHOICE {
596 * streamAccess [0] SEQUENCE {
597 * fileStartPosition INTEGER,
598 * fileData OCTET STRING
600 * recordAccess [1] SEQUENCE {
601 * fileStartRecord INTEGER,
602 * recordCount Unsigned,
603 * fileRecordData SEQUENCE OF OCTET STRING
607 * @param tvb the tv buffer of the current data
608 * @param pinfo the packet info of the current data
609 * @param tree the tree to append this item to
610 * @param offset the offset in the tvb
611 * @return modified offset
614 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
617 * AtomicWriteFile-ACK ::= SEQUENCE {
618 * fileStartPosition [0] INTEGER,
619 * fileStartRecord [1] INTEGER,
621 * @param tvb the tv buffer of the current data
622 * @param pinfo the packet info of the current data
623 * @param tree the tree to append this item to
624 * @param offset the offset in the tvb
625 * @return modified offset
628 fAtomicWriteFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
631 * AddListElement-Request ::= SEQUENCE {
632 * objectIdentifier [0] BACnetObjectIdentifier,
633 * propertyIdentifier [1] BACnetPropertyIdentifier,
634 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
635 * listOfElements [3] ABSTRACT-SYNTAX.&Type
637 * @param tvb the tv buffer of the current data
638 * @param pinfo the packet info of the current data
639 * @param tree the tree to append this item to
640 * @param offset the offset in the tvb
641 * @return modified offset
644 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
647 * CreateObject-Request ::= SEQUENCE {
648 * objectSpecifier [0] ObjectSpecifier,
649 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
651 * @param tvb the tv buffer of the current data
652 * @param pinfo the packet info of the current data
653 * @param subtree the sub tree to append this item to
654 * @param offset the offset in the tvb
655 * @return modified offset
658 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
661 * CreateObject-Request ::= BACnetObjectIdentifier
662 * @param tvb the tv buffer of the current data
663 * @param pinfo the packet info of the current data
664 * @param tree the tree to append this item to
665 * @param offset the offset in the tvb
666 * @return modified offset
669 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
672 * DeleteObject-Request ::= SEQUENCE {
673 * ObjectIdentifier BACnetObjectIdentifer
675 * @param tvb the tv buffer of the current data
676 * @param pinfo the packet info of the current data
677 * @param tree the tree to append this item to
678 * @param offset the offset in the tvb
679 * @return modified offset
682 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
685 * ReadProperty-Request ::= SEQUENCE {
686 * objectIdentifier [0] BACnetObjectIdentifier,
687 * propertyIdentifier [1] BACnetPropertyIdentifier,
688 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
690 * @param tvb the tv buffer of the current data
691 * @param pinfo the packet info of the current data
692 * @param tree the tree to append this item to
693 * @param offset the offset in the tvb
694 * @return modified offset
697 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
700 * ReadProperty-ACK ::= SEQUENCE {
701 * objectIdentifier [0] BACnetObjectIdentifier,
702 * propertyIdentifier [1] BACnetPropertyIdentifier,
703 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
704 * propertyValue [3] ABSTRACT-SYNTAX.&Type
706 * @param tvb the tv buffer of the current data
707 * @param pinfo the packet info of the current data
708 * @param tree the tree to append this item to
709 * @param offset the offset in the tvb
710 * @return modified offset
713 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
716 * ReadPropertyConditional-Request ::= SEQUENCE {
717 * objectSelectionCriteria [0] objectSelectionCriteria,
718 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
720 * @param tvb the tv buffer of the current data
721 * @param pinfo the packet info of the current data
722 * @param subtree the sub tree to append this item to
723 * @param offset the offset in the tvb
724 * @return modified offset
727 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
730 * ReadPropertyConditional-ACK ::= SEQUENCE {
731 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
733 * @param tvb the tv buffer of the current data
734 * @param pinfo the packet info of the current data
735 * @param tree the tree to append this item to
736 * @param offset the offset in the tvb
737 * @return modified offset
740 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
743 * ReadPropertyMultiple-Request ::= SEQUENCE {
744 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
746 * @param tvb the tv buffer of the current data
747 * @param pinfo the packet info of the current data
748 * @param subtree the sub tree to append this item to
749 * @param offset the offset in the tvb
750 * @return offset modified
753 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
756 * ReadPropertyMultiple-Ack ::= SEQUENCE {
757 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
759 * @param tvb the tv buffer of the current data
761 * @param tree the tree to append this item to
762 * @param offset the offset in the tvb
763 * @return offset modified
766 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
769 * ReadRange-Request ::= SEQUENCE {
770 * objectIdentifier [0] BACnetObjectIdentifier,
771 * propertyIdentifier [1] BACnetPropertyIdentifier,
772 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
774 * byPosition [3] SEQUENCE {
775 * referencedIndex Unsigned,
778 * byTime [4] SEQUENCE {
779 * referenceTime BACnetDateTime,
782 * timeRange [5] SEQUENCE {
783 * beginningTime BACnetDateTime,
784 * endingTime BACnetDateTime
788 * @param tvb the tv buffer of the current data
789 * @param pinfo the packet info of the current data
790 * @param tree the tree to append this item to
791 * @param offset the offset in the tvb
792 * @return modified offset
795 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
798 * ReadRange-ACK ::= SEQUENCE {
799 * objectIdentifier [0] BACnetObjectIdentifier,
800 * propertyIdentifier [1] BACnetPropertyIdentifier,
801 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
802 * resultFlags [3] BACnetResultFlags,
803 * itemCount [4] Unsigned,
804 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
806 * @param tvb the tv buffer of the current data
807 * @param pinfo the packet info of the current data
808 * @param tree the tree to append this item to
809 * @param offset the offset in the tvb
810 * @return modified offset
813 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
816 * RemoveListElement-Request ::= SEQUENCE {
817 * objectIdentifier [0] BACnetObjectIdentifier,
818 * propertyIdentifier [1] BACnetPropertyIdentifier,
819 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
820 * listOfElements [3] ABSTRACT-SYNTAX.&Type
822 * @param tvb the tv buffer of the current data
823 * @param pinfo the packet info of the current data
824 * @param tree the tree to append this item to
825 * @param offset the offset in the tvb
826 * @return modified offset
829 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
832 * WriteProperty-Request ::= SEQUENCE {
833 * objectIdentifier [0] BACnetObjectIdentifier,
834 * propertyIdentifier [1] BACnetPropertyIdentifier,
835 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
836 * propertyValue [3] ABSTRACT-SYNTAX.&Type
837 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
839 * @param tvb the tv buffer of the current data
840 * @param pinfo the packet info of the current data
841 * @param tree the tree to append this item to
842 * @param offset the offset in the tvb
843 * @return modified offset
846 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
849 * WritePropertyMultiple-Request ::= SEQUENCE {
850 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
852 * @param tvb the tv buffer of the current data
853 * @param pinfo the packet info of the current data
854 * @param tree the tree to append this item to
855 * @param offset the offset in the tvb
856 * @return modified offset
859 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
862 * DeviceCommunicationControl-Request ::= SEQUENCE {
863 * timeDuration [0] Unsigned16 OPTIONAL,
864 * enable-disable [1] ENUMERATED {
868 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
870 * @param tvb the tv buffer of the current data
871 * @param pinfo the packet info of the current data
872 * @param tree the tree to append this item to
873 * @param offset the offset in the tvb
874 * @return modified offset
877 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
880 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
881 * vendorID [0] Unsigned,
882 * serviceNumber [1] Unsigned,
883 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
885 * @param tvb the tv buffer of the current data
886 * @param pinfo the packet info of the current data
887 * @param tree the tree to append this item to
888 * @param offset the offset in the tvb
889 * @return modified offset
892 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
895 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
896 * vendorID [0] Unsigned,
897 * serviceNumber [1] Unsigned,
898 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
900 * @param tvb the tv buffer of the current data
901 * @param pinfo the packet info of the current data
902 * @param tree the tree to append this item to
903 * @param offset the offset in the tvb
904 * @return modified offset
907 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
910 * ConfirmedTextMessage-Request ::= SEQUENCE {
911 * textMessageSourceDevice [0] BACnetObjectIdentifier,
912 * messageClass [1] CHOICE {
913 * numeric [0] Unsigned,
914 * character [1] CharacterString
916 * messagePriority [2] ENUMERATED {
920 * message [3] CharacterString
922 * @param tvb the tv buffer of the current data
923 * @param pinfo the packet info of the current data
924 * @param tree the tree to append this item to
925 * @param offset the offset in the tvb
926 * @return modified offset
929 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
932 * ReinitializeDevice-Request ::= SEQUENCE {
933 * reinitializedStateOfDevice [0] ENUMERATED {
942 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
944 * @param tvb the tv buffer of the current data
945 * @param pinfo the packet info of the current data
946 * @param tree the tree to append this item to
947 * @param offset the offset in the tvb
948 * @return modified offset
951 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
954 * VTOpen-Request ::= SEQUENCE {
955 * vtClass BACnetVTClass,
956 * localVTSessionIdentifier Unsigned8
958 * @param tvb the tv buffer of the current data
959 * @param pinfo the packet info of the current data
960 * @param tree the tree to append this item to
961 * @param offset the offset in the tvb
962 * @return modified offset
965 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
968 * VTOpen-ACK ::= SEQUENCE {
969 * remoteVTSessionIdentifier Unsigned8
971 * @param tvb the tv buffer of the current data
972 * @param pinfo the packet info of the current data
973 * @param tree the tree to append this item to
974 * @param offset the offset in the tvb
975 * @return modified offset
978 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
981 * VTClose-Request ::= SEQUENCE {
982 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
984 * @param tvb the tv buffer of the current data
985 * @param pinfo the packet info of the current data
986 * @param tree the tree to append this item to
987 * @param offset the offset in the tvb
988 * @return modified offset
991 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
994 * VTData-Request ::= SEQUENCE {
995 * vtSessionIdentifier Unsigned8,
996 * vtNewData OCTET STRING,
997 * vtDataFlag Unsigned (0..1)
999 * @param tvb the tv buffer of the current data
1000 * @param pinfo the packet info of the current data
1001 * @param tree the tree to append this item to
1002 * @param offset the offset in the tvb
1003 * @return modified offset
1006 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1009 * VTData-ACK ::= SEQUENCE {
1010 * allNewDataAccepted [0] BOOLEAN,
1011 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1013 * @param tvb the tv buffer of the current data
1014 * @param pinfo the packet info of the current data
1015 * @param tree the tree to append this item to
1016 * @param offset the offset in the tvb
1017 * @return modified offset
1020 fVtDataAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1023 * Authenticate-Request ::= SEQUENCE {
1024 * pseudoRandomNumber [0] Unsigned32,
1025 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1026 * operatorName [2] CharacterString OPTIONAL,
1027 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1028 * startEncypheredSession [4] BOOLEAN OPTIONAL
1030 * @param tvb the tv buffer of the current data
1031 * @param pinfo the packet info of the current data
1032 * @param tree the tree to append this item to
1033 * @param offset the offset in the tvb
1034 * @return modified offset
1037 fAuthenticateRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1040 * Authenticate-ACK ::= SEQUENCE {
1041 * modifiedRandomNumber Unsigned32,
1043 * @param tvb the tv buffer of the current data
1044 * @param pinfo the packet info of the current data
1045 * @param tree the tree to append this item to
1046 * @param offset the offset in the tvb
1047 * @return modified offset
1050 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1053 * RequestKey-Request ::= SEQUENCE {
1054 * requestingDeviceIdentifier BACnetObjectIdentifier,
1055 * requestingDeviceAddress BACnetAddress,
1056 * remoteDeviceIdentifier BACnetObjectIdentifier,
1057 * remoteDeviceAddress BACnetAddress
1059 * @param tvb the tv buffer of the current data
1060 * @param pinfo the packet info of the current data
1061 * @param tree the tree to append this item to
1062 * @param offset the offset in the tvb
1063 * @return modified offset
1066 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1069 * Unconfirmed-Service-Request ::= CHOICE {
1071 * @param tvb the tv buffer of the current data
1072 * @param pinfo the packet info of the current data
1073 * @param tree the tree to append this item to
1074 * @param offset the offset in the tvb
1075 * @param service_choice the service choice
1076 * @return modified offset
1079 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1082 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1083 * subscriberProcessIdentifier [0] Unsigned32,
1084 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1085 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1086 * timeRemaining [3] unsigned,
1087 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1089 * @param tvb the tv buffer of the current data
1090 * @param pinfo the packet info of the current data
1091 * @param tree the tree to append this item to
1092 * @param offset the offset in the tvb
1093 * @return modified offset
1096 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1099 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1100 * ProcessIdentifier [0] Unsigned32,
1101 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1102 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1103 * timeStamp [3] BACnetTimeStamp,
1104 * notificationClass [4] unsigned,
1105 * priority [5] unsigned8,
1106 * eventType [6] BACnetEventType,
1107 * messageText [7] CharacterString OPTIONAL,
1108 * notifyType [8] BACnetNotifyType,
1109 * ackRequired [9] BOOLEAN OPTIONAL,
1110 * fromState [10] BACnetEventState OPTIONAL,
1111 * toState [11] BACnetEventState,
1112 * eventValues [12] BACnetNotificationParameters OPTIONAL
1114 * @param tvb the tv buffer of the current data
1115 * @param pinfo the packet info of the current data
1116 * @param tree the tree to append this item to
1117 * @param offset the offset in the tvb
1118 * @return modified offset
1121 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1124 * I-Am-Request ::= SEQUENCE {
1125 * aAmDeviceIdentifier BACnetObjectIdentifier,
1126 * maxAPDULengthAccepted Unsigned,
1127 * segmentationSupported BACnetSegmentation,
1130 * @param tvb the tv buffer of the current data
1131 * @param pinfo the packet info of the current data
1132 * @param tree the tree to append this item to
1133 * @param offset the offset in the tvb
1134 * @return modified offset
1137 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1141 * I-Have-Request ::= SEQUENCE {
1142 * deviceIdentifier BACnetObjectIdentifier,
1143 * objectIdentifier BACnetObjectIdentifier,
1144 * objectName CharacterString
1146 * @param tvb the tv buffer of the current data
1147 * @param pinfo the packet info of the current data
1148 * @param tree the tree to append this item to
1149 * @param offset the offset in the tvb
1150 * @return modified offset
1153 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1156 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1157 * vendorID [0] Unsigned,
1158 * serviceNumber [1] Unsigned,
1159 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1161 * @param tvb the tv buffer of the current data
1162 * @param pinfo the packet info of the current data
1163 * @param tree the tree to append this item to
1164 * @param offset the offset in the tvb
1165 * @return modified offset
1168 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1171 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1172 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1173 * messageClass [1] CHOICE {
1174 * numeric [0] Unsigned,
1175 * character [1] CharacterString
1177 * messagePriority [2] ENUMERATED {
1181 * message [3] CharacterString
1183 * @param tvb the tv buffer of the current data
1184 * @param pinfo the packet info of the current data
1185 * @param tree the tree to append this item to
1186 * @param offset the offset in the tvb
1187 * @return modified offset
1190 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1193 * TimeSynchronization-Request ::= SEQUENCE {
1196 * @param tvb the tv buffer of the current data
1197 * @param pinfo the packet info of the current data
1198 * @param tree the tree to append this item to
1199 * @param offset the offset in the tvb
1200 * @return modified offset
1203 fTimeSynchronizationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1206 * UTCTimeSynchronization-Request ::= SEQUENCE {
1209 * @param tvb the tv buffer of the current data
1210 * @param pinfo the packet info of the current data
1211 * @param tree the tree to append this item to
1212 * @param offset the offset in the tvb
1213 * @return modified offset
1216 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1219 * Who-Has-Request ::= SEQUENCE {
1221 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1222 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1225 * objectIdentifier [2] BACnetObjectIdentifier,
1226 * objectName [3] CharacterString
1229 * @param tvb the tv buffer of the current data
1230 * @param pinfo the packet info of the current data
1231 * @param tree the tree to append this item to
1232 * @param offset the offset in the tvb
1233 * @return modified offset
1236 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1239 * Who-Is-Request ::= SEQUENCE {
1240 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1241 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1243 * @param tvb the tv buffer of the current data
1244 * @param tree the tree to append this item to
1245 * @param offset the offset in the tvb
1246 * @return modified offset
1249 fWhoIsRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1252 * BACnet-Error ::= CHOICE {
1253 * addListElement [8] ChangeList-Error,
1254 * removeListElement [9] ChangeList-Error,
1255 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1256 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1257 * vtClose [22] VTClose-Error,
1258 * readRange [26] ObjectAccessService-Error
1261 * @param tvb the tv buffer of the current data
1262 * @param pinfo the packet info of the current data
1263 * @param tree the tree to append this item to
1264 * @param offset the offset in the tvb
1265 * @param service the service
1266 * @return modified offset
1269 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1272 * Dissect a BACnetError in a context tag
1274 * @param tvb the tv buffer of the current data
1275 * @param pinfo the packet info of the current data
1276 * @param tree the tree to append this item to
1277 * @param offset the offset in the tvb
1278 * @return modified offset
1280 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1283 * ChangeList-Error ::= SEQUENCE {
1284 * errorType [0] Error,
1285 * firstFailedElementNumber [1] Unsigned
1288 * @param tvb the tv buffer of the current data
1289 * @param pinfo the packet info of the current data
1290 * @param tree the tree to append this item to
1291 * @param offset the offset in the tvb
1292 * @return modified offset
1295 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1298 * CreateObject-Error ::= SEQUENCE {
1299 * errorType [0] Error,
1300 * firstFailedElementNumber [1] Unsigned
1303 * @param tvb the tv buffer of the current data
1304 * @param pinfo the packet info of the current data
1305 * @param tree the tree to append this item to
1306 * @param offset the offset in the tvb
1307 * @return modified offset
1310 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1313 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1314 * errorType [0] Error,
1315 * vendorID [1] Unsigned,
1316 * serviceNumber [2] Unsigned,
1317 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1320 * @param tvb the tv buffer of the current data
1321 * @param pinfo the packet info of the current data
1322 * @param tree the tree to append this item to
1323 * @param offset the offset in the tvb
1324 * @return modified offset
1327 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1330 * WritePropertyMultiple-Error ::= SEQUENCE {
1331 * errorType [0] Error,
1332 * firstFailedWriteAttempt [1] Unsigned
1335 * @param tvb the tv buffer of the current data
1336 * @param pinfo the packet info of the current data
1337 * @param tree the tree to append this item to
1338 * @param offset the offset in the tvb
1339 * @return modified offset
1342 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1345 * VTClose-Error ::= SEQUENCE {
1346 * errorType [0] Error,
1347 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1350 * @param tvb the tv buffer of the current data
1351 * @param pinfo the packet info of the current data
1352 * @param tree the tree to append this item to
1353 * @param offset the offset in the tvb
1354 * @return modified offset
1357 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1360 * BACnet Application Types chapter 20.2.1
1361 * @param tvb the tv buffer of the current data
1362 * @param pinfo the packet info of the current data
1363 * @param tree the tree to append this item to
1364 * @param offset the offset in the tvb
1365 * @param label the label of this item
1366 * @return modified offset
1369 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1372 * BACnetActionCommand ::= SEQUENCE {
1373 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1374 * objectIdentifier [1] BACnetObjectIdentifier,
1375 * propertyIdentifier [2] BACnetPropertyIdentifier,
1376 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1377 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1378 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1379 * postDelay [6] Unsigned OPTIONAL,
1380 * quitOnFailure [7] BOOLEAN,
1381 * writeSuccessful [8] BOOLEAN
1383 * @param tvb the tv buffer of the current data
1384 * @param pinfo the packet info of the current data
1385 * @param tree the tree to append this item to
1386 * @param offset the offset in the tvb
1387 * @param tag_match the tag number
1388 * @return modified offset
1391 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1394 * BACnetActionList ::= SEQUENCE {
1395 * action [0] SEQUENCE of BACnetActionCommand
1397 * @param tvb the tv buffer of the current data
1398 * @param pinfo the packet info of the current data
1399 * @param tree the tree to append this item to
1400 * @param offset the offset in the tvb
1401 * @return modified offset
1404 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1406 /** BACnetAddress ::= SEQUENCE {
1407 * network-number Unsigned16, -- A value 0 indicates the local network
1408 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1410 * @param tvb the tv buffer of the current data
1411 * @param pinfo the packet info of the current data
1412 * @param tree the tree to append this item to
1413 * @param offset the offset in the tvb
1414 * @return modified offset
1417 fAddress (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1420 * BACnetAddressBinding ::= SEQUENCE {
1421 * deviceObjectID BACnetObjectIdentifier
1422 * deviceAddress BacnetAddress
1424 * @param tvb the tv buffer of the current data
1425 * @param pinfo the packet info of the current data
1426 * @param tree the tree to append this item to
1427 * @param offset the offset in the tvb
1428 * @return modified offset
1431 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1434 * BACnetCalendarEntry ::= CHOICE {
1436 * dateRange [1] BACnetDateRange,
1437 * weekNDay [2] BacnetWeekNday
1439 * @param tvb the tv buffer of the current data
1440 * @param pinfo the packet info of the current data
1441 * @param tree the tree to append this item to
1442 * @param offset the offset in the tvb
1443 * @return modified offset
1446 fCalendarEntry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1449 * BACnetClientCOV ::= CHOICE {
1450 * real-increment REAL,
1451 * default-increment NULL
1453 * @param tvb the tv buffer of the current data
1454 * @param tree the tree to append this item to
1455 * @param offset the offset in the tvb
1456 * @return modified offset
1459 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1463 * BACnetDailySchedule ::= SEQUENCE {
1464 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1466 * @param tvb the tv buffer of the current data
1467 * @param pinfo the packet info of the current data
1468 * @param tree the tree to append this item to
1469 * @param offset the offset in the tvb
1470 * @return modified offset
1473 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1476 * BACnetWeeklySchedule ::= SEQUENCE {
1477 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1479 * @param tvb the tv buffer of the current data
1480 * @param pinfo the packet info of the current data
1481 * @param tree the tree to append this item to
1482 * @param offset the offset in the tvb
1483 * @return modified offset
1486 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1489 * BACnetDateRange ::= SEQUENCE {
1493 * @param tvb the tv buffer of the current data
1494 * @param pinfo the packet info of the current data
1495 * @param tree the tree to append this item to
1496 * @param offset the offset in the tvb
1497 * @return modified offset
1500 fDateRange (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1503 * BACnetDateTime ::= SEQUENCE {
1507 * @param tvb the tv buffer of the current data
1508 * @param pinfo the packet info of the current data
1509 * @param tree the tree to append this item to
1510 * @param offset the offset in the tvb
1511 * @param label the label of this item
1512 * @return modified offset
1515 fDateTime (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1518 * BACnetDestination ::= SEQUENCE {
1519 * validDays BACnetDaysOfWeek,
1522 * recipient BACnetRecipient,
1523 * processIdentifier Unsigned32,
1524 * issueConfirmedNotifications BOOLEAN,
1525 * transitions BACnetEventTransitionBits
1527 * @param tvb the tv buffer of the current data
1528 * @param pinfo the packet info of the current data
1529 * @param tree the tree to append this item to
1530 * @param offset the offset in the tvb
1531 * @return modified offset
1534 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1537 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1538 * objectIdentifier [0] BACnetObjectIdentifier,
1539 * propertyIdentifier [1] BACnetPropertyIdentifier,
1540 * propertyArrayIndex [2] Unsigend OPTIONAL,
1541 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1543 * @param tvb the tv buffer of the current data
1544 * @param pinfo the packet info of the current data
1545 * @param tree the tree to append this item to
1546 * @param offset the offset in the tvb
1547 * @return modified offset
1550 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1553 * BACnetObjectPropertyReference ::= SEQUENCE {
1554 * objectIdentifier [0] BACnetObjectIdentifier,
1555 * propertyIdentifier [1] BACnetPropertyIdentifier,
1556 * propertyArrayIndex [2] Unsigend OPTIONAL,
1558 * @param tvb the tv buffer of the current data
1559 * @param pinfo the packet info of the current data
1560 * @param tree the tree to append this item to
1561 * @param offset the offset in the tvb
1562 * @return modified offset
1565 fObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1568 * BACnetDeviceObjectReference ::= SEQUENCE {
1569 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1570 * objectIdentifier [1] BACnetObjectIdentifier
1572 * @param tvb the tv buffer of the current data
1573 * @param pinfo the packet info of the current data
1574 * @param tree the tree to append this item to
1575 * @param offset the offset in the tvb
1576 * @return modified offset
1579 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1582 * BACnetEventParameter ::= CHOICE {
1583 * change-of-bitstring [0] SEQUENCE {
1584 * time-delay [0] Unsigned,
1585 * bitmask [1] BIT STRING,
1586 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1588 * change-of-state [1] SEQUENCE {
1589 * time-delay [0] Unsigned,
1590 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1592 * change-of-value [2] SEQUENCE {
1593 * time-delay [0] Unsigned,
1594 * cov-criteria [1] CHOICE {
1595 * bitmask [0] BIT STRING,
1596 * referenced-property-increment [1] REAL
1599 * command-failure [3] SEQUENCE {
1600 * time-delay [0] Unsigned,
1601 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1603 * floating-limit [4] SEQUENCE {
1604 * time-delay [0] Unsigned,
1605 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1606 * low-diff-limit [2] REAL,
1607 * high-diff-limit [3] REAL,
1610 * out-of-range [5] SEQUENCE {
1611 * time-delay [0] Unsigned,
1612 * low-limit [1] REAL,
1613 * high-limit [2] REAL,
1616 * -- context tag 7 is deprecated
1617 * change-of-life-safety [8] SEQUENCE {
1618 * time-delay [0] Unsigned,
1619 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1620 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1621 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1623 * extended [9] SEQUENCE {
1624 * vendor-id [0] Unsigned16,
1625 * extended-event-type [1] Unsigned,
1626 * parameters [2] SEQUENCE OF CHOICE {
1632 * octet OCTET STRING,
1633 * bitstring BIT STRING,
1635 * reference [0] BACnetDeviceObjectPropertyReference
1638 * buffer-ready [10] SEQUENCE {
1639 * notification-threshold [0] Unsigned,
1640 * previous-notification-count [1] Unsigned32
1642 * unsigned-range [11] SEQUENCE {
1643 * time-delay [0] Unsigned,
1644 * low-limit [1] Unsigned,
1645 * high-limit [2] Unsigned,
1647 * -- context tag 12 is reserved for future addenda
1648 * access-event [13] SEQUENCE {
1649 * list-of-access-events [0] SEQUENCE OF BACnetAccessEvent,
1650 * access-event-time-reference [1] BACnetDeviceObjectPropertyReference
1652 * double-out-of-range [14] SEQUENCE {
1653 * time-delay [0] Unsigned,
1654 * low-limit [1] Double,
1655 * high-limit [2] Double,
1656 * deadband [3] Double
1658 * signed-out-of-range [15] SEQUENCE {
1659 * time-delay [0] Unsigned,
1660 * low-limit [1] INTEGER,
1661 * high-limit [2] INTEGER,
1662 * deadband [3] Unsigned
1664 * unsigned-out-of-range [16] SEQUENCE {
1665 * time-delay [0] Unsigned,
1666 * low-limit [1] Unsigned,
1667 * high-limit [2] Unsigned,
1668 * deadband [3] Unsigned
1670 * change-of-characterstring [17] SEQUENCE {
1671 * time-delay [0] Unsigned,
1672 * list-of-alarm-values [1] SEQUENCE OF CharacterString,
1674 * change-of-status-flags [18] SEQUENCE {
1675 * time-delay [0] Unsigned,
1676 * selected-flags [1] BACnetStatusFlags
1679 * @param tvb the tv buffer of the current data
1680 * @param tree the tree to append this item to
1681 * @param offset the offset in the tvb
1682 * @return modified offset
1685 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1690 * BACnetLogRecord ::= SEQUENCE {
1691 * timestamp [0] BACnetDateTime,
1692 * logDatum [1] CHOICE {
1693 * log-status [0] BACnetLogStatus,
1694 * boolean-value [1] BOOLEAN,
1695 * real-value [2] REAL,
1696 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1697 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1698 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1699 * bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
1700 * null-value [7] NULL,
1701 * failure [8] Error,
1702 * time-change [9] REAL,
1703 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1705 * statusFlags [2] BACnetStatusFlags OPTIONAL
1707 * @param tvb the tv buffer of the current data
1708 * @param pinfo the packet info of the current data
1709 * @param tree the tree to append this item to
1710 * @param offset the offset in the tvb
1711 * @return modified offset
1714 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1717 * BACnetEventLogRecord ::= SEQUENCE {
1718 * timestamp [0] BACnetDateTime,
1719 * logDatum [1] CHOICE {
1720 * log-status [0] BACnetLogStatus,
1721 * notification [1] ConfirmedEventNotification-Request,
1722 * time-change [2] REAL,
1725 * @param tvb the tv buffer of the current data
1726 * @param pinfo the packet info of the current data
1727 * @param tree the tree to append this item to
1728 * @param offset the offset in the tvb
1729 * @return modified offset
1732 fEventLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1735 fLogMultipleRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1738 * BACnetNotificationParameters ::= CHOICE {
1739 * change-of-bitstring [0] SEQUENCE {
1740 * referenced-bitstring [0] BIT STRING,
1741 * status-flags [1] BACnetStatusFlags
1743 * change-of-state [1] SEQUENCE {
1744 * new-state [0] BACnetPropertyStatus,
1745 * status-flags [1] BACnetStatusFlags
1747 * change-of-value [2] SEQUENCE {
1748 * new-value [0] CHOICE {
1749 * changed-bits [0] BIT STRING,
1750 * changed-value [1] REAL
1752 * status-flags [1] BACnetStatusFlags
1754 * command-failure [3] SEQUENCE {
1755 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1756 * status-flags [1] BACnetStatusFlags
1757 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1759 * floating-limit [4] SEQUENCE {
1760 * reference-value [0] REAL,
1761 * status-flags [1] BACnetStatusFlags
1762 * setpoint-value [2] REAL,
1763 * error-limit [3] REAL
1765 * out-of-range [5] SEQUENCE {
1766 * exceeding-value [0] REAL,
1767 * status-flags [1] BACnetStatusFlags
1768 * deadband [2] REAL,
1769 * exceeded-limit [3] REAL
1771 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1772 * -- complex tag 7 is deprecated
1773 * change-of-life-safety [8] SEQUENCE {
1774 * new-state [0] BACnetLifeSafetyState,
1775 * new-mode [1] BACnetLifeSafetyState
1776 * status-flags [2] BACnetStatusFlags,
1777 * operation-expected [3] BACnetLifeSafetyOperation
1779 * extended [9] SEQUENCE {
1780 * vendor-id [0] Unsigned16,
1781 * extended-event-type [1] Unsigned,
1782 * parameters [2] SEQUENCE OF CHOICE {
1788 * octet OCTET STRING,
1789 * bitstring BIT STRING,
1791 * propertyValue [0] BACnetDeviceObjectPropertyValue
1794 * buffer-ready [10] SEQUENCE {
1795 * buffer-property [0] BACnetDeviceObjectPropertyReference,
1796 * previous-notification[1] Unsigned32,
1797 * current-notification [2] BACneUnsigned32tDateTime
1799 * unsigned-range [11] SEQUENCE {
1800 * exceeding-value [0] Unsigned,
1801 * status-flags [1] BACnetStatusFlags,
1802 * exceeded-limit [2] Unsigned
1804 * -- context tag 12 is reserved for future addenda
1805 * access-event [13] SEQUENCE {
1806 * access-event [0] BACnetAccessEvent,
1807 * status-flags [1] BACnetStatusFlags,
1808 * access-event-tag [2] Unsigned,
1809 * access-event-time [3] BACnetTimeStamp,
1810 * access-credential [4] BACnetDeviceObjectReference,
1811 * authentication-factor [5] BACnetAuthenticationFactor OPTIONAL
1813 * double-out-of-range [14] SEQUENCE {
1814 * exceeding-value [0] Double,
1815 * status-flags [1] BACnetStatusFlags
1816 * deadband [2] Double,
1817 * exceeded-limit [3] Double
1819 * signed-out-of-range [15] SEQUENCE {
1820 * exceeding-value [0] INTEGER,
1821 * status-flags [1] BACnetStatusFlags
1822 * deadband [2] Unsigned,
1823 * exceeded-limit [3] INTEGER
1825 * unsigned-out-of-range [16] SEQUENCE {
1826 * exceeding-value [0] Unsigned,
1827 * status-flags [1] BACnetStatusFlags
1828 * deadband [2] Unsigned,
1829 * exceeded-limit [3] Unsigned
1831 * change-of-characterstring [17] SEQUENCE {
1832 * changed-value [0] CharacterString,
1833 * status-flags [1] BACnetStatusFlags
1834 * alarm-value [2] CharacterString
1836 * change-of-status-flags [18] SEQUENCE {
1837 * present-value [0] ABSTRACT-SYNTAX.&Type OPTIONAL,
1838 * -- depends on referenced property
1839 * referenced-flags [1] BACnetStatusFlags
1842 * @param tvb the tv buffer of the current data
1843 * @param pinfo the packet info of the current data
1844 * @param tree the tree to append this item to
1845 * @param offset the offset in the tvb
1846 * @return modified offset
1849 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1852 * BACnetObjectPropertyReference ::= SEQUENCE {
1853 * objectIdentifier [0] BACnetObjectIdentifier,
1854 * propertyIdentifier [1] BACnetPropertyIdentifier,
1855 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1857 * @param tvb the tv buffer of the current data
1858 * @param pinfo the packet info of the current data
1859 * @param tree the tree to append this item to
1860 * @param offset the offset in the tvb
1861 * @return modified offset
1864 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1868 * BACnetObjectPropertyValue ::= SEQUENCE {
1869 * objectIdentifier [0] BACnetObjectIdentifier,
1870 * propertyIdentifier [1] BACnetPropertyIdentifier,
1871 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1872 * -- if omitted with an array the entire array is referenced
1873 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1874 * priority [4] Unsigned (1..16) OPTIONAL
1876 * @param tvb the tv buffer of the current data
1877 * @param tree the tree to append this item to
1878 * @param offset the offset in the tvb
1879 * @return modified offset
1882 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
1886 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1887 * @param tvb the tv buffer of the current data
1888 * @param pinfo the packet info of the current data
1889 * @param tree the tree to append this item to
1890 * @param offset the offset in the tvb
1891 * @return modified offset
1894 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1897 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1900 * BACnetPropertyReference ::= SEQUENCE {
1901 * propertyIdentifier [0] BACnetPropertyIdentifier,
1902 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1904 * @param tvb the tv buffer of the current data
1905 * @param pinfo the packet info of the current data
1906 * @param tree the tree to append this item to
1907 * @param offset the offset in the tvb
1908 * @return modified offset
1911 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1914 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1917 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1920 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1923 * BACnetPropertyValue ::= SEQUENCE {
1924 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1925 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1926 * -- if omitted with an array the entire array is referenced
1927 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1928 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1930 * @param tvb the tv buffer of the current data
1931 * @param pinfo the packet info of the current data
1932 * @param tree the tree to append this item to
1933 * @param offset the offset in the tvb
1934 * @return modified offset
1937 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1940 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1943 * BACnet Application PDUs chapter 21
1944 * BACnetRecipient::= CHOICE {
1945 * device [0] BACnetObjectIdentifier
1946 * address [1] BACnetAddress
1948 * @param tvb the tv buffer of the current data
1949 * @param pinfo the packet info of the current data
1950 * @param tree the tree to append this item to
1951 * @param offset the offset in the tvb
1952 * @return modified offset
1955 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1958 * BACnet Application PDUs chapter 21
1959 * BACnetRecipientProcess::= SEQUENCE {
1960 * recipient [0] BACnetRecipient
1961 * processID [1] Unsigned32
1963 * @param tvb the tv buffer of the current data
1964 * @param pinfo the packet info of the current data
1965 * @param tree the tree to append this item to
1966 * @param offset the offset in the tvb
1967 * @return modified offset
1970 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1973 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1977 * BACnetSessionKey ::= SEQUENCE {
1978 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1979 * peerAddress BACnetAddress
1981 * @param tvb the tv buffer of the current data
1982 * @param tree the tree to append this item to
1983 * @param offset the offset in the tvb
1984 * @return modified offset
1985 * @todo check if checksum is displayed correctly
1988 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
1992 * BACnetSpecialEvent ::= SEQUENCE {
1994 * calendarEntry [0] BACnetCalendarEntry,
1995 * calendarRefernce [1] BACnetObjectIdentifier
1997 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1998 * eventPriority [3] Unsigned (1..16)
2000 * @param tvb the tv buffer of the current data
2001 * @param pinfo the packet info of the current data
2002 * @param tree the tree to append this item to
2003 * @param offset the offset in the tvb
2004 * @return modified offset
2007 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2010 * BACnetTimeStamp ::= CHOICE {
2012 * sequenceNumber [1] Unsigned (0..65535),
2013 * dateTime [2] BACnetDateTime
2015 * @param tvb the tv buffer of the current data
2016 * @param pinfo the packet info of the current data
2017 * @param tree the tree to append this item to
2018 * @param offset the offset in the tvb
2019 * @param label the label of this item
2020 * @return modified offset
2023 fTimeStamp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2026 fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2029 * BACnetTimeValue ::= SEQUENCE {
2031 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
2033 * @param tvb the tv buffer of the current data
2034 * @param pinfo the packet info of the current data
2035 * @param tree the tree to append this item to
2036 * @param offset the offset in the tvb
2037 * @return modified offset
2040 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2044 * BACnetVTSession ::= SEQUENCE {
2045 * local-vtSessionID Unsigned8,
2046 * remote-vtSessionID Unsigned8,
2047 * remote-vtAddress BACnetAddress
2049 * @param tvb the tv buffer of the current data
2050 * @param tree the tree to append this item to
2051 * @param offset the offset in the tvb
2052 * @return modified offset
2055 fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
2059 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
2060 * -- first octet month (1..12) January = 1, X'FF' = any month
2061 * -- second octet weekOfMonth where: 1 = days numbered 1-7
2062 * -- 2 = days numbered 8-14
2063 * -- 3 = days numbered 15-21
2064 * -- 4 = days numbered 22-28
2065 * -- 5 = days numbered 29-31
2066 * -- 6 = last 7 days of this month
2067 * -- X'FF' = any week of this month
2068 * -- third octet dayOfWeek (1..7) where 1 = Monday
2070 * -- X'FF' = any day of week
2071 * @param tvb the tv buffer of the current data
2072 * @param pinfo the packet info of the current data
2073 * @param tree the tree to append this item to
2074 * @param offset the offset in the tvb
2075 * @return modified offset
2078 fWeekNDay (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2081 * ReadAccessResult ::= SEQUENCE {
2082 * objectIdentifier [0] BACnetObjectIdentifier,
2083 * listOfResults [1] SEQUENCE OF SEQUENCE {
2084 * propertyIdentifier [2] BACnetPropertyIdentifier,
2085 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
2086 * readResult CHOICE {
2087 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
2088 * propertyAccessError [5] Error
2092 * @param tvb the tv buffer of the current data
2093 * @param pinfo the packet info of the current data
2094 * @param tree the tree to append this item to
2095 * @param offset the offset in the tvb
2096 * @return modified offset
2099 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2102 * ReadAccessSpecification ::= SEQUENCE {
2103 * objectIdentifier [0] BACnetObjectIdentifier,
2104 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
2106 * @param tvb the tv buffer of the current data
2107 * @param pinfo the packet info of the current data
2108 * @param subtree the subtree to append this item to
2109 * @param offset the offset in the tvb
2110 * @return modified offset
2113 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2116 * WriteAccessSpecification ::= SEQUENCE {
2117 * objectIdentifier [0] BACnetObjectIdentifier,
2118 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
2120 * @param tvb the tv buffer of the current data
2121 * @param pinfo the packet info of the current data
2122 * @param subtree the sub tree to append this item to
2123 * @param offset the offset in the tvb
2124 * @return modified offset
2127 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2130 /********************************************************* Helper functions *******************************************/
2133 * extracts the tag number from the tag header.
2134 * @param tvb the tv buffer of the current data "TestyVirtualBuffer"
2135 * @param offset the offset in the tvb in actual tvb
2136 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
2139 fTagNo (tvbuff_t *tvb, guint offset);
2142 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
2143 * @param tvb the tv buffer of the current data = "TestyVirtualBuffer"
2144 * @param pinfo the packet info of the current data = packet info
2145 * @param offset the offset in the tvb = offset in actual tvb
2146 * @return tag_no BACnet 20.2.1.2 Tag Number
2147 * @return class_tag BACnet 20.2.1.1 Class
2148 * @return lvt BACnet 20.2.1.3 Length/Value/Type
2149 * @return offs = length of this header
2153 fTagHeader (tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
2157 * adds processID with max 32Bit unsigned Integer Value to tree
2158 * @param tvb the tv buffer of the current data
2159 * @param pinfo the packet info of the current data
2160 * @param tree the tree to append this item to
2161 * @param offset the offset in the tvb
2162 * @return modified offset
2165 fProcessId (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2168 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2169 * @param tvb the tv buffer of the current data
2170 * @param pinfo the packet info of the current data
2171 * @param tree the tree to append this item to
2172 * @param offset the offset in the tvb
2173 * @return modified offset
2176 fTimeSpan (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2179 * BACnet Application PDUs chapter 21
2180 * BACnetPropertyIdentifier::= ENUMERATED {
2181 * @see bacapp_property_identifier
2183 * @param tvb the tv buffer of the current data
2184 * @param pinfo the packet info of the current data
2185 * @param tree the tree to append this item to
2186 * @param offset the offset in the tvb
2187 * @return modified offset
2190 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2193 * BACnet Application PDUs chapter 21
2194 * BACnetPropertyArrayIndex::= ENUMERATED {
2195 * @see bacapp_property_array_index
2197 * @param tvb the tv buffer of the current data
2198 * @param pinfo the packet info of the current data
2199 * @param tree the tree to append this item to
2200 * @param offset the offset in the tvb
2201 * @return modified offset
2204 fPropertyArrayIndex (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2207 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2208 * objectIdentifier [0] BACnetObjectIdentifier,
2209 * eventState [1] BACnetEventState,
2210 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2211 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2212 * notifyType [4] BACnetNotifyType,
2213 * eventEnable [5] BACnetEventTransitionBits,
2214 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2216 * @param tvb the tv buffer of the current data
2217 * @param pinfo the packet info of the current data
2218 * @param tree the tree to append this item to
2219 * @param offset the offset in the tvb
2220 * @return modified offset
2223 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2226 * SelectionCriteria ::= SEQUENCE {
2227 * propertyIdentifier [0] BACnetPropertyIdentifier,
2228 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2229 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2230 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2232 * @param tvb the tv buffer of the current data
2233 * @param pinfo the packet info of the current data
2234 * @param tree the tree to append this item to
2235 * @param offset the offset in the tvb
2236 * @return modified offset
2239 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2242 * objectSelectionCriteria ::= SEQUENCE {
2243 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2244 * listOfSelectionCriteria [1] SelectionCriteria
2246 * @param tvb the tv buffer of the current data
2247 * @param pinfo the packet info of the current data
2248 * @param subtree the sub tree to append this item to
2249 * @param offset the offset in the tvb
2250 * @return modified offset
2253 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2256 * BACnet-Error ::= SEQUENCE {
2257 * error-class ENUMERATED {},
2258 * error-code ENUMERATED {}
2261 * @param tvb the tv buffer of the current data
2262 * @param pinfo the packet info of the current data
2263 * @param tree the tree to append this item to
2264 * @param offset the offset in the tvb
2265 * @return modified offset
2268 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2271 * Generic handler for context tagged values. Mostly for handling
2272 * vendor-defined properties and services.
2273 * @param tvb the tv buffer of the current data
2274 * @param pinfo the packet info of the current data
2275 * @param tree the tree to append this item to
2276 * @param offset the offset in the tvb
2277 * @return modified offset
2278 * @todo beautify this ugly construct
2281 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2284 * realizes some ABSTRACT-SYNTAX.&Type
2285 * @param tvb the tv buffer of the current data
2286 * @param pinfo the packet info of the current data
2287 * @param tree the tree to append this item to
2288 * @param offset the offset in the tvb
2289 * @return modified offset
2290 * @todo beautify this ugly construct
2293 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2297 fBitStringTagVS (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
2298 const value_string *src);
2304 proto_register_bacapp(void);
2307 * proto_reg_handoff_bacapp
2310 proto_reg_handoff_bacapp(void);
2313 * converts XXX coded strings to UTF-8
2314 * else 'in' is copied to 'out'
2315 * @param in -- pointer to string
2316 * @param inbytesleft size of int bytes
2317 * @param out -- pointer to string
2318 * @param outbytesleft size of out bytes
2319 * @param fromcoding coding type
2320 * @return count of modified characters of returned string, -1 for errors
2323 fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
2326 uni_to_string(char * data, gsize str_length, char *dest_buf);
2328 /* <<<< formerly bacapp.h */
2330 /* reassembly table for segmented messages */
2331 static reassembly_table msg_reassembly_table;
2333 /* some necessary forward function prototypes */
2335 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2336 const gchar *label, const value_string *vs);
2338 static const char *bacapp_unknown_service_str = "unknown service"; /* Usage: no format specifiers */
2339 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2340 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2342 static const value_string
2343 BACnetTypeName[] = {
2344 { 0, "Confirmed-REQ"},
2345 { 1, "Unconfirmed-REQ"},
2347 { 3, "Complex-ACK"},
2348 { 4, "Segment-ACK"},
2355 static const true_false_string segments_follow = {
2356 "Segmented Request",
2357 "Unsegmented Request"
2360 static const true_false_string more_follow = {
2361 "More Segments Follow",
2362 "No More Segments Follow"
2365 static const true_false_string segmented_accept = {
2366 "Segmented Response accepted",
2367 "Segmented Response not accepted"
2370 static const true_false_string
2372 "Context Specific Tag",
2376 static const value_string
2377 BACnetMaxSegmentsAccepted [] = {
2378 { 0, "Unspecified"},
2382 { 4, "16 segments"},
2383 { 5, "32 segments"},
2384 { 6, "64 segments"},
2385 { 7, "Greater than 64 segments"},
2389 static const value_string
2390 BACnetMaxAPDULengthAccepted [] = {
2391 { 0, "Up to MinimumMessageSize (50 octets)"},
2392 { 1, "Up to 128 octets"},
2393 { 2, "Up to 206 octets (fits in a LonTalk frame)"},
2394 { 3, "Up to 480 octets (fits in an ARCNET frame)"},
2395 { 4, "Up to 1024 octets"},
2396 { 5, "Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2397 { 6, "reserved by ASHRAE"},
2398 { 7, "reserved by ASHRAE"},
2399 { 8, "reserved by ASHRAE"},
2400 { 9, "reserved by ASHRAE"},
2401 { 10, "reserved by ASHRAE"},
2402 { 11, "reserved by ASHRAE"},
2403 { 12, "reserved by ASHRAE"},
2404 { 13, "reserved by ASHRAE"},
2405 { 14, "reserved by ASHRAE"},
2406 { 15, "reserved by ASHRAE"},
2410 static const value_string
2411 BACnetRejectReason [] = {
2413 {1, "buffer-overflow"},
2414 {2, "inconsistent-parameters"},
2415 {3, "invalid-parameter-data-type"},
2417 {5, "missing-required-parameter"},
2418 {6, "parameter-out-of-range"},
2419 {7, "too-many-arguments"},
2420 {8, "undefined-enumeration"},
2421 {9, "unrecognized-service"},
2425 static const value_string
2426 BACnetRestartReason [] = {
2430 { 3, "detected-power-lost"},
2431 { 4, "detected-powered-off"},
2432 { 5, "hardware-watchdog"},
2433 { 6, "software-watchdog"},
2438 static const value_string
2439 BACnetApplicationTagNumber [] = {
2442 { 2, "Unsigned Integer"},
2443 { 3, "Signed Integer (2's complement notation)"},
2444 { 4, "Real (ANSI/IEE-754 floating point)"},
2445 { 5, "Double (ANSI/IEE-754 double precision floating point)"},
2446 { 6, "Octet String"},
2447 { 7, "Character String"},
2452 { 12, "BACnetObjectIdentifier"},
2453 { 13, "reserved by ASHRAE"},
2454 { 14, "reserved by ASHRAE"},
2455 { 15, "reserved by ASHRAE"},
2459 static const value_string
2466 static const value_string
2467 BACnetAccessEvent [] = {
2471 { 3, "passback-detected"},
2474 { 6, "lockout-max-attempts"},
2475 { 7, "lockout-other"},
2476 { 8, "lockout-relinquished"},
2477 { 9, "lockout-by-higher-priority"},
2478 { 10, "out-of-service"},
2479 { 11, "out-of-service-relinquished"},
2480 { 12, "accompaniment-by"},
2481 { 13, "authentication-factor-read"},
2482 { 14, "authorization-delayed"},
2483 { 15, "verification-required"},
2484 /* Enumerated values 128-511 are used for events
2485 * which indicate that access has been denied. */
2486 { 128, "denied-deny-all"},
2487 { 129, "denied-unknown-credential"},
2488 { 130, "denied-authentication-unavailable"},
2489 { 131, "denied-authentication-factor-timeout"},
2490 { 132, "denied-incorrect-authentication-factor"},
2491 { 133, "denied-zone-no-access-rights"},
2492 { 134, "denied-point-no-access-rights"},
2493 { 135, "denied-no-access-rights"},
2494 { 136, "denied-out-of-time-range"},
2495 { 137, "denied-threat-level"},
2496 { 138, "denied-passback"},
2497 { 139, "denied-unexpected-location-usage"},
2498 { 140, "denied-max-attempts"},
2499 { 141, "denied-lower-occupancy-limit"},
2500 { 142, "denied-upper-occupancy-limit"},
2501 { 143, "denied-authentication-factor-lost"},
2502 { 144, "denied-authentication-factor-stolen"},
2503 { 145, "denied-authentication-factor-damaged"},
2504 { 146, "denied-authentication-factor-destroyed"},
2505 { 147, "denied-authentication-factor-disabled"},
2506 { 148, "denied-authentication-factor-error"},
2507 { 149, "denied-credential-unassigned"},
2508 { 150, "denied-credential-not-provisioned"},
2509 { 151, "denied-credential-not-yet-active"},
2510 { 152, "denied-credential-expired"},
2511 { 153, "denied-credential-manual-disable"},
2512 { 154, "denied-credential-lockout"},
2513 { 155, "denied-credential-max-days"},
2514 { 156, "denied-credential-max-uses"},
2515 { 157, "denied-credential-inactivity"},
2516 { 158, "denied-credential-disabled"},
2517 { 159, "denied-no-accompaniment"},
2518 { 160, "denied-incorrect-accompaniment"},
2519 { 161, "denied-lockout"},
2520 { 162, "denied-verification-failed"},
2521 { 163, "denied-verification-timeout"},
2522 { 164, "denied-other"},
2524 /* Enumerated values 0-512 are reserved for definition by ASHRAE.
2525 Enumerated values 512-65535 may be used by others subject to
2526 procedures and constraints described in Clause 23. */
2529 static const value_string
2530 BACnetFileAccessMethod [] = {
2531 { 0, "record-access"},
2532 { 1, "stream-access"},
2536 /* For some reason, BACnet defines the choice parameter
2537 in the file read and write services backwards from the
2538 BACnetFileAccessMethod enumeration.
2540 static const value_string
2541 BACnetFileAccessOption [] = {
2542 { 0, "stream access"},
2543 { 1, "record access"},
2547 static const value_string
2548 BACnetFileStartOption [] = {
2549 { 0, "File Start Position: "},
2550 { 1, "File Start Record: "},
2554 static const value_string
2555 BACnetFileRequestCount [] = {
2556 { 0, "Requested Octet Count: "},
2557 { 1, "Requested Record Count: "},
2561 static const value_string
2562 BACnetFileWriteInfo [] = {
2563 { 0, "File Data: "},
2564 { 1, "Record Count: "},
2568 static const value_string
2569 BACnetAbortReason [] = {
2571 { 1, "buffer-overflow"},
2572 { 2, "invalid-apdu-in-this-state"},
2573 { 3, "preempted-by-higher-priority-task"},
2574 { 4, "segmentation-not-supported"},
2578 static const value_string
2579 BACnetLifeSafetyMode [] = {
2590 { 10, "disconnected"},
2593 { 13, "atomic-release-disabled"},
2596 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2597 Enumerated values 256-65535 may be used by others subject to
2598 procedures and constraints described in Clause 23. */
2601 static const value_string
2602 BACnetLifeSafetyOperation [] = {
2605 { 2, "silence-audible"},
2606 { 3, "silence-visual"},
2608 { 5, "reset-alarm"},
2609 { 6, "reset-fault"},
2611 { 8, "unsilence-audible"},
2612 { 9, "unsilence-visual"},
2614 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2615 Enumerated values 64-65535 may be used by others subject to
2616 procedures and constraints described in Clause 23. */
2619 static const value_string
2620 BACnetLimitEnable [] = {
2621 { 0, "lowLimitEnable"},
2622 { 1, "highLimitEnable"},
2626 static const value_string
2627 BACnetLifeSafetyState [] = {
2632 { 4, "fault-pre-alarm"},
2633 { 5, "fault-alarm"},
2638 { 10, "test-active"},
2639 { 11, "test-fault"},
2640 { 12, "test-fault-alarm"},
2643 { 15, "tamper-alarm"},
2645 { 17, "emergency-power"},
2648 { 20, "local-alarm"},
2649 { 21, "general-alarm"},
2650 { 22, "supervisory"},
2651 { 23, "test-supervisory"},
2653 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2654 Enumerated values 256-65535 may be used by others subject to
2655 procedures and constraints described in Clause 23. */
2658 static const value_string
2659 BACnetConfirmedServiceChoice [] = {
2660 { 0, "acknowledgeAlarm"},
2661 { 1, "confirmedCOVNotification"},
2662 { 2, "confirmedEventNotification"},
2663 { 3, "getAlarmSummary"},
2664 { 4, "getEnrollmentSummary"},
2665 { 5, "subscribeCOV"},
2666 { 6, "atomicReadFile"},
2667 { 7, "atomicWriteFile"},
2668 { 8, "addListElement"},
2669 { 9, "removeListElement"},
2670 { 10, "createObject"},
2671 { 11, "deleteObject"},
2672 { 12, "readProperty"},
2673 { 13, "readPropertyConditional"},
2674 { 14, "readPropertyMultiple"},
2675 { 15, "writeProperty"},
2676 { 16, "writePropertyMultiple"},
2677 { 17, "deviceCommunicationControl"},
2678 { 18, "confirmedPrivateTransfer"},
2679 { 19, "confirmedTextMessage"},
2680 { 20, "reinitializeDevice"},
2684 { 24, "authenticate"},
2685 { 25, "requestKey"},
2687 { 27, "lifeSafetyOperation"},
2688 { 28, "subscribeCOVProperty"},
2689 { 29, "getEventInformation"},
2690 { 30, "reserved by ASHRAE"},
2694 static const value_string
2695 BACnetReliability [] = {
2696 { 0, "no-fault-detected"},
2699 { 3, "under-range"},
2701 { 5, "shorted-loop"},
2703 { 7, "unreliable-other"},
2704 { 8, "process-error"},
2705 { 9, "multi-state-fault"},
2706 { 10, "configuration-error"},
2707 /* enumeration value 11 is reserved for a future addendum */
2708 { 12, "communication-failure"},
2709 { 13, "member-fault"},
2713 static const value_string
2714 BACnetUnconfirmedServiceChoice [] = {
2717 { 2, "unconfirmedCOVNotification"},
2718 { 3, "unconfirmedEventNotification"},
2719 { 4, "unconfirmedPrivateTransfer"},
2720 { 5, "unconfirmedTextMessage"},
2721 { 6, "timeSynchronization"},
2724 { 9, "utcTimeSynchronization"},
2728 static const value_string
2729 BACnetUnconfirmedServiceRequest [] = {
2730 { 0, "i-Am-Request"},
2731 { 1, "i-Have-Request"},
2732 { 2, "unconfirmedCOVNotification-Request"},
2733 { 3, "unconfirmedEventNotification-Request"},
2734 { 4, "unconfirmedPrivateTransfer-Request"},
2735 { 5, "unconfirmedTextMessage-Request"},
2736 { 6, "timeSynchronization-Request"},
2737 { 7, "who-Has-Request"},
2738 { 8, "who-Is-Request"},
2739 { 9, "utcTimeSynchonization-Request"},
2743 static const value_string
2744 BACnetObjectType [] = {
2745 { 0, "analog-input"},
2746 { 1, "analog-output"},
2747 { 2, "analog-value"},
2748 { 3, "binary-input"},
2749 { 4, "binary-output"},
2750 { 5, "binary-value"},
2754 { 9, "event-enrollment"},
2758 { 13, "multi-state-input"},
2759 { 14, "multi-state-output"},
2760 { 15, "notification-class"},
2764 { 19, "multi-state-value"},
2766 { 21, "life-safety-point"},
2767 { 22, "life-safety-zone"},
2768 { 23, "accumulator"},
2769 { 24, "pulse-converter"},
2771 { 26, "global-group"},
2772 { 27, "trend-log-multiple"},
2773 { 28, "load-control"},
2774 { 29, "structured-view"},
2775 { 30, "access-door"}, /* 30-37 added with addanda 135-2008j */
2776 /* value 31 is unassigned */
2777 { 32, "access-credential"},
2778 { 33, "access-point"},
2779 { 34, "access-rights"},
2780 { 35, "access-user"},
2781 { 36, "access-zone"},
2782 { 37, "credential-data-input"},
2783 { 38, "network-security"},
2784 { 39, "bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2785 { 40, "characterstring-value"},
2786 { 41, "date-pattern-value"},
2787 { 42, "date-value"},
2788 { 43, "datetime-pattern-value"},
2789 { 44, "datetime-value"},
2790 { 45, "integer-value"},
2791 { 46, "large-analog-value"},
2792 { 47, "octetstring-value"},
2793 { 48, "positive-integer-value"},
2794 { 49, "time-pattern-value"},
2795 { 50, "time-value"},
2797 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2798 Enumerated values 128-1023 may be used by others subject to
2799 the procedures and constraints described in Clause 23. */
2802 static const value_string
2803 BACnetEngineeringUnits [] = {
2806 { 2, "Milliamperes"},
2812 { 8, "Volt Amperes"},
2813 { 9, "Kilovolt Amperes"},
2814 { 10, "Megavolt Amperes"},
2815 { 11, "Volt Amperes Reactive"},
2816 { 12, "Kilovolt Amperes Reactive"},
2817 { 13, "Megavolt Amperes Reactive"},
2818 { 14, "Degrees Phase"},
2819 { 15, "Power Factor"},
2821 { 17, "Kilojoules"},
2822 { 18, "Watt Hours"},
2823 { 19, "Kilowatt Hours"},
2827 { 23, "Joules Per Kg Dry Air"},
2828 { 24, "BTUs Per Pound Dry Air"},
2829 { 25, "Cycles Per Hour"},
2830 { 26, "Cycles Per Minute"},
2832 { 28, "Grams Of Water Per Kilogram Dry Air"},
2833 { 29, "Relative Humidity"},
2834 { 30, "Millimeters"},
2838 { 34, "Watts Per Sq Foot"},
2839 { 35, "Watts Per Sq meter"},
2842 { 38, "Foot Candles"},
2844 { 40, "Pounds Mass"},
2846 { 42, "Kgs per Second"},
2847 { 43, "Kgs Per Minute"},
2848 { 44, "Kgs Per Hour"},
2849 { 45, "Pounds Mass Per Minute"},
2850 { 46, "Pounds Mass Per Hour"},
2854 { 50, "BTUs Per Hour"},
2855 { 51, "Horsepower"},
2856 { 52, "Tons Refrigeration"},
2858 { 54, "Kilopascals"},
2860 { 56, "Pounds Force Per Square Inch"},
2861 { 57, "Centimeters Of Water"},
2862 { 58, "Inches Of Water"},
2863 { 59, "Millimeters Of Mercury"},
2864 { 60, "Centimeters Of Mercury"},
2865 { 61, "Inches Of Mercury"},
2866 { 62, "Degrees Celsius"},
2867 { 63, "Degrees Kelvin"},
2868 { 64, "Degrees Fahrenheit"},
2869 { 65, "Degree Days Celsius"},
2870 { 66, "Degree Days Fahrenheit"},
2878 { 74, "Meters Per Second"},
2879 { 75, "Kilometers Per Hour"},
2880 { 76, "Feed Per Second"},
2881 { 77, "Feet Per Minute"},
2882 { 78, "Miles Per Hour"},
2883 { 79, "Cubic Feet"},
2884 { 80, "Cubic Meters"},
2885 { 81, "Imperial Gallons"},
2887 { 83, "US Gallons"},
2888 { 84, "Cubic Feet Per Minute"},
2889 { 85, "Cubic Meters Per Second"},
2890 { 86, "Imperial Gallons Per Minute"},
2891 { 87, "Liters Per Second"},
2892 { 88, "Liters Per Minute"},
2893 { 89, "US Gallons Per Minute"},
2894 { 90, "Degrees Angular"},
2895 { 91, "Degrees Celsius Per Hour"},
2896 { 92, "Degrees Celsius Per Minute"},
2897 { 93, "Degrees Fahrenheit Per Hour"},
2898 { 94, "Degrees Fahrenheit Per Minute"},
2900 { 96, "Parts Per Million"},
2901 { 97, "Parts Per Billion"},
2903 { 99, "Pecent Per Second"},
2904 { 100, "Per Minute"},
2905 { 101, "Per Second"},
2906 { 102, "Psi Per Degree Fahrenheit"},
2908 { 104, "Revolutions Per Min"},
2909 { 105, "Currency1"},
2910 { 106, "Currency2"},
2911 { 107, "Currency3"},
2912 { 108, "Currency4"},
2913 { 109, "Currency5"},
2914 { 110, "Currency6"},
2915 { 111, "Currency7"},
2916 { 112, "Currency8"},
2917 { 113, "Currency9"},
2918 { 114, "Currency10"},
2919 { 115, "Sq Inches"},
2920 { 116, "Sq Centimeters"},
2921 { 117, "BTUs Per Pound"},
2922 { 118, "Centimeters"},
2923 { 119, "Pounds Mass Per Second"},
2924 { 120, "Delta Degrees Fahrenheit"},
2925 { 121, "Delta Degrees Kelvin"},
2928 { 124, "Millivolts"},
2929 { 125, "Kilojoules Per Kg"},
2930 { 126, "Megajoules"},
2931 { 127, "Joules Per Degree Kelvin"},
2932 { 128, "Joules Per Kg Degree Kelvin"},
2933 { 129, "Kilohertz"},
2934 { 130, "Megahertz"},
2936 { 132, "Milliwatts"},
2937 { 133, "Hectopascals"},
2938 { 134, "Millibars"},
2939 { 135, "Cubic Meters Per Hour"},
2940 { 136, "Liters Per Hour"},
2941 { 137, "KWatt Hours Per Square Meter"},
2942 { 138, "KWatt Hours Per Square Foot"},
2943 { 139, "Megajoules Per Square Meter"},
2944 { 140, "Megajoules Per Square Foot"},
2945 { 141, "Watts Per Sq Meter Degree Kelvin"},
2946 { 142, "Cubic Feet Per Second"},
2947 { 143, "Percent Obstruction Per Foot"},
2948 { 144, "Percent Obstruction Per Meter"},
2949 { 145, "milliohms"},
2950 { 146, "megawatt-hours"},
2951 { 147, "kilo-btus"},
2952 { 148, "mega-btus"},
2953 { 149, "kilojoules-per-kilogram-dry-air"},
2954 { 150, "megajoules-per-kilogram-dry-air"},
2955 { 151, "kilojoules-per-degree-Kelvin"},
2956 { 152, "megajoules-per-degree-Kelvin"},
2958 { 154, "grams-per-second"},
2959 { 155, "grams-per-minute"},
2960 { 156, "tons-per-hour"},
2961 { 157, "kilo-btus-per-hour"},
2962 { 158, "hundredths-seconds"},
2963 { 159, "milliseconds"},
2964 { 160, "newton-meters"},
2965 { 161, "millimeters-per-second"},
2966 { 162, "millimeters-per-minute"},
2967 { 163, "meters-per-minute"},
2968 { 164, "meters-per-hour"},
2969 { 165, "cubic-meters-per-minute"},
2970 { 166, "meters-per-second-per-second"},
2971 { 167, "amperes-per-meter"},
2972 { 168, "amperes-per-square-meter"},
2973 { 169, "ampere-square-meters"},
2976 { 172, "ohm-meters"},
2978 { 174, "siemens-per-meter"},
2980 { 176, "volts-per-degree-Kelvin"},
2981 { 177, "volts-per-meter"},
2984 { 180, "candelas-per-square-meter"},
2985 { 181, "degrees-Kelvin-per-hour"},
2986 { 182, "degrees-Kelvin-per-minute"},
2987 { 183, "joule-seconds"},
2988 { 184, "radians-per-second"},
2989 { 185, "square-meters-per-Newton"},
2990 { 186, "kilograms-per-cubic-meter"},
2991 { 187, "newton-seconds"},
2992 { 188, "newtons-per-meter"},
2993 { 189, "watts-per-meter-per-degree-Kelvin"},
2994 { 190, "micro-siemens"},
2995 { 191, "cubic-feet-per-hour"},
2996 { 192, "us-gallons-per-hour"},
2997 { 193, "kilometers"},
2998 { 194, "micrometers"},
3000 { 196, "milligrams"},
3001 { 197, "milliliters"},
3002 { 198, "milliliters-per-second"},
3004 { 200, "decibels-millivolt"},
3005 { 201, "decibels-volt"},
3006 { 202, "millisiemens"},
3007 { 203, "watt-hours-reactive"},
3008 { 204, "kilowatt-hours-reactive"},
3009 { 205, "megawatt-hours-reactive"},
3010 { 206, "millimeters-of-water"},
3011 { 207, "per-mille"},
3012 { 208, "grams-per-gram"},
3013 { 209, "kilograms-per-kilogram"},
3014 { 210, "grams-per-kilogram"},
3015 { 211, "milligrams-per-gram"},
3016 { 212, "milligrams-per-kilogram"},
3017 { 213, "grams-per-milliliter"},
3018 { 214, "grams-per-liter"},
3019 { 215, "milligrams-per-liter"},
3020 { 216, "micrograms-per-liter"},
3021 { 217, "grams-per-cubic-meter"},
3022 { 218, "milligrams-per-cubic-meter"},
3023 { 219, "micrograms-per-cubic-meter"},
3024 { 220, "nanograms-per-cubic-meter"},
3025 { 221, "grams-per-cubic-centimeter"},
3026 { 222, "becquerels"},
3027 { 223, "kilobecquerels"},
3028 { 224, "megabecquerels"},
3030 { 226, "milligray"},
3031 { 227, "microgray"},
3033 { 229, "millisieverts"},
3034 { 230, "microsieverts"},
3035 { 231, "microsieverts-per-hour"},
3036 { 232, "decibels-a"},
3037 { 233, "nephelometric-turbidity-unit"},
3039 { 235, "grams-per-square-meter"},
3040 { 236, "minutes-per-degree-kelvin"},
3042 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
3043 Enumerated values 256-65535 may be used by others subject to
3044 the procedures and constraints described in Clause 23. */
3047 static const value_string
3048 BACnetErrorCode [] = {
3050 { 1, "authentication-failed"},
3051 { 2, "configuration-in-progress"},
3052 { 3, "device-busy"},
3053 { 4, "dynamic-creation-not-supported"},
3054 { 5, "file-access-denied"},
3055 { 6, "incompatible-security-levels"},
3056 { 7, "inconsistent-parameters"},
3057 { 8, "inconsistent-selection-criterion"},
3058 { 9, "invalid-data-type"},
3059 { 10, "invalid-file-access-method"},
3060 { 11, "invalid-file-start-position"},
3061 { 12, "invalid-operator-name"},
3062 { 13, "invalid-parameter-data-type"},
3063 { 14, "invalid-time-stamp"},
3064 { 15, "key-generation-error"},
3065 { 16, "missing-required-parameter"},
3066 { 17, "no-objects-of-specified-type"},
3067 { 18, "no-space-for-object"},
3068 { 19, "no-space-to-add-list-element"},
3069 { 20, "no-space-to-write-property"},
3070 { 21, "no-vt-sessions-available"},
3071 { 22, "property-is-not-a-list"},
3072 { 23, "object-deletion-not-permitted"},
3073 { 24, "object-identifier-already-exists"},
3074 { 25, "operational-problem"},
3075 { 26, "password-failure"},
3076 { 27, "read-access-denied"},
3077 { 28, "security-not-supported"},
3078 { 29, "service-request-denied"},
3080 { 31, "unknown-object"},
3081 { 32, "unknown-property"},
3082 { 33, "removed enumeration"},
3083 { 34, "unknown-vt-class"},
3084 { 35, "unknown-vt-session"},
3085 { 36, "unsupported-object-type"},
3086 { 37, "value-out-of-range"},
3087 { 38, "vt-session-already-closed"},
3088 { 39, "vt-session-termination-failure"},
3089 { 40, "write-access-denied"},
3090 { 41, "character-set-not-supported"},
3091 { 42, "invalid-array-index"},
3092 { 43, "cov-subscription-failed"},
3093 { 44, "not-cov-property"},
3094 { 45, "optional-functionality-not-supported"},
3095 { 46, "invalid-configuration-data"},
3096 { 47, "datatype-not-supported"},
3097 { 48, "duplicate-name"},
3098 { 49, "duplicate-object-id"},
3099 { 50, "property-is-not-an-array"},
3100 { 73, "invalid-event-state"},
3101 { 74, "no-alarm-configured"},
3102 { 75, "log-buffer-full"},
3103 { 76, "logged-value-purged"},
3104 { 77, "no-property-specified"},
3105 { 78, "not-configured-for-triggered-logging"},
3106 { 79, "unknown-subscription"},
3107 { 80, "parameter-out-of-range"},
3108 { 81, "list-element-not-found"},
3110 { 83, "communication-disabled"},
3112 { 85, "access-denied"},
3113 { 86, "bad-destination-address"},
3114 { 87, "bad-destination-device-id"},
3115 { 88, "bad-signature"},
3116 { 89, "bad-source-address"},
3117 { 90, "bad-timestamp"},
3118 { 91, "cannot-use-key"},
3119 { 92, "cannot-verify-message-id"},
3120 { 93, "correct-key-revision"},
3121 { 94, "destination-device-id-required"},
3122 { 95, "duplicate-message"},
3123 { 96, "encryption-not-configured"},
3124 { 97, "encryption-required"},
3125 { 98, "incorrect-key"},
3126 { 99, "invalid-key-data"},
3127 { 100, "key-update-in-progress"},
3128 { 101, "malformed-message"},
3129 { 102, "not-key-server"},
3130 { 103, "security-not-configured"},
3131 { 104, "source-security-required"},
3132 { 105, "too-many-keys"},
3133 { 106, "unknown-authentication-type"},
3134 { 107, "unknown-key"},
3135 { 108, "unknown-key-revision"},
3136 { 109, "unknown-source-message"},
3137 { 110, "not-router-to-dnet"},
3138 { 111, "router-busy"},
3139 { 112, "unknown-network-message"},
3140 { 113, "message-too-long"},
3141 { 114, "security-error"},
3142 { 115, "addressing-error"},
3143 { 116, "write-bdt-failed"},
3144 { 117, "read-bdt-failed"},
3145 { 118, "register-foreign-device-failed"},
3146 { 119, "read-fdt-failed"},
3147 { 120, "delete-fdt-entry-failed"},
3148 { 121, "distribute-broadcast-failed"},
3149 { 122, "unknown-file-size"},
3150 { 123, "abort-apdu-too-long"},
3151 { 124, "abort-application-exceeded-reply-time"},
3152 { 125, "abort-out-of-resources"},
3153 { 126, "abort-tsm-timeout"},
3154 { 127, "abort-window-size-out-of-range"},
3155 { 128, "file-full"},
3156 { 129, "inconsistent-configuration"},
3157 { 130, "inconsistent-object-type"},
3158 { 131, "internal-error"},
3159 { 132, "not-configured"},
3160 { 133, "out-of-memory"},
3161 { 134, "value-too-long"},
3162 { 135, "abort-insufficient-security"},
3163 { 136, "abort-security-error"},
3165 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
3166 Enumerated values 256-65535 may be used by others subject to the
3167 procedures and constraints described in Clause 23. */
3170 static const value_string
3171 BACnetPropertyIdentifier [] = {
3172 { 0, "acked-transition"},
3173 { 1, "ack-required"},
3175 { 3, "action-text"},
3176 { 4, "active-text"},
3177 { 5, "active-vt-session"},
3178 { 6, "alarm-value"},
3179 { 7, "alarm-values"},
3181 { 9, "all-write-successful"},
3182 { 10, "apdu-segment-timeout"},
3183 { 11, "apdu-timeout"},
3184 { 12, "application-software-version"},
3187 { 15, "change-of-state-count"},
3188 { 16, "change-of-state-time"},
3189 { 17, "notification-class"},
3190 { 18, "the property in this place was deleted"},
3191 { 19, "controlled-variable-reference"},
3192 { 20, "controlled-variable-units"},
3193 { 21, "controlled-variable-value"},
3194 { 22, "cov-increment"},
3196 { 24, "daylights-savings-status"},
3198 { 26, "derivative-constant"},
3199 { 27, "derivative-constant-units"},
3200 { 28, "description"},
3201 { 29, "description-of-halt"},
3202 { 30, "device-address-binding"},
3203 { 31, "device-type"},
3204 { 32, "effective-period"},
3205 { 33, "elapsed-active-time"},
3206 { 34, "error-limit"},
3207 { 35, "event-enable"},
3208 { 36, "event-state"},
3209 { 37, "event-type"},
3210 { 38, "exception-schedule"},
3211 { 39, "fault-values"},
3212 { 40, "feedback-value"},
3213 { 41, "file-access-method"},
3216 { 44, "firmware-revision"},
3217 { 45, "high-limit"},
3218 { 46, "inactive-text"},
3219 { 47, "in-progress"},
3220 { 48, "instance-of"},
3221 { 49, "integral-constant"},
3222 { 50, "integral-constant-units"},
3223 { 51, "issue-confirmed-notifications"},
3224 { 52, "limit-enable"},
3225 { 53, "list-of-group-members"},
3226 { 54, "list-of-object-property-references"},
3227 { 55, "list-of-session-keys"},
3228 { 56, "local-date"},
3229 { 57, "local-time"},
3232 { 60, "manipulated-variable-reference"},
3233 { 61, "maximum-output"},
3234 { 62, "max-apdu-length-accepted"},
3235 { 63, "max-info-frames"},
3236 { 64, "max-master"},
3237 { 65, "max-pres-value"},
3238 { 66, "minimum-off-time"},
3239 { 67, "minimum-on-time"},
3240 { 68, "minimum-output"},
3241 { 69, "min-pres-value"},
3242 { 70, "model-name"},
3243 { 71, "modification-date"},
3244 { 72, "notify-type"},
3245 { 73, "number-of-APDU-retries"},
3246 { 74, "number-of-states"},
3247 { 75, "object-identifier"},
3248 { 76, "object-list"},
3249 { 77, "object-name"},
3250 { 78, "object-property-reference"},
3251 { 79, "object-type"},
3253 { 81, "out-of-service"},
3254 { 82, "output-units"},
3255 { 83, "event-parameters"},
3257 { 85, "present-value"},
3259 { 87, "priority-array"},
3260 { 88, "priority-for-writing"},
3261 { 89, "process-identifier"},
3262 { 90, "program-change"},
3263 { 91, "program-location"},
3264 { 92, "program-state"},
3265 { 93, "proportional-constant"},
3266 { 94, "proportional-constant-units"},
3267 { 95, "protocol-conformance-class"},
3268 { 96, "protocol-object-types-supported"},
3269 { 97, "protocol-services-supported"},
3270 { 98, "protocol-version"},
3272 { 100, "reason-for-halt"},
3273 { 101, "recipient"},
3274 { 102, "recipient-list"},
3275 { 103, "reliability"},
3276 { 104, "relinquish-default"},
3278 { 106, "resolution"},
3279 { 107, "segmentation-supported"},
3281 { 109, "setpoint-reference"},
3282 { 110, "state-text"},
3283 { 111, "status-flags"},
3284 { 112, "system-status"},
3285 { 113, "time-delay"},
3286 { 114, "time-of-active-time-reset"},
3287 { 115, "time-of-state-count-reset"},
3288 { 116, "time-synchronization-recipients"},
3290 { 118, "update-interval"},
3291 { 119, "utc-offset"},
3292 { 120, "vendor-identifier"},
3293 { 121, "vendor-name"},
3294 { 122, "vt-class-supported"},
3295 { 123, "weekly-schedule"},
3296 { 124, "attempted-samples"},
3297 { 125, "average-value"},
3298 { 126, "buffer-size"},
3299 { 127, "client-cov-increment"},
3300 { 128, "cov-resubscription-interval"},
3301 { 129, "current-notify-time"},
3302 { 130, "event-time-stamp"},
3303 { 131, "log-buffer"},
3304 { 132, "log-device-object-property"},
3305 { 133, "enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
3306 { 134, "log-interval"},
3307 { 135, "maximum-value"},
3308 { 136, "minimum-value"},
3309 { 137, "notification-threshold"},
3310 { 138, "previous-notify-time"},
3311 { 139, "protocol-revision"},
3312 { 140, "records-since-notification"},
3313 { 141, "record-count"},
3314 { 142, "start-time"},
3315 { 143, "stop-time"},
3316 { 144, "stop-when-full"},
3317 { 145, "total-record-count"},
3318 { 146, "valid-samples"},
3319 { 147, "window-interval"},
3320 { 148, "window-samples"},
3321 { 149, "maximum-value-time-stamp"},
3322 { 150, "minimum-value-time-stamp"},
3323 { 151, "variance-value"},
3324 { 152, "active-cov-subscriptions"},
3325 { 153, "backup-failure-timeout"},
3326 { 154, "configuration-files"},
3327 { 155, "database-revision"},
3328 { 156, "direct-reading"},
3329 { 157, "last-restore-time"},
3330 { 158, "maintenance-required"},
3331 { 159, "member-of"},
3333 { 161, "operation-expected"},
3336 { 164, "tracking-value"},
3337 { 165, "zone-members"},
3338 { 166, "life-safety-alarm-values"},
3339 { 167, "max-segments-accepted"},
3340 { 168, "profile-name"},
3341 { 169, "auto-slave-discovery"},
3342 { 170, "manual-slave-address-binding"},
3343 { 171, "slave-address-binding"},
3344 { 172, "slave-proxy-enable"},
3345 { 173, "last-notify-record"}, /* bug 4117 */
3346 { 174, "schedule-default"},
3347 { 175, "accepted-modes"},
3348 { 176, "adjust-value"},
3350 { 178, "count-before-change"},
3351 { 179, "count-change-time"},
3352 { 180, "cov-period"},
3353 { 181, "input-reference"},
3354 { 182, "limit-monitoring-interval"},
3355 { 183, "logging-device"},
3356 { 184, "logging-record"},
3358 { 186, "pulse-rate"},
3360 { 188, "scale-factor"},
3361 { 189, "update-time"},
3362 { 190, "value-before-change"},
3363 { 191, "value-set"},
3364 { 192, "value-change-time"},
3365 { 193, "align-intervals"},
3366 { 194, "group-member-names"},
3367 { 195, "interval-offset"},
3368 { 196, "last-restart-reason"},
3369 { 197, "logging-type"},
3370 { 198, "member-status-flags"},
3371 { 199, "notification-period"},
3372 { 200, "previous-notify-record"},
3373 { 201, "requested-update-interval"},
3374 { 202, "restart-notification-recipients"},
3375 { 203, "time-of-device-restart"},
3376 { 204, "time-synchronization-interval"},
3378 { 206, "UTC-time-synchronization-recipients"},
3379 { 207, "node-subtype"},
3380 { 208, "node-type"},
3381 { 209, "structured-object-list"},
3382 { 210, "subordinate-annotations"},
3383 { 211, "subordinate-list"},
3384 { 212, "actual-shed-level"},
3385 { 213, "duty-window"},
3386 { 214, "expected-shed-level"},
3387 { 215, "full-duty-baseline"},
3388 { 216, "node-subtype"},
3389 { 217, "node-type"},
3390 { 218, "requested-shed-level"},
3391 { 219, "shed-duration"},
3392 { 220, "shed-level-descriptions"},
3393 { 221, "shed-levels"},
3394 { 222, "state-description"},
3395 /* enumeration values 223-225 are unassigned */
3396 { 226, "door-alarm-state"},
3397 { 227, "door-extended-pulse-time"},
3398 { 228, "door-members"},
3399 { 229, "door-open-too-long-time"},
3400 { 230, "door-pulse-time"},
3401 { 231, "door-status"},
3402 { 232, "door-unlock-delay-time"},
3403 { 233, "lock-status"},
3404 { 234, "masked-alarm-values"},
3405 { 235, "secured-status"},
3406 /* enumeration values 236-243 are unassigned */
3407 { 244, "absentee-limit"}, /* added with addenda 135-2008j */
3408 { 245, "access-alarm-events"},
3409 { 246, "access-doors"},
3410 { 247, "access-event"},
3411 { 248, "access-event-authentication-factor"},
3412 { 249, "access-event-credential"},
3413 { 250, "access-event-time"},
3414 { 251, "access-transaction-events"},
3415 { 252, "accompaniment"},
3416 { 253, "accompaniment-time"},
3417 { 254, "activation-time"},
3418 { 255, "active-authentication-policy"},
3419 { 256, "assigned-access-rights"},
3420 { 257, "authentication-factors"},
3421 { 258, "authentication-policy-list"},
3422 { 259, "authentication-policy-names"},
3423 { 260, "authentication-status"},
3424 { 261, "authorization-mode"},
3425 { 262, "belongs-to"},
3426 { 263, "credential-disable"},
3427 { 264, "credential-status"},
3428 { 265, "credentials"},
3429 { 266, "credentials-in-zone"},
3430 { 267, "days-remaining"},
3431 { 268, "entry-points"},
3432 { 269, "exit-points"},
3433 { 270, "expiry-time"},
3434 { 271, "extended-time-enable"},
3435 { 272, "failed-attempt-events"},
3436 { 273, "failed-attempts"},
3437 { 274, "failed-attempts-time"},
3438 { 275, "last-access-event"},
3439 { 276, "last-access-point"},
3440 { 277, "last-credential-added"},
3441 { 278, "last-credential-added-time"},
3442 { 279, "last-credential-removed"},
3443 { 280, "last-credential-removed-time"},
3444 { 281, "last-use-time"},
3446 { 283, "lockout-relinquish-time"},
3447 { 284, "master-exemption"},
3448 { 285, "max-failed-attempts"},
3450 { 287, "muster-point"},
3451 { 288, "negative-access-rules"},
3452 { 289, "number-of-authentication-policies"},
3453 { 290, "occupancy-count"},
3454 { 291, "occupancy-count-adjust"},
3455 { 292, "occupancy-count-enable"},
3456 { 293, "occupancy-exemption"},
3457 { 294, "occupancy-lower-limit"},
3458 { 295, "occupancy-lower-limit-enforced"},
3459 { 296, "occupancy-state"},
3460 { 297, "occupancy-upper-limit"},
3461 { 298, "occupancy-upper-limit-enforced"},
3462 { 299, "passback-exemption"},
3463 { 300, "passback-mode"},
3464 { 301, "passback-timeout"},
3465 { 302, "positive-access-rules"},
3466 { 303, "reason-for-disable"},
3467 { 304, "supported-formats"},
3468 { 305, "supported-format-classes"},
3469 { 306, "threat-authority"},
3470 { 307, "threat-level"},
3471 { 308, "trace-flag"},
3472 { 309, "transaction-notification-class"},
3473 { 310, "user-external-identifier"},
3474 { 311, "user-information-reference"},
3475 /* enumeration values 312-316 are unassigned */
3476 { 317, "user-name"},
3477 { 318, "user-type"},
3478 { 319, "uses-remaining"},
3479 { 320, "zone-from"},
3481 { 322, "access-event-tag"},
3482 { 323, "global-identifier"},
3483 /* enumeration values 324-325 reserved for future addenda */
3484 { 326, "verification-time"},
3485 { 327, "base-device-security-policy"},
3486 { 328, "distribution-key-revision"},
3487 { 329, "do-not-hide"},
3489 { 331, "last-key-server"},
3490 { 332, "network-access-security-policies"},
3491 { 333, "packet-reorder-time"},
3492 { 334, "security-pdu-timeout"},
3493 { 335, "security-time-window"},
3494 { 336, "supported-security-algorithms"},
3495 { 337, "update-key-set-timeout"},
3496 { 338, "backup-and-restore-state"},
3497 { 339, "backup-preparation-time"},
3498 { 340, "restore-completion-time"},
3499 { 341, "restore-preparation-time"},
3500 { 342, "bit-mask"}, /* addenda 135-2008w */
3503 { 345, "group-members"},
3504 { 346, "group-member-names"},
3505 { 347, "member-status-flags"},
3506 { 348, "requested-update-interval"},
3507 { 349, "covu-period"},
3508 { 350, "covu-recipients"},
3509 { 351, "event-message-texts"},
3511 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3512 Enumerated values 512-4194303 may be used by others subject to
3513 the procedures and constraints described in Clause 23. */
3516 static const value_string
3517 BACnetBinaryPV [] = {
3525 #define IBM_MS_DBCS 1
3526 #define JIS_C_6226 2
3527 #define ISO_10646_UCS4 3
3528 #define ISO_10646_UCS2 4
3529 #define ISO_18859_1 5
3530 static const value_string
3531 BACnetCharacterSet [] = {
3532 { ANSI_X34, "ANSI X3.4 / UTF-8 (since 2010)"},
3533 { IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3534 { JIS_C_6226, "JIS C 6226"},
3535 { ISO_10646_UCS4, "ISO 10646(UCS-4)"},
3536 { ISO_10646_UCS2, "ISO 10646(UCS-2)"},
3537 { ISO_18859_1, "ISO 18859-1"},
3541 static const value_string
3542 BACnetStatusFlags [] = {
3546 { 3, "out-of-service"},
3550 static const value_string
3551 BACnetMessagePriority [] = {
3557 static const value_string
3558 BACnetAcknowledgementFilter [] = {
3565 static const value_string
3566 BACnetResultFlags [] = {
3573 static const value_string
3574 BACnetRelationSpecifier [] = {
3578 { 3, "greater-than"},
3579 { 4, "less-than-or-equal"},
3580 { 5, "greater-than-or-equal"},
3584 static const value_string
3585 BACnetSelectionLogic [] = {
3592 static const value_string
3593 BACnetEventStateFilter [] = {
3602 static const value_string
3603 BACnetEventTransitionBits [] = {
3604 { 0, "to-offnormal"},
3610 static const value_string
3611 BACnetSegmentation [] = {
3612 { 0, "segmented-both"},
3613 { 1, "segmented-transmit"},
3614 { 2, "segmented-receive"},
3615 { 3, "no-segmentation"},
3619 static const value_string
3620 BACnetSilencedState [] = {
3622 { 1, "audible-silenced"},
3623 { 2, "visible-silenced"},
3624 { 3, "all-silenced"},
3628 static const value_string
3629 BACnetDeviceStatus [] = {
3630 { 0, "operational"},
3631 { 1, "operational-read-only"},
3632 { 2, "download-required"},
3633 { 3, "download-in-progress"},
3634 { 4, "non-operational"},
3635 { 5, "backup-in-progress"},
3639 static const value_string
3640 BACnetEnableDisable [] = {
3643 { 2, "disable-initiation"},
3647 static const value_string
3661 { 255, "any month" },
3665 static const value_string
3667 { 1, "days numbered 1-7" },
3668 { 2, "days numbered 8-14" },
3669 { 3, "days numbered 15-21" },
3670 { 4, "days numbered 22-28" },
3671 { 5, "days numbered 29-31" },
3672 { 6, "last 7 days of this month" },
3673 { 255, "any week of this month" },
3677 /* note: notification class object recipient-list uses
3678 different day-of-week enum */
3679 static const value_string
3688 { 255, "any day of week" },
3692 static const value_string
3693 BACnetErrorClass [] = {
3701 { 7, "communication" },
3703 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3704 Enumerated values64-65535 may be used by others subject to
3705 the procedures and constraints described in Clause 23. */
3708 static const value_string
3709 BACnetVTClass [] = {
3710 { 0, "default-terminal" },
3711 { 1, "ansi-x3-64" },
3720 static const value_string
3721 BACnetEventType [] = {
3722 { 0, "change-of-bitstring" },
3723 { 1, "change-of-state" },
3724 { 2, "change-of-value" },
3725 { 3, "command-failure" },
3726 { 4, "floating-limit" },
3727 { 5, "out-of-range" },
3728 { 6, "complex-event-type" },
3729 { 7, "(deprecated)buffer-ready" },
3730 { 8, "change-of-life-safety" },
3732 { 10, "buffer-ready" },
3733 { 11, "unsigned-range" },
3734 { 14, "double-out-of-range"}, /* added with addenda 135-2008w */
3735 { 15, "signed-out-of-range"},
3736 { 16, "unsigned-out-of-range"},
3737 { 17, "change-of-characterstring"},
3738 { 18, "change-of-status-flags"},
3740 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3741 Enumerated values 64-65535 may be used by others subject to
3742 the procedures and constraints described in Clause 23.
3743 It is expected that these enumerated values will correspond
3744 to the use of the complex-event-type CHOICE [6] of the
3745 BACnetNotificationParameters production. */
3748 static const value_string
3749 BACnetEventState [] = {
3753 { 3, "high-limit" },
3755 { 5, "life-safety-alarm" },
3757 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3758 Enumerated values 64-65535 may be used by others subject to
3759 the procedures and constraints described in Clause 23. */
3762 static const value_string
3763 BACnetLogStatus [] = {
3764 { 0, "log-disabled" },
3765 { 1, "buffer-purged" },
3766 { 2, "log-interrupted"},
3770 static const value_string
3771 BACnetMaintenance [] = {
3773 { 1, "periodic-test" },
3774 { 2, "need-service-operational" },
3775 { 3, "need-service-inoperative" },
3779 static const value_string
3780 BACnetNotifyType [] = {
3783 { 2, "ack-notification" },
3787 static const value_string
3788 BACnetServicesSupported [] = {
3789 { 0, "acknowledgeAlarm"},
3790 { 1, "confirmedCOVNotification"},
3791 { 2, "confirmedEventNotification"},
3792 { 3, "getAlarmSummary"},
3793 { 4, "getEnrollmentSummary"},
3794 { 5, "subscribeCOV"},
3795 { 6, "atomicReadFile"},
3796 { 7, "atomicWriteFile"},
3797 { 8, "addListElement"},
3798 { 9, "removeListElement"},
3799 { 10, "createObject"},
3800 { 11, "deleteObject"},
3801 { 12, "readProperty"},
3802 { 13, "readPropertyConditional"},
3803 { 14, "readPropertyMultiple"},
3804 { 15, "writeProperty"},
3805 { 16, "writePropertyMultiple"},
3806 { 17, "deviceCommunicationControl"},
3807 { 18, "confirmedPrivateTransfer"},
3808 { 19, "confirmedTextMessage"},
3809 { 20, "reinitializeDevice"},
3813 { 24, "authenticate"},
3814 { 25, "requestKey"},
3817 { 28, "unconfirmedCOVNotification"},
3818 { 29, "unconfirmedEventNotification"},
3819 { 30, "unconfirmedPrivateTransfer"},
3820 { 31, "unconfirmedTextMessage"},
3821 { 32, "timeSynchronization"},
3825 { 36, "utcTimeSynchronization"},
3826 { 37, "lifeSafetyOperation"},
3827 { 38, "subscribeCOVProperty"},
3828 { 39, "getEventInformation"},
3832 static const value_string
3833 BACnetPropertyStates [] = {
3834 { 0, "boolean-value"},
3835 { 1, "binary-value"},
3838 { 4, "program-change"},
3839 { 5, "program-state"},
3840 { 6, "reason-for-halt"},
3841 { 7, "reliability"},
3843 { 9, "system-status"},
3845 { 11, "unsigned-value"},
3846 { 12, "life-safety-mode"},
3847 { 13, "life-safety-state"},
3848 { 14, "restart-reason"},
3849 { 15, "door-alarm-state"},
3851 { 17, "door-secured-status"},
3852 { 18, "door-status"},
3853 { 19, "door-value"},
3854 { 20, "file-access-method"},
3855 { 21, "lock-status"},
3856 { 22, "life-safety-operation"},
3857 { 23, "maintenance"},
3859 { 25, "notify-type"},
3860 { 26, "security-level"},
3861 { 27, "shed-state"},
3862 { 28, "silenced-state"},
3863 /* context tag 29 reserved for future addenda */
3864 { 29, "unknown-29"},
3865 { 30, "access-event"},
3866 { 31, "zone-occupancy-state"},
3867 { 32, "access-credential-disable-reason"},
3868 { 33, "access-credential-disable"},
3869 { 34, "authentication-status"},
3870 { 35, "unknown-35"},
3871 { 36, "backup-state"},
3873 /* Tag values 0-63 are reserved for definition by ASHRAE.
3874 Tag values of 64-254 may be used by others to accommodate
3875 vendor specific properties that have discrete or enumerated values,
3876 subject to the constraints described in Clause 23. */
3879 static const value_string
3880 BACnetProgramError [] = {
3882 { 1, "load-failed"},
3887 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3888 Enumerated values 64-65535 may be used by others subject to
3889 the procedures and constraints described in Clause 23. */
3892 static const value_string
3893 BACnetProgramRequest [] = {
3903 static const value_string
3904 BACnetProgramState [] = {
3914 static const value_string
3915 BACnetReinitializedStateOfDevice [] = {
3918 { 2, "startbackup"},
3920 { 4, "startrestore"},
3922 { 6, "abortrestore"},
3926 static const value_string
3927 BACnetPolarity [] = {
3933 static const value_string
3934 BACnetTagNames[] = {
3935 { 5, "Extended Value" },
3936 { 6, "Opening Tag" },
3937 { 7, "Closing Tag" },
3941 static const value_string
3942 BACnetReadRangeOptions[] = {
3943 { 3, "range byPosition" },
3944 { 4, "range byTime" },
3945 { 5, "range timeRange" },
3946 { 6, "range bySequenceNumber" },
3947 { 7, "range byTime" },
3951 /* Present_Value for Load Control Object */
3952 static const value_string
3953 BACnetShedState[] = {
3954 { 0, "shed-inactive" },
3955 { 1, "shed-request-pending" },
3956 { 2, "shed-compliant" },
3957 { 3, "shed-non-compliant" },
3961 static const value_string
3962 BACnetNodeType [] = {
3967 { 4, "organizational" },
3971 { 8, "collection" },
3973 { 10, "functional" },
3978 static const value_string
3979 BACnetLoggingType [] = {
3986 static const value_string
3987 BACnetDoorStatus [] = {
3994 static const value_string
3995 BACnetLockStatus [] = {
4003 static const value_string
4004 BACnetDoorSecuredStatus [] = {
4011 static const value_string
4012 BACnetDoorAlarmState [] = {
4015 { 2, "door-open-too-long" },
4016 { 3, "forced-open" },
4018 { 5, "door-fault" },
4020 { 7, "free-access" },
4021 { 8, "egress-open" },
4025 static const value_string
4026 BACnetAccumulatorStatus [] = {
4035 static const value_string
4036 BACnetVendorIdentifiers [] = {
4039 { 2, "The Trane Company" },
4040 { 3, "McQuay International" },
4042 { 5, "Johnson Controls, Inc." },
4043 { 6, "American Auto-Matrix" },
4044 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
4045 { 8, "Delta Controls" },
4046 { 9, "Siemens Building Technologies, Inc." },
4047 { 10, "Tour Andover Controls Corporation" },
4049 { 12, "Orion Analysis Corporation" },
4050 { 13, "Teletrol Systems Inc." },
4051 { 14, "Cimetrics Technology" },
4052 { 15, "Cornell University" },
4053 { 16, "United Technologies Carrier" },
4054 { 17, "Honeywell Inc." },
4055 { 18, "Alerton / Honeywell" },
4057 { 20, "Hewlett-Packard Company" },
4058 { 21, "Dorsette's Inc." },
4059 { 22, "Cerberus AG" },
4060 { 23, "York Controls Group" },
4061 { 24, "Automated Logic Corporation" },
4062 { 25, "CSI Control Systems International" },
4063 { 26, "Phoenix Controls Corporation" },
4064 { 27, "Innovex Technologies, Inc." },
4065 { 28, "KMC Controls, Inc." },
4066 { 29, "Xn Technologies, Inc." },
4067 { 30, "Hyundai Information Technology Co., Ltd." },
4068 { 31, "Tokimec Inc." },
4070 { 33, "North Communications Limited" },
4072 { 35, "Reliable Controls Corporation" },
4073 { 36, "Tridium Inc." },
4074 { 37, "Sierra Monitor Corp." },
4075 { 38, "Silicon Energy" },
4076 { 39, "Kieback & Peter GmbH & Co KG" },
4077 { 40, "Anacon Systems, Inc." },
4078 { 41, "Systems Controls & Instruments, LLC" },
4079 { 42, "Lithonia Lighting" },
4080 { 43, "Micropower Manufacturing" },
4081 { 44, "Matrix Controls" },
4082 { 45, "METALAIRE" },
4083 { 46, "ESS Engineering" },
4084 { 47, "Sphere Systems Pty Ltd." },
4085 { 48, "Walker Technologies Corporation" },
4086 { 49, "H I Solutions, Inc." },
4088 { 51, "SAMSON AG" },
4089 { 52, "Badger Meter Inc." },
4090 { 53, "DAIKIN Industries Ltd." },
4091 { 54, "NARA Controls Inc." },
4092 { 55, "Mammoth Inc." },
4093 { 56, "Liebert Corporation" },
4094 { 57, "SEMCO Incorporated" },
4095 { 58, "Air Monitor Corporation" },
4096 { 59, "TRIATEK, Inc." },
4098 { 61, "Multistack" },
4099 { 62, "TSI Incorporated" },
4100 { 63, "Weather-Rite, Inc." },
4101 { 64, "Dunham-Bush" },
4102 { 65, "Reliance Electric" },
4104 { 67, "Regulator Australia PTY Ltd." },
4105 { 68, "Touch-Plate Lighting Controls" },
4106 { 69, "Amann GmbH" },
4107 { 70, "RLE Technologies" },
4108 { 71, "Cardkey Systems" },
4109 { 72, "SECOM Co., Ltd." },
4110 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
4111 { 74, "KNX Association cvba" },
4112 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
4113 { 76, "Nohmi Bosai, Ltd." },
4114 { 77, "Carel S.p.A." },
4115 { 78, "AirSense Technology, Inc." },
4116 { 79, "Hochiki Corporation" },
4117 { 80, "Fr. Sauter AG" },
4118 { 81, "Matsushita Electric Works, Ltd." },
4119 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
4120 { 83, "Mitsubishi Heavy Industries, Ltd." },
4121 { 84, "ITT Bell & Gossett" },
4122 { 85, "Yamatake Building Systems Co., Ltd." },
4123 { 86, "The Watt Stopper, Inc." },
4124 { 87, "Aichi Tokei Denki Co., Ltd." },
4125 { 88, "Activation Technologies, LLC" },
4126 { 89, "Saia-Burgess Controls, Ltd." },
4127 { 90, "Hitachi, Ltd." },
4128 { 91, "Novar Corp./Trend Control Systems Ltd." },
4129 { 92, "Mitsubishi Electric Lighting Corporation" },
4130 { 93, "Argus Control Systems, Ltd." },
4131 { 94, "Kyuki Corporation" },
4132 { 95, "Richards-Zeta Building Intelligence, Inc." },
4133 { 96, "Scientech R&D, Inc." },
4134 { 97, "VCI Controls, Inc." },
4135 { 98, "Toshiba Corporation" },
4136 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
4137 { 100, "Custom Mechanical Equipment, LLC" },
4138 { 101, "ClimateMaster" },
4139 { 102, "ICP Panel-Tec, Inc." },
4140 { 103, "D-Tek Controls" },
4141 { 104, "NEC Engineering, Ltd." },
4142 { 105, "PRIVA BV" },
4143 { 106, "Meidensha Corporation" },
4144 { 107, "JCI Systems Integration Services" },
4145 { 108, "Freedom Corporation" },
4146 { 109, "Neuberger Gebaudeautomation GmbH" },
4147 { 110, "Sitronix" },
4148 { 111, "Leviton Manufacturing" },
4149 { 112, "Fujitsu Limited" },
4150 { 113, "Emerson Network Power" },
4151 { 114, "S. A. Armstrong, Ltd." },
4152 { 115, "Visonet AG" },
4153 { 116, "M&M Systems, Inc." },
4154 { 117, "Custom Software Engineering" },
4155 { 118, "Nittan Company, Limited" },
4156 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
4157 { 120, "Pacom Systems Pty., Ltd." },
4158 { 121, "Unico, Inc." },
4159 { 122, "Ebtron, Inc." },
4160 { 123, "Scada Engine" },
4161 { 124, "AC Technology Corporation" },
4162 { 125, "Eagle Technology" },
4163 { 126, "Data Aire, Inc." },
4164 { 127, "ABB, Inc." },
4165 { 128, "Transbit Sp. z o. o." },
4166 { 129, "Toshiba Carrier Corporation" },
4167 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
4168 { 131, "Tokai Soft" },
4170 { 133, "Veris Industries" },
4171 { 134, "Centaurus Prime" },
4172 { 135, "Sand Network Systems" },
4173 { 136, "Regulvar, Inc." },
4174 { 137, "Fastek International, Ltd." },
4175 { 138, "PowerCold Comfort Air Solutions, Inc." },
4176 { 139, "I Controls" },
4177 { 140, "Viconics Electronics, Inc." },
4178 { 141, "Yaskawa Electric America, Inc." },
4179 { 142, "Plueth Regelsysteme" },
4180 { 143, "Digitale Mess- und Steuersysteme AG" },
4181 { 144, "Fujitsu General Limited" },
4182 { 145, "Project Engineering S.r.l." },
4183 { 146, "Sanyo Electric Co., Ltd." },
4184 { 147, "Integrated Information Systems, Inc." },
4185 { 148, "Temco Controls, Ltd." },
4186 { 149, "Airtek Technologies, Inc." },
4187 { 150, "Advantech Corporation" },
4188 { 151, "Titan Products, Ltd." },
4189 { 152, "Regel Partners" },
4190 { 153, "National Environmental Product" },
4191 { 154, "Unitec Corporation" },
4192 { 155, "Kanden Engineering Company" },
4193 { 156, "Messner Gebaudetechnik GmbH" },
4194 { 157, "Integrated.CH" },
4195 { 158, "EH Price Limited" },
4196 { 159, "SE-Elektronic GmbH" },
4197 { 160, "Rockwell Automation" },
4198 { 161, "Enflex Corp." },
4199 { 162, "ASI Controls" },
4200 { 163, "SysMik GmbH Dresden" },
4201 { 164, "HSC Regelungstechnik GmbH" },
4202 { 165, "Smart Temp Australia Pty. Ltd." },
4203 { 166, "PCI Lighting Control Systems" },
4204 { 167, "Duksan Mecasys Co., Ltd." },
4205 { 168, "Fuji IT Co., Ltd." },
4206 { 169, "Vacon Plc" },
4207 { 170, "Leader Controls" },
4208 { 171, "Cylon Controls, Ltd." },
4210 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
4211 { 174, "Building Control Integrators" },
4212 { 175, "ITG Worldwide (M) Sdn Bhd" },
4213 { 176, "Lutron Electronics Co., Inc." },
4214 { 177, "Cooper-Atkins Corporation" },
4215 { 178, "LOYTEC Electronics GmbH" },
4217 { 180, "Mega Controls Limited" },
4218 { 181, "Micro Control Systems, Inc." },
4219 { 182, "Kiyon, Inc." },
4220 { 183, "Dust Networks" },
4221 { 184, "Advanced Building Automation Systems" },
4222 { 185, "Hermos AG" },
4225 { 188, "Lynxspring" },
4226 { 189, "Schneider Toshiba Inverter Europe" },
4227 { 190, "Danfoss Drives A/S" },
4228 { 191, "Eaton Corporation" },
4229 { 192, "Matyca S.A." },
4230 { 193, "Botech AB" },
4231 { 194, "Noveo, Inc." },
4233 { 196, "Yokogawa Electric Corporation" },
4234 { 197, "GFR Gesellschaft fur Regelungstechnik" },
4235 { 198, "Exact Logic" },
4236 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
4237 { 200, "Kandenko Co., Ltd." },
4238 { 201, "DTF, Daten-Technik Fries" },
4239 { 202, "Klimasoft, Ltd." },
4240 { 203, "Toshiba Schneider Inverter Corporation" },
4241 { 204, "Control Applications, Ltd." },
4242 { 205, "KDT Systems Co., Ltd." },
4243 { 206, "Onicon Incorporated" },
4244 { 207, "Automation Displays, Inc." },
4245 { 208, "Control Solutions, Inc." },
4246 { 209, "Remsdaq Limited" },
4247 { 210, "NTT Facilities, Inc." },
4248 { 211, "VIPA GmbH" },
4249 { 212, "TSC21 Association of Japan" },
4250 { 213, "BBP Energie Ltee" },
4251 { 214, "HRW Limited" },
4252 { 215, "Lighting Control & Design, Inc." },
4253 { 216, "Mercy Electronic and Electrical Industries" },
4254 { 217, "Samsung SDS Co., Ltd" },
4255 { 218, "Impact Facility Solutions, Inc." },
4256 { 219, "Aircuity" },
4257 { 220, "Control Techniques, Ltd." },
4258 { 221, "Evolve Control Systems, LLC" },
4259 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
4260 { 223, "Cerus Industrial" },
4261 { 224, "Chloride Power Protection Company" },
4262 { 225, "Computrols, Inc." },
4263 { 226, "Phoenix Contact GmbH & Co. KG" },
4264 { 227, "Grundfos Management A/S" },
4265 { 228, "Ridder Drive Systems" },
4266 { 229, "Soft Device SDN BHD" },
4267 { 230, "Integrated Control Technology Limited" },
4268 { 231, "AIRxpert Systems, Inc." },
4269 { 232, "Microtrol Limited" },
4270 { 233, "Red Lion Controls" },
4271 { 234, "Digital Electronics Corporation" },
4272 { 235, "Ennovatis GmbH" },
4273 { 236, "Serotonin Software Technologies, Inc." },
4274 { 237, "LS Industrial Systems Co., Ltd." },
4275 { 238, "Square D Company" },
4276 { 239, "S Squared Innovations, Inc." },
4277 { 240, "Aricent Ltd." },
4278 { 241, "EtherMetrics, LLC" },
4279 { 242, "Industrial Control Communications, Inc." },
4280 { 243, "Paragon Controls, Inc." },
4281 { 244, "A. O. Smith Corporation" },
4282 { 245, "Contemporary Control Systems, Inc." },
4283 { 246, "Intesis Software SL" },
4284 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
4285 { 248, "Heat-Timer Corporation" },
4286 { 249, "Ingrasys Technology, Inc." },
4287 { 250, "Costerm Building Automation" },
4289 { 252, "Embedia Technologies Corp." },
4290 { 253, "Technilog" },
4291 { 254, "HR Controls Ltd. & Co. KG" },
4292 { 255, "Lennox International, Inc." },
4293 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
4294 { 257, "Thermomax, Ltd." },
4295 { 258, "ELCON Electronic Control, Ltd." },
4296 { 259, "Larmia Control AB" },
4297 { 260, "BACnet Stack at SourceForge" },
4298 { 261, "G4S Security Services A/S" },
4299 { 262, "Sitek S.p.A." },
4300 { 263, "Cristal Controles" },
4301 { 264, "Regin AB" },
4302 { 265, "Dimension Software, Inc. " },
4303 { 266, "SynapSense Corporation" },
4304 { 267, "Beijing Nantree Electronic Co., Ltd." },
4305 { 268, "Camus Hydronics Ltd." },
4306 { 269, "Kawasaki Heavy Industries, Ltd. " },
4307 { 270, "Critical Environment Technologies" },
4308 { 271, "ILSHIN IBS Co., Ltd." },
4309 { 272, "ELESTA Energy Control AG" },
4310 { 273, "KROPMAN Installatietechniek" },
4311 { 274, "Baldor Electric Company" },
4312 { 275, "INGA mbH" },
4313 { 276, "GE Consumer & Industrial" },
4314 { 277, "Functional Devices, Inc." },
4316 { 279, "M-System Co., Ltd." },
4317 { 280, "Yokota Co., Ltd." },
4318 { 281, "Hitranse Technology Co., LTD" },
4319 { 282, "Federspiel Controls" },
4320 { 283, "Kele, Inc." },
4321 { 284, "Opera Electronics, Inc." },
4323 { 286, "Embedded Science Labs, LLC" },
4324 { 287, "Parker Hannifin Corporation" },
4325 { 288, "MaCaPS International Limited" },
4326 { 289, "Link4 Corporation" },
4327 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
4328 { 291, "Pribusin, Inc." },
4329 { 292, "Advantage Controls" },
4330 { 293, "Critical Room Control" },
4332 { 295, "Tongdy Control Technology Co., Ltd." },
4333 { 296, "ISSARO Integrierte Systemtechnik" },
4334 { 297, "Pro-Dev Industries" },
4335 { 298, "DRI-STEEM" },
4336 { 299, "Creative Electronic GmbH" },
4337 { 300, "Swegon AB" },
4338 { 301, "Jan Brachacek" },
4339 { 302, "Hitachi Appliances, Inc." },
4340 { 303, "Real Time Automation, Inc." },
4341 { 304, "ITEC Hankyu-Hanshin Co." },
4342 { 305, "Cyrus E&M Engineering Co., Ltd." },
4343 { 306, "Racine Federated, Inc." },
4344 { 307, "Verari Systems, Inc." },
4345 { 308, "Elesta GmbH Building Automation" },
4346 { 309, "Securiton" },
4347 { 310, "OSlsoft, Inc." },
4348 { 311, "Hanazeder Electronic GmbH" },
4349 { 312, "Honeywell Security Deutschland, Novar GmbH" },
4350 { 313, "Siemens Energy & Automation, Inc." },
4351 { 314, "ETM Professional Control GmbH" },
4352 { 315, "Meitav-tec, Ltd." },
4353 { 316, "Janitza Electronics GmbH" },
4354 { 317, "MKS Nordhausen" },
4355 { 318, "De Gier Drive Systems B.V." },
4356 { 319, "Cypress Envirosystems" },
4357 { 320, "SMARTron s.r.o." },
4358 { 321, "Verari Systems, Inc." },
4359 { 322, "K-W Electronic Service, Inc." },
4360 { 323, "ALFA-SMART Energy Management" },
4361 { 324, "Telkonet, Inc." },
4362 { 325, "Securiton GmbH" },
4363 { 326, "Cemtrex, Inc." },
4364 { 327, "Performance Technologies, Inc." },
4365 { 328, "Xtralis (Aust) Pty Ltd" },
4366 { 329, "TROX GmbH" },
4367 { 330, "Beijing Hysine Technology Co., Ltd" },
4368 { 331, "RCK Controls, Inc." },
4370 { 333, "Novar/Honeywell" },
4371 { 334, "The S4 Group, Inc." },
4372 { 335, "Schneider Electric" },
4373 { 336, "LHA Systems" },
4374 { 337, "GHM engineering Group, Inc." },
4375 { 338, "Cllimalux S.A." },
4376 { 339, "VAISALA Oyj" },
4377 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
4378 { 342, "POWERPEG NSI Limited" },
4379 { 343, "BACnet Interoperability Testing Services, Inc." },
4380 { 344, "Teco a.s." },
4381 { 345, "Plexus Technology Limited"},
4382 { 346, "Energy Focus, Inc."},
4383 { 347, "Powersmiths International Corp."},
4384 { 348, "Nichibei Co., Ltd."},
4385 { 349, "HKC Technology Ltd."},
4386 { 350, "Ovation Networks, Inc."},
4387 { 351, "Setra Systems"},
4388 { 352, "AVG Automation"},
4390 { 354, "Byte Sphere"},
4391 { 355, "Generiton Co., Ltd."},
4392 { 356, "Holter Regelarmaturen GmbH & Co. KG"},
4393 { 357, "Bedford Instruments, LLC"},
4394 { 358, "Standair Inc."},
4395 { 359, "WEG Automation - R&D"},
4396 { 360, "Prolon Control Systems ApS"},
4397 { 361, "Inneasoft"},
4398 { 362, "ConneXSoft GmbH"},
4399 { 363, "CEAG Notlichtsysteme GmbH"},
4400 { 364, "Distech Controls Inc."},
4401 { 365, "Industrial Technology Research Institute"},
4402 { 366, "ICONICS, Inc."},
4403 { 367, "IQ Controls s.c."},
4404 { 368, "OJ Electronics A/S"},
4405 { 369, "Rolbit Ltd."},
4406 { 370, "Synapsys Solutions Ltd."},
4407 { 371, "ACME Engineering Prod. Ltd."},
4408 { 372, "Zener Electric Pty, Ltd."},
4409 { 373, "Selectronix, Inc."},
4410 { 374, "Gorbet & Banerjee, LLC."},
4412 { 376, "Stephen H. Dawson Computer Service"},
4413 { 377, "Accutrol, LLC"},
4414 { 378, "Schneider Elektronik GmbH"},
4415 { 379, "Alpha-Inno Tec GmbH"},
4416 { 380, "ADMMicro, Inc."},
4417 { 381, "Greystone Energy Systems, Inc."},
4418 { 382, "CAP Technologie"},
4419 { 383, "KeRo Systems"},
4420 { 384, "Domat Control System s.r.o."},
4421 { 385, "Efektronics Pty. Ltd."},
4422 { 386, "Hekatron Vertriebs GmbH"},
4423 { 387, "Securiton AG"},
4424 { 388, "Carlo Gavazzi Controls SpA"},
4425 { 389, "Chipkin Automation Systems"},
4426 { 390, "Savant Systems, LLC"},
4427 { 391, "Simmtronic Lighting Controls"},
4428 { 392, "Abelko Innovation AB"},
4429 { 393, "Seresco Technologies Inc."},
4430 { 394, "IT Watchdogs"},
4431 { 395, "Automation Assist Japan Corp."},
4432 { 396, "Thermokon Sensortechnik GmbH"},
4433 { 397, "EGauge Systems, LLC"},
4434 { 398, "Quantum Automation (ASIA) PTE, Ltd."},
4435 { 399, "Toshiba Lighting & Technology Corp."},
4436 { 400, "SPIN Engenharia de Automaca Ltda."},
4437 { 401, "Logistics Systems & Software Services India PVT. Ltd."},
4438 { 402, "Delta Controls Integration Products"},
4439 { 403, "Focus Media"},
4440 { 404, "LUMEnergi Inc."},
4441 { 405, "Kara Systems"},
4442 { 406, "RF Code, Inc."},
4443 { 407, "Fatek Automation Corp."},
4444 { 408, "JANDA Software Company, LLC"},
4445 { 409, "Open System Solutions Limited"},
4446 { 410, "Intelec Systems PTY Ltd."},
4447 { 411, "Ecolodgix, LLC"},
4448 { 412, "Douglas Lighting Controls"},
4449 { 413, "iSAtech GmbH intelligente Sensoren Aktoren technologie"},
4451 { 415, "Beckhoff Automation GmbH"},
4452 { 416, "IPAS GmbH"},
4453 { 417, "KE2 Therm Solutions"},
4454 { 418, "Base2Products"},
4455 { 419, "DTL Controls, LLC"},
4456 { 420, "INNCOM International, Inc."},
4457 { 421, "BTR Netcom GmbH"},
4458 { 422, "Greentrol Automation, Inc"},
4459 { 423, "BELIMO Automation AG"},
4460 { 424, "Samsung Heavy Industries Co, Ltd"},
4461 { 425, "Triacta Power Technologies, Inc."},
4462 { 426, "Globestar Systems"},
4463 { 427, "MLB Advanced Media, LP"},
4464 { 428, "SWG Stuckmann Wirtschaftliche Gebaudesysteme GmbH"},
4465 { 429, "SensorSwitch"},
4466 { 430, "Multitek Power Limited"},
4467 { 431, "Aquametro AG"},
4468 { 432, "LG Electronics Inc."},
4469 { 433, "Electronic Theatre Controls, Inc."},
4470 { 434, "Mitsubishi Electric Corporation Nagoya Works"},
4471 { 435, "Delta Electronics, Inc."},
4472 { 436, "Elma Kurtalj, Ltd."},
4473 { 437, "ADT Fire and Security Sp. A.o.o."},
4474 { 438, "Nedap Security Management"},
4475 { 439, "ESC Automation Inc."},
4476 { 440, "DSP4YOU Ltd."},
4477 { 441, "GE Sensing and Inspection Technologies"},
4478 { 442, "Embedded Systems SIA"},
4479 { 443, "BEFEGA GmbH"},
4480 { 444, "Baseline Inc."},
4481 { 445, "M2M Systems Integrators"},
4483 { 447, "Clarkson Controls Limited"},
4484 { 448, "Rogerwell Control System Limited"},
4485 { 449, "SCL Elements"},
4486 { 450, "Hitachi Ltd."},
4487 { 451, "Newron System SA"},
4488 { 452, "BEVECO Gebouwautomatisering BV"},
4489 { 453, "Streamside Solutions"},
4490 { 454, "Yellowstone Soft"},
4491 { 455, "Oztech Intelligent Systems Pty Ltd."},
4492 { 456, "Novelan GmbH"},
4493 { 457, "Flexim Americas Corporation"},
4494 { 458, "ICP DAS Co., Ltd."},
4495 { 459, "CARMA Industries Inc."},
4496 { 460, "Log-One Ltd."},
4497 { 461, "TECO Electric & Machinery Co., Ltd."},
4498 { 462, "ConnectEx, Inc."},
4499 { 463, "Turbo DDC Sudwest"},
4500 { 464, "Quatrosense Environmental Ltd."},
4501 { 465, "Fifth Light Technology Ltd."},
4502 { 466, "Scientific Solutions, Ltd."},
4503 { 467, "Controller Area Network Solutions (M) Sdn Bhd"},
4504 { 468, "RESOL - Elektronische Regelungen GmbH"},
4505 { 469, "RPBUS LLC"},
4506 { 470, "BRS Sistemas Eletronicos"},
4507 { 471, "WindowMaster A/S"},
4508 { 472, "Sunlux Technologies Ltd."},
4509 { 473, "Measurlogic"},
4510 { 474, "Frimat GmbH"},
4511 { 475, "Spirax Sarco"},
4513 { 477, "Raypak Inc"},
4514 { 478, "Air Monitor Corporation"},
4515 { 479, "Regler Och Webbteknik Sverige (ROWS)"},
4516 { 480, "Intelligent Lighting Controls Inc."},
4517 { 481, "Sanyo Electric Industry Co., Ltd"},
4518 { 482, "E-Mon Energy Monitoring Products"},
4519 { 483, "Digital Control Systems"},
4520 { 484, "ATI Airtest Technologies, Inc."},
4522 { 486, "HMS Industrial Networks AB"},
4523 { 487, "Shenzhen Universal Intellisys Co Ltd"},
4524 { 488, "EK Intellisys Sdn Bhd"},
4526 { 490, "Firecom, Inc."},
4527 { 491, "ESA Elektroschaltanlagen Grimma GmbH"},
4528 { 492, "Kumahira Co Ltd"},
4530 { 494, "SABO Elektronik GmbH"},
4531 { 495, "Equip'Trans"},
4532 { 496, "TCS Basys Controls"},
4533 { 497, "FlowCon International A/S"},
4534 { 498, "ThyssenKrupp Elevator Americas"},
4535 { 499, "Abatement Technologies"},
4536 { 500, "Continental Control Systems, LLC"},
4537 { 501, "WISAG Automatisierungstechnik GmbH & Co KG"},
4539 { 503, "EAP-Electric GmbH"},
4540 { 504, "Hardmeier"},
4541 { 505, "Mircom Group of Companies"},
4542 { 506, "Quest Controls"},
4543 { 507, "Mestek, Inc"},
4544 { 508, "Pulse Energy"},
4545 { 509, "Tachikawa Corporation"},
4546 { 510, "University of Nebraska-Lincoln"},
4547 { 511, "Redwood Systems"},
4548 { 512, "PASStec Industrie-Elektronik GmbH"},
4549 { 513, "NgEK, Inc."},
4550 { 514, "FAW Electronics Ltd"},
4551 { 515, "Jireh Energy Tech Co., Ltd."},
4552 { 516, "Enlighted Inc."},
4553 { 517, "El-Piast Sp. Z o.o"},
4554 { 518, "NetxAutomation Software GmbH"},
4555 { 519, "Invertek Drives"},
4556 { 520, "Deutschmann Automation GmbH & Co. KG"},
4557 { 521, "EMU Electronic AG"},
4558 { 522, "Phaedrus Limited"},
4559 { 523, "Sigmatek GmbH & Co KG"},
4560 { 524, "Marlin Controls"},
4561 { 525, "Circutor, SA"},
4562 { 526, "UTC Fire & Security"},
4563 { 527, "DENT Instruments, Inc."},
4564 { 528, "FHP Manufacturing Company - Bosch Group"},
4565 { 529, "GE Intelligent Platforms"},
4566 { 530, "Inner Range Pty Ltd"},
4567 { 531, "GLAS Energy Technology"},
4568 { 532, "MSR-Electronic-GmbH"},
4572 static int proto_bacapp = -1;
4573 static int hf_bacapp_type = -1;
4574 static int hf_bacapp_pduflags = -1;
4575 static int hf_bacapp_SEG = -1;
4576 static int hf_bacapp_MOR = -1;
4577 static int hf_bacapp_SA = -1;
4578 static int hf_bacapp_response_segments = -1;
4579 static int hf_bacapp_max_adpu_size = -1;
4580 static int hf_bacapp_invoke_id = -1;
4581 static int hf_bacapp_objectType = -1;
4582 static int hf_bacapp_instanceNumber = -1;
4583 static int hf_bacapp_sequence_number = -1;
4584 static int hf_bacapp_window_size = -1;
4585 static int hf_bacapp_service = -1;
4586 static int hf_bacapp_NAK = -1;
4587 static int hf_bacapp_SRV = -1;
4588 static int hf_Device_Instance_Range_Low_Limit = -1;
4589 static int hf_Device_Instance_Range_High_Limit = -1;
4590 static int hf_BACnetRejectReason = -1;
4591 static int hf_BACnetAbortReason = -1;
4592 static int hf_BACnetApplicationTagNumber = -1;
4593 static int hf_BACnetContextTagNumber = -1;
4594 static int hf_BACnetExtendedTagNumber = -1;
4595 static int hf_BACnetNamedTag = -1;
4596 static int hf_BACnetTagClass = -1;
4597 static int hf_BACnetCharacterSet = -1;
4598 static int hf_bacapp_tag_lvt = -1;
4599 static int hf_bacapp_tag_ProcessId = -1;
4600 static int hf_bacapp_uservice = -1;
4601 static int hf_BACnetPropertyIdentifier = -1;
4602 static int hf_BACnetVendorIdentifier = -1;
4603 static int hf_BACnetRestartReason = -1;
4604 static int hf_bacapp_tag_IPV4 = -1;
4605 static int hf_bacapp_tag_IPV6 = -1;
4606 static int hf_bacapp_tag_PORT = -1;
4607 /* some more variables for segmented messages */
4608 static int hf_msg_fragments = -1;
4609 static int hf_msg_fragment = -1;
4610 static int hf_msg_fragment_overlap = -1;
4611 static int hf_msg_fragment_overlap_conflicts = -1;
4612 static int hf_msg_fragment_multiple_tails = -1;
4613 static int hf_msg_fragment_too_long_fragment = -1;
4614 static int hf_msg_fragment_error = -1;
4615 static int hf_msg_fragment_count = -1;
4616 static int hf_msg_reassembled_in = -1;
4617 static int hf_msg_reassembled_length = -1;
4619 static gint ett_msg_fragment = -1;
4620 static gint ett_msg_fragments = -1;
4622 static gint ett_bacapp = -1;
4623 static gint ett_bacapp_control = -1;
4624 static gint ett_bacapp_tag = -1;
4625 static gint ett_bacapp_list = -1;
4626 static gint ett_bacapp_value = -1;
4628 static expert_field ei_bacapp_bad_length = EI_INIT;
4630 static dissector_handle_t data_handle;
4631 static gint32 propertyIdentifier = -1;
4632 static gint32 propertyArrayIndex = -1;
4633 static guint32 object_type = 4096;
4635 static guint8 bacapp_flags = 0;
4636 static guint8 bacapp_seq = 0;
4638 /* Defined to allow vendor identifier registration of private transfer dissectors */
4639 static dissector_table_t bacapp_dissector_table;
4642 /* Stat: BACnet Packets sorted by IP */
4643 bacapp_info_value_t bacinfo;
4645 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
4646 static const gchar* st_str_packets_by_ip_dst = "By Destination";
4647 static const gchar* st_str_packets_by_ip_src = "By Source";
4648 static int st_node_packets_by_ip = -1;
4649 static int st_node_packets_by_ip_dst = -1;
4650 static int st_node_packets_by_ip_src = -1;
4653 bacapp_packet_stats_tree_init(stats_tree* st)
4655 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4656 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4657 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4661 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4663 int packets_for_this_dst;
4664 int packets_for_this_src;
4665 int service_for_this_dst;
4666 int service_for_this_src;
4667 int src_for_this_dst;
4668 int dst_for_this_src;
4669 int objectid_for_this_dst;
4670 int objectid_for_this_src;
4671 int instanceid_for_this_dst;
4672 int instanceid_for_this_src;
4675 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4677 srcstr = wmem_strconcat(wmem_packet_scope(), "Src: ", address_to_str(&pinfo->src), NULL);
4678 dststr = wmem_strconcat(wmem_packet_scope(), "Dst: ", address_to_str(&pinfo->dst), NULL);
4680 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4681 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4682 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4683 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4684 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4685 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4686 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4687 if (binfo->service_type) {
4688 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4689 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4690 if (binfo->object_ident) {
4691 instanceid_for_this_dst = tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4692 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4693 instanceid_for_this_src = tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4694 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4701 /* Stat: BACnet Packets sorted by Service */
4702 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4703 static int st_node_packets_by_service = -1;
4706 bacapp_service_stats_tree_init(stats_tree* st)
4708 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4712 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4721 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4723 srcstr = wmem_strconcat(wmem_packet_scope(), "Src: ", address_to_str(&pinfo->src), NULL);
4724 dststr = wmem_strconcat(wmem_packet_scope(), "Dst: ", address_to_str(&pinfo->dst), NULL);
4726 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4727 if (binfo->service_type) {
4728 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4729 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4730 dst = tick_stat_node(st, dststr, src, TRUE);
4731 if (binfo->object_ident) {
4732 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4733 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4740 /* Stat: BACnet Packets sorted by Object Type */
4741 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
4742 static int st_node_packets_by_objectid = -1;
4745 bacapp_objectid_stats_tree_init(stats_tree* st)
4747 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
4751 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4759 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4761 srcstr = wmem_strconcat(wmem_packet_scope(), "Src: ", address_to_str(&pinfo->src), NULL);
4762 dststr = wmem_strconcat(wmem_packet_scope(), "Dst: ", address_to_str(&pinfo->dst), NULL);
4764 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
4765 if (binfo->object_ident) {
4766 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
4767 src = tick_stat_node(st, srcstr, objectid, TRUE);
4768 dst = tick_stat_node(st, dststr, src, TRUE);
4769 if (binfo->service_type) {
4770 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4771 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
4778 /* Stat: BACnet Packets sorted by Instance No */
4779 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
4780 static int st_node_packets_by_instanceid = -1;
4783 bacapp_instanceid_stats_tree_init(stats_tree* st)
4785 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
4789 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4797 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4799 srcstr = wmem_strconcat(wmem_packet_scope(), "Src: ", address_to_str(&pinfo->src), NULL);
4800 dststr = wmem_strconcat(wmem_packet_scope(), "Dst: ", address_to_str(&pinfo->dst), NULL);
4802 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
4803 if (binfo->object_ident) {
4804 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
4805 src = tick_stat_node(st, srcstr, instanceid, TRUE);
4806 dst = tick_stat_node(st, dststr, src, TRUE);
4807 if (binfo->service_type) {
4808 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4809 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
4816 /* register all BACnet Ststistic trees */
4818 register_bacapp_stat_trees(void)
4820 stats_tree_register("bacapp","bacapp_ip","BACnet/Packets sorted by IP", 0,
4821 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
4822 stats_tree_register("bacapp","bacapp_service","BACnet/Packets sorted by Service", 0,
4823 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
4824 stats_tree_register("bacapp","bacapp_objectid","BACnet/Packets sorted by Object Type", 0,
4825 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
4826 stats_tree_register("bacapp","bacapp_instanceid","BACnet/Packets sorted by Instance ID", 0,
4827 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
4830 /* 'data' must be ep_ allocated */
4832 updateBacnetInfoValue(gint whichval, const gchar *data)
4834 if (whichval == BACINFO_SERVICE) {
4835 bacinfo.service_type = data;
4838 if (whichval == BACINFO_INVOKEID) {
4839 bacinfo.invoke_id = data;
4842 if (whichval == BACINFO_OBJECTID) {
4843 bacinfo.object_ident = data;
4846 if (whichval == BACINFO_INSTANCEID) {
4847 bacinfo.instance_ident = data;
4853 static const fragment_items msg_frag_items = {
4854 /* Fragment subtrees */
4857 /* Fragment fields */
4860 &hf_msg_fragment_overlap,
4861 &hf_msg_fragment_overlap_conflicts,
4862 &hf_msg_fragment_multiple_tails,
4863 &hf_msg_fragment_too_long_fragment,
4864 &hf_msg_fragment_error,
4865 &hf_msg_fragment_count,
4866 /* Reassembled in field */
4867 &hf_msg_reassembled_in,
4868 /* Reassembled length field */
4869 &hf_msg_reassembled_length,
4870 /* Reassembled data field */
4876 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
4877 static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
4880 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
4882 fGetMaxAPDUSize(guint8 idx)
4884 /* only 16 values are defined, so use & 0x0f */
4885 /* check the size of the Array, deliver either the entry
4886 or the first entry if idx is outside of the array (bug 3736 comment#7) */
4888 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
4889 return MaxAPDUSize[0];
4891 return MaxAPDUSize[idx & 0x0f];
4896 /* Used when there are ranges of reserved and proprietary enumerations */
4898 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
4899 const char *fmt, const char *split_fmt)
4901 if (val < split_val)
4902 return val_to_str(val, vs, fmt);
4904 return val_to_str(val, vs, split_fmt);
4907 /* from clause 20.2.1.3.2 Constructed Data */
4908 /* returns true if the extended value is used */
4910 tag_is_extended_value(guint8 tag)
4912 return (tag & 0x07) == 5;
4916 tag_is_opening(guint8 tag)
4918 return (tag & 0x07) == 6;
4922 tag_is_closing(guint8 tag)
4924 return (tag & 0x07) == 7;
4927 /* from clause 20.2.1.1 Class
4928 class bit shall be one for context specific tags */
4929 /* returns true if the tag is context specific */
4931 tag_is_context_specific(guint8 tag)
4933 return (tag & 0x08) != 0;
4937 tag_is_extended_tag_number(guint8 tag)
4939 return ((tag & 0xF0) == 0xF0);
4943 object_id_type(guint32 object_identifier)
4945 return ((object_identifier >> 22) & 0x3FF);
4949 object_id_instance(guint32 object_identifier)
4951 return (object_identifier & 0x3FFFFF);
4955 fTagNo (tvbuff_t *tvb, guint offset)
4957 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
4961 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
4963 gboolean valid = TRUE;
4967 *val = tvb_get_guint8(tvb, offset);
4970 *val = tvb_get_ntohs(tvb, offset);
4973 *val = tvb_get_ntoh24(tvb, offset);
4976 *val = tvb_get_ntohl(tvb, offset);
4987 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
4989 gboolean valid = FALSE;
4993 if (lvt && (lvt <= 8)) {
4995 for (i = 0; i < lvt; i++) {
4996 data = tvb_get_guint8(tvb, offset+i);
4997 value = (value << 8) + data;
5005 /* BACnet Signed Value uses 2's complement notation, but with a twist:
5006 All signed integers shall be encoded in the smallest number of octets
5007 possible. That is, the first octet of any multi-octet encoded value
5008 shall not be X'00' if the most significant bit (bit 7) of the second
5009 octet is 0, and the first octet shall not be X'FF' if the most
5010 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
5012 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
5014 gboolean valid = FALSE;
5019 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
5020 if (lvt && (lvt <= 7)) {
5022 data = tvb_get_guint8(tvb, offset);
5023 if ((data & 0x80) != 0)
5024 value = (-1 << 8) | data;
5027 for (i = 1; i < lvt; i++) {
5028 data = tvb_get_guint8(tvb, offset+i);
5029 value = (value << 8) + data;
5038 fTagHeaderTree (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5039 guint offset, guint8 *tag_no, guint8* tag_info, guint32 *lvt)
5041 proto_item *ti = NULL;
5045 guint lvt_len = 1; /* used for tree display of lvt */
5046 guint lvt_offset; /* used for tree display of lvt */
5048 lvt_offset = offset;
5049 tag = tvb_get_guint8(tvb, offset);
5053 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
5054 /* can mean open/close tag or length of 6/7 after the length is */
5055 /* computed below - store whole tag info, not just context bit. */
5056 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
5058 if (tag_is_extended_tag_number(tag)) {
5059 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
5061 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
5062 lvt_offset += tag_len;
5063 value = tvb_get_guint8(tvb, lvt_offset);
5065 if (value == 254) { /* length is encoded with 16 Bits */
5066 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
5069 } else if (value == 255) { /* length is encoded with 32 Bits */
5070 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
5078 proto_tree *subtree;
5079 if (tag_is_opening(tag))
5080 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
5081 else if (tag_is_closing(tag))
5082 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
5083 else if (tag_is_context_specific(tag)) {
5084 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
5085 "Context Tag: %u, Length/Value/Type: %u",
5088 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
5089 "Application Tag: %s, Length/Value/Type: %u",
5091 BACnetApplicationTagNumber,
5092 ASHRAE_Reserved_Fmt),
5095 /* details if needed */
5096 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5097 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
5098 if (tag_is_extended_tag_number(tag)) {
5099 proto_tree_add_uint_format(subtree,
5100 hf_BACnetContextTagNumber,
5101 tvb, offset, 1, tag,
5102 "Extended Tag Number");
5103 proto_tree_add_item(subtree,
5104 hf_BACnetExtendedTagNumber,
5105 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
5107 if (tag_is_context_specific(tag))
5108 proto_tree_add_item(subtree,
5109 hf_BACnetContextTagNumber,
5110 tvb, offset, 1, ENC_BIG_ENDIAN);
5112 proto_tree_add_item(subtree,
5113 hf_BACnetApplicationTagNumber,
5114 tvb, offset, 1, ENC_BIG_ENDIAN);
5116 if (tag_is_closing(tag) || tag_is_opening(tag))
5117 proto_tree_add_item(subtree,
5119 tvb, offset, 1, ENC_BIG_ENDIAN);
5120 else if (tag_is_extended_value(tag)) {
5121 proto_tree_add_item(subtree,
5123 tvb, offset, 1, ENC_BIG_ENDIAN);
5124 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
5125 tvb, lvt_offset, lvt_len, *lvt);
5127 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
5128 tvb, lvt_offset, lvt_len, *lvt);
5131 if (*lvt > tvb_length(tvb)) {
5132 expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
5133 "LVT length too long: %d > %d", *lvt,
5142 fTagHeader (tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* tag_info,
5145 return fTagHeaderTree (tvb, pinfo, NULL, offset, tag_no, tag_info, lvt);
5149 fNullTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5151 guint8 tag_no, tag_info;
5154 proto_tree *subtree;
5156 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
5157 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5158 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5164 fBooleanTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5166 guint8 tag_no, tag_info;
5169 proto_tree *subtree;
5172 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5173 if (tag_info && lvt == 1) {
5174 lvt = tvb_get_guint8(tvb, offset+1);
5178 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
5179 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
5180 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5181 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5183 return offset + bool_len;
5187 fUnsignedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5190 guint8 tag_no, tag_info;
5194 proto_tree *subtree;
5196 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5197 /* only support up to an 8 byte (64-bit) integer */
5198 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
5199 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5200 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
5202 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5203 "%s - %u octets (Unsigned)", label, lvt);
5204 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5205 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5207 return offset+tag_len+lvt;
5211 fDevice_Instance (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, int hf)
5213 guint8 tag_no, tag_info;
5214 guint32 lvt, safe_lvt;
5217 proto_tree *subtree;
5219 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5226 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, safe_lvt, ENC_BIG_ENDIAN);
5228 if (lvt != safe_lvt)
5229 expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
5230 "This field claims to be an impossible %u bytes, while the max is %u", lvt, safe_lvt);
5232 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5233 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5235 return offset+tag_len+lvt;
5238 /* set split_val to zero when not needed */
5240 fEnumeratedTagSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5241 guint offset, const gchar *label, const value_string *vs, guint32 split_val)
5244 guint8 tag_no, tag_info;
5248 proto_tree *subtree;
5250 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5251 /* only support up to a 4 byte (32-bit) enumeration */
5252 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
5254 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5255 "%s %s", label, val_to_split_str(val, split_val, vs,
5256 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
5258 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5259 "%s %u", label, val);
5261 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5262 "%s - %u octets (enumeration)", label, lvt);
5264 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5265 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5267 return offset+tag_len+lvt;
5271 fEnumeratedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5272 guint offset, const gchar *label, const value_string *vs)
5274 return fEnumeratedTagSplit (tvb, pinfo, tree, offset, label, vs, 0);
5278 fSignedTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5281 guint8 tag_no, tag_info;
5285 proto_tree *subtree;
5287 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5288 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
5289 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5290 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
5292 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5293 "%s - %u octets (Signed)", label, lvt);
5294 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5295 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5297 return offset+tag_len+lvt;
5301 fRealTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5303 guint8 tag_no, tag_info;
5308 proto_tree *subtree;
5310 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5311 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
5312 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
5313 "%s%f (Real)", label, f_val);
5314 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5315 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5317 return offset+tag_len+4;
5321 fDoubleTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5323 guint8 tag_no, tag_info;
5328 proto_tree *subtree;
5330 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5331 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
5332 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
5333 "%s%f (Double)", label, d_val);
5334 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5335 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5337 return offset+tag_len+8;
5341 fProcessId (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5343 guint32 val = 0, lvt;
5344 guint8 tag_no, tag_info;
5346 proto_tree *subtree;
5349 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5350 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5351 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
5352 tvb, offset, lvt+tag_len, val);
5354 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5355 "Process Identifier - %u octets (Signed)", lvt);
5356 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5357 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5358 offset += tag_len + lvt;
5364 fTimeSpan (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5366 guint32 val = 0, lvt;
5367 guint8 tag_no, tag_info;
5369 proto_tree *subtree;
5372 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5373 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
5374 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5375 "%s (hh.mm.ss): %d.%02d.%02d%s",
5377 (val / 3600), ((val % 3600) / 60), (val % 60),
5378 val == 0 ? " (indefinite)" : "");
5380 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5381 "%s - %u octets (Signed)", label, lvt);
5382 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5383 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5385 return offset+tag_len+lvt;
5389 fWeekNDay (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5391 guint32 month, weekOfMonth, dayOfWeek;
5392 guint8 tag_no, tag_info;
5396 proto_tree *subtree;
5398 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5399 month = tvb_get_guint8(tvb, offset+tag_len);
5400 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
5401 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
5402 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
5403 val_to_str(month, months, "month (%d) not found"),
5404 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
5405 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
5406 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5407 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5409 return offset+tag_len+lvt;
5413 fDate (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5415 guint32 year, month, day, weekday;
5416 guint8 tag_no, tag_info;
5420 proto_tree *subtree;
5422 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5423 year = tvb_get_guint8(tvb, offset+tag_len);
5424 month = tvb_get_guint8(tvb, offset+tag_len+1);
5425 day = tvb_get_guint8(tvb, offset+tag_len+2);
5426 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
5427 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
5428 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5431 else if (year != 255) {
5433 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5434 "%s%s %d, %d, (Day of Week = %s)",
5435 label, val_to_str(month,
5437 "month (%d) not found"),
5438 day, year, val_to_str(weekday,
5442 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5443 "%s%s %d, any year, (Day of Week = %s)",
5444 label, val_to_str(month, months, "month (%d) not found"),
5445 day, val_to_str(weekday, day_of_week, "(%d) not found"));
5447 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5448 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5450 return offset+tag_len+lvt;
5454 fTime (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5456 guint32 hour, minute, second, msec, lvt;
5457 guint8 tag_no, tag_info;
5460 proto_tree *subtree;
5462 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5463 hour = tvb_get_guint8(tvb, offset+tag_len);
5464 minute = tvb_get_guint8(tvb, offset+tag_len+1);
5465 second = tvb_get_guint8(tvb, offset+tag_len+2);
5466 msec = tvb_get_guint8(tvb, offset+tag_len+3);
5467 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
5468 ti = proto_tree_add_text(tree, tvb, offset,
5469 lvt+tag_len, "%sany", label);
5471 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5472 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
5474 hour > 12 ? hour - 12 : hour,
5475 minute, second, msec,
5476 hour >= 12 ? "P.M." : "A.M.",
5477 hour, minute, second, msec);
5478 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5479 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5481 return offset+tag_len+lvt;
5485 fDateTime (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5487 proto_tree *subtree = tree;
5490 if (label != NULL) {
5491 tt = proto_tree_add_text (subtree, tvb, offset, 10, "%s", label);
5492 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5494 offset = fDate (tvb,pinfo,subtree,offset,"Date: ");
5495 return fTime (tvb,pinfo,subtree,offset,"Time: ");
5499 fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5501 guint lastoffset = 0;
5502 guint8 tag_no, tag_info;
5505 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5506 lastoffset = offset;
5507 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5508 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
5511 offset = fTime (tvb,pinfo,tree,offset,"Time: ");
5512 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
5514 if (offset==lastoffset) break; /* exit loop if nothing happens inside */
5520 fCalendarEntry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5522 guint8 tag_no, tag_info;
5525 switch (fTagNo(tvb, offset)) {
5527 offset = fDate (tvb, pinfo, tree, offset, "Date: ");
5529 case 1: /* dateRange */
5530 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5531 offset = fDateRange (tvb, pinfo, tree, offset);
5532 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5534 case 2: /* BACnetWeekNDay */
5535 offset = fWeekNDay (tvb, pinfo, tree, offset);
5545 fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
5548 proto_tree* subtree = tree;
5551 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5552 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
5554 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5556 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-OFFNORMAL timestamp: ");
5557 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-FAULT timestamp: ");
5558 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-NORMAL timestamp: ");
5564 fTimeStamp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5566 guint8 tag_no = 0, tag_info = 0;
5569 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
5570 switch (fTagNo(tvb, offset)) {
5572 offset = fTime (tvb, pinfo, tree, offset, label?label:"time: ");
5574 case 1: /* sequenceNumber */
5575 offset = fUnsignedTag (tvb, pinfo, tree, offset,
5576 label?label:"sequence number: ");
5578 case 2: /* dateTime */
5579 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5580 offset = fDateTime (tvb, pinfo, tree, offset, label?label:"date time: ");
5581 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5593 fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5595 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5596 offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
5601 static const value_string
5602 BACnetDaysOfWeek [] = {
5614 fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5616 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5617 offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
5618 "valid Days: ", BACnetDaysOfWeek);
5619 offset = fTime (tvb,pinfo,tree,offset,"from time: ");
5620 offset = fTime (tvb,pinfo,tree,offset,"to time: ");
5621 offset = fRecipient (tvb,pinfo,tree,offset);
5622 offset = fProcessId (tvb,pinfo,tree,offset);
5623 offset = fApplicationTypes (tvb,pinfo,tree,offset,
5624 "issue confirmed notifications: ");
5625 offset = fBitStringTagVS (tvb,pinfo,tree,offset,
5626 "transitions: ", BACnetEventTransitionBits);
5633 fOctetString (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5636 guint start = offset;
5637 guint8 tag_no, tag_info;
5638 proto_tree *subtree = tree;
5641 offset += fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5644 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5645 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
5650 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5652 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5658 fMacAddress (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5661 guint start = offset;
5662 guint8 tag_no, tag_info;
5663 proto_tree* subtree = tree;
5666 offset += fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5668 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
5671 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
5673 guint32 ip = tvb_get_ipv4(tvb, offset);
5674 guint16 port = tvb_get_ntohs(tvb, offset+4);
5676 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
5677 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
5680 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
5681 struct e_in6_addr addr;
5682 guint16 port = tvb_get_ntohs(tvb, offset+16);
5683 tvb_get_ipv6(tvb, offset, &addr);
5685 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
5686 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
5688 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
5689 tmp = tvb_bytes_to_str(tvb, offset, lvt);
5690 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
5697 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5699 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5705 fAddress (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5707 guint8 tag_no, tag_info;
5711 offset = fUnsignedTag (tvb, pinfo, tree, offset, "network-number");
5712 offs = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5714 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5717 offset = fMacAddress (tvb, pinfo, tree, offset, "MAC-address: ", lvt);
5723 fSessionKey (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5725 offset = fOctetString (tvb,pinfo,tree,offset,"session key: ", 8);
5726 return fAddress (tvb,pinfo,tree,offset);
5730 fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5732 guint8 tag_no, tag_info;
5736 proto_tree *subtree;
5739 tag_length = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5740 object_id = tvb_get_ntohl(tvb,offset+tag_length);
5741 object_type = object_id_type(object_id);
5742 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
5743 "ObjectIdentifier: %s, %u",
5744 val_to_split_str(object_type,
5747 ASHRAE_Reserved_Fmt,
5748 Vendor_Proprietary_Fmt),
5749 object_id_instance(object_id));
5750 if (col_get_writable(pinfo->cinfo))
5751 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5752 val_to_split_str(object_type,
5755 ASHRAE_Reserved_Fmt,
5756 Vendor_Proprietary_Fmt),
5757 object_id_instance(object_id));
5759 /* update BACnet Statistics */
5760 updateBacnetInfoValue(BACINFO_OBJECTID,
5761 wmem_strdup(wmem_packet_scope(),
5762 val_to_split_str(object_type, 128,
5763 BACnetObjectType, ASHRAE_Reserved_Fmt,
5764 Vendor_Proprietary_Fmt)));
5765 updateBacnetInfoValue(BACINFO_INSTANCEID,
5766 wmem_strdup_printf(wmem_packet_scope(),
5768 object_id_instance(object_id)));
5770 /* here are the details of how we arrived at the above text */
5771 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5772 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5773 offset += tag_length;
5774 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
5775 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
5782 fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5784 guint8 tag_no, tag_info;
5787 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5789 if (tag_no == 0) { /* device */
5790 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5792 else { /* address */
5793 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5794 offset = fAddress (tvb, pinfo, tree, offset);
5795 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5802 fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5804 guint lastoffset = 0;
5805 guint8 tag_no, tag_info;
5807 proto_tree *orgtree = tree;
5809 proto_tree *subtree;
5811 /* beginning of new item - indent and label */
5812 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
5813 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5815 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5816 lastoffset = offset;
5818 switch (fTagNo(tvb, offset)) {
5819 case 0: /* recipient */
5820 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5821 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5822 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5823 offset = fRecipient (tvb, pinfo, subtree, offset);
5824 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5826 case 1: /* processId */
5827 offset = fProcessId (tvb, pinfo, tree, offset);
5828 lastoffset = offset;
5833 if (offset == lastoffset) break; /* nothing happened, exit loop */
5839 fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5841 guint lastoffset = 0;
5842 guint8 tag_no, tag_info;
5844 proto_tree *subtree;
5846 proto_tree *orgtree = tree;
5849 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5850 lastoffset = offset;
5851 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5852 if (tag_is_closing(tag_info) ) {
5857 case 0: /* recipient */
5858 /* beginning of new item in list */
5859 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
5860 itemno = itemno + 1;
5861 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5863 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5864 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5865 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5866 offset = fRecipientProcess (tvb, pinfo, subtree, offset);
5867 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5869 case 1: /* MonitoredPropertyReference */
5870 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
5871 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5872 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5873 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
5874 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5876 case 2: /* IssueConfirmedNotifications - boolean */
5877 offset = fBooleanTag (tvb, pinfo, tree, offset, "Issue Confirmed Notifications: ");
5879 case 3: /* TimeRemaining */
5880 offset = fUnsignedTag (tvb, pinfo, tree, offset, "Time Remaining: ");
5882 case 4: /* COVIncrement */
5883 offset = fRealTag (tvb, pinfo, tree, offset, "COV Increment: ");
5888 if (offset == lastoffset) break; /* nothing happened, exit loop */
5894 fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5896 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
5897 return fAddress (tvb, pinfo, tree, offset);
5901 fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
5903 guint lastoffset = 0, len;
5904 guint8 tag_no, tag_info;
5906 proto_tree *subtree = tree;
5908 /* set the optional global properties to indicate not-used */
5909 propertyArrayIndex = -1;
5910 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5911 lastoffset = offset;
5912 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5913 if (tag_is_closing(tag_info) ) {
5914 if (tag_no == tag_match) {
5923 case 0: /* deviceIdentifier */
5924 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5926 case 1: /* objectIdentifier */
5927 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
5929 case 2: /* propertyIdentifier */
5930 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
5932 case 3: /* propertyArrayIndex */
5933 offset = fPropertyArrayIndex (tvb, pinfo, subtree, offset);
5935 case 4: /* propertyValue */
5936 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
5938 case 5: /* priority */
5939 offset = fUnsignedTag (tvb,pinfo,subtree,offset,"Priority: ");
5941 case 6: /* postDelay */
5942 offset = fUnsignedTag (tvb,pinfo,subtree,offset,"Post Delay: ");
5944 case 7: /* quitOnFailure */
5945 offset = fBooleanTag(tvb, pinfo, subtree, offset,
5946 "Quit On Failure: ");
5948 case 8: /* writeSuccessful */
5949 offset = fBooleanTag(tvb, pinfo, subtree, offset,
5950 "Write Successful: ");
5955 if (offset == lastoffset) break; /* nothing happened, exit loop */
5960 /* BACnetActionList ::= SEQUENCE{
5961 action [0] SEQUENCE OF BACnetActionCommand
5965 fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5967 guint lastoffset = 0, len;
5968 guint8 tag_no, tag_info;
5970 proto_tree *subtree = tree;
5973 while (tvb_reported_length_remaining(tvb, offset) > 0) {
5974 lastoffset = offset;
5975 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5976 if (tag_is_closing(tag_info)) {
5978 if ( tag_no != 0 ) /* don't eat the closing property tag, just return */
5983 if (tag_is_opening(tag_info)) {
5984 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
5985 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5986 offset += fTagHeaderTree (tvb, pinfo, subtree, offset,
5987 &tag_no, &tag_info, &lvt);
5990 case 0: /* BACnetActionCommand */
5991 offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
5996 if (offset == lastoffset) break; /* nothing happened, exit loop */
6002 fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6004 guint8 tag_no, tag_info;
6008 proto_tree *subtree;
6009 const gchar *label = "Property Identifier";
6011 propertyIdentifier = 0; /* global Variable */
6012 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6013 /* can we decode this value? */
6014 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
6015 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6016 "%s: %s (%u)", label,
6017 val_to_split_str(propertyIdentifier, 512,
6018 BACnetPropertyIdentifier,
6019 ASHRAE_Reserved_Fmt,
6020 Vendor_Proprietary_Fmt), propertyIdentifier);
6021 if (col_get_writable(pinfo->cinfo))
6022 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
6023 val_to_split_str(propertyIdentifier, 512,
6024 BACnetPropertyIdentifier,
6025 ASHRAE_Reserved_Fmt,
6026 Vendor_Proprietary_Fmt));
6028 /* property identifiers cannot be larger than 22-bits */
6031 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6032 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6033 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
6034 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6036 return offset+tag_len+lvt;
6040 fPropertyArrayIndex (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6042 guint8 tag_no, tag_info;
6046 proto_tree *subtree;
6048 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6049 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
6050 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6051 "property Array Index (Unsigned) %u", propertyArrayIndex);
6053 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6054 "property Array Index - %u octets (Unsigned)", lvt);
6055 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6056 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6058 return offset+tag_len+lvt;
6062 fCharacterString (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6064 guint8 tag_no, tag_info, character_set;
6066 gsize inbytesleft, outbytesleft = 512;
6067 guint offs, extra = 1;
6070 guint8 bf_arr[512], *out = &bf_arr[0];
6072 proto_tree *subtree;
6073 guint start = offset;
6075 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6077 offs = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6079 character_set = tvb_get_guint8(tvb, offset+offs);
6080 /* Account for code page if DBCS */
6081 if (character_set == 1) {
6084 offset += (offs+extra);
6088 inbytesleft = l = MIN(lvt, 256);
6090 * XXX - are we guaranteed that these encoding
6091 * names correspond, on *all* platforms with
6092 * iconv(), to the encodings we want?
6093 * If not (and perhaps even if so), we should
6094 * perhaps have our own iconv() implementation,
6095 * with a different name, so that we control the
6096 * encodings it supports and the names of those
6099 * We should also handle that in the general
6100 * string handling code, rather than making it
6101 * specific to the BACAPP dissector, as many
6102 * other dissectors need to handle various
6103 * character encodings.
6105 str_val = tvb_get_ephemeral_string(tvb, offset, l);
6106 /** this decoding may be not correct for multi-byte characters, Lka */
6107 switch (character_set) {
6109 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UTF-8");
6114 coding = "IBM MS DBCS";
6118 coding = "JIS C 6226";
6120 case ISO_10646_UCS4:
6121 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
6122 coding = "ISO 10646 UCS-4";
6124 case ISO_10646_UCS2:
6125 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
6126 coding = "ISO 10646 UCS-2";
6129 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
6130 coding = "ISO 8859-1";
6137 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s '%s'", label, coding, out);
6142 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6144 fTagHeaderTree (tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6145 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
6147 if (character_set == 1) {
6148 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
6150 /* XXX - put the string value here */
6156 fBitStringTagVS (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
6157 const value_string *src)
6159 guint8 tag_no, tag_info, tmp;
6160 gint j, unused, skip;
6161 guint start = offset;
6163 guint32 lvt, i, numberOfBytes;
6165 proto_tree* subtree = tree;
6168 offs = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6169 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
6171 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
6172 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
6173 "%s(Bit String)", label);
6175 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6177 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6178 proto_tree_add_text(subtree, tvb, offset, 1,
6179 "Unused bits: %u", unused);
6181 for (i = 0; i < numberOfBytes; i++) {
6182 tmp = tvb_get_guint8(tvb, (offset)+i+1);
6183 if (i == numberOfBytes-1) { skip = unused; }
6184 for (j = 0; j < 8-skip; j++) {
6186 if (tmp & (1 << (7 - j)))
6187 proto_tree_add_text(subtree, tvb,
6190 val_to_str((guint) (i*8 +j),
6192 ASHRAE_Reserved_Fmt));
6194 proto_tree_add_text(subtree, tvb,
6197 val_to_str((guint) (i*8 +j),
6199 ASHRAE_Reserved_Fmt));
6201 bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
6207 bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
6208 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
6217 fBitStringTag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6219 return fBitStringTagVS (tvb, pinfo, tree, offset, label, NULL);
6222 /* handles generic application types, as well as enumerated and enumerations
6223 with reserved and proprietarty ranges (split) */
6225 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6226 const gchar *label, const value_string *src, guint32 split_val)
6228 guint8 tag_no, tag_info;
6232 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6234 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6235 if (!tag_is_context_specific(tag_info)) {
6237 case 0: /** NULL 20.2.2 */
6238 offset = fNullTag(tvb, pinfo, tree, offset, label);
6240 case 1: /** BOOLEAN 20.2.3 */
6241 offset = fBooleanTag(tvb, pinfo, tree, offset, label);
6243 case 2: /** Unsigned Integer 20.2.4 */
6244 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
6246 case 3: /** Signed Integer 20.2.5 */
6247 offset = fSignedTag(tvb, pinfo, tree, offset, label);
6249 case 4: /** Real 20.2.6 */
6250 offset = fRealTag(tvb, pinfo, tree, offset, label);
6252 case 5: /** Double 20.2.7 */
6253 offset = fDoubleTag(tvb, pinfo, tree, offset, label);
6255 case 6: /** Octet String 20.2.8 */
6256 offset = fOctetString (tvb, pinfo, tree, offset, label, lvt);
6258 case 7: /** Character String 20.2.9 */
6259 offset = fCharacterString (tvb,pinfo,tree,offset,label);
6261 case 8: /** Bit String 20.2.10 */
6262 offset = fBitStringTagVS (tvb, pinfo, tree, offset, label, src);
6264 case 9: /** Enumerated 20.2.11 */
6265 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset, label, src, split_val);
6267 case 10: /** Date 20.2.12 */
6268 offset = fDate (tvb, pinfo, tree, offset, label);
6270 case 11: /** Time 20.2.13 */
6271 offset = fTime (tvb, pinfo, tree, offset, label);
6273 case 12: /** BACnetObjectIdentifier 20.2.14 */
6274 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6276 case 13: /* reserved for ASHRAE */
6279 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
6280 offset += lvt + tag_len;
6292 fShedLevel (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6294 guint lastoffset = 0;
6296 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6297 lastoffset = offset;
6299 switch (fTagNo(tvb,offset)) {
6300 case 0: /* percent */
6301 offset = fUnsignedTag (tvb, pinfo, tree, offset, "shed percent: ");
6304 offset = fUnsignedTag (tvb, pinfo, tree, offset, "shed level: ");
6306 case 2: /* amount */
6307 offset = fRealTag(tvb, pinfo, tree, offset, "shed amount: ");
6312 if (offset == lastoffset) break; /* nothing happened, exit loop */
6318 fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6319 const gchar *label, const value_string *vs)
6321 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
6325 fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6328 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
6332 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6334 guint8 tag_no, tag_info;
6338 proto_tree *subtree;
6342 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6343 /* cap the the suggested length in case of bad data */
6344 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
6345 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
6348 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
6349 "Context Value (as %u DATA octets)", lvt);
6351 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6352 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6354 return offset + tag_len + lvt;
6357 BACnetPrescale ::= SEQUENCE {
6358 multiplier [0] Unsigned,
6359 moduloDivide [1] Unsigned
6363 fPrescale (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6365 guint8 tag_no, tag_info;
6367 guint lastoffset = 0;
6369 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6370 lastoffset = offset;
6371 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6372 if (tag_is_closing(tag_info) ) {
6376 case 0: /* multiplier */
6377 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Multiplier: ");
6379 case 1: /* moduloDivide */
6380 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Modulo Divide: ");
6385 if (offset == lastoffset) break; /* nothing happened, exit loop */
6391 BACnetScale ::= CHOICE {
6392 floatScale [0] REAL,
6393 integerScale [1] INTEGER
6397 fScale (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6399 guint8 tag_no, tag_info;
6401 guint lastoffset = 0;
6403 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6404 lastoffset = offset;
6405 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6406 if (tag_is_closing(tag_info) ) {
6410 case 0: /* floatScale */
6411 offset = fRealTag (tvb,pinfo,tree,offset,"Float Scale: ");
6413 case 1: /* integerScale */
6414 offset = fSignedTag (tvb,pinfo,tree,offset,"Integer Scale: ");
6419 if (offset == lastoffset) break; /* nothing happened, exit loop */
6424 BACnetAccumulatorRecord ::= SEQUENCE {
6425 timestamp [0] BACnetDateTime,
6426 presentValue [1] Unsigned,
6427 accumulatedValue [2] Unsigned,
6428 accumulatortStatus [3] ENUMERATED {
6438 fLoggingRecord (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6440 guint8 tag_no, tag_info;
6442 guint lastoffset = 0;
6444 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6445 lastoffset = offset;
6446 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6447 if (tag_is_closing(tag_info) ) {
6451 case 0: /* timestamp */
6452 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6453 offset = fDateTime (tvb, pinfo, tree, offset, "Timestamp: ");
6454 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6456 case 1: /* presentValue */
6457 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Present Value: ");
6459 case 2: /* accumulatedValue */
6460 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Accumulated Value: ");
6462 case 3: /* accumulatorStatus */
6463 offset = fEnumeratedTag (tvb, pinfo, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus);
6468 if (offset == lastoffset) break; /* nothing happened, exit loop */
6474 SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState
6477 fSequenceOfEnums (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, const value_string *vs)
6479 guint8 tag_no, tag_info;
6481 guint lastoffset = 0;
6483 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6484 lastoffset = offset;
6485 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6486 if (tag_is_closing(tag_info) ) {
6489 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs);
6490 if ( offset == lastoffset ) break;
6496 SEQ OF BACnetDeviceObjectReference (accessed as an array)
6500 fDoorMembers (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6502 guint8 tag_no, tag_info;
6504 guint lastoffset = 0;
6506 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6507 lastoffset = offset;
6508 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6509 if (tag_is_closing(tag_info) ) {
6512 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6513 if (offset == lastoffset) break;
6519 SEQ OF ReadAccessSpecification
6522 fListOfGroupMembers (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6524 guint8 tag_no, tag_info;
6526 guint lastoffset = 0;
6528 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6529 lastoffset = offset;
6530 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6531 if (tag_is_closing(tag_info) ) {
6534 offset = fReadAccessSpecification(tvb, pinfo, tree, offset);
6535 if ( offset == lastoffset ) break;
6541 fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6543 guint8 tag_no, tag_info;
6545 guint lastoffset = 0, depth = 0;
6547 guint32 save_object_type;
6549 if (propertyIdentifier >= 0) {
6550 g_snprintf (ar, sizeof(ar), "%s: ",
6551 val_to_split_str(propertyIdentifier, 512,
6552 BACnetPropertyIdentifier,
6553 ASHRAE_Reserved_Fmt,
6554 Vendor_Proprietary_Fmt));
6556 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
6558 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6559 lastoffset = offset;
6560 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6561 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
6562 if (depth <= 0) return offset;
6565 /* Application Tags */
6566 switch (propertyIdentifier) {
6567 case 2: /* action */
6568 /* loop object is application tagged,
6569 command object is context tagged */
6570 if (tag_is_context_specific(tag_info)) {
6571 /* BACnetActionList */
6572 offset = fActionList (tvb, pinfo, tree,offset);
6575 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6579 case 30: /* BACnetAddressBinding */
6580 offset = fAddressBinding (tvb,pinfo,tree,offset);
6582 case 54: /* list of object property reference */
6583 offset = fLOPR (tvb, pinfo, tree,offset);
6585 case 55: /* list-of-session-keys */
6586 fSessionKey (tvb, pinfo, tree, offset);
6588 case 79: /* object-type */
6589 case 96: /* protocol-object-types-supported */
6590 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
6591 BACnetObjectType, 128);
6593 case 97: /* Protocol-Services-Supported */
6594 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6595 BACnetServicesSupported);
6597 case 102: /* recipient-list */
6598 offset = fDestination (tvb, pinfo, tree, offset);
6600 case 107: /* segmentation-supported */
6601 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6602 BACnetSegmentation);
6604 case 111: /* Status-Flags */
6605 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6608 case 112: /* System-Status */
6609 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6610 BACnetDeviceStatus);
6612 case 117: /* units */
6613 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
6614 BACnetEngineeringUnits);
6616 case 87: /* priority-array -- accessed as a BACnetARRAY */
6617 if (propertyArrayIndex == 0) {
6618 /* BACnetARRAY index 0 refers to the length
6619 of the array, not the elements of the array */
6620 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6622 offset = fPriorityArray (tvb, pinfo, tree, offset);
6625 case 38: /* exception-schedule */
6626 if (object_type < 128) {
6627 if (propertyArrayIndex == 0) {
6628 /* BACnetARRAY index 0 refers to the length
6629 of the array, not the elements of the array */
6630 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6632 offset = fSpecialEvent (tvb,pinfo,tree,offset);
6636 case 19: /* controlled-variable-reference */
6637 case 60: /* manipulated-variable-reference */
6638 case 132: /* log-device-object-property */
6639 offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
6641 case 109: /* Setpoint-Reference */
6642 /* setpoint-Reference is actually BACnetSetpointReference which is a SEQ of [0] */
6643 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6644 offset = fBACnetObjectPropertyReference (tvb, pinfo, tree, offset);
6645 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6647 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
6648 if (object_type < 128) {
6649 if (propertyArrayIndex == 0) {
6650 /* BACnetARRAY index 0 refers to the length
6651 of the array, not the elements of the array */
6652 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6654 offset = fWeeklySchedule (tvb, pinfo, tree, offset);
6658 case 127: /* client COV increment */
6659 offset = fClientCOV (tvb, pinfo, tree, offset);
6661 case 131: /* log-buffer */
6662 if ( object_type == 25 )
6663 offset = fEventLogRecord(tvb, pinfo, tree, offset);
6664 else if ( object_type == 27 )
6665 offset = fLogMultipleRecord (tvb, pinfo, tree, offset);
6667 offset = fLogRecord (tvb, pinfo, tree, offset);
6669 case 159: /* member-of */
6670 case 165: /* zone-members */
6671 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6673 case 196: /* last-restart-reason */
6674 offset = fRestartReason (tvb, pinfo, tree, offset);
6676 case 212: /* actual-shed-level */
6677 case 214: /* expected-shed-level */
6678 case 218: /* requested-shed-level */
6679 offset = fShedLevel (tvb, pinfo, tree, offset);
6681 case 152: /* active-cov-subscriptions */
6682 offset = fCOVSubscription (tvb, pinfo, tree, offset);
6684 case 23: /* date-list */
6685 offset = fCalendarEntry(tvb, pinfo, tree, offset);
6687 case 116: /* time-sychronization-recipients */
6688 offset = fRecipient(tvb, pinfo, tree, offset);
6690 case 83: /* event-parameters */
6691 offset = fEventParameter(tvb, pinfo, tree, offset);
6693 case 211: /* subordinate-list */
6694 offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
6696 case 130: /* event-time-stamp */
6697 offset = fEventTimeStamps(tvb, pinfo, tree, offset);
6699 case 197: /* logging-type */
6700 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType);
6702 case 36: /* event-state */
6703 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64);
6705 case 103: /* reliability */
6706 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability);
6708 case 72: /* notify-type */
6709 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNotifyType);
6711 case 208: /* node-type */
6712 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType);
6714 case 231: /* door-status */
6715 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus);
6717 case 233: /* lock-status */
6718 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus);
6720 case 235: /* secured-status */
6721 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus);
6723 case 158: /* maintenance-required */
6724 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance);
6726 case 92: /* program-state */
6727 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState);
6729 case 90: /* program-change */
6730 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest);
6732 case 100: /* reason-for-halt */
6733 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError);
6735 case 160: /* mode */
6736 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode);
6738 case 163: /* silenced */
6739 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState);
6741 case 161: /* operation-expected */
6742 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation);
6744 case 164: /* tracking-value */
6745 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState);
6747 case 41: /* file-access-method */
6748 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod);
6750 case 185: /* prescale */
6751 offset = fPrescale(tvb, pinfo, tree, offset);
6753 case 187: /* scale */
6754 offset = fScale(tvb, pinfo, tree, offset);
6756 case 184: /* logging-record */
6757 offset = fLoggingRecord(tvb, pinfo, tree, offset);
6759 case 228: /* door-members */
6760 offset = fDoorMembers(tvb, pinfo, tree, offset);
6762 case 181: /* input-reference */
6763 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6765 case 78: /* object-property-reference */
6766 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6768 case 234: /* masked-alarm-values */
6769 offset = fSequenceOfEnums(tvb, pinfo, tree, offset, "masked-alarm-value: ", BACnetDoorAlarmState);
6771 case 53: /* list-of-group-members */
6772 save_object_type = object_type;
6773 offset = fListOfGroupMembers(tvb, pinfo, tree, offset);
6774 object_type = save_object_type;
6776 case 85: /* present-value */
6777 if ( object_type == 11 ) /* group object handling of present-value */
6779 offset = fReadAccessResult(tvb, pinfo, tree, offset);
6782 /* intentially fall through here so don't reorder this case statement */
6785 if (tag_is_opening(tag_info)) {
6787 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6788 } else if (tag_is_closing(tag_info)) {
6790 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6792 offset = fContextTaggedValue(tvb, pinfo, tree, offset, ar);
6795 offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
6799 if (offset == lastoffset) break; /* nothing happened, exit loop */
6806 fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
6811 if (tag_is_opening(tag_info)) {
6812 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
6813 &tag_no, &tag_info, &lvt);
6814 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
6815 if (tvb_length_remaining(tvb, offset) > 0) {
6816 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
6817 &tag_no, &tag_info, &lvt);
6820 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
6821 "expected Opening Tag!");
6822 offset = tvb_length(tvb);
6830 fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
6832 guint lastoffset = offset;
6833 guint8 tag_no, tag_info;
6836 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
6837 if (offset > lastoffset) {
6838 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6839 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
6840 offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
6847 fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6849 guint lastoffset = 0;
6850 guint8 tag_no, tag_info;
6853 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6854 lastoffset = offset;
6855 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
6856 if (offset > lastoffset) {
6857 /* detect optional priority
6858 by looking to see if the next tag is context tag number 3 */
6859 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6860 if (tag_is_context_specific(tag_info) && (tag_no == 3))
6861 offset = fUnsignedTag (tvb,pinfo,tree,offset,"Priority: ");
6863 if (offset == lastoffset) break; /* nothing happened, exit loop */
6869 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6871 guint lastoffset = 0, len;
6872 guint8 tag_no, tag_info;
6874 proto_tree *subtree = tree;
6877 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6878 lastoffset = offset;
6879 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6880 if (tag_is_closing(tag_info)) {
6887 case 0: /* ProcessId */
6888 offset = fUnsignedTag (tvb, pinfo, tree, offset, "subscriber Process Id: ");
6890 case 1: /* monitored ObjectId */
6891 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6893 case 2: /* issueConfirmedNotifications */
6894 offset = fBooleanTag (tvb, pinfo, tree, offset, "issue Confirmed Notifications: ");
6896 case 3: /* life time */
6897 offset = fTimeSpan (tvb,pinfo,tree,offset,"life time");
6899 case 4: /* monitoredPropertyIdentifier */
6900 if (tag_is_opening(tag_info)) {
6901 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
6903 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6905 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6906 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
6911 case 5: /* covIncrement */
6912 offset = fRealTag (tvb, pinfo, tree, offset, "COV Increment: ");
6917 if (offset == lastoffset) break; /* nothing happened, exit loop */
6923 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6925 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
6929 fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6931 guint lastoffset = 0;
6933 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6934 lastoffset = offset;
6936 switch (fTagNo(tvb, offset)) {
6937 case 0: /* deviceInstanceLowLimit */
6938 offset = fUnsignedTag (tvb, pinfo, tree, offset, "device Instance Low Limit: ");
6940 case 1: /* deviceInstanceHighLimit */
6941 offset = fUnsignedTag (tvb, pinfo, tree, offset, "device Instance High Limit: ");
6943 case 2: /* BACnetObjectId */
6944 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
6946 case 3: /* messageText */
6947 offset = fCharacterString (tvb,pinfo,tree,offset, "Object Name: ");
6952 if (offset == lastoffset) break; /* nothing happened, exit loop */
6959 fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
6961 guint lastoffset = 0;
6962 guint8 tag_no, tag_info;
6965 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6966 if (tag_is_opening(tag_info) && tag_no == 0) {
6967 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
6968 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6969 lastoffset = offset;
6970 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6971 if (tag_is_closing(tag_info)) {
6972 /* should be closing context tag 0 */
6973 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6977 offset = fTimeValue (tvb, pinfo, subtree, offset);
6978 if (offset == lastoffset) break; /* nothing happened, exit loop */
6980 } else if (tag_no == 0 && lvt == 0) {
6981 /* not sure null (empty array element) is legal */
6982 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6988 fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6990 guint lastoffset = 0;
6991 guint8 tag_no, tag_info;
6993 guint i = 1; /* day of week array index */
6994 proto_tree *subtree = tree;
6997 if (propertyArrayIndex > 0) {
6998 /* BACnetARRAY index 0 refers to the length
6999 of the array, not the elements of the array.
7000 BACnetARRAY index -1 is our internal flag that
7001 the optional index was not used.
7002 BACnetARRAY refers to this as all elements of the array.
7003 If the optional index is specified for a BACnetARRAY,
7004 then that specific array element is referenced. */
7005 i = propertyArrayIndex;
7007 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7008 lastoffset = offset;
7009 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7010 if (tag_is_closing(tag_info)) {
7011 return offset; /* outer encoding will print out closing tag */
7013 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
7014 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7015 offset = fDailySchedule (tvb, pinfo, subtree, offset);
7016 if (offset == lastoffset) break; /* nothing happened, exit loop */
7023 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7025 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7028 return fDateTime (tvb, pinfo, tree, offset, "UTC-Time: ");
7032 fTimeSynchronizationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7034 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7037 return fDateTime (tvb, pinfo, tree, offset, NULL);
7041 fDateRange (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7043 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7045 offset = fDate (tvb,pinfo,tree,offset,"Start Date: ");
7046 return fDate (tvb, pinfo, tree, offset, "End Date: ");
7050 fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7053 guint8 tag_no, tag_info;
7057 proto_tree *subtree;
7058 const gchar *label = "Vendor ID";
7060 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7061 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
7062 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7065 val_to_str_const(val,BACnetVendorIdentifiers,"Unknown Vendor"),
7068 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7069 "%s - %u octets (Unsigned)", label, lvt);
7070 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7071 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7073 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
7074 proto_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
7075 "Wrong length indicated. Expected 1 or 2, got %u", lvt);
7076 return offset+tag_len+lvt;
7079 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
7080 offset+tag_len, lvt, ENC_BIG_ENDIAN);
7082 return offset+tag_len+lvt;
7086 fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7089 guint8 tag_no, tag_info;
7093 proto_tree *subtree;
7094 const gchar *label = "Restart Reason";
7096 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7097 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
7098 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7099 "%s: %s (%u)", label,
7100 val_to_str_const(val,BACnetRestartReason,"Unknown reason"), val);
7102 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7103 "%s - %u octets (Unsigned)", label, lvt);
7104 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7105 fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7108 proto_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
7109 "Wrong length indicated. Expected 1, got %u", lvt);
7110 return offset+tag_len+lvt;
7113 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
7114 offset+tag_len, lvt, ENC_BIG_ENDIAN);
7116 return offset+tag_len+lvt;
7120 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7122 guint lastoffset = 0;
7124 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7125 lastoffset = offset;
7126 switch (fTagNo(tvb, offset)) {
7128 case 0: /* textMessageSourceDevice */
7129 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7131 case 1: /* messageClass */
7132 switch (fTagNo(tvb, offset)) {
7133 case 0: /* numeric */
7134 offset = fUnsignedTag (tvb, pinfo, tree, offset, "message Class: ");
7136 case 1: /* character */
7137 offset = fCharacterString (tvb, pinfo, tree, offset, "message Class: ");
7141 case 2: /* messagePriority */
7142 offset = fEnumeratedTag (tvb, pinfo, tree, offset, "message Priority: ",
7143 BACnetMessagePriority);
7145 case 3: /* message */
7146 offset = fCharacterString (tvb, pinfo, tree, offset, "message: ");
7151 if (offset == lastoffset) break; /* nothing happened, exit loop */
7157 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7159 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
7163 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7165 guint lastoffset, len;
7166 guint8 tag_no, tag_info;
7168 proto_tree *subtree = tree;
7171 guint vendor_identifier = 0;
7172 guint service_number = 0;
7174 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7175 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
7176 if (col_get_writable(pinfo->cinfo))
7177 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
7178 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
7180 next_tvb = tvb_new_subset_remaining(tvb,offset);
7181 if (dissector_try_uint(bacapp_dissector_table,
7182 vendor_identifier, next_tvb, pinfo, tree)) {
7183 /* we parsed it so skip over length and we are done */
7184 offset += tvb_length(next_tvb);
7188 /* Not handled by vendor dissector */
7190 /* exit loop if nothing happens inside */
7191 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7192 lastoffset = offset;
7193 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7194 if (tag_is_closing(tag_info)) {
7195 if (tag_no == 2) { /* Make sure it's the expected tag */
7200 break; /* End loop if incorrect closing tag */
7205 /* vendorID is now parsed above */
7206 case 1: /* serviceNumber */
7207 fUnsigned32(tvb, offset+len, lvt, &service_number);
7208 if (col_get_writable(pinfo->cinfo))
7209 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
7210 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "service Number: ");
7212 case 2: /*serviceParameters */
7213 if (tag_is_opening(tag_info)) {
7214 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
7215 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7216 propertyIdentifier = -1;
7217 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7225 if (offset == lastoffset) break; /* nothing happened, exit loop */
7232 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7234 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7238 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7240 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7244 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
7246 guint lastoffset = 0;
7247 guint8 tag_no, tag_info;
7249 proto_tree *subtree = tree;
7252 if (label != NULL) {
7253 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
7254 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7257 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7258 lastoffset = offset;
7259 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7262 case 0: /* subscriberProcessId */
7263 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "requesting Process Id: ");
7265 case 1: /* requestingSource */
7266 offset = fCharacterString (tvb, pinfo, tree, offset, "requesting Source: ");
7268 case 2: /* request */
7269 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
7270 "request: ", BACnetLifeSafetyOperation, 64);
7272 case 3: /* objectId */
7273 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
7278 if (offset == lastoffset) break; /* nothing happened, exit loop */
7283 typedef struct _value_string_enum {
7284 const value_string *valstr;
7285 } value_string_enum;
7287 static const value_string_enum
7288 BACnetPropertyStatesEnums[] = {
7293 {BACnetProgramRequest },
7294 {BACnetProgramState },
7295 {BACnetProgramError },
7296 {BACnetReliability },
7297 {BACnetEventState },
7298 {BACnetDeviceStatus },
7299 {BACnetEngineeringUnits },
7301 {BACnetLifeSafetyMode },
7302 {BACnetLifeSafetyState },
7303 {BACnetRestartReason },
7304 {BACnetDoorAlarmState },
7306 {BACnetDoorSecuredStatus },
7307 {BACnetDoorStatus },
7308 { NULL }, /* {BACnetDoorValue }, */
7309 {BACnetFileAccessMethod },
7310 {BACnetLockStatus },
7311 {BACnetLifeSafetyOperation },
7312 {BACnetMaintenance },
7314 {BACnetNotifyType },
7315 { NULL }, /* {BACnetSecurityLevel }, */
7317 {BACnetSilencedState },
7319 { NULL }, /* {BACnetAccessEvent }, */
7320 { NULL }, /* {BACnetZoneOccupancyState }, */
7321 { NULL }, /* {BACnetAccessCredentialDisableReason }, */
7322 { NULL }, /* {BACnetAccessCredentialDisable }, */
7323 { NULL }, /* {BACnetAuthenticationStatus }, */
7325 { NULL }, /* {BACnetBackupState }, */
7327 #define BACnetPropertyStatesEnums_Size 36
7330 fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
7332 guint8 tag_no, tag_info;
7336 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7337 label = wmem_strdup_printf(wmem_packet_scope(), "%s: ",
7338 val_to_str_const( tag_no, VALS(BACnetPropertyStates), "Unknown State" ));
7342 offset = fBooleanTag (tvb, pinfo, tree, offset, label);
7345 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
7348 if ( (tag_no > BACnetPropertyStatesEnums_Size) ||
7349 VALS(BACnetPropertyStatesEnums[tag_no].valstr) == NULL)
7351 offset = fEnumeratedTag(tvb, pinfo, tree, offset, label, NULL);
7352 /* don't use Abstract type here because it is context tagged and therefore we don't know app type */
7356 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label,
7357 VALS(BACnetPropertyStatesEnums[tag_no].valstr), 64);
7366 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
7367 deviceIdentifier [0] BACnetObjectIdentifier,
7368 objectIdentifier [1] BACnetObjectIdentifier,
7369 propertyIdentifier [2] BACnetPropertyIdentifier,
7370 arrayIndex [3] Unsigned OPTIONAL,
7371 value [4] ABSTRACT-SYNTAX.&Type
7375 fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7377 guint lastoffset = 0;
7378 guint8 tag_no, tag_info;
7381 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7382 lastoffset = offset;
7383 /* check the tag. A closing tag means we are done */
7384 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7385 if (tag_is_closing(tag_info)) {
7389 case 0: /* deviceIdentifier */
7390 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7392 case 1: /* objectIdentifier */
7393 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7395 case 2: /* propertyIdentifier */
7396 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7398 case 3: /* arrayIndex - OPTIONAL */
7399 offset = fUnsignedTag (tvb, pinfo, tree, offset,
7403 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7404 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
7405 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7410 if (offset == lastoffset) break; /* nothing happened, exit loop */
7416 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7417 objectIdentifier [0] BACnetObjectIdentifier,
7418 propertyIdentifier [1] BACnetPropertyIdentifier,
7419 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7420 -- if omitted with an array then
7421 -- the entire array is referenced
7422 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7426 fObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7428 return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7432 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7433 objectIdentifier [0] BACnetObjectIdentifier,
7434 propertyIdentifier [1] BACnetPropertyIdentifier,
7435 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7436 -- if omitted with an array then
7437 -- the entire array is referenced
7438 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7442 fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7444 guint lastoffset = 0;
7445 guint8 tag_no, tag_info;
7448 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7449 lastoffset = offset;
7450 /* check the tag. A closing tag means we are done */
7451 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7452 if (tag_is_closing(tag_info)) {
7456 case 0: /* objectIdentifier */
7457 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7459 case 1: /* propertyIdentifier */
7460 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
7462 case 2: /* arrayIndex - OPTIONAL */
7463 offset = fUnsignedTag (tvb, pinfo, tree, offset,
7466 case 3: /* deviceIdentifier - OPTIONAL */
7467 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
7472 if (offset == lastoffset) break; /* nothing happened, exit loop */
7478 fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7480 guint lastoffset = offset;
7481 guint8 tag_no, tag_info;
7483 proto_tree *subtree = tree;
7486 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7487 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
7488 tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
7489 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7490 /* Opening tag for parameter choice */
7491 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7494 case 0: /* change-of-bitstring */
7495 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7496 lastoffset = offset;
7497 switch (fTagNo(tvb, offset)) {
7499 offset = fBitStringTag (tvb, pinfo, subtree, offset,
7500 "referenced-bitstring: ");
7503 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7504 "status-flags: ", BACnetStatusFlags);
7505 lastoffset = offset;
7510 if (offset == lastoffset) break; /* nothing happened, exit loop */
7513 case 1: /* change-of-state */
7514 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7515 lastoffset = offset;
7516 switch (fTagNo(tvb, offset)) {
7518 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7519 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7520 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7523 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7524 "status-flags: ", BACnetStatusFlags);
7525 lastoffset = offset;
7530 if (offset == lastoffset) break; /* nothing happened, exit loop */
7533 case 2: /* change-of-value */
7534 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7535 lastoffset = offset;
7536 switch (fTagNo(tvb, offset)) {
7538 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7539 switch (fTagNo(tvb, offset)) {
7541 offset = fBitStringTag (tvb, pinfo, subtree, offset,
7545 offset = fRealTag (tvb, pinfo, subtree, offset,
7551 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7554 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7555 "status-flags: ", BACnetStatusFlags);
7556 lastoffset = offset;
7561 if (offset == lastoffset) break; /* nothing happened, exit loop */
7564 case 3: /* command-failure */
7565 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7566 lastoffset = offset;
7567 switch (fTagNo(tvb, offset)) {
7568 case 0: /* "command-value: " */
7569 /* from BACnet Table 13-3,
7570 Standard Object Property Values Returned in Notifications */
7571 propertyIdentifier = 85; /* PRESENT_VALUE */
7572 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7573 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7574 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7577 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7578 "status-flags: ", BACnetStatusFlags);
7580 case 2: /* "feedback-value: " */
7581 propertyIdentifier = 40; /* FEEDBACK_VALUE */
7582 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7583 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
7584 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7585 lastoffset = offset;
7590 if (offset == lastoffset) break; /* nothing happened, exit loop */
7593 case 4: /* floating-limit */
7594 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7595 lastoffset = offset;
7596 switch (fTagNo(tvb, offset)) {
7598 offset = fRealTag (tvb, pinfo, subtree, offset, "reference-value: ");
7601 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7602 "status-flags: ", BACnetStatusFlags);
7605 offset = fRealTag (tvb, pinfo, subtree, offset, "setpoint-value: ");
7608 offset = fRealTag (tvb, pinfo, subtree, offset, "error-limit: ");
7609 lastoffset = offset;
7614 if (offset == lastoffset) break; /* nothing happened, exit loop */
7617 case 5: /* out-of-range */
7618 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7619 lastoffset = offset;
7620 switch (fTagNo(tvb, offset)) {
7622 offset = fRealTag (tvb, pinfo, subtree, offset, "exceeding-value: ");
7625 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7626 "status-flags: ", BACnetStatusFlags);
7629 offset = fRealTag (tvb, pinfo, subtree, offset, "deadband: ");
7632 offset = fRealTag (tvb, pinfo, subtree, offset, "exceeded-limit: ");
7633 lastoffset = offset;
7638 if (offset == lastoffset) break; /* nothing happened, exit loop */
7642 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7643 lastoffset = offset;
7644 offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
7645 if (offset == lastoffset) break; /* nothing happened, exit loop */
7648 case 7: /* deprecated (was 'buffer-ready', changed and moved to [10]) */
7649 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7650 lastoffset = offset;
7651 switch (fTagNo(tvb, offset)) {
7653 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
7656 offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
7659 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7660 offset = fDateTime (tvb, pinfo, subtree, offset, "previous-notification: ");
7661 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7664 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7665 offset = fDateTime (tvb, pinfo, subtree, offset, "current-notification: ");
7666 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7667 lastoffset = offset;
7672 if (offset == lastoffset) break; /* nothing happened, exit loop */
7675 case 8: /* change-of-life-safety */
7676 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7677 lastoffset = offset;
7678 switch (fTagNo(tvb, offset)) {
7680 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
7681 "new-state: ", BACnetLifeSafetyState, 256);
7684 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
7685 "new-mode: ", BACnetLifeSafetyMode, 256);
7688 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7689 "status-flags: ", BACnetStatusFlags);
7692 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
7693 "operation-expected: ", BACnetLifeSafetyOperation, 64);
7694 lastoffset = offset;
7699 if (offset == lastoffset) break; /* nothing happened, exit loop */
7702 case 9: /* extended */
7703 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7704 lastoffset = offset;
7705 switch (fTagNo(tvb, offset)) {
7707 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
7710 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7711 "extended-event-type: ");
7713 case 2: /* parameters */
7714 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7715 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
7716 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
7717 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7718 lastoffset = offset;
7723 if (offset == lastoffset) break; /* nothing happened, exit loop */
7726 case 10: /* buffer ready */
7727 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7728 lastoffset = offset;
7729 switch (fTagNo(tvb, offset)) {
7730 case 0: /* buffer-property */
7731 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7732 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
7733 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7736 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7737 "previous-notification: ");
7740 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7741 "current-notification: ");
7742 lastoffset = offset;
7747 if (offset == lastoffset) break; /* nothing happened, exit loop */
7750 case 11: /* unsigned range */
7751 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7752 lastoffset = offset;
7753 switch (fTagNo(tvb, offset)) {
7755 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7756 "exceeding-value: ");
7759 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7760 "status-flags: ", BACnetStatusFlags);
7763 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
7764 "exceeded-limit: ");
7765 lastoffset = offset;
7770 if (offset == lastoffset) break; /* nothing happened, exit loop */
7774 case 13: /* access-event */
7776 case 14: /* double-out-of-range */
7777 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7778 lastoffset = offset;
7779 switch (fTagNo(tvb, offset)) {
7781 offset = fDoubleTag (tvb, pinfo, subtree, offset, "exceeding-value: ");
7784 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7785 "status-flags: ", BACnetStatusFlags);
7788 offset = fDoubleTag (tvb, pinfo, subtree, offset, "deadband: ");
7791 offset = fDoubleTag (tvb, pinfo, subtree, offset, "exceeded-limit: ");
7792 lastoffset = offset;
7797 if (offset == lastoffset) break; /* nothing happened, exit loop */
7800 case 15: /* signed-out-of-range */
7801 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7802 lastoffset = offset;
7803 switch (fTagNo(tvb, offset)) {
7805 offset = fSignedTag (tvb, pinfo, subtree, offset, "exceeding-value: ");
7808 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7809 "status-flags: ", BACnetStatusFlags);
7812 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "deadband: ");
7815 offset = fSignedTag (tvb, pinfo, subtree, offset, "exceeded-limit: ");
7816 lastoffset = offset;
7821 if (offset == lastoffset) break; /* nothing happened, exit loop */
7824 case 16: /* unsigned-out-of-range */
7825 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7826 lastoffset = offset;
7827 switch (fTagNo(tvb, offset)) {
7829 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "exceeding-value: ");
7832 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
7833 "status-flags: ", BACnetStatusFlags);
7836 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "deadband: ");
7839 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "exceeded-limit: ");
7840 lastoffset = offset;
7845 if (offset == lastoffset) break; /* nothing happened, exit loop */
7848 case 17: /* change-of-characterstring */
7850 case 18: /* change-of-status-flags */
7852 /* todo: add new parameters here ... */
7854 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7858 /* Closing tag for parameter choice */
7859 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7865 fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7867 guint lastoffset = offset;
7868 guint8 tag_no, tag_info;
7870 proto_tree *subtree = tree;
7873 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7874 tt = proto_tree_add_text(subtree, tvb, offset, 0, "event parameters (%d) %s",
7875 tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
7876 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7877 /* Opening tag for parameter choice */
7878 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7881 case 0: /* change-of-bitstring */
7882 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7883 lastoffset = offset;
7884 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7885 if (tag_is_closing(tag_info)) {
7890 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7893 offset = fBitStringTag (tvb, pinfo, subtree, offset, "bitmask: ");
7895 case 2: /* SEQUENCE OF BIT STRING */
7896 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7897 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7898 lastoffset = offset;
7899 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7900 if (tag_is_closing(tag_info)) {
7903 offset = fBitStringTag(tvb, pinfo, subtree, offset,
7904 "bitstring value: ");
7906 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7913 case 1: /* change-of-state */
7914 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7915 lastoffset = offset;
7916 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7917 if (tag_is_closing(tag_info)) {
7922 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7924 case 1: /* SEQUENCE OF BACnetPropertyStates */
7925 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7926 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7927 lastoffset = offset;
7928 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7929 if (tag_is_closing(tag_info)) {
7932 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7934 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7941 case 2: /* change-of-value */
7942 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7943 lastoffset = offset;
7944 switch (fTagNo(tvb, offset)) {
7946 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7948 case 1: /* don't loop it, it's a CHOICE */
7949 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7950 switch (fTagNo(tvb, offset)) {
7952 offset = fBitStringTag (tvb, pinfo, subtree, offset, "bitmask: ");
7955 offset = fRealTag (tvb, pinfo, subtree, offset,
7956 "referenced Property Increment: ");
7961 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7968 case 3: /* command-failure */
7969 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7970 lastoffset = offset;
7971 tag_no = fTagNo(tvb, offset);
7974 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7977 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7978 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
7979 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7986 case 4: /* floating-limit */
7987 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
7988 lastoffset = offset;
7989 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7990 if (tag_is_closing(tag_info)) {
7995 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
7998 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7999 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
8000 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8003 offset = fRealTag (tvb, pinfo, subtree, offset, "low diff limit: ");
8006 offset = fRealTag (tvb, pinfo, subtree, offset, "high diff limit: ");
8009 offset = fRealTag (tvb, pinfo, subtree, offset, "deadband: ");
8016 case 5: /* out-of-range */
8017 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8018 lastoffset = offset;
8019 switch (fTagNo(tvb, offset)) {
8021 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
8024 offset = fRealTag (tvb, pinfo, subtree, offset, "low limit: ");
8027 offset = fRealTag (tvb, pinfo, subtree, offset, "high limit: ");
8030 offset = fRealTag (tvb, pinfo, subtree, offset, "deadband: ");
8039 offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
8043 case 7: /* buffer-ready */
8046 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
8047 lastoffset = offset;
8048 switch (fTagNo(tvb, offset)) {
8050 offset = fUnsignedTag (tvb,pinfo,tree,offset,"notification threshold");
8053 offset = fUnsignedTag (tvb,pinfo,tree,offset,
8054 "previous notification count: ");
8062 case 8: /* change-of-life-safety */
8063 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8064 lastoffset = offset;
8065 switch (fTagNo(tvb, offset)) {
8067 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
8070 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8071 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8072 lastoffset = offset;
8073 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8074 if (tag_is_closing(tag_info)) {
8077 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
8078 "life safety alarm value: ", BACnetLifeSafetyState, 256);
8080 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8083 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8084 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8085 lastoffset = offset;
8086 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8087 if (tag_is_closing(tag_info)) {
8090 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
8091 "alarm value: ", BACnetLifeSafetyState, 256);
8093 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8096 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8097 offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
8098 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8105 case 9: /* extended */
8106 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8107 lastoffset = offset;
8108 switch (fTagNo(tvb, offset)) {
8110 offset = fVendorIdentifier (tvb, pinfo, tree, offset);
8113 offset = fUnsignedTag (tvb, pinfo, tree, offset,
8114 "extended-event-type: ");
8116 case 2: /* parameters */
8117 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8118 offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
8119 offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
8120 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8121 lastoffset = offset;
8126 if (offset == lastoffset) break; /* nothing happened, exit loop */
8129 case 10: /* buffer-ready */
8130 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8131 lastoffset = offset;
8132 switch (fTagNo(tvb, offset)) {
8134 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
8135 "notification-threshold: ");
8138 offset = fUnsignedTag (tvb, pinfo, subtree, offset,
8139 "previous-notification-count: ");
8146 case 11: /* unsigned-range */
8147 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8148 lastoffset = offset;
8149 switch (fTagNo(tvb, offset)) {
8151 offset = fTimeSpan (tvb, pinfo, tree, offset, "Time Delay");
8154 offset = fUnsignedTag (tvb, pinfo, tree, offset,
8158 offset = fUnsignedTag (tvb, pinfo, tree, offset,
8166 case 13: /* access-event */
8167 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8168 lastoffset = offset;
8169 switch (fTagNo(tvb, offset)) {
8171 /* TODO: [0] SEQUENCE OF BACnetAccessEvent */
8172 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8173 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8174 lastoffset = offset;
8175 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8176 if (tag_is_closing(tag_info)) {
8179 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset,
8180 "access event: ", BACnetAccessEvent, 512);
8182 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8185 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8186 offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
8187 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8194 case 14: /* double-out-of-range */
8195 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8196 lastoffset = offset;
8197 switch (fTagNo(tvb, offset)) {
8199 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
8202 offset = fDoubleTag (tvb, pinfo, subtree, offset, "low limit: ");
8205 offset = fDoubleTag (tvb, pinfo, subtree, offset, "high limit: ");
8208 offset = fDoubleTag (tvb, pinfo, subtree, offset, "deadband: ");
8215 case 15: /* signed-out-of-range */
8216 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8217 lastoffset = offset;
8218 switch (fTagNo(tvb, offset)) {
8220 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
8223 offset = fSignedTag (tvb, pinfo, subtree, offset, "low limit: ");
8226 offset = fSignedTag (tvb, pinfo, subtree, offset, "high limit: ");
8229 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "deadband: ");
8236 case 16: /* unsigned-out-of-range */
8237 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8238 lastoffset = offset;
8239 switch (fTagNo(tvb, offset)) {
8241 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
8244 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "low limit: ");
8247 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "high limit: ");
8250 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "deadband: ");
8257 case 17: /* change-of-characterstring */
8258 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8259 lastoffset = offset;
8260 switch (fTagNo(tvb, offset)) {
8262 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
8264 case 1: /* SEQUENCE OF CharacterString */
8265 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8266 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8267 lastoffset = offset;
8268 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8269 if (tag_is_closing(tag_info)) {
8272 offset = fCharacterString(tvb, pinfo, tree, offset, "alarm value: ");
8274 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8281 case 18: /* change-of-status-flags */
8282 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8283 lastoffset = offset;
8284 switch (fTagNo(tvb, offset)) {
8286 offset = fTimeSpan (tvb, pinfo, subtree, offset, "Time Delay");
8289 offset = fBitStringTagVS (tvb, pinfo, subtree, offset,
8290 "selected flags: ", BACnetStatusFlags);
8297 /* todo: add new event-parameter cases here */
8302 /* Closing tag for parameter choice */
8303 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8308 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8310 guint lastoffset = 0;
8311 guint8 tag_no, tag_info;
8313 proto_tree *subtree = tree;
8316 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8317 lastoffset = offset;
8318 switch (fTagNo(tvb, offset)) {
8319 case 0: /* timestamp */
8320 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8321 offset = fDate (tvb,pinfo,tree,offset,"Date: ");
8322 offset = fTime (tvb,pinfo,tree,offset,"Time: ");
8323 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8325 case 1: /* logDatum: don't loop, it's a CHOICE */
8326 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8327 switch (fTagNo(tvb, offset)) {
8328 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8329 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8331 case 1: /* todo: move this to new method fConfirmedEventNotificationRequestTag... */
8332 tt = proto_tree_add_text(tree, tvb, offset, 1, "notification: ");
8333 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8334 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8335 offset = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset);
8336 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8339 offset = fRealTag (tvb, pinfo, tree, offset, "time-change: ");
8344 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8349 if (offset == lastoffset) break; /* nothing happened, exit loop */
8355 fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8357 guint lastoffset = 0;
8358 guint8 tag_no, tag_info;
8361 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8362 lastoffset = offset;
8363 switch (fTagNo(tvb, offset)) {
8364 case 0: /* timestamp */
8365 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8366 offset = fDate (tvb,pinfo,tree,offset,"Date: ");
8367 offset = fTime (tvb,pinfo,tree,offset,"Time: ");
8368 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8370 case 1: /* logDatum: don't loop, it's a CHOICE */
8371 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8372 switch (fTagNo(tvb, offset)) {
8373 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8374 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8377 offset = fBooleanTag (tvb, pinfo, tree, offset, "boolean-value: ");
8380 offset = fRealTag (tvb, pinfo, tree, offset, "real value: ");
8383 offset = fUnsignedTag (tvb, pinfo, tree, offset, "enum value: ");
8386 offset = fUnsignedTag (tvb, pinfo, tree, offset, "unsigned value: ");
8389 offset = fSignedTag (tvb, pinfo, tree, offset, "signed value: ");
8392 offset = fBitStringTag (tvb, pinfo, tree, offset, "bitstring value: ");
8395 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8398 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8399 offset = fError (tvb, pinfo, tree, offset);
8400 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8403 offset = fRealTag (tvb, pinfo, tree, offset, "time change: ");
8405 case 10: /* any Value */
8406 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8407 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
8408 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8413 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8416 /* Changed this to BitString per BACnet Spec. */
8417 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "Status Flags:", BACnetStatusFlags);
8422 if (offset == lastoffset) break; /* nothing happened, exit loop */
8428 fLogMultipleRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8430 guint lastoffset = 0;
8431 guint8 tag_no, tag_info;
8434 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8435 lastoffset = offset;
8436 switch (fTagNo(tvb, offset)) {
8437 case 0: /* timestamp */
8438 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8439 offset = fDate (tvb,pinfo,tree,offset,"Date: ");
8440 offset = fTime (tvb,pinfo,tree,offset,"Time: ");
8441 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8443 case 1: /* logData: don't loop, it's a CHOICE */
8444 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8445 switch (fTagNo(tvb, offset)) {
8446 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8447 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8449 case 1: /* log-data: SEQUENCE OF CHOICE */
8450 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8451 while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset != lastoffset)) { /* exit loop if nothing happens inside */
8452 lastoffset = offset;
8453 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8454 if (tag_is_closing(tag_info)) {
8455 lastoffset = offset;
8460 offset = fBooleanTag (tvb, pinfo, tree, offset, "boolean-value: ");
8463 offset = fRealTag (tvb, pinfo, tree, offset, "real value: ");
8466 offset = fUnsignedTag (tvb, pinfo, tree, offset, "enum value: ");
8469 offset = fUnsignedTag (tvb, pinfo, tree, offset, "unsigned value: ");
8472 offset = fSignedTag (tvb, pinfo, tree, offset, "signed value: ");
8475 offset = fBitStringTag (tvb, pinfo, tree, offset, "bitstring value: ");
8478 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8481 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8482 offset = fError (tvb, pinfo, tree, offset);
8483 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8485 case 8: /* any Value */
8486 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8487 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
8488 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8494 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8497 offset = fRealTag (tvb, pinfo, tree, offset, "time-change: ");
8502 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8507 if (offset == lastoffset) break; /* nothing happened, exit loop */
8514 fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8516 guint lastoffset = 0;
8517 guint8 tag_no, tag_info;
8520 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8521 lastoffset = offset;
8522 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8523 if (tag_is_closing(tag_info)) {
8528 case 0: /* ProcessId */
8529 offset = fProcessId (tvb,pinfo,tree,offset);
8531 case 1: /* initiating ObjectId */
8532 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8534 case 2: /* event ObjectId */
8535 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8537 case 3: /* time stamp */
8538 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8539 offset = fTimeStamp (tvb, pinfo, tree, offset, NULL);
8540 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8542 case 4: /* notificationClass */
8543 offset = fUnsignedTag (tvb, pinfo, tree, offset, "Notification Class: ");
8545 case 5: /* Priority */
8546 offset = fUnsignedTag (tvb, pinfo, tree, offset, "Priority: ");
8548 case 6: /* EventType */
8549 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
8550 "Event Type: ", BACnetEventType, 64);
8552 case 7: /* messageText */
8553 offset = fCharacterString (tvb, pinfo, tree, offset, "message Text: ");
8555 case 8: /* NotifyType */
8556 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8557 "Notify Type: ", BACnetNotifyType);
8559 case 9: /* ackRequired */
8560 offset = fBooleanTag (tvb, pinfo, tree, offset, "ack Required: ");
8562 case 10: /* fromState */
8563 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
8564 "from State: ", BACnetEventState, 64);
8566 case 11: /* toState */
8567 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
8568 "to State: ", BACnetEventState, 64);
8570 case 12: /* NotificationParameters */
8571 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8572 offset = fNotificationParameters (tvb, pinfo, tree, offset);
8573 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8578 if (offset == lastoffset) break; /* nothing happened, exit loop */
8584 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8586 return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
8590 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8592 guint lastoffset = 0, len;
8593 guint8 tag_no, tag_info;
8595 proto_tree *subtree = tree;
8598 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8599 lastoffset = offset;
8600 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8601 if (tag_is_closing(tag_info)) {
8608 case 0: /* ProcessId */
8609 offset = fProcessId (tvb,pinfo,tree,offset);
8611 case 1: /* initiating DeviceId */
8612 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8614 case 2: /* monitored ObjectId */
8615 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
8617 case 3: /* time remaining */
8618 offset = fTimeSpan (tvb, pinfo, tree, offset, "Time remaining");
8620 case 4: /* List of Values */
8621 if (tag_is_opening(tag_info)) {
8622 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
8623 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8624 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8625 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
8633 if (offset == lastoffset) break; /* nothing happened, exit loop */
8639 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8641 return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
8645 fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8647 guint lastoffset = 0;
8648 guint8 tag_no = 0, tag_info = 0;
8651 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8652 lastoffset = offset;
8653 switch (fTagNo(tvb, offset)) {
8654 case 0: /* acknowledgingProcessId */
8655 offset = fUnsignedTag (tvb, pinfo, tree, offset, "acknowledging Process Id: ");
8657 case 1: /* eventObjectId */
8658 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8660 case 2: /* eventStateAcknowledged */
8661 offset = fEnumeratedTagSplit (tvb, pinfo, tree, offset,
8662 "event State Acknowledged: ", BACnetEventState, 64);
8664 case 3: /* timeStamp */
8665 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8666 offset = fTimeStamp(tvb, pinfo, tree, offset, NULL);
8667 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8669 case 4: /* acknowledgementSource */
8670 offset = fCharacterString (tvb, pinfo, tree, offset, "acknowledgement Source: ");
8672 case 5: /* timeOfAcknowledgement */
8673 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8674 offset = fTimeStamp(tvb, pinfo, tree, offset, "acknowledgement timestamp: ");
8675 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8680 if (offset == lastoffset) break; /* nothing happened, exit loop */
8686 fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8688 guint lastoffset = 0;
8690 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8691 lastoffset = offset;
8692 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8693 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8694 "alarm State: ", BACnetEventState, 64);
8695 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8696 "acknowledged Transitions: ", BACnetEventTransitionBits);
8697 if (offset == lastoffset) break; /* nothing happened, exit loop */
8703 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8705 guint lastoffset = 0;
8706 guint8 tag_no, tag_info;
8709 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8710 lastoffset = offset;
8711 switch (fTagNo(tvb, offset)) {
8712 case 0: /* acknowledgmentFilter */
8713 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8714 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
8716 case 1: /* eventObjectId - OPTIONAL */
8717 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8718 offset = fRecipientProcess (tvb, pinfo, tree, offset);
8719 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8721 case 2: /* eventStateFilter */
8722 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8723 "event State Filter: ", BACnetEventStateFilter);
8725 case 3: /* eventTypeFilter - OPTIONAL */
8726 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8727 "event Type Filter: ", BACnetEventType);
8729 case 4: /* priorityFilter */
8730 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8731 offset = fUnsignedTag (tvb, pinfo, tree, offset, "min Priority: ");
8732 offset = fUnsignedTag (tvb, pinfo, tree, offset, "max Priority: ");
8733 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8735 case 5: /* notificationClassFilter - OPTIONAL */
8736 offset = fUnsignedTag (tvb, pinfo, tree, offset, "notification Class Filter: ");
8741 if (offset == lastoffset) break; /* nothing happened, exit loop */
8747 fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8749 guint lastoffset = 0;
8751 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8752 lastoffset = offset;
8753 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
8754 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
8755 "event Type: ", BACnetEventType, 64);
8756 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8757 "event State: ", BACnetEventState);
8758 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
8759 if (tvb_reported_length_remaining(tvb, offset) > 0 && fTagNo(tvb, offset) == 2) /* Notification Class - OPTIONAL */
8760 offset = fUnsignedTag (tvb, pinfo, tree, offset, "Notification Class: ");
8761 if (offset == lastoffset) break; /* nothing happened, exit loop */
8768 fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8770 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8771 if (fTagNo(tvb, offset) == 0) {
8772 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8779 flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8781 guint lastoffset = 0;
8782 guint8 tag_no, tag_info;
8784 proto_tree* subtree = tree;
8787 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8788 lastoffset = offset;
8789 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8790 /* we are finished here if we spot a closing tag */
8791 if (tag_is_closing(tag_info)) {
8795 case 0: /* ObjectId */
8796 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
8798 case 1: /* eventState */
8799 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8800 "event State: ", BACnetEventState);
8802 case 2: /* acknowledgedTransitions */
8803 offset = fBitStringTagVS (tvb, pinfo, tree, offset,
8804 "acknowledged Transitions: ", BACnetEventTransitionBits);
8806 case 3: /* eventTimeStamps */
8807 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
8809 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8811 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8812 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-OFFNORMAL timestamp: ");
8813 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-FAULT timestamp: ");
8814 offset = fTimeStamp (tvb, pinfo, subtree, offset,"TO-NORMAL timestamp: ");
8815 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8817 case 4: /* notifyType */
8818 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8819 "Notify Type: ", BACnetNotifyType);
8821 case 5: /* eventEnable */
8822 offset = fBitStringTagVS (tvb, pinfo, tree, offset,
8823 "event Enable: ", BACnetEventTransitionBits);
8825 case 6: /* eventPriorities */
8826 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
8828 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8830 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8831 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "TO-OFFNORMAL Priority: ");
8832 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "TO-FAULT Priority: ");
8833 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "TO-NORMAL Priority: ");
8834 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8839 if (offset == lastoffset) break; /* nothing happened, exit loop */
8845 fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8847 guint lastoffset = 0;
8848 guint8 tag_no, tag_info;
8851 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8852 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8853 lastoffset = offset;
8854 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8855 /* we are finished here if we spot a closing tag */
8856 if (tag_is_closing(tag_info)) {
8859 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
8860 if (offset == lastoffset) break; /* nothing happened, exit loop */
8866 fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8868 guint lastoffset = 0;
8869 guint8 tag_no, tag_info;
8872 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8873 lastoffset = offset;
8874 switch (fTagNo(tvb, offset)) {
8875 case 0: /* listOfEventSummaries */
8876 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8877 offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
8878 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8880 case 1: /* moreEvents */
8881 offset = fBooleanTag (tvb, pinfo, tree, offset, "more Events: ");
8886 if (offset == lastoffset) break; /* nothing happened, exit loop */
8892 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8894 guint lastoffset = 0, len;
8895 guint8 tag_no, tag_info;
8897 proto_tree *subtree = tree;
8900 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8902 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8903 lastoffset = offset;
8904 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8905 if (tag_is_closing(tag_info)) {
8912 case 0: /* ObjectId */
8913 offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
8915 case 3: /* listOfElements */
8916 if (tag_is_opening(tag_info)) {
8917 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
8918 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8919 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8920 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
8928 if (offset == lastoffset) break; /* nothing happened, exit loop */
8934 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8936 return fObjectIdentifier (tvb, pinfo, tree, offset);
8940 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8942 guint lastoffset = 0;
8944 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8945 lastoffset = offset;
8947 switch (fTagNo(tvb, offset)) {
8948 case 0: /* timeDuration */
8949 offset = fUnsignedTag (tvb,pinfo,tree,offset,"time Duration: ");
8951 case 1: /* enable-disable */
8952 offset = fEnumeratedTag (tvb, pinfo, tree, offset, "enable-disable: ",
8953 BACnetEnableDisable);
8955 case 2: /* password - OPTIONAL */
8956 offset = fCharacterString (tvb, pinfo, tree, offset, "Password: ");
8961 if (offset == lastoffset) break; /* nothing happened, exit loop */
8967 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8969 guint lastoffset = 0;
8971 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8972 lastoffset = offset;
8974 switch (fTagNo(tvb, offset)) {
8975 case 0: /* reinitializedStateOfDevice */
8976 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
8977 "reinitialized State Of Device: ",
8978 BACnetReinitializedStateOfDevice);
8980 case 1: /* password - OPTIONAL */
8981 offset = fCharacterString (tvb, pinfo, tree, offset, "Password: ");
8986 if (offset == lastoffset) break; /* nothing happened, exit loop */
8992 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8994 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
8995 "vtClass: ", BACnetVTClass);
8996 return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
9000 fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9002 return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
9006 fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9008 guint lastoffset = 0;
9010 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9011 lastoffset = offset;
9012 offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
9013 if (offset == lastoffset) break; /* nothing happened, exit loop */
9019 fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9021 offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
9022 offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
9023 return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");
9027 fVtDataAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9029 guint lastoffset = 0;
9031 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9032 lastoffset = offset;
9034 switch (fTagNo(tvb,offset)) {
9035 case 0: /* BOOLEAN */
9036 offset = fBooleanTag (tvb, pinfo, tree, offset, "all New Data Accepted: ");
9038 case 1: /* Unsigned OPTIONAL */
9039 offset = fUnsignedTag (tvb, pinfo, tree, offset, "accepted Octet Count: ");
9044 if (offset == lastoffset) break; /* nothing happened, exit loop */
9050 fAuthenticateRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9052 guint lastoffset = 0;
9054 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9055 lastoffset = offset;
9057 switch (fTagNo(tvb,offset)) {
9058 case 0: /* Unsigned32 */
9059 offset = fUnsignedTag (tvb, pinfo, tree, offset, "pseudo Random Number: ");
9061 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
9062 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
9064 case 2: /* Chararacter String OPTIONAL */
9065 offset = fCharacterString (tvb, pinfo, tree, offset, "operator Name: ");
9067 case 3: /* Chararacter String OPTIONAL */
9068 offset = fCharacterString (tvb, pinfo, tree, offset, "operator Password: ");
9070 case 4: /* Boolean OPTIONAL */
9071 offset = fBooleanTag (tvb, pinfo, tree, offset, "start Encyphered Session: ");
9076 if (offset == lastoffset) break; /* nothing happened, exit loop */
9082 fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9084 return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
9088 fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9090 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
9091 offset = fAddress (tvb, pinfo, tree, offset);
9092 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
9093 return fAddress (tvb, pinfo, tree, offset);
9097 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9099 /* Same as AddListElement request after service choice */
9100 return fAddListElementRequest(tvb, pinfo, tree, offset);
9104 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9106 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
9110 fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9112 guint lastoffset = 0, len;
9113 guint8 tag_no, tag_info;
9115 proto_tree *subtree = tree;
9117 /* set the optional global properties to indicate not-used */
9118 propertyArrayIndex = -1;
9119 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9120 lastoffset = offset;
9121 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9122 if (tag_is_closing(tag_info)) {
9128 case 0: /* objectIdentifier */
9129 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9131 case 1: /* propertyIdentifier */
9132 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
9134 case 2: /* propertyArrayIndex */
9135 offset = fPropertyArrayIndex (tvb, pinfo, subtree, offset);
9137 case 3: /* propertyValue */
9138 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
9143 if (offset == lastoffset) break; /* nothing happened, exit loop */
9149 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9151 guint lastoffset = 0;
9152 guint8 tag_no, tag_info;
9154 proto_tree *subtree = tree;
9156 /* set the optional global properties to indicate not-used */
9157 propertyArrayIndex = -1;
9158 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9159 lastoffset = offset;
9160 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9161 /* quit loop if we spot a closing tag */
9162 if (tag_is_closing(tag_info)) {
9167 case 0: /* objectIdentifier */
9168 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9170 case 1: /* propertyIdentifier */
9171 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
9173 case 2: /* propertyArrayIndex */
9174 offset = fPropertyArrayIndex (tvb, pinfo, subtree, offset);
9176 case 3: /* propertyValue */
9177 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
9179 case 4: /* Priority (only used for write) */
9180 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "Priority: ");
9185 if (offset == lastoffset) break; /* nothing happened, exit loop */
9191 fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9193 guint lastoffset = 0, len;
9194 guint8 tag_no, tag_info;
9197 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9198 lastoffset = offset;
9199 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9200 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
9201 if (tag_is_closing(tag_info)) {
9207 case 0: /* objectIdentifier */
9208 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9210 case 1: /* listOfPropertyValues */
9211 if (tag_is_opening(tag_info)) {
9212 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9213 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
9221 if (offset == lastoffset) break; /* nothing happened, exit loop */
9227 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9229 if (offset >= tvb_reported_length(tvb))
9232 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9233 return fWriteAccessSpecification (tvb, pinfo, tree, offset);
9237 fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
9239 guint lastoffset = 0;
9240 guint8 tag_no, tag_info;
9243 /* set the optional global properties to indicate not-used */
9244 propertyArrayIndex = -1;
9245 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9246 lastoffset = offset;
9247 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9248 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
9250 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
9253 switch (tag_no-tagoffset) {
9254 case 0: /* PropertyIdentifier */
9255 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
9257 case 1: /* propertyArrayIndex */
9258 offset = fPropertyArrayIndex (tvb, pinfo, tree, offset);
9259 if (list != 0) break; /* Continue decoding if this may be a list */
9261 lastoffset = offset; /* Set loop end condition */
9264 if (offset == lastoffset) break; /* nothing happened, exit loop */
9270 fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
9272 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9273 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
9277 fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9279 guint lastoffset = 0;
9281 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9282 lastoffset = offset;
9284 switch (fTagNo(tvb,offset)) {
9285 case 0: /* ObjectIdentifier */
9286 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9288 case 1: /* PropertyIdentifier and propertyArrayIndex */
9289 offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
9290 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9292 lastoffset = offset; /* Set loop end condition */
9295 if (offset == lastoffset) break; /* nothing happened, exit loop */
9302 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
9304 guint lastoffset = 0;
9305 guint8 tag_no, tag_info;
9307 proto_tree* subtree = tree;
9310 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
9311 lastoffset = offset;
9312 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9313 if (tag_is_closing(tag_info)) {
9314 offset += fTagHeaderTree (tvb, pinfo, subtree, offset,
9315 &tag_no, &tag_info, &lvt);
9319 case 0: /* ObjectIdentifier */
9320 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9322 case 1: /* PropertyIdentifier */
9323 offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
9325 case 2: /* propertyArrayIndex */
9326 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "property Array Index: ");
9329 offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
9331 case 4: /* Priority */
9332 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "Priority: ");
9343 fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9345 char i = 1, ar[256];
9346 guint lastoffset = 0;
9348 if (propertyArrayIndex > 0) {
9349 /* BACnetARRAY index 0 refers to the length
9350 of the array, not the elements of the array.
9351 BACnetARRAY index -1 is our internal flag that
9352 the optional index was not used.
9353 BACnetARRAY refers to this as all elements of the array.
9354 If the optional index is specified for a BACnetARRAY,
9355 then that specific array element is referenced. */
9356 i = propertyArrayIndex;
9358 while (tvb_reported_length_remaining(tvb, offset) > 0) {
9359 /* exit loop if nothing happens inside */
9360 lastoffset = offset;
9361 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
9362 val_to_split_str(87 , 512,
9363 BACnetPropertyIdentifier,
9364 ASHRAE_Reserved_Fmt,
9365 Vendor_Proprietary_Fmt),
9367 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
9368 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
9369 /* there are only 16 priority array elements */
9373 if (offset == lastoffset) break; /* nothing happened, exit loop */
9380 fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9382 guint lastoffset = 0;
9384 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9385 lastoffset = offset;
9387 switch (fTagNo(tvb,offset)) {
9388 case 0: /* deviceIdentifier - OPTIONAL */
9389 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9391 case 1: /* ObjectIdentifier */
9392 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9397 if (offset == lastoffset) break; /* nothing happened, exit loop */
9403 fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9405 guint8 tag_no, tag_info;
9407 guint lastoffset = 0, len;
9408 gboolean closing_found = FALSE; /* tracks when we are done decoding the fSpecialEvent entries */
9410 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9411 lastoffset = offset;
9412 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9413 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
9414 if (tag_is_closing(tag_info)) {
9415 /* if we find 2 closing tags in succession we need to exit without incrementing the offset again */
9416 /* This handles the special case where we have a special event entry in an RPM-ACK msg */
9417 if ( closing_found == TRUE )
9420 closing_found = TRUE;
9425 case 0: /* calendarEntry */
9426 if (tag_is_opening(tag_info)) {
9427 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9428 offset = fCalendarEntry (tvb, pinfo, subtree, offset);
9429 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9432 case 1: /* calendarReference */
9433 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9435 case 2: /* list of BACnetTimeValue */
9436 if (tag_is_opening(tag_info)) {
9437 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9438 offset = fTimeValue (tvb, pinfo, subtree, offset);
9439 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9444 case 3: /* eventPriority */
9445 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "event priority: ");
9450 closing_found = FALSE; /* reset our closing tag status, we processed another open tag */
9451 if (offset == lastoffset) break; /* nothing happened, exit loop */
9457 fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9459 guint lastoffset = 0, len;
9460 guint8 tag_no, tag_info;
9463 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9464 lastoffset = offset;
9465 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9466 /* maybe a listOfSelectionCriteria if we spot a closing tag */
9467 if (tag_is_closing(tag_info)) {
9472 switch (fTagNo(tvb,offset)) {
9473 case 0: /* propertyIdentifier */
9474 offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
9476 case 1: /* propertyArrayIndex */
9477 offset = fPropertyArrayIndex (tvb, pinfo, tree, offset);
9479 case 2: /* relationSpecifier */
9480 offset = fEnumeratedTag (tvb, pinfo, tree, offset,
9481 "relation Specifier: ", BACnetRelationSpecifier);
9483 case 3: /* comparisonValue */
9484 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9485 offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
9486 offset += fTagHeaderTree (tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9491 if (offset == lastoffset) break; /* nothing happened, exit loop */
9497 fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9499 guint lastoffset = 0;
9500 guint8 tag_no, tag_info;
9503 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9504 lastoffset = offset;
9505 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9506 /* quit loop if we spot a closing tag */
9507 if (tag_is_closing(tag_info)) {
9512 case 0: /* selectionLogic */
9513 offset = fEnumeratedTag (tvb, pinfo, subtree, offset,
9514 "selection Logic: ", BACnetSelectionLogic);
9516 case 1: /* listOfSelectionCriteria */
9517 if (tag_is_opening(tag_info)) {
9518 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9519 offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
9520 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9528 if (offset == lastoffset) break; /* nothing happened, exit loop */
9535 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
9537 guint lastoffset = 0;
9538 guint8 tag_no, tag_info;
9541 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9542 lastoffset = offset;
9543 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9545 if (tag_is_opening(tag_info) && tag_no < 2) {
9546 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9548 case 0: /* objectSelectionCriteria */
9549 offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
9551 case 1: /* listOfPropertyReferences */
9552 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
9557 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9559 if (offset == lastoffset) break; /* nothing happened, exit loop */
9565 fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9567 guint lastoffset = 0;
9568 guint8 tag_no, tag_info;
9571 proto_tree *subtree = tree;
9573 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9574 lastoffset = offset;
9575 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9577 case 0: /* objectIdentifier */
9578 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9580 case 1: /* listOfPropertyReferences */
9581 if (tag_is_opening(tag_info)) {
9582 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
9583 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9584 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9585 offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
9586 } else if (tag_is_closing(tag_info)) {
9587 offset += fTagHeaderTree (tvb, pinfo, subtree, offset,
9588 &tag_no, &tag_info, &lvt);
9591 /* error condition: let caller handle */
9598 if (offset == lastoffset) break; /* nothing happened, exit loop */
9604 fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9606 guint lastoffset = 0, len;
9610 proto_tree *subtree = tree;
9613 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9614 lastoffset = offset;
9615 len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9616 /* maybe a listOfReadAccessResults if we spot a closing tag here */
9617 if (tag_is_closing(tag_info)) {
9619 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
9624 case 0: /* objectSpecifier */
9625 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9627 case 1: /* list of Results */
9628 if (tag_is_opening(tag_info)) {
9629 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
9630 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9631 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9636 case 2: /* propertyIdentifier */
9637 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
9639 case 5: /* propertyAccessError */
9640 if (tag_is_opening(tag_info)) {
9641 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
9642 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9643 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9644 /* Error Code follows */
9645 offset = fError(tvb, pinfo, subtree, offset);
9653 if (offset == lastoffset) break; /* nothing happened, exit loop */
9660 fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9662 /* listOfReadAccessResults */
9663 return fReadAccessResult (tvb, pinfo, tree, offset);
9668 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9670 guint lastoffset = 0;
9671 guint8 tag_no, tag_info;
9674 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9675 lastoffset = offset;
9676 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9679 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9681 case 0: /* objectSpecifier */
9682 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
9683 case 0: /* objectType */
9684 offset = fEnumeratedTagSplit (tvb, pinfo, subtree, offset, "Object Type: ", BACnetObjectType, 128);
9686 case 1: /* objectIdentifier */
9687 offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
9693 case 1: /* propertyValue */
9694 if (tag_is_opening(tag_info)) {
9695 offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
9703 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9705 if (offset == lastoffset) break; /* nothing happened, exit loop */
9711 fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9713 return fObjectIdentifier (tvb, pinfo, tree, offset);
9717 fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9719 guint8 tag_no, tag_info;
9721 proto_tree *subtree = tree;
9724 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9726 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9727 /* optional range choice */
9728 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9729 if (tag_is_opening(tag_info)) {
9730 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str_const(tag_no, BACnetReadRangeOptions, "unknown range option"));
9731 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9732 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9734 case 3: /* range byPosition */
9735 case 6: /* range bySequenceNumber, 2004 spec */
9736 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
9737 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
9739 case 4: /* range byTime - deprecated in 2004 */
9740 case 7: /* 2004 spec */
9741 offset = fDateTime(tvb, pinfo, subtree, offset, "reference Date/Time: ");
9742 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
9744 case 5: /* range timeRange - deprecated in 2004 */
9745 offset = fDateTime(tvb, pinfo, subtree, offset, "beginning Time: ");
9746 offset = fDateTime(tvb, pinfo, subtree, offset, "ending Time: ");
9751 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9758 fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9760 guint8 tag_no, tag_info;
9762 proto_tree *subtree = tree;
9765 /* set the optional global properties to indicate not-used */
9766 propertyArrayIndex = -1;
9767 /* objectIdentifier, propertyIdentifier, and
9768 OPTIONAL propertyArrayIndex */
9769 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9770 /* resultFlags => BACnetResultFlags ::= BIT STRING */
9771 offset = fBitStringTagVS (tvb, pinfo, tree, offset,
9775 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "item Count: ");
9777 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9778 if (tag_is_opening(tag_info)) {
9779 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9780 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
9781 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9782 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9783 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
9784 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9786 /* firstSequenceNumber - OPTIONAL */
9787 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9788 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "first Sequence Number: ");
9795 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9797 guint lastoffset = 0;
9799 guint8 tag_no, tag_info;
9801 proto_tree* subtree = NULL;
9803 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9805 if (tag_is_opening(tag_info)) {
9806 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str_const(tag_no, BACnetFileAccessOption, "invalid access method"));
9807 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9808 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9809 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "invalid option"));
9810 offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileWriteInfo, "unknown option"));
9813 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
9814 /* exit loop if nothing happens inside */
9815 lastoffset = offset;
9816 offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
9820 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
9821 /* More Flag is not set, so we can look for closing tag in this segment */
9822 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9823 if (tag_is_closing(tag_info)) {
9824 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9832 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9834 guint8 tag_no, tag_info;
9836 proto_tree *subtree = tree;
9839 offset = fObjectIdentifier (tvb, pinfo, tree, offset);
9841 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9843 if (tag_is_opening(tag_info)) {
9844 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str_const(tag_no, BACnetFileAccessOption, "unknown access method"));
9845 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9846 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9847 offset = fSignedTag (tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
9848 offset = fUnsignedTag (tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileRequestCount, "unknown option"));
9849 offset += fTagHeaderTree (tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9855 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9858 offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
9859 offset = fAccessMethod(tvb, pinfo, tree, offset);
9865 fAtomicWriteFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9867 guint tag_no = fTagNo(tvb, offset);
9868 return fSignedTag (tvb, pinfo, tree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
9872 fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9874 offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
9875 offset = fAccessMethod(tvb,pinfo, tree, offset);
9881 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9883 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9884 return fReadAccessSpecification (tvb,pinfo,subtree,offset);
9888 fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9890 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9891 return fReadAccessResult (tvb,pinfo,tree,offset);
9895 fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9897 if (tvb_reported_length_remaining(tvb,offset) <= 0)
9900 switch (service_choice) {
9901 case 0: /* acknowledgeAlarm */
9902 offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
9904 case 1: /* confirmedCOVNotification */
9905 offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
9907 case 2: /* confirmedEventNotification */
9908 offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
9910 case 3: /* confirmedGetAlarmSummary conveys no parameters */
9912 case 4: /* getEnrollmentSummaryRequest */
9913 offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
9915 case 5: /* subscribeCOVRequest */
9916 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
9918 case 6: /* atomicReadFile-Request */
9919 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
9921 case 7: /* atomicWriteFile-Request */
9922 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
9924 case 8: /* AddListElement-Request */
9925 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
9927 case 9: /* removeListElement-Request */
9928 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
9930 case 10: /* createObjectRequest */
9931 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
9933 case 11: /* deleteObject */
9934 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
9937 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
9940 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
9943 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
9946 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
9949 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
9952 offset = fDeviceCommunicationControlRequest(tvb, pinfo, tree, offset);
9955 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
9958 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
9961 offset = fReinitializeDeviceRequest(tvb, pinfo, tree, offset);
9964 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
9967 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
9970 offset = fVtDataRequest (tvb, pinfo, tree, offset);
9973 offset = fAuthenticateRequest (tvb, pinfo, tree, offset);
9976 offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
9979 offset = fReadRangeRequest (tvb, pinfo, tree, offset);
9982 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
9985 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
9988 offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
9997 fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
9999 if (tvb_reported_length_remaining(tvb,offset) <= 0)
10002 switch (service_choice) {
10003 case 3: /* confirmedEventNotificationAck */
10004 offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
10006 case 4: /* getEnrollmentSummaryAck */
10007 offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
10009 case 6: /* atomicReadFile */
10010 offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
10012 case 7: /* atomicReadFileAck */
10013 offset = fAtomicWriteFileAck (tvb, pinfo, tree, offset);
10015 case 10: /* createObject */
10016 offset = fCreateObjectAck (tvb, pinfo, tree, offset);
10019 offset = fReadPropertyAck (tvb, pinfo, tree, offset);
10022 offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
10025 offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
10028 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
10031 offset = fVtOpenAck (tvb, pinfo, tree, offset);
10034 offset = fVtDataAck (tvb, pinfo, tree, offset);
10037 offset = fAuthenticateAck (tvb, pinfo, tree, offset);
10040 offset = fReadRangeAck (tvb, pinfo, tree, offset);
10043 offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
10052 fIAmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10054 /* BACnetObjectIdentifier */
10055 offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
10057 /* MaxAPDULengthAccepted */
10058 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
10060 /* segmentationSupported */
10061 offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
10062 "Segmentation Supported: ", BACnetSegmentation);
10065 return fVendorIdentifier (tvb, pinfo, tree, offset);
10069 fIHaveRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10071 /* BACnetDeviceIdentifier */
10072 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
10074 /* BACnetObjectIdentifier */
10075 offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
10078 return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
10083 fWhoIsRequest (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
10085 guint lastoffset = 0;
10089 guint8 tag_no, tag_info;
10092 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10093 lastoffset = offset;
10095 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10099 /* DeviceInstanceRangeLowLimit Optional */
10100 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
10101 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
10102 offset = fDevice_Instance (tvb, pinfo, tree, offset,
10103 hf_Device_Instance_Range_Low_Limit);
10106 /* DeviceInstanceRangeHighLimit Optional but
10107 required if DeviceInstanceRangeLowLimit is there */
10108 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
10109 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
10110 offset = fDevice_Instance (tvb, pinfo, tree, offset,
10111 hf_Device_Instance_Range_High_Limit);
10116 if (offset == lastoffset) break; /* nothing happened, exit loop */
10122 fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10124 if (tvb_reported_length_remaining(tvb,offset) <= 0)
10127 switch (service_choice) {
10128 case 0: /* I-Am-Request */
10129 offset = fIAmRequest (tvb, pinfo, tree, offset);
10131 case 1: /* i-Have Request */
10132 offset = fIHaveRequest (tvb, pinfo, tree, offset);
10134 case 2: /* unconfirmedCOVNotification */
10135 offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
10137 case 3: /* unconfirmedEventNotification */
10138 offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
10140 case 4: /* unconfirmedPrivateTransfer */
10141 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
10143 case 5: /* unconfirmedTextMessage */
10144 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
10146 case 206: /* utc-time-synchronization-recipients */
10147 case 6: /* timeSynchronization */
10148 offset = fTimeSynchronizationRequest (tvb, pinfo, tree, offset);
10150 case 7: /* who-Has */
10151 offset = fWhoHas (tvb, pinfo, tree, offset);
10153 case 8: /* who-Is */
10154 offset = fWhoIsRequest (tvb, pinfo, tree, offset);
10156 case 9: /* utcTimeSynchronization */
10157 offset = fUTCTimeSynchronizationRequest (tvb, pinfo, tree, offset);
10166 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
10167 gint *svc, proto_item **tt)
10170 proto_tree *bacapp_tree_control;
10175 tmp = (gint) tvb_get_guint8(tvb, offset);
10176 bacapp_flags = tmp & 0x0f;
10181 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
10182 if (bacapp_flags & 0x08)
10183 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
10185 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10186 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
10187 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
10189 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
10190 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
10191 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
10192 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
10193 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
10194 offset, 1, ENC_BIG_ENDIAN);
10195 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
10196 offset, 1, ENC_BIG_ENDIAN);
10199 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
10200 if (bacapp_flags & 0x08) {
10201 bacapp_seq = tvb_get_guint8(tvb, offset);
10202 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
10203 offset++, 1, ENC_BIG_ENDIAN);
10204 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
10205 offset++, 1, ENC_BIG_ENDIAN);
10207 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
10208 offset++, 1, ENC_BIG_ENDIAN);
10213 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
10214 { /* BACnet-Confirmed-Request */
10215 /* ASHRAE 135-2001 20.1.2 */
10217 return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
10221 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10222 { /* BACnet-Confirmed-Request */
10223 /* ASHRAE 135-2001 20.1.2 */
10225 proto_item *tt = 0;
10227 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
10228 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
10232 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10233 { /* BACnet-Unconfirmed-Request-PDU */
10234 /* ASHRAE 135-2001 20.1.3 */
10238 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10240 tmp = tvb_get_guint8(tvb, offset);
10241 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
10242 offset++, 1, ENC_BIG_ENDIAN);
10243 /* Service Request follows... Variable Encoding 20.2ff */
10244 return fUnconfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, tmp);
10248 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10249 { /* BACnet-Simple-Ack-PDU */
10250 /* ASHRAE 135-2001 20.1.4 */
10252 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10254 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
10255 offset++, 1, ENC_BIG_ENDIAN);
10256 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
10257 offset++, 1, ENC_BIG_ENDIAN);
10263 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
10264 { /* BACnet-Complex-Ack-PDU */
10265 /* ASHRAE 135-2001 20.1.5 */
10267 /* Service ACK follows... */
10268 return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
10272 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10273 { /* BACnet-Complex-Ack-PDU */
10274 /* ASHRAE 135-2001 20.1.5 */
10276 proto_item *tt = 0;
10278 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
10279 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
10283 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10284 { /* BACnet-SegmentAck-PDU */
10285 /* ASHRAE 135-2001 20.1.6 */
10288 proto_tree *bacapp_tree_control;
10290 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10291 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10293 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
10294 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10295 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10296 offset++, 1, ENC_BIG_ENDIAN);
10297 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
10298 offset++, 1, ENC_BIG_ENDIAN);
10299 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
10300 offset++, 1, ENC_BIG_ENDIAN);
10305 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10307 guint8 tag_info = 0;
10308 guint8 parsed_tag = 0;
10311 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
10312 offset = fError(tvb, pinfo, tree, offset);
10313 return offset + fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
10317 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10319 guint lastoffset = 0;
10320 guint8 tag_no = 0, tag_info = 0;
10322 proto_tree *subtree = tree;
10325 guint vendor_identifier = 0;
10326 guint service_number = 0;
10327 guint8 tag_len = 0;
10329 while (tvb_reported_length_remaining(tvb, offset) > 0) {
10330 /* exit loop if nothing happens inside */
10331 lastoffset = offset;
10332 tag_len = fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10334 case 0: /* errorType */
10335 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
10337 case 1: /* vendorID */
10338 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
10339 if (col_get_writable(pinfo->cinfo))
10340 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
10341 offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
10343 case 2: /* serviceNumber */
10344 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
10345 if (col_get_writable(pinfo->cinfo))
10346 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
10347 offset = fUnsignedTag (tvb, pinfo, subtree, offset, "service Number: ");
10349 case 3: /* errorParameters */
10350 if (tag_is_opening(tag_info)) {
10351 tt = proto_tree_add_text(subtree, tvb, offset, 1,
10352 "error Parameters");
10353 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
10354 propertyIdentifier = -1;
10355 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10356 offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
10357 } else if (tag_is_closing(tag_info)) {
10358 offset += fTagHeaderTree (tvb, pinfo, subtree, offset,
10359 &tag_no, &tag_info, &lvt);
10362 /* error condition: let caller handle */
10369 if (offset == lastoffset) break; /* nothing happened, exit loop */
10375 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10377 guint lastoffset = 0;
10379 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10380 lastoffset = offset;
10381 switch (fTagNo(tvb, offset)) {
10382 case 0: /* errorType */
10383 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10385 case 1: /* firstFailedElementNumber */
10386 offset = fUnsignedTag (tvb,pinfo,tree,offset,"first failed element number: ");
10391 if (offset == lastoffset) break; /* nothing happened, exit loop */
10397 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10399 /* Identical to CreateObjectError */
10400 return fCreateObjectError(tvb, pinfo, tree, offset);
10404 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10406 guint8 tag_no = 0, tag_info = 0;
10409 if (fTagNo(tvb, offset) == 0) {
10411 offset = fContextTaggedError(tvb, pinfo, tree,offset);
10412 if (fTagNo(tvb, offset) == 1) {
10413 /* listOfVTSessionIdentifiers [OPTIONAL] */
10414 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10415 offset = fVtCloseRequest (tvb, pinfo, tree, offset);
10416 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10419 /* should report bad packet if initial tag wasn't 0 */
10424 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10426 guint lastoffset = 0;
10427 guint8 tag_no = 0, tag_info = 0;
10430 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10431 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10432 lastoffset = offset;
10433 switch (fTagNo(tvb, offset)) {
10434 case 0: /* errorType */
10435 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10437 case 1: /* firstFailedWriteAttempt */
10438 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10439 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
10440 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10445 if (offset == lastoffset) break; /* nothing happened, exit loop */
10451 fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10453 offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
10454 "error Class: ", BACnetErrorClass, 64);
10455 return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
10456 "error Code: ", BACnetErrorCode, 256);
10460 fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
10463 case 8: /* no break here !!!! */
10465 offset = fChangeListError (tvb, pinfo, tree, offset);
10468 offset = fCreateObjectError (tvb, pinfo, tree, offset);
10471 offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
10474 offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
10477 offset = fVTCloseError (tvb, pinfo, tree, offset);
10480 return fError (tvb, pinfo, tree, offset);
10486 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10487 { /* BACnet-Error-PDU */
10488 /* ASHRAE 135-2001 20.1.7 */
10491 proto_tree *bacapp_tree_control;
10494 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10495 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10497 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10498 offset++, 1, ENC_BIG_ENDIAN);
10499 tmp = tvb_get_guint8(tvb, offset);
10500 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
10501 offset++, 1, ENC_BIG_ENDIAN);
10502 /* Error Handling follows... */
10503 return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
10507 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10508 { /* BACnet-Reject-PDU */
10509 /* ASHRAE 135-2001 20.1.8 */
10512 proto_tree *bacapp_tree_control;
10514 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10515 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10517 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10518 offset++, 1, ENC_BIG_ENDIAN);
10519 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
10520 offset++, 1, ENC_BIG_ENDIAN);
10525 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10526 { /* BACnet-Abort-PDU */
10527 /* ASHRAE 135-2001 20.1.9 */
10530 proto_tree *bacapp_tree_control;
10532 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10533 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10535 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10536 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10537 offset++, 1, ENC_BIG_ENDIAN);
10538 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
10539 offset++, 1, ENC_BIG_ENDIAN);
10544 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10546 guint8 flag, bacapp_type;
10549 flag = (gint) tvb_get_guint8(tvb, 0);
10550 bacapp_type = (flag >> 4) & 0x0f;
10556 /* ASHRAE 135-2001 20.1.1 */
10557 switch (bacapp_type) {
10558 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
10559 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
10561 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
10562 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
10564 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
10565 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
10567 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
10568 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
10570 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
10571 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
10573 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
10574 offset = fErrorPDU(tvb, pinfo, tree, offset);
10576 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
10577 offset = fRejectPDU(tvb, pinfo, tree, offset);
10579 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
10580 offset = fAbortPDU(tvb, pinfo, tree, offset);
10587 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10589 guint8 flag, bacapp_type;
10590 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
10591 tvbuff_t* new_tvb = NULL;
10593 guint8 bacapp_seqno = 0;
10594 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
10595 guint8 bacapp_invoke_id = 0;
10597 proto_tree *bacapp_tree = NULL;
10600 proto_item *tt = 0;
10603 /* Strings for BACnet Statistics */
10604 const gchar errstr[] = "ERROR: ";
10605 const gchar rejstr[] = "REJECTED: ";
10606 const gchar abortstr[] = "ABORTED: ";
10607 const gchar sackstr[] = " (SimpleAck)";
10608 const gchar cackstr[] = " (ComplexAck)";
10609 const gchar uconfsreqstr[] = " (Unconfirmed Service Request)";
10610 const gchar confsreqstr[] = " (Confirmed Service Request)";
10612 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
10613 col_clear (pinfo->cinfo, COL_INFO);
10615 flag = tvb_get_guint8(tvb, 0);
10616 bacapp_type = (flag >> 4) & 0x0f;
10618 /* show some descriptive text in the INFO column */
10619 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
10620 val_to_str_const(bacapp_type, BACnetTypeName, "# unknown APDU #"));
10622 bacinfo.service_type = NULL;
10623 bacinfo.invoke_id = NULL;
10624 bacinfo.instance_ident = NULL;
10625 bacinfo.object_ident = NULL;
10627 switch (bacapp_type) {
10628 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10629 /* segmented messages have 2 additional bytes */
10630 if (flag & BACAPP_SEGMENTED_REQUEST) {
10633 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
10634 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10635 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
10636 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
10637 bacapp_service = tvb_get_guint8(tvb, offset + 5);
10640 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10641 bacapp_service = tvb_get_guint8(tvb, offset + 3);
10643 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
10644 val_to_str_const(bacapp_service,
10645 BACnetConfirmedServiceChoice,
10646 bacapp_unknown_service_str),
10649 updateBacnetInfoValue(BACINFO_INVOKEID,
10650 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10652 updateBacnetInfoValue(BACINFO_SERVICE,
10653 wmem_strconcat(wmem_packet_scope(),
10654 val_to_str_const(bacapp_service,
10655 BACnetConfirmedServiceChoice,
10656 bacapp_unknown_service_str),
10657 confsreqstr, NULL));
10659 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
10660 bacapp_service = tvb_get_guint8(tvb, offset + 1);
10661 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
10662 val_to_str_const(bacapp_service,
10663 BACnetUnconfirmedServiceChoice,
10664 bacapp_unknown_service_str));
10666 updateBacnetInfoValue(BACINFO_SERVICE,
10667 wmem_strconcat(wmem_packet_scope(),
10668 val_to_str_const(bacapp_service,
10669 BACnetUnconfirmedServiceChoice,
10670 bacapp_unknown_service_str),
10671 uconfsreqstr, NULL));
10673 case BACAPP_TYPE_SIMPLE_ACK:
10674 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10675 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10676 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10677 val_to_str_const(bacapp_service,
10678 BACnetConfirmedServiceChoice,
10679 bacapp_unknown_service_str),
10682 updateBacnetInfoValue(BACINFO_INVOKEID,
10683 wmem_strdup_printf(wmem_packet_scope(),
10684 "Invoke ID: %d", bacapp_invoke_id));
10686 updateBacnetInfoValue(BACINFO_SERVICE,
10687 wmem_strconcat(wmem_packet_scope(),
10688 val_to_str_const(bacapp_service,
10689 BACnetConfirmedServiceChoice,
10690 bacapp_unknown_service_str),
10693 case BACAPP_TYPE_COMPLEX_ACK:
10694 /* segmented messages have 2 additional bytes */
10695 if (flag & BACAPP_SEGMENTED_REQUEST) {
10698 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
10699 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10700 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
10701 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
10702 bacapp_service = tvb_get_guint8(tvb, offset + 4);
10705 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10706 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10708 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10709 val_to_str_const(bacapp_service,
10710 BACnetConfirmedServiceChoice,
10711 bacapp_unknown_service_str),
10714 updateBacnetInfoValue(BACINFO_INVOKEID,
10715 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10717 updateBacnetInfoValue(BACINFO_SERVICE,
10718 wmem_strconcat(wmem_packet_scope(),
10719 val_to_str_const(bacapp_service,
10720 BACnetConfirmedServiceChoice,
10721 bacapp_unknown_service_str),
10724 case BACAPP_TYPE_SEGMENT_ACK:
10725 /* nothing more to add */
10727 case BACAPP_TYPE_ERROR:
10728 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10729 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10730 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10731 val_to_str_const(bacapp_service,
10732 BACnetConfirmedServiceChoice,
10733 bacapp_unknown_service_str),
10736 updateBacnetInfoValue(BACINFO_INVOKEID,
10737 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10739 updateBacnetInfoValue(BACINFO_SERVICE,
10740 wmem_strconcat(wmem_packet_scope(),
10742 val_to_str_const(bacapp_service,
10743 BACnetConfirmedServiceChoice,
10744 bacapp_unknown_service_str),
10747 case BACAPP_TYPE_REJECT:
10748 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10749 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10750 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10751 val_to_split_str(bacapp_reason,
10753 BACnetRejectReason,
10754 ASHRAE_Reserved_Fmt,
10755 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10757 updateBacnetInfoValue(BACINFO_INVOKEID,
10758 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10760 updateBacnetInfoValue(BACINFO_SERVICE,
10761 wmem_strconcat(wmem_packet_scope(), rejstr,
10762 val_to_split_str(bacapp_reason, 64,
10763 BACnetRejectReason,
10764 ASHRAE_Reserved_Fmt,
10765 Vendor_Proprietary_Fmt),
10768 case BACAPP_TYPE_ABORT:
10769 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10770 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10771 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10772 val_to_split_str(bacapp_reason,
10775 ASHRAE_Reserved_Fmt,
10776 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10778 updateBacnetInfoValue(BACINFO_INVOKEID,
10779 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10781 updateBacnetInfoValue(BACINFO_SERVICE,
10782 wmem_strconcat(wmem_packet_scope(), abortstr,
10783 val_to_split_str(bacapp_reason,
10786 ASHRAE_Reserved_Fmt,
10787 Vendor_Proprietary_Fmt),
10792 /* nothing more to add */
10796 save_fragmented = pinfo->fragmented;
10798 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA);
10799 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
10802 do_the_dissection(tvb,pinfo,bacapp_tree);
10804 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
10805 /* not resetting the offset so the remaining can be done */
10807 if (fragment) { /* fragmented */
10808 fragment_head *frag_msg;
10810 pinfo->fragmented = TRUE;
10812 frag_msg = fragment_add_seq_check(&msg_reassembly_table,
10815 bacapp_invoke_id, /* ID for fragments belonging together */
10817 bacapp_seqno, /* fragment sequence number */
10818 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
10819 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
10820 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
10821 "Reassembled BACapp", frag_msg, &msg_frag_items,
10824 if (new_tvb) { /* Reassembled */
10825 col_append_str(pinfo->cinfo, COL_INFO,
10826 " (Message Reassembled)");
10827 } else { /* Not last packet of reassembled Short Message */
10828 col_append_fstr(pinfo->cinfo, COL_INFO,
10829 " (Message fragment %u)", bacapp_seqno);
10831 if (new_tvb) { /* take it all */
10832 switch (bacapp_type) {
10833 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10834 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10836 case BACAPP_TYPE_COMPLEX_ACK:
10837 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10846 pinfo->fragmented = save_fragmented;
10849 tap_queue_packet(bacapp_tap,pinfo,&bacinfo);
10853 bacapp_init_routine(void)
10855 reassembly_table_init(&msg_reassembly_table,
10856 &addresses_reassembly_table_functions);
10860 fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
10865 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
10866 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
10867 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
10870 g_iconv_close (icd);
10874 uni_to_string(in,*inbytesleft,out);
10875 out[*inbytesleft] = '\0';
10876 *outbytesleft -= *inbytesleft;
10883 uni_to_string(char * data, gsize str_length, char *dest_buf)
10887 gsize length_remaining;
10889 length_remaining = str_length;
10890 dest_buf[0] = '\0';
10891 if(str_length == 0) {
10894 for ( i = 0; i < (gint) str_length; i++ ) {
10896 if (c_char<0x20 || c_char>0x7e) {
10897 if (c_char != 0x00) {
10899 dest_buf[i] = c_char & 0xff;
10905 dest_buf[i] = c_char & 0xff;
10907 length_remaining--;
10909 if(length_remaining==0) {
10910 dest_buf[i+1] = '\0';
10917 dest_buf[i] = '\0';
10922 proto_register_bacapp(void)
10924 static hf_register_info hf[] = {
10926 { "APDU Type", "bacapp.type",
10927 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
10929 { &hf_bacapp_pduflags,
10930 { "PDU Flags", "bacapp.pduflags",
10931 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
10934 { "Segmented Request", "bacapp.segmented_request",
10935 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
10938 { "More Segments", "bacapp.more_segments",
10939 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
10942 { "SA", "bacapp.SA",
10943 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
10945 { &hf_bacapp_max_adpu_size,
10946 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
10947 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
10949 { &hf_bacapp_response_segments,
10950 { "Max Response Segments accepted", "bacapp.response_segments",
10951 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
10953 { &hf_bacapp_objectType,
10954 { "Object Type", "bacapp.objectType",
10955 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
10957 { &hf_bacapp_instanceNumber,
10958 { "Instance Number", "bacapp.instance_number",
10959 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
10961 { &hf_BACnetPropertyIdentifier,
10962 { "Property Identifier", "bacapp.property_identifier",
10963 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
10965 { &hf_BACnetVendorIdentifier,
10966 { "Vendor Identifier", "bacapp.vendor_identifier",
10967 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
10969 { &hf_BACnetRestartReason,
10970 { "Restart Reason", "bacapp.restart_reason",
10971 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
10973 { &hf_bacapp_invoke_id,
10974 { "Invoke ID", "bacapp.invoke_id",
10975 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10977 { &hf_bacapp_sequence_number,
10978 { "Sequence Number", "bacapp.sequence_number",
10979 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10981 { &hf_bacapp_window_size,
10982 { "Proposed Window Size", "bacapp.window_size",
10983 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
10985 { &hf_bacapp_service,
10986 { "Service Choice", "bacapp.confirmed_service",
10987 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
10989 { &hf_bacapp_uservice,
10990 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
10991 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
10994 { "NAK", "bacapp.NAK",
10995 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
10998 { "SRV", "bacapp.SRV",
10999 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
11001 { &hf_Device_Instance_Range_Low_Limit,
11002 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
11003 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
11005 { &hf_Device_Instance_Range_High_Limit,
11006 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
11007 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
11009 { &hf_BACnetRejectReason,
11010 { "Reject Reason", "bacapp.reject_reason",
11011 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
11013 { &hf_BACnetAbortReason,
11014 { "Abort Reason", "bacapp.abort_reason",
11015 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
11017 { &hf_BACnetApplicationTagNumber,
11018 { "Application Tag Number",
11019 "bacapp.application_tag_number",
11020 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
11023 { &hf_BACnetContextTagNumber,
11024 { "Context Tag Number",
11025 "bacapp.context_tag_number",
11026 FT_UINT8, BASE_DEC, NULL, 0xF0,
11029 { &hf_BACnetExtendedTagNumber,
11030 { "Extended Tag Number",
11031 "bacapp.extended_tag_number",
11032 FT_UINT8, BASE_DEC, NULL, 0,
11035 { &hf_BACnetNamedTag,
11037 "bacapp.named_tag",
11038 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
11041 { &hf_BACnetCharacterSet,
11042 { "String Character Set",
11043 "bacapp.string_character_set",
11044 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet),0,
11047 { &hf_BACnetTagClass,
11048 { "Tag Class", "bacapp.tag_class",
11049 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
11051 { &hf_bacapp_tag_lvt,
11052 { "Length Value Type",
11054 FT_UINT8, BASE_DEC, NULL, 0,
11057 { &hf_bacapp_tag_ProcessId,
11058 { "ProcessIdentifier", "bacapp.processId",
11059 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
11061 { &hf_bacapp_tag_IPV4,
11062 { "IPV4", "bacapp.IPV4",
11063 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
11065 { &hf_bacapp_tag_IPV6,
11066 { "IPV6", "bacapp.IPV6",
11067 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
11069 { &hf_bacapp_tag_PORT,
11070 { "Port", "bacapp.Port",
11071 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
11073 {&hf_msg_fragments,
11074 {"Message fragments", "bacapp.fragments",
11075 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11077 {"Message fragment", "bacapp.fragment",
11078 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11079 {&hf_msg_fragment_overlap,
11080 {"Message fragment overlap", "bacapp.fragment.overlap",
11081 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11082 {&hf_msg_fragment_overlap_conflicts,
11083 {"Message fragment overlapping with conflicting data",
11084 "bacapp.fragment.overlap.conflicts",
11085 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11086 {&hf_msg_fragment_multiple_tails,
11087 {"Message has multiple tail fragments",
11088 "bacapp.fragment.multiple_tails",
11089 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11090 {&hf_msg_fragment_too_long_fragment,
11091 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
11092 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11093 {&hf_msg_fragment_error,
11094 {"Message defragmentation error", "bacapp.fragment.error",
11095 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11096 {&hf_msg_fragment_count,
11097 {"Message fragment count", "bacapp.fragment.count",
11098 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
11099 {&hf_msg_reassembled_in,
11100 {"Reassembled in", "bacapp.reassembled.in",
11101 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11102 {&hf_msg_reassembled_length,
11103 {"Reassembled BACapp length", "bacapp.reassembled.length",
11104 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
11106 static gint *ett[] = {
11108 &ett_bacapp_control,
11117 static ei_register_info ei[] = {
11118 { &ei_bacapp_bad_length, { "bacapp.bad_length", PI_MALFORMED, PI_ERROR, "Wrong length indicated", EXPFILL }},
11121 expert_module_t* expert_bacapp;
11123 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
11124 "BACapp", "bacapp");
11126 proto_register_field_array(proto_bacapp, hf, array_length(hf));
11127 proto_register_subtree_array(ett, array_length(ett));
11128 expert_bacapp = expert_register_protocol(proto_bacapp);
11129 expert_register_field_array(expert_bacapp, ei, array_length(ei));
11130 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
11131 register_init_routine (&bacapp_init_routine);
11133 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
11134 "BACapp Vendor Identifier",
11135 FT_UINT8, BASE_HEX);
11137 /* Register BACnet Statistic trees */
11138 register_bacapp_stat_trees();
11139 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
11143 proto_reg_handoff_bacapp(void)
11145 data_handle = find_dissector("data");
11149 * Editor modelines - http://www.wireshark.org/tools/modelines.html
11152 * c-basic-offset: 4
11154 * indent-tabs-mode: nil
11157 * vi: set shiftwidth=4 tabstop=8 expandtab:
11158 * :indentSize=4:tabSize=8:noTabs=true: