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
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald[AT]wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <epan/packet.h>
33 #include <epan/to_str.h>
34 #include <epan/wmem/wmem.h>
35 #include <epan/reassemble.h>
36 #include <epan/expert.h>
37 #include <epan/stats_tree.h>
38 #include "packet-bacapp.h"
40 static int bacapp_tap = -1;
42 /* formerly bacapp.h contains definitions and forward declarations */
45 #define FAULT proto_tree_add_text(subtree, tvb, offset, tvb_length(tvb) - offset, "something is going wrong here !!"); \
46 offset = tvb_length(tvb);
49 /* BACnet PDU Types */
50 #define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0
51 #define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1
52 #define BACAPP_TYPE_SIMPLE_ACK 2
53 #define BACAPP_TYPE_COMPLEX_ACK 3
54 #define BACAPP_TYPE_SEGMENT_ACK 4
55 #define BACAPP_TYPE_ERROR 5
56 #define BACAPP_TYPE_REJECT 6
57 #define BACAPP_TYPE_ABORT 7
58 #define MAX_BACAPP_TYPE 8
60 #define BACAPP_SEGMENTED_REQUEST 0x08
61 #define BACAPP_MORE_SEGMENTS 0x04
62 #define BACAPP_SEGMENTED_RESPONSE 0x02
63 #define BACAPP_SEGMENT_NAK 0x02
64 #define BACAPP_SENT_BY 0x01
68 * dissect_bacapp ::= CHOICE {
69 * confirmed-request-PDU [0] BACnet-Confirmed-Request-PDU,
70 * unconfirmed-request-PDU [1] BACnet-Unconfirmed-Request-PDU,
71 * simpleACK-PDU [2] BACnet-SimpleACK-PDU,
72 * complexACK-PDU [3] BACnet-ComplexACK-PDU,
73 * segmentACK-PDU [4] BACnet-SegmentACK-PDU,
74 * error-PDU [5] BACnet-Error-PDU,
75 * reject-PDU [6] BACnet-Reject-PDU,
76 * abort-PDU [7] BACnet-Abort-PDU
78 * @param tvb the tv buffer of the current data
79 * @param pinfo the packet info of the current data
80 * @param tree the tree to append this item to
83 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
86 * ConfirmedRequest-PDU ::= SEQUENCE {
87 * pdu-type [0] Unsigned (0..15), -- 0 for this PDU Type
88 * segmentedMessage [1] BOOLEAN,
89 * moreFollows [2] BOOLEAN,
90 * segmented-response-accepted [3] BOOLEAN,
91 * reserved [4] Unsigned (0..3), -- must be set zero
92 * max-segments-accepted [5] Unsigned (0..7), -- as per 20.1.2.4
93 * max-APDU-length-accepted [5] Unsigned (0..15), -- as per 20.1.2.5
94 * invokeID [6] Unsigned (0..255),
95 * sequence-number [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
96 * proposed-window-size [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
97 * service-choice [9] BACnetConfirmedServiceChoice,
98 * service-request [10] BACnet-Confirmed-Service-Request OPTIONAL
100 * @param tvb the tv buffer of the current data
101 * @param pinfo the packet info of the current data
102 * @param tree the tree to append this item to
103 * @param offset the offset in the tvb
104 * @return modified offset
107 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
110 * @param tvb the tv buffer of the current data
111 * @param pinfo the packet info of the current data
112 * @param tree the tree to append this item to
113 * @param offset the offset in the tvb
114 * @param ack - indocates whether working on request or ack
115 * @param svc - output variable to return service choice
116 * @param tt - output varable to return service choice item
117 * @return modified offset
120 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 ack,
121 gint *svc, proto_item **tt);
124 * Unconfirmed-Request-PDU ::= SEQUENCE {
125 * pdu-type [0] Unsigned (0..15), -- 1 for this PDU type
126 * reserved [1] Unsigned (0..15), -- must be set zero
127 * service-choice [2] BACnetUnconfirmedServiceChoice,
128 * service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
130 * @param tvb the tv buffer of the current data
131 * @param pinfo the packet info of the current data
132 * @param tree the tree to append this item to
133 * @param offset the offset in the tvb
134 * @return modified offset
137 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
140 * SimpleACK-PDU ::= SEQUENCE {
141 * pdu-type [0] Unsigned (0..15), -- 2 for this PDU type
142 * reserved [1] Unsigned (0..15), -- must be set zero
143 * invokeID [2] Unsigned (0..255),
144 * service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
146 * @param tvb the tv buffer of the current data
147 * @param pinfo the packet info of the current data
148 * @param tree the tree to append this item to
149 * @param offset the offset in the tvb
150 * @return modified offset
153 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
156 * ComplexACK-PDU ::= SEQUENCE {
157 * pdu-type [0] Unsigned (0..15), -- 3 for this PDU Type
158 * segmentedMessage [1] BOOLEAN,
159 * moreFollows [2] BOOLEAN,
160 * reserved [3] Unsigned (0..3), -- must be set zero
161 * invokeID [4] Unsigned (0..255),
162 * sequence-number [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
163 * proposed-window-size [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
164 * service-ACK-choice [7] BACnetConfirmedServiceChoice,
165 * service-ACK [8] BACnet-Confirmed-Service-Request -- Context-specific tags 0..8 are NOT used in header encoding
167 * @param tvb the tv buffer of the current data
168 * @param pinfo the packet info of the current data
169 * @param tree the tree to append this item to
170 * @param offset the offset in the tvb
171 * @return modified offset
174 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
177 * SegmentACK-PDU ::= SEQUENCE {
178 * pdu-type [0] Unsigned (0..15), -- 4 for this PDU Type
179 * reserved [1] Unsigned (0..3), -- must be set zero
180 * negative-ACK [2] BOOLEAN,
181 * server [3] BOOLEAN,
182 * original-invokeID [4] Unsigned (0..255),
183 * sequence-number [5] Unsigned (0..255),
184 * actual-window-size [6] Unsigned (0..127)
186 * @param tvb the tv buffer of the current data
187 * @param pinfo the packet info of the current data
188 * @param tree the tree to append this item to
189 * @param offset the offset in the tvb
190 * @return modified offset
193 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
196 * Error-PDU ::= SEQUENCE {
197 * pdu-type [0] Unsigned (0..15), -- 5 for this PDU Type
198 * reserved [1] Unsigned (0..3), -- must be set zero
199 * original-invokeID [2] Unsigned (0..255),
200 * error-choice [3] BACnetConfirmedServiceChoice,
201 * error [4] BACnet-Error
203 * @param tvb the tv buffer of the current data
204 * @param pinfo the packet info of the current data
205 * @param tree the tree to append this item to
206 * @param offset the offset in the tvb
207 * @return modified offset
210 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
213 * Reject-PDU ::= SEQUENCE {
214 * pdu-type [0] Unsigned (0..15), -- 6 for this PDU Type
215 * reserved [1] Unsigned (0..3), -- must be set zero
216 * original-invokeID [2] Unsigned (0..255),
217 * reject-reason [3] BACnetRejectReason
219 * @param tvb the tv buffer of the current data
220 * @param pinfo the packet info of the current data
221 * @param tree the tree to append this item to
222 * @param offset the offset in the tvb
223 * @return modified offset
226 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
229 * Abort-PDU ::= SEQUENCE {
230 * pdu-type [0] Unsigned (0..15), -- 7 for this PDU Type
231 * reserved [1] Unsigned (0..3), -- must be set zero
232 * server [2] BOOLEAN,
233 * original-invokeID [3] Unsigned (0..255),
234 * abort-reason [4] BACnetAbortReason
236 * @param tvb the tv buffer of the current data
237 * @param pinfo the packet info of the current data
238 * @param tree the tree to append this item to
239 * @param offset the offset in the tvb
240 * @return modified offset
243 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
246 * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree
247 * @param tvb the tv buffer of the current data
248 * @param pinfo the packet info of the current data
249 * @param tree the tree to append this item to
250 * @param offset the offset in the tvb
251 * @param label the label of this item
252 * @return modified offset
255 fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
258 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
259 * @param tvb the tv buffer of the current data
260 * @param pinfo the packet info of the current data
261 * @param tree the tree to append this item to
262 * @param offset the offset in the tvb
263 * @param label the label of this item
264 * @return modified offset
267 fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
270 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
271 * @param tvb the tv buffer of the current data
272 * @param pinfo the packet info of the current data
273 * @param tree the tree to append this item to
274 * @param offset the offset in the tvb
275 * @param label the label of this item
276 * @param lvt length of String
277 * @return modified offset
280 fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
283 * 20.2.12, adds the label with Date Value to tree
284 * @param tvb the tv buffer of the current data
285 * @param pinfo the packet info of the current data
286 * @param tree the tree to append this item to
287 * @param offset the offset in the tvb
288 * @param label the label of this item
289 * @return modified offset
292 fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
295 * 20.2.13, adds the label with Time Value to tree
296 * @param tvb the tv buffer of the current data
297 * @param pinfo the packet info of the current data
298 * @param tree the tree to append this item to
299 * @param offset the offset in the tvb
300 * @param label the label of this item
301 * @return modified offset
304 fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
307 * 20.2.14, adds Object Identifier to tree
308 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
309 * @param tvb the tv buffer of the current data
310 * @param pinfo the packet info of the current data
311 * @param tree the tree to append this item to
312 * @param offset the offset in the tvb
313 * @return modified offset
316 fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
319 * BACnet-Confirmed-Service-Request ::= CHOICE {
321 * @param tvb the tv buffer of the current data
322 * @param pinfo the packet info of the current data
323 * @param tree the tree to append this item to
324 * @param offset the offset in the tvb
325 * @param service_choice the service choice
329 fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
332 * BACnet-Confirmed-Service-ACK ::= CHOICE {
334 * @param tvb the tv buffer of the current data
335 * @param pinfo the packet info of the current data
336 * @param tree the tree to append this item to
337 * @param offset the offset in the tvb
338 * @param service_choice the service choice
342 fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
345 * AcknowledgeAlarm-Request ::= SEQUENCE {
346 * acknowledgingProcessIdentifier [0] Unsigned32,
347 * eventObjectIdentifier [1] BACnetObjectIdentifer,
348 * eventStateAcknowledge [2] BACnetEventState,
349 * timeStamp [3] BACnetTimeStamp,
350 * acknowledgementSource [4] Character String,
351 * timeOfAcknowledgement [5] BACnetTimeStamp
353 * @param tvb the tv buffer of the current data
354 * @param pinfo the packet info of the current data
355 * @param tree the tree to append this item to
356 * @param offset the offset in the tvb
357 * @return modified offset
360 fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
363 * ConfirmedCOVNotification-Request ::= SEQUENCE {
364 * subscriberProcessIdentifier [0] Unsigned32,
365 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
366 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
367 * timeRemaining [3] unsigned,
368 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
370 * @param tvb the tv buffer of the current data
371 * @param pinfo the packet info of the current data
372 * @param tree the tree to append this item to
373 * @param offset the offset in the tvb
374 * @return modified offset
377 fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
380 * ConfirmedEventNotification-Request ::= SEQUENCE {
381 * ProcessIdentifier [0] Unsigned32,
382 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
383 * eventObjectIdentifier [2] BACnetObjectIdentifer,
384 * timeStamp [3] BACnetTimeStamp,
385 * notificationClass [4] unsigned,
386 * priority [5] unsigned8,
387 * eventType [6] BACnetEventType,
388 * messageText [7] CharacterString OPTIONAL,
389 * notifyType [8] BACnetNotifyType,
390 * ackRequired [9] BOOLEAN OPTIONAL,
391 * fromState [10] BACnetEventState OPTIONAL,
392 * toState [11] BACnetEventState,
393 * eventValues [12] BACnetNotificationParameters OPTIONAL
395 * @param tvb the tv buffer of the current data
396 * @param pinfo the packet info of the current data
397 * @param tree the tree to append this item to
398 * @param offset the offset in the tvb
399 * @return modified offset
402 fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
405 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
406 * objectIdentifier BACnetObjectIdentifer,
407 * alarmState BACnetEventState,
408 * acknowledgedTransitions BACnetEventTransitionBits
410 * @param tvb the tv buffer of the current data
411 * @param pinfo the packet info of the current data
412 * @param tree the tree to append this item to
413 * @param offset the offset in the tvb
414 * @return modified offset
417 fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
420 * GetEnrollmentSummary-Request ::= SEQUENCE {
421 * acknowledgmentFilter [0] ENUMERATED {
426 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
427 * eventStateFilter [2] ENUMERATED {
434 * eventTypeFilter [3] BACnetEventType OPTIONAL,
435 * priorityFilter [4] SEQUENCE {
436 * minPriority [0] Unsigned8,
437 * maxPriority [1] Unsigned8
439 * notificationClassFilter [5] Unsigned OPTIONAL
441 * @param tvb the tv buffer of the current data
442 * @param pinfo the packet info of the current data
443 * @param tree the tree to append this item to
444 * @param offset the offset in the tvb
445 * @return modified offset
448 fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
451 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
452 * objectIdentifier BACnetObjectIdentifer,
453 * eventType BACnetEventType,
454 * eventState BACnetEventState,
455 * priority Unsigned8,
456 * notificationClass Unsigned OPTIONAL
458 * @param tvb the tv buffer of the current data
459 * @param pinfo the packet info of the current data
460 * @param tree the tree to append this item to
461 * @param offset the offset in the tvb
462 * @return modified offset
465 fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
468 * GetEventInformation-Request ::= SEQUENCE {
469 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
471 * @param tvb the tv buffer of the current data
472 * @param pinfo the packet info of the current data
473 * @param tree the tree to append this item to
474 * @param offset the offset in the tvb
475 * @return modified offset
478 fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
481 * GetEventInformation-ACK ::= SEQUENCE {
482 * listOfEventSummaries [0] listOfEventSummaries,
483 * moreEvents [1] BOOLEAN
485 * @param tvb the tv buffer of the current data
486 * @param pinfo the packet info of the current data
487 * @param tree the tree to append this item to
488 * @param offset the offset in the tvb
489 * @return modified offset
492 fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
495 * LifeSafetyOperation-Request ::= SEQUENCE {
496 * requestingProcessIdentifier [0] Unsigned32
497 * requestingSource [1] CharacterString
498 * request [2] BACnetLifeSafetyOperation
499 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
501 * @param tvb the tv buffer of the current data
502 * @param pinfo the packet info of the current data
503 * @param tree the tree to append this item to
504 * @param offset the offset in the tvb
505 * @return modified offset
508 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
511 * SubscribeCOV-Request ::= SEQUENCE {
512 * subscriberProcessIdentifier [0] Unsigned32
513 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
514 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
515 * lifetime [3] Unsigned OPTIONAL
517 * @param tvb the tv buffer of the current data
518 * @param pinfo the packet info of the current data
519 * @param tree the tree to append this item to
520 * @param offset the offset in the tvb
521 * @return modified offset
524 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
527 * SubscribeCOVProperty-Request ::= SEQUENCE {
528 * subscriberProcessIdentifier [0] Unsigned32
529 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
530 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
531 * lifetime [3] Unsigned OPTIONAL
532 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
533 * covIncrement [5] Unsigned OPTIONAL
535 * @param tvb the tv buffer of the current data
536 * @param pinfo the packet info of the current data
537 * @param tree the tree to append this item to
538 * @param offset the offset in the tvb
539 * @return modified offset
542 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
545 * AtomicReadFile-Request ::= SEQUENCE {
546 * fileIdentifier BACnetObjectIdentifier,
547 * accessMethod CHOICE {
548 * streamAccess [0] SEQUENCE {
549 * fileStartPosition INTEGER,
550 * requestedOctetCount Unsigned
552 * recordAccess [1] SEQUENCE {
553 * fileStartRecord INTEGER,
554 * requestedRecordCount Unsigned
558 * @param tvb the tv buffer of the current data
559 * @param pinfo the packet info of the current data
560 * @param tree the tree to append this item to
561 * @param offset the offset in the tvb
562 * @return modified offset
565 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
568 * AtomicWriteFile-ACK ::= SEQUENCE {
570 * accessMethod CHOICE {
571 * streamAccess [0] SEQUENCE {
572 * fileStartPosition INTEGER,
573 * fileData OCTET STRING
575 * recordAccess [1] SEQUENCE {
576 * fileStartRecord INTEGER,
577 * returnedRecordCount Unsigned,
578 * fileRecordData SEQUENCE OF OCTET STRING
582 * @param tvb the tv buffer of the current data
583 * @param pinfo the packet info of the current data
584 * @param tree the tree to append this item to
585 * @param offset the offset in the tvb
586 * @return modified offset
589 fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
592 * AtomicWriteFile-Request ::= SEQUENCE {
593 * fileIdentifier BACnetObjectIdentifier,
594 * accessMethod CHOICE {
595 * streamAccess [0] SEQUENCE {
596 * fileStartPosition INTEGER,
597 * fileData OCTET STRING
599 * recordAccess [1] SEQUENCE {
600 * fileStartRecord INTEGER,
601 * recordCount Unsigned,
602 * fileRecordData SEQUENCE OF OCTET STRING
606 * @param tvb the tv buffer of the current data
607 * @param pinfo the packet info of the current data
608 * @param tree the tree to append this item to
609 * @param offset the offset in the tvb
610 * @return modified offset
613 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
616 * AtomicWriteFile-ACK ::= SEQUENCE {
617 * fileStartPosition [0] INTEGER,
618 * fileStartRecord [1] INTEGER,
620 * @param tvb the tv buffer of the current data
621 * @param pinfo the packet info of the current data
622 * @param tree the tree to append this item to
623 * @param offset the offset in the tvb
624 * @return modified offset
627 fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
630 * AddListElement-Request ::= SEQUENCE {
631 * objectIdentifier [0] BACnetObjectIdentifier,
632 * propertyIdentifier [1] BACnetPropertyIdentifier,
633 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
634 * listOfElements [3] ABSTRACT-SYNTAX.&Type
636 * @param tvb the tv buffer of the current data
637 * @param pinfo the packet info of the current data
638 * @param tree the tree to append this item to
639 * @param offset the offset in the tvb
640 * @return modified offset
643 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
646 * CreateObject-Request ::= SEQUENCE {
647 * objectSpecifier [0] ObjectSpecifier,
648 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
650 * @param tvb the tv buffer of the current data
651 * @param pinfo the packet info of the current data
652 * @param subtree the sub tree to append this item to
653 * @param offset the offset in the tvb
654 * @return modified offset
657 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
660 * CreateObject-Request ::= BACnetObjectIdentifier
661 * @param tvb the tv buffer of the current data
662 * @param pinfo the packet info of the current data
663 * @param tree the tree to append this item to
664 * @param offset the offset in the tvb
665 * @return modified offset
668 fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
671 * DeleteObject-Request ::= SEQUENCE {
672 * ObjectIdentifier BACnetObjectIdentifer
674 * @param tvb the tv buffer of the current data
675 * @param pinfo the packet info of the current data
676 * @param tree the tree to append this item to
677 * @param offset the offset in the tvb
678 * @return modified offset
681 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
684 * ReadProperty-Request ::= SEQUENCE {
685 * objectIdentifier [0] BACnetObjectIdentifier,
686 * propertyIdentifier [1] BACnetPropertyIdentifier,
687 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
689 * @param tvb the tv buffer of the current data
690 * @param pinfo the packet info of the current data
691 * @param tree the tree to append this item to
692 * @param offset the offset in the tvb
693 * @return modified offset
696 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
699 * ReadProperty-ACK ::= SEQUENCE {
700 * objectIdentifier [0] BACnetObjectIdentifier,
701 * propertyIdentifier [1] BACnetPropertyIdentifier,
702 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
703 * propertyValue [3] ABSTRACT-SYNTAX.&Type
705 * @param tvb the tv buffer of the current data
706 * @param pinfo the packet info of the current data
707 * @param tree the tree to append this item to
708 * @param offset the offset in the tvb
709 * @return modified offset
712 fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
715 * ReadPropertyConditional-Request ::= SEQUENCE {
716 * objectSelectionCriteria [0] objectSelectionCriteria,
717 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
719 * @param tvb the tv buffer of the current data
720 * @param pinfo the packet info of the current data
721 * @param subtree the sub tree to append this item to
722 * @param offset the offset in the tvb
723 * @return modified offset
726 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
729 * ReadPropertyConditional-ACK ::= SEQUENCE {
730 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
732 * @param tvb the tv buffer of the current data
733 * @param pinfo the packet info of the current data
734 * @param tree the tree to append this item to
735 * @param offset the offset in the tvb
736 * @return modified offset
739 fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
742 * ReadPropertyMultiple-Request ::= SEQUENCE {
743 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
745 * @param tvb the tv buffer of the current data
746 * @param pinfo the packet info of the current data
747 * @param subtree the sub tree to append this item to
748 * @param offset the offset in the tvb
749 * @return offset modified
752 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
755 * ReadPropertyMultiple-Ack ::= SEQUENCE {
756 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
758 * @param tvb the tv buffer of the current data
760 * @param tree the tree to append this item to
761 * @param offset the offset in the tvb
762 * @return offset modified
765 fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
768 * ReadRange-Request ::= SEQUENCE {
769 * objectIdentifier [0] BACnetObjectIdentifier,
770 * propertyIdentifier [1] BACnetPropertyIdentifier,
771 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
773 * byPosition [3] SEQUENCE {
774 * referencedIndex Unsigned,
777 * byTime [4] SEQUENCE {
778 * referenceTime BACnetDateTime,
781 * timeRange [5] SEQUENCE {
782 * beginningTime BACnetDateTime,
783 * endingTime BACnetDateTime
787 * @param tvb the tv buffer of the current data
788 * @param pinfo the packet info of the current data
789 * @param tree the tree to append this item to
790 * @param offset the offset in the tvb
791 * @return modified offset
794 fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
797 * ReadRange-ACK ::= SEQUENCE {
798 * objectIdentifier [0] BACnetObjectIdentifier,
799 * propertyIdentifier [1] BACnetPropertyIdentifier,
800 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
801 * resultFlags [3] BACnetResultFlags,
802 * itemCount [4] Unsigned,
803 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
805 * @param tvb the tv buffer of the current data
806 * @param pinfo the packet info of the current data
807 * @param tree the tree to append this item to
808 * @param offset the offset in the tvb
809 * @return modified offset
812 fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
815 * RemoveListElement-Request ::= SEQUENCE {
816 * objectIdentifier [0] BACnetObjectIdentifier,
817 * propertyIdentifier [1] BACnetPropertyIdentifier,
818 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
819 * listOfElements [3] ABSTRACT-SYNTAX.&Type
821 * @param tvb the tv buffer of the current data
822 * @param pinfo the packet info of the current data
823 * @param tree the tree to append this item to
824 * @param offset the offset in the tvb
825 * @return modified offset
828 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
831 * WriteProperty-Request ::= SEQUENCE {
832 * objectIdentifier [0] BACnetObjectIdentifier,
833 * propertyIdentifier [1] BACnetPropertyIdentifier,
834 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
835 * propertyValue [3] ABSTRACT-SYNTAX.&Type
836 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
838 * @param tvb the tv buffer of the current data
839 * @param pinfo the packet info of the current data
840 * @param tree the tree to append this item to
841 * @param offset the offset in the tvb
842 * @return modified offset
845 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
848 * WritePropertyMultiple-Request ::= SEQUENCE {
849 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
851 * @param tvb the tv buffer of the current data
852 * @param pinfo the packet info of the current data
853 * @param tree the tree to append this item to
854 * @param offset the offset in the tvb
855 * @return modified offset
858 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
861 * DeviceCommunicationControl-Request ::= SEQUENCE {
862 * timeDuration [0] Unsigned16 OPTIONAL,
863 * enable-disable [1] ENUMERATED {
867 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
869 * @param tvb the tv buffer of the current data
870 * @param pinfo the packet info of the current data
871 * @param tree the tree to append this item to
872 * @param offset the offset in the tvb
873 * @return modified offset
876 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
879 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
880 * vendorID [0] Unsigned,
881 * serviceNumber [1] Unsigned,
882 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
884 * @param tvb the tv buffer of the current data
885 * @param pinfo the packet info of the current data
886 * @param tree the tree to append this item to
887 * @param offset the offset in the tvb
888 * @return modified offset
891 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
894 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
895 * vendorID [0] Unsigned,
896 * serviceNumber [1] Unsigned,
897 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
899 * @param tvb the tv buffer of the current data
900 * @param pinfo the packet info of the current data
901 * @param tree the tree to append this item to
902 * @param offset the offset in the tvb
903 * @return modified offset
906 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
909 * ConfirmedTextMessage-Request ::= SEQUENCE {
910 * textMessageSourceDevice [0] BACnetObjectIdentifier,
911 * messageClass [1] CHOICE {
912 * numeric [0] Unsigned,
913 * character [1] CharacterString
915 * messagePriority [2] ENUMERATED {
919 * message [3] CharacterString
921 * @param tvb the tv buffer of the current data
922 * @param pinfo the packet info of the current data
923 * @param tree the tree to append this item to
924 * @param offset the offset in the tvb
925 * @return modified offset
928 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
931 * ReinitializeDevice-Request ::= SEQUENCE {
932 * reinitializedStateOfDevice [0] ENUMERATED {
941 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
943 * @param tvb the tv buffer of the current data
944 * @param pinfo the packet info of the current data
945 * @param tree the tree to append this item to
946 * @param offset the offset in the tvb
947 * @return modified offset
950 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
953 * VTOpen-Request ::= SEQUENCE {
954 * vtClass BACnetVTClass,
955 * localVTSessionIdentifier Unsigned8
957 * @param tvb the tv buffer of the current data
958 * @param pinfo the packet info of the current data
959 * @param tree the tree to append this item to
960 * @param offset the offset in the tvb
961 * @return modified offset
964 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
967 * VTOpen-ACK ::= SEQUENCE {
968 * remoteVTSessionIdentifier Unsigned8
970 * @param tvb the tv buffer of the current data
971 * @param pinfo the packet info of the current data
972 * @param tree the tree to append this item to
973 * @param offset the offset in the tvb
974 * @return modified offset
977 fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
980 * VTClose-Request ::= SEQUENCE {
981 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
983 * @param tvb the tv buffer of the current data
984 * @param pinfo the packet info of the current data
985 * @param tree the tree to append this item to
986 * @param offset the offset in the tvb
987 * @return modified offset
990 fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
993 * VTData-Request ::= SEQUENCE {
994 * vtSessionIdentifier Unsigned8,
995 * vtNewData OCTET STRING,
996 * vtDataFlag Unsigned (0..1)
998 * @param tvb the tv buffer of the current data
999 * @param pinfo the packet info of the current data
1000 * @param tree the tree to append this item to
1001 * @param offset the offset in the tvb
1002 * @return modified offset
1005 fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1008 * VTData-ACK ::= SEQUENCE {
1009 * allNewDataAccepted [0] BOOLEAN,
1010 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1012 * @param tvb the tv buffer of the current data
1013 * @param pinfo the packet info of the current data
1014 * @param tree the tree to append this item to
1015 * @param offset the offset in the tvb
1016 * @return modified offset
1019 fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1022 * Authenticate-Request ::= SEQUENCE {
1023 * pseudoRandomNumber [0] Unsigned32,
1024 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1025 * operatorName [2] CharacterString OPTIONAL,
1026 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1027 * startEncypheredSession [4] BOOLEAN OPTIONAL
1029 * @param tvb the tv buffer of the current data
1030 * @param pinfo the packet info of the current data
1031 * @param tree the tree to append this item to
1032 * @param offset the offset in the tvb
1033 * @return modified offset
1036 fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1039 * Authenticate-ACK ::= SEQUENCE {
1040 * modifiedRandomNumber Unsigned32,
1042 * @param tvb the tv buffer of the current data
1043 * @param pinfo the packet info of the current data
1044 * @param tree the tree to append this item to
1045 * @param offset the offset in the tvb
1046 * @return modified offset
1049 fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1052 * RequestKey-Request ::= SEQUENCE {
1053 * requestingDeviceIdentifier BACnetObjectIdentifier,
1054 * requestingDeviceAddress BACnetAddress,
1055 * remoteDeviceIdentifier BACnetObjectIdentifier,
1056 * remoteDeviceAddress BACnetAddress
1058 * @param tvb the tv buffer of the current data
1059 * @param pinfo the packet info of the current data
1060 * @param tree the tree to append this item to
1061 * @param offset the offset in the tvb
1062 * @return modified offset
1065 fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1068 * Unconfirmed-Service-Request ::= CHOICE {
1070 * @param tvb the tv buffer of the current data
1071 * @param pinfo the packet info of the current data
1072 * @param tree the tree to append this item to
1073 * @param offset the offset in the tvb
1074 * @param service_choice the service choice
1075 * @return modified offset
1078 fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1081 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1082 * subscriberProcessIdentifier [0] Unsigned32,
1083 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1084 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1085 * timeRemaining [3] unsigned,
1086 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1088 * @param tvb the tv buffer of the current data
1089 * @param pinfo the packet info of the current data
1090 * @param tree the tree to append this item to
1091 * @param offset the offset in the tvb
1092 * @return modified offset
1095 fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1098 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1099 * ProcessIdentifier [0] Unsigned32,
1100 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1101 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1102 * timeStamp [3] BACnetTimeStamp,
1103 * notificationClass [4] unsigned,
1104 * priority [5] unsigned8,
1105 * eventType [6] BACnetEventType,
1106 * messageText [7] CharacterString OPTIONAL,
1107 * notifyType [8] BACnetNotifyType,
1108 * ackRequired [9] BOOLEAN OPTIONAL,
1109 * fromState [10] BACnetEventState OPTIONAL,
1110 * toState [11] BACnetEventState,
1111 * eventValues [12] BACnetNotificationParameters OPTIONAL
1113 * @param tvb the tv buffer of the current data
1114 * @param pinfo the packet info of the current data
1115 * @param tree the tree to append this item to
1116 * @param offset the offset in the tvb
1117 * @return modified offset
1120 fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1123 * I-Am-Request ::= SEQUENCE {
1124 * aAmDeviceIdentifier BACnetObjectIdentifier,
1125 * maxAPDULengthAccepted Unsigned,
1126 * segmentationSupported BACnetSegmentation,
1129 * @param tvb the tv buffer of the current data
1130 * @param pinfo the packet info of the current data
1131 * @param tree the tree to append this item to
1132 * @param offset the offset in the tvb
1133 * @return modified offset
1136 fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1140 * I-Have-Request ::= SEQUENCE {
1141 * deviceIdentifier BACnetObjectIdentifier,
1142 * objectIdentifier BACnetObjectIdentifier,
1143 * objectName CharacterString
1145 * @param tvb the tv buffer of the current data
1146 * @param pinfo the packet info of the current data
1147 * @param tree the tree to append this item to
1148 * @param offset the offset in the tvb
1149 * @return modified offset
1152 fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1155 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1156 * vendorID [0] Unsigned,
1157 * serviceNumber [1] Unsigned,
1158 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1160 * @param tvb the tv buffer of the current data
1161 * @param pinfo the packet info of the current data
1162 * @param tree the tree to append this item to
1163 * @param offset the offset in the tvb
1164 * @return modified offset
1167 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1170 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1171 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1172 * messageClass [1] CHOICE {
1173 * numeric [0] Unsigned,
1174 * character [1] CharacterString
1176 * messagePriority [2] ENUMERATED {
1180 * message [3] CharacterString
1182 * @param tvb the tv buffer of the current data
1183 * @param pinfo the packet info of the current data
1184 * @param tree the tree to append this item to
1185 * @param offset the offset in the tvb
1186 * @return modified offset
1189 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1192 * TimeSynchronization-Request ::= SEQUENCE {
1195 * @param tvb the tv buffer of the current data
1196 * @param pinfo the packet info of the current data
1197 * @param tree the tree to append this item to
1198 * @param offset the offset in the tvb
1199 * @return modified offset
1202 fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1205 * UTCTimeSynchronization-Request ::= SEQUENCE {
1208 * @param tvb the tv buffer of the current data
1209 * @param pinfo the packet info of the current data
1210 * @param tree the tree to append this item to
1211 * @param offset the offset in the tvb
1212 * @return modified offset
1215 fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1218 * Who-Has-Request ::= SEQUENCE {
1220 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1221 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1224 * objectIdentifier [2] BACnetObjectIdentifier,
1225 * objectName [3] CharacterString
1228 * @param tvb the tv buffer of the current data
1229 * @param pinfo the packet info of the current data
1230 * @param tree the tree to append this item to
1231 * @param offset the offset in the tvb
1232 * @return modified offset
1235 fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1238 * Who-Is-Request ::= SEQUENCE {
1239 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1240 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1242 * @param tvb the tv buffer of the current data
1243 * @param tree the tree to append this item to
1244 * @param offset the offset in the tvb
1245 * @return modified offset
1248 fWhoIsRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1251 * BACnet-Error ::= CHOICE {
1252 * addListElement [8] ChangeList-Error,
1253 * removeListElement [9] ChangeList-Error,
1254 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1255 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1256 * vtClose [22] VTClose-Error,
1257 * readRange [26] ObjectAccessService-Error
1260 * @param tvb the tv buffer of the current data
1261 * @param pinfo the packet info of the current data
1262 * @param tree the tree to append this item to
1263 * @param offset the offset in the tvb
1264 * @param service the service
1265 * @return modified offset
1268 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1271 * Dissect a BACnetError in a context tag
1273 * @param tvb the tv buffer of the current data
1274 * @param pinfo the packet info of the current data
1275 * @param tree the tree to append this item to
1276 * @param offset the offset in the tvb
1277 * @return modified offset
1279 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1282 * ChangeList-Error ::= SEQUENCE {
1283 * errorType [0] Error,
1284 * firstFailedElementNumber [1] Unsigned
1287 * @param tvb the tv buffer of the current data
1288 * @param pinfo the packet info of the current data
1289 * @param tree the tree to append this item to
1290 * @param offset the offset in the tvb
1291 * @return modified offset
1294 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1297 * CreateObject-Error ::= SEQUENCE {
1298 * errorType [0] Error,
1299 * firstFailedElementNumber [1] Unsigned
1302 * @param tvb the tv buffer of the current data
1303 * @param pinfo the packet info of the current data
1304 * @param tree the tree to append this item to
1305 * @param offset the offset in the tvb
1306 * @return modified offset
1309 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1312 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1313 * errorType [0] Error,
1314 * vendorID [1] Unsigned,
1315 * serviceNumber [2] Unsigned,
1316 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1319 * @param tvb the tv buffer of the current data
1320 * @param pinfo the packet info of the current data
1321 * @param tree the tree to append this item to
1322 * @param offset the offset in the tvb
1323 * @return modified offset
1326 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1329 * WritePropertyMultiple-Error ::= SEQUENCE {
1330 * errorType [0] Error,
1331 * firstFailedWriteAttempt [1] Unsigned
1334 * @param tvb the tv buffer of the current data
1335 * @param pinfo the packet info of the current data
1336 * @param tree the tree to append this item to
1337 * @param offset the offset in the tvb
1338 * @return modified offset
1341 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1344 * VTClose-Error ::= SEQUENCE {
1345 * errorType [0] Error,
1346 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1349 * @param tvb the tv buffer of the current data
1350 * @param pinfo the packet info of the current data
1351 * @param tree the tree to append this item to
1352 * @param offset the offset in the tvb
1353 * @return modified offset
1356 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1359 * BACnet Application Types chapter 20.2.1
1360 * @param tvb the tv buffer of the current data
1361 * @param pinfo the packet info of the current data
1362 * @param tree the tree to append this item to
1363 * @param offset the offset in the tvb
1364 * @param label the label of this item
1365 * @return modified offset
1368 fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1371 * BACnetActionCommand ::= SEQUENCE {
1372 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1373 * objectIdentifier [1] BACnetObjectIdentifier,
1374 * propertyIdentifier [2] BACnetPropertyIdentifier,
1375 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1376 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1377 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1378 * postDelay [6] Unsigned OPTIONAL,
1379 * quitOnFailure [7] BOOLEAN,
1380 * writeSuccessful [8] BOOLEAN
1382 * @param tvb the tv buffer of the current data
1383 * @param pinfo the packet info of the current data
1384 * @param tree the tree to append this item to
1385 * @param offset the offset in the tvb
1386 * @param tag_match the tag number
1387 * @return modified offset
1390 fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1393 * BACnetActionList ::= SEQUENCE {
1394 * action [0] SEQUENCE of BACnetActionCommand
1396 * @param tvb the tv buffer of the current data
1397 * @param pinfo the packet info of the current data
1398 * @param tree the tree to append this item to
1399 * @param offset the offset in the tvb
1400 * @return modified offset
1403 fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1405 /** BACnetAddress ::= SEQUENCE {
1406 * network-number Unsigned16, -- A value 0 indicates the local network
1407 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1409 * @param tvb the tv buffer of the current data
1410 * @param pinfo the packet info of the current data
1411 * @param tree the tree to append this item to
1412 * @param offset the offset in the tvb
1413 * @return modified offset
1416 fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1419 * BACnetAddressBinding ::= SEQUENCE {
1420 * deviceObjectID BACnetObjectIdentifier
1421 * deviceAddress BacnetAddress
1423 * @param tvb the tv buffer of the current data
1424 * @param pinfo the packet info of the current data
1425 * @param tree the tree to append this item to
1426 * @param offset the offset in the tvb
1427 * @return modified offset
1430 fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1433 * BACnetCalendarEntry ::= CHOICE {
1435 * dateRange [1] BACnetDateRange,
1436 * weekNDay [2] BacnetWeekNday
1438 * @param tvb the tv buffer of the current data
1439 * @param pinfo the packet info of the current data
1440 * @param tree the tree to append this item to
1441 * @param offset the offset in the tvb
1442 * @return modified offset
1445 fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1448 * BACnetClientCOV ::= CHOICE {
1449 * real-increment REAL,
1450 * default-increment NULL
1452 * @param tvb the tv buffer of the current data
1453 * @param tree the tree to append this item to
1454 * @param offset the offset in the tvb
1455 * @return modified offset
1458 fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1462 * BACnetDailySchedule ::= SEQUENCE {
1463 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1465 * @param tvb the tv buffer of the current data
1466 * @param pinfo the packet info of the current data
1467 * @param tree the tree to append this item to
1468 * @param offset the offset in the tvb
1469 * @return modified offset
1472 fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1475 * BACnetWeeklySchedule ::= SEQUENCE {
1476 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1478 * @param tvb the tv buffer of the current data
1479 * @param pinfo the packet info of the current data
1480 * @param tree the tree to append this item to
1481 * @param offset the offset in the tvb
1482 * @return modified offset
1485 fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1488 * BACnetDateRange ::= SEQUENCE {
1492 * @param tvb the tv buffer of the current data
1493 * @param pinfo the packet info of the current data
1494 * @param tree the tree to append this item to
1495 * @param offset the offset in the tvb
1496 * @return modified offset
1499 fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1502 * BACnetDateTime ::= SEQUENCE {
1506 * @param tvb the tv buffer of the current data
1507 * @param pinfo the packet info of the current data
1508 * @param tree the tree to append this item to
1509 * @param offset the offset in the tvb
1510 * @param label the label of this item
1511 * @return modified offset
1514 fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1517 * BACnetDestination ::= SEQUENCE {
1518 * validDays BACnetDaysOfWeek,
1521 * recipient BACnetRecipient,
1522 * processIdentifier Unsigned32,
1523 * issueConfirmedNotifications BOOLEAN,
1524 * transitions BACnetEventTransitionBits
1526 * @param tvb the tv buffer of the current data
1527 * @param pinfo the packet info of the current data
1528 * @param tree the tree to append this item to
1529 * @param offset the offset in the tvb
1530 * @return modified offset
1533 fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1536 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1537 * objectIdentifier [0] BACnetObjectIdentifier,
1538 * propertyIdentifier [1] BACnetPropertyIdentifier,
1539 * propertyArrayIndex [2] Unsigend OPTIONAL,
1540 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1542 * @param tvb the tv buffer of the current data
1543 * @param pinfo the packet info of the current data
1544 * @param tree the tree to append this item to
1545 * @param offset the offset in the tvb
1546 * @return modified offset
1549 fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1552 * BACnetObjectPropertyReference ::= SEQUENCE {
1553 * objectIdentifier [0] BACnetObjectIdentifier,
1554 * propertyIdentifier [1] BACnetPropertyIdentifier,
1555 * propertyArrayIndex [2] Unsigend OPTIONAL,
1557 * @param tvb the tv buffer of the current data
1558 * @param pinfo the packet info of the current data
1559 * @param tree the tree to append this item to
1560 * @param offset the offset in the tvb
1561 * @return modified offset
1564 fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1567 * BACnetDeviceObjectReference ::= SEQUENCE {
1568 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1569 * objectIdentifier [1] BACnetObjectIdentifier
1571 * @param tvb the tv buffer of the current data
1572 * @param pinfo the packet info of the current data
1573 * @param tree the tree to append this item to
1574 * @param offset the offset in the tvb
1575 * @return modified offset
1578 fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1581 * BACnetEventParameter ::= CHOICE {
1582 * change-of-bitstring [0] SEQUENCE {
1583 * time-delay [0] Unsigned,
1584 * bitmask [1] BIT STRING,
1585 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1587 * change-of-state [1] SEQUENCE {
1588 * time-delay [0] Unsigned,
1589 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1591 * change-of-value [2] SEQUENCE {
1592 * time-delay [0] Unsigned,
1593 * cov-criteria [1] CHOICE {
1594 * bitmask [0] BIT STRING,
1595 * referenced-property-increment [1] REAL
1598 * command-failure [3] SEQUENCE {
1599 * time-delay [0] Unsigned,
1600 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1602 * floating-limit [4] SEQUENCE {
1603 * time-delay [0] Unsigned,
1604 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1605 * low-diff-limit [2] REAL,
1606 * high-diff-limit [3] REAL,
1609 * out-of-range [5] SEQUENCE {
1610 * time-delay [0] Unsigned,
1611 * low-limit [1] REAL,
1612 * high-limit [2] REAL,
1615 * -- context tag 7 is deprecated
1616 * change-of-life-safety [8] SEQUENCE {
1617 * time-delay [0] Unsigned,
1618 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1619 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1620 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1622 * extended [9] SEQUENCE {
1623 * vendor-id [0] Unsigned16,
1624 * extended-event-type [1] Unsigned,
1625 * parameters [2] SEQUENCE OF CHOICE {
1631 * octet OCTET STRING,
1632 * bitstring BIT STRING,
1634 * reference [0] BACnetDeviceObjectPropertyReference
1637 * buffer-ready [10] SEQUENCE {
1638 * notification-threshold [0] Unsigned,
1639 * previous-notification-count [1] Unsigned32
1641 * unsigned-range [11] SEQUENCE {
1642 * time-delay [0] Unsigned,
1643 * low-limit [1] Unsigned,
1644 * high-limit [2] Unsigned,
1646 * -- context tag 12 is reserved for future addenda
1647 * access-event [13] SEQUENCE {
1648 * list-of-access-events [0] SEQUENCE OF BACnetAccessEvent,
1649 * access-event-time-reference [1] BACnetDeviceObjectPropertyReference
1651 * double-out-of-range [14] SEQUENCE {
1652 * time-delay [0] Unsigned,
1653 * low-limit [1] Double,
1654 * high-limit [2] Double,
1655 * deadband [3] Double
1657 * signed-out-of-range [15] SEQUENCE {
1658 * time-delay [0] Unsigned,
1659 * low-limit [1] INTEGER,
1660 * high-limit [2] INTEGER,
1661 * deadband [3] Unsigned
1663 * unsigned-out-of-range [16] SEQUENCE {
1664 * time-delay [0] Unsigned,
1665 * low-limit [1] Unsigned,
1666 * high-limit [2] Unsigned,
1667 * deadband [3] Unsigned
1669 * change-of-characterstring [17] SEQUENCE {
1670 * time-delay [0] Unsigned,
1671 * list-of-alarm-values [1] SEQUENCE OF CharacterString,
1673 * change-of-status-flags [18] SEQUENCE {
1674 * time-delay [0] Unsigned,
1675 * selected-flags [1] BACnetStatusFlags
1678 * @param tvb the tv buffer of the current data
1679 * @param tree the tree to append this item to
1680 * @param offset the offset in the tvb
1681 * @return modified offset
1684 fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1689 * BACnetLogRecord ::= SEQUENCE {
1690 * timestamp [0] BACnetDateTime,
1691 * logDatum [1] CHOICE {
1692 * log-status [0] BACnetLogStatus,
1693 * boolean-value [1] BOOLEAN,
1694 * real-value [2] REAL,
1695 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1696 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1697 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1698 * bitstring-value [6] BIT STRING, -- Optionally limited to 32 bits
1699 * null-value [7] NULL,
1700 * failure [8] Error,
1701 * time-change [9] REAL,
1702 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1704 * statusFlags [2] BACnetStatusFlags OPTIONAL
1706 * @param tvb the tv buffer of the current data
1707 * @param pinfo the packet info of the current data
1708 * @param tree the tree to append this item to
1709 * @param offset the offset in the tvb
1710 * @return modified offset
1713 fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1716 * BACnetEventLogRecord ::= SEQUENCE {
1717 * timestamp [0] BACnetDateTime,
1718 * logDatum [1] CHOICE {
1719 * log-status [0] BACnetLogStatus,
1720 * notification [1] ConfirmedEventNotification-Request,
1721 * time-change [2] REAL,
1724 * @param tvb the tv buffer of the current data
1725 * @param pinfo the packet info of the current data
1726 * @param tree the tree to append this item to
1727 * @param offset the offset in the tvb
1728 * @return modified offset
1731 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1734 fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1737 * BACnetNotificationParameters ::= CHOICE {
1738 * change-of-bitstring [0] SEQUENCE {
1739 * referenced-bitstring [0] BIT STRING,
1740 * status-flags [1] BACnetStatusFlags
1742 * change-of-state [1] SEQUENCE {
1743 * new-state [0] BACnetPropertyStatus,
1744 * status-flags [1] BACnetStatusFlags
1746 * change-of-value [2] SEQUENCE {
1747 * new-value [0] CHOICE {
1748 * changed-bits [0] BIT STRING,
1749 * changed-value [1] REAL
1751 * status-flags [1] BACnetStatusFlags
1753 * command-failure [3] SEQUENCE {
1754 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1755 * status-flags [1] BACnetStatusFlags
1756 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1758 * floating-limit [4] SEQUENCE {
1759 * reference-value [0] REAL,
1760 * status-flags [1] BACnetStatusFlags
1761 * setpoint-value [2] REAL,
1762 * error-limit [3] REAL
1764 * out-of-range [5] SEQUENCE {
1765 * exceeding-value [0] REAL,
1766 * status-flags [1] BACnetStatusFlags
1767 * deadband [2] REAL,
1768 * exceeded-limit [3] REAL
1770 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1771 * -- complex tag 7 is deprecated
1772 * change-of-life-safety [8] SEQUENCE {
1773 * new-state [0] BACnetLifeSafetyState,
1774 * new-mode [1] BACnetLifeSafetyState
1775 * status-flags [2] BACnetStatusFlags,
1776 * operation-expected [3] BACnetLifeSafetyOperation
1778 * extended [9] SEQUENCE {
1779 * vendor-id [0] Unsigned16,
1780 * extended-event-type [1] Unsigned,
1781 * parameters [2] SEQUENCE OF CHOICE {
1787 * octet OCTET STRING,
1788 * bitstring BIT STRING,
1790 * propertyValue [0] BACnetDeviceObjectPropertyValue
1793 * buffer-ready [10] SEQUENCE {
1794 * buffer-property [0] BACnetDeviceObjectPropertyReference,
1795 * previous-notification[1] Unsigned32,
1796 * current-notification [2] BACneUnsigned32tDateTime
1798 * unsigned-range [11] SEQUENCE {
1799 * exceeding-value [0] Unsigned,
1800 * status-flags [1] BACnetStatusFlags,
1801 * exceeded-limit [2] Unsigned
1803 * -- context tag 12 is reserved for future addenda
1804 * access-event [13] SEQUENCE {
1805 * access-event [0] BACnetAccessEvent,
1806 * status-flags [1] BACnetStatusFlags,
1807 * access-event-tag [2] Unsigned,
1808 * access-event-time [3] BACnetTimeStamp,
1809 * access-credential [4] BACnetDeviceObjectReference,
1810 * authentication-factor [5] BACnetAuthenticationFactor OPTIONAL
1812 * double-out-of-range [14] SEQUENCE {
1813 * exceeding-value [0] Double,
1814 * status-flags [1] BACnetStatusFlags
1815 * deadband [2] Double,
1816 * exceeded-limit [3] Double
1818 * signed-out-of-range [15] SEQUENCE {
1819 * exceeding-value [0] INTEGER,
1820 * status-flags [1] BACnetStatusFlags
1821 * deadband [2] Unsigned,
1822 * exceeded-limit [3] INTEGER
1824 * unsigned-out-of-range [16] SEQUENCE {
1825 * exceeding-value [0] Unsigned,
1826 * status-flags [1] BACnetStatusFlags
1827 * deadband [2] Unsigned,
1828 * exceeded-limit [3] Unsigned
1830 * change-of-characterstring [17] SEQUENCE {
1831 * changed-value [0] CharacterString,
1832 * status-flags [1] BACnetStatusFlags
1833 * alarm-value [2] CharacterString
1835 * change-of-status-flags [18] SEQUENCE {
1836 * present-value [0] ABSTRACT-SYNTAX.&Type OPTIONAL,
1837 * -- depends on referenced property
1838 * referenced-flags [1] BACnetStatusFlags
1841 * @param tvb the tv buffer of the current data
1842 * @param pinfo the packet info of the current data
1843 * @param tree the tree to append this item to
1844 * @param offset the offset in the tvb
1845 * @return modified offset
1848 fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1851 * BACnetObjectPropertyReference ::= SEQUENCE {
1852 * objectIdentifier [0] BACnetObjectIdentifier,
1853 * propertyIdentifier [1] BACnetPropertyIdentifier,
1854 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1856 * @param tvb the tv buffer of the current data
1857 * @param pinfo the packet info of the current data
1858 * @param tree the tree to append this item to
1859 * @param offset the offset in the tvb
1860 * @return modified offset
1863 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1867 * BACnetObjectPropertyValue ::= SEQUENCE {
1868 * objectIdentifier [0] BACnetObjectIdentifier,
1869 * propertyIdentifier [1] BACnetPropertyIdentifier,
1870 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1871 * -- if omitted with an array the entire array is referenced
1872 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1873 * priority [4] Unsigned (1..16) OPTIONAL
1875 * @param tvb the tv buffer of the current data
1876 * @param tree the tree to append this item to
1877 * @param offset the offset in the tvb
1878 * @return modified offset
1881 fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, guint offset);
1885 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1886 * @param tvb the tv buffer of the current data
1887 * @param pinfo the packet info of the current data
1888 * @param tree the tree to append this item to
1889 * @param offset the offset in the tvb
1890 * @return modified offset
1893 fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1896 fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1899 * BACnetPropertyReference ::= SEQUENCE {
1900 * propertyIdentifier [0] BACnetPropertyIdentifier,
1901 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1903 * @param tvb the tv buffer of the current data
1904 * @param pinfo the packet info of the current data
1905 * @param tree the tree to append this item to
1906 * @param offset the offset in the tvb
1907 * @return modified offset
1910 fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1913 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1916 fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1919 fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1922 * BACnetPropertyValue ::= SEQUENCE {
1923 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1924 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1925 * -- if omitted with an array the entire array is referenced
1926 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1927 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1929 * @param tvb the tv buffer of the current data
1930 * @param pinfo the packet info of the current data
1931 * @param tree the tree to append this item to
1932 * @param offset the offset in the tvb
1933 * @return modified offset
1936 fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1939 fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1942 * BACnet Application PDUs chapter 21
1943 * BACnetRecipient::= CHOICE {
1944 * device [0] BACnetObjectIdentifier
1945 * address [1] BACnetAddress
1947 * @param tvb the tv buffer of the current data
1948 * @param pinfo the packet info of the current data
1949 * @param tree the tree to append this item to
1950 * @param offset the offset in the tvb
1951 * @return modified offset
1954 fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1957 * BACnet Application PDUs chapter 21
1958 * BACnetRecipientProcess::= SEQUENCE {
1959 * recipient [0] BACnetRecipient
1960 * processID [1] Unsigned32
1962 * @param tvb the tv buffer of the current data
1963 * @param pinfo the packet info of the current data
1964 * @param tree the tree to append this item to
1965 * @param offset the offset in the tvb
1966 * @return modified offset
1969 fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1972 fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1976 * BACnetSessionKey ::= SEQUENCE {
1977 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1978 * peerAddress BACnetAddress
1980 * @param tvb the tv buffer of the current data
1981 * @param tree the tree to append this item to
1982 * @param offset the offset in the tvb
1983 * @return modified offset
1984 * @todo check if checksum is displayed correctly
1987 fSessionKey(tvbuff_t *tvb, proto_tree *tree, guint offset);
1991 * BACnetSpecialEvent ::= SEQUENCE {
1993 * calendarEntry [0] BACnetCalendarEntry,
1994 * calendarRefernce [1] BACnetObjectIdentifier
1996 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1997 * eventPriority [3] Unsigned (1..16)
1999 * @param tvb the tv buffer of the current data
2000 * @param pinfo the packet info of the current data
2001 * @param tree the tree to append this item to
2002 * @param offset the offset in the tvb
2003 * @return modified offset
2006 fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2009 * BACnetTimeStamp ::= CHOICE {
2011 * sequenceNumber [1] Unsigned (0..65535),
2012 * dateTime [2] BACnetDateTime
2014 * @param tvb the tv buffer of the current data
2015 * @param pinfo the packet info of the current data
2016 * @param tree the tree to append this item to
2017 * @param offset the offset in the tvb
2018 * @param label the label of this item
2019 * @return modified offset
2022 fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2025 fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2028 * BACnetTimeValue ::= SEQUENCE {
2030 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
2032 * @param tvb the tv buffer of the current data
2033 * @param pinfo the packet info of the current data
2034 * @param tree the tree to append this item to
2035 * @param offset the offset in the tvb
2036 * @return modified offset
2039 fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2043 * BACnetVTSession ::= SEQUENCE {
2044 * local-vtSessionID Unsigned8,
2045 * remote-vtSessionID Unsigned8,
2046 * remote-vtAddress BACnetAddress
2048 * @param tvb the tv buffer of the current data
2049 * @param tree the tree to append this item to
2050 * @param offset the offset in the tvb
2051 * @return modified offset
2054 fVTSession(tvbuff_t *tvb, proto_tree *tree, guint offset);
2058 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
2059 * -- first octet month (1..12) January = 1, X'FF' = any month
2060 * -- second octet weekOfMonth where: 1 = days numbered 1-7
2061 * -- 2 = days numbered 8-14
2062 * -- 3 = days numbered 15-21
2063 * -- 4 = days numbered 22-28
2064 * -- 5 = days numbered 29-31
2065 * -- 6 = last 7 days of this month
2066 * -- X'FF' = any week of this month
2067 * -- third octet dayOfWeek (1..7) where 1 = Monday
2069 * -- X'FF' = any day of week
2070 * @param tvb the tv buffer of the current data
2071 * @param pinfo the packet info of the current data
2072 * @param tree the tree to append this item to
2073 * @param offset the offset in the tvb
2074 * @return modified offset
2077 fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2080 * ReadAccessResult ::= SEQUENCE {
2081 * objectIdentifier [0] BACnetObjectIdentifier,
2082 * listOfResults [1] SEQUENCE OF SEQUENCE {
2083 * propertyIdentifier [2] BACnetPropertyIdentifier,
2084 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
2085 * readResult CHOICE {
2086 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
2087 * propertyAccessError [5] Error
2091 * @param tvb the tv buffer of the current data
2092 * @param pinfo the packet info of the current data
2093 * @param tree the tree to append this item to
2094 * @param offset the offset in the tvb
2095 * @return modified offset
2098 fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2101 * ReadAccessSpecification ::= SEQUENCE {
2102 * objectIdentifier [0] BACnetObjectIdentifier,
2103 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
2105 * @param tvb the tv buffer of the current data
2106 * @param pinfo the packet info of the current data
2107 * @param subtree the subtree to append this item to
2108 * @param offset the offset in the tvb
2109 * @return modified offset
2112 fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2115 * WriteAccessSpecification ::= SEQUENCE {
2116 * objectIdentifier [0] BACnetObjectIdentifier,
2117 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
2119 * @param tvb the tv buffer of the current data
2120 * @param pinfo the packet info of the current data
2121 * @param subtree the sub tree to append this item to
2122 * @param offset the offset in the tvb
2123 * @return modified offset
2126 fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2129 /********************************************************* Helper functions *******************************************/
2132 * extracts the tag number from the tag header.
2133 * @param tvb the tv buffer of the current data "TestyVirtualBuffer"
2134 * @param offset the offset in the tvb in actual tvb
2135 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
2138 fTagNo(tvbuff_t *tvb, guint offset);
2141 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
2142 * @param tvb the tv buffer of the current data = "TestyVirtualBuffer"
2143 * @param pinfo the packet info of the current data = packet info
2144 * @param offset the offset in the tvb = offset in actual tvb
2145 * @return tag_no BACnet 20.2.1.2 Tag Number
2146 * @return class_tag BACnet 20.2.1.1 Class
2147 * @return lvt BACnet 20.2.1.3 Length/Value/Type
2148 * @return offs = length of this header
2152 fTagHeader(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
2156 * adds processID with max 32Bit unsigned Integer Value to tree
2157 * @param tvb the tv buffer of the current data
2158 * @param pinfo the packet info of the current data
2159 * @param tree the tree to append this item to
2160 * @param offset the offset in the tvb
2161 * @return modified offset
2164 fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2167 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2168 * @param tvb the tv buffer of the current data
2169 * @param pinfo the packet info of the current data
2170 * @param tree the tree to append this item to
2171 * @param offset the offset in the tvb
2172 * @return modified offset
2175 fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2178 * BACnet Application PDUs chapter 21
2179 * BACnetPropertyIdentifier::= ENUMERATED {
2180 * @see bacapp_property_identifier
2182 * @param tvb the tv buffer of the current data
2183 * @param pinfo the packet info of the current data
2184 * @param tree the tree to append this item to
2185 * @param offset the offset in the tvb
2186 * @return modified offset
2189 fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2192 * BACnet Application PDUs chapter 21
2193 * BACnetPropertyArrayIndex::= ENUMERATED {
2194 * @see bacapp_property_array_index
2196 * @param tvb the tv buffer of the current data
2197 * @param pinfo the packet info of the current data
2198 * @param tree the tree to append this item to
2199 * @param offset the offset in the tvb
2200 * @return modified offset
2203 fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2206 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2207 * objectIdentifier [0] BACnetObjectIdentifier,
2208 * eventState [1] BACnetEventState,
2209 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2210 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2211 * notifyType [4] BACnetNotifyType,
2212 * eventEnable [5] BACnetEventTransitionBits,
2213 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2215 * @param tvb the tv buffer of the current data
2216 * @param pinfo the packet info of the current data
2217 * @param tree the tree to append this item to
2218 * @param offset the offset in the tvb
2219 * @return modified offset
2222 flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2225 * SelectionCriteria ::= SEQUENCE {
2226 * propertyIdentifier [0] BACnetPropertyIdentifier,
2227 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2228 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2229 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2231 * @param tvb the tv buffer of the current data
2232 * @param pinfo the packet info of the current data
2233 * @param tree the tree to append this item to
2234 * @param offset the offset in the tvb
2235 * @return modified offset
2238 fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2241 * objectSelectionCriteria ::= SEQUENCE {
2242 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2243 * listOfSelectionCriteria [1] SelectionCriteria
2245 * @param tvb the tv buffer of the current data
2246 * @param pinfo the packet info of the current data
2247 * @param subtree the sub tree to append this item to
2248 * @param offset the offset in the tvb
2249 * @return modified offset
2252 fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2255 * BACnet-Error ::= SEQUENCE {
2256 * error-class ENUMERATED {},
2257 * error-code ENUMERATED {}
2260 * @param tvb the tv buffer of the current data
2261 * @param pinfo the packet info of the current data
2262 * @param tree the tree to append this item to
2263 * @param offset the offset in the tvb
2264 * @return modified offset
2267 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2270 * Generic handler for context tagged values. Mostly for handling
2271 * vendor-defined properties and services.
2272 * @param tvb the tv buffer of the current data
2273 * @param pinfo the packet info of the current data
2274 * @param tree the tree to append this item to
2275 * @param offset the offset in the tvb
2276 * @return modified offset
2277 * @todo beautify this ugly construct
2280 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2283 * realizes some ABSTRACT-SYNTAX.&Type
2284 * @param tvb the tv buffer of the current data
2285 * @param pinfo the packet info of the current data
2286 * @param tree the tree to append this item to
2287 * @param offset the offset in the tvb
2288 * @return modified offset
2289 * @todo beautify this ugly construct
2292 fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2296 fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
2297 const value_string *src);
2303 proto_register_bacapp(void);
2306 * proto_reg_handoff_bacapp
2309 proto_reg_handoff_bacapp(void);
2311 /* <<<< formerly bacapp.h */
2313 /* reassembly table for segmented messages */
2314 static reassembly_table msg_reassembly_table;
2316 /* some necessary forward function prototypes */
2318 fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2319 const gchar *label, const value_string *vs);
2321 static const char *bacapp_unknown_service_str = "unknown service"; /* Usage: no format specifiers */
2322 static const char ASHRAE_Reserved_Fmt[] = "(%d) Reserved for Use by ASHRAE";
2323 static const char Vendor_Proprietary_Fmt[] = "(%d) Vendor Proprietary Value";
2325 static const value_string
2326 BACnetTypeName[] = {
2327 { 0, "Confirmed-REQ"},
2328 { 1, "Unconfirmed-REQ"},
2330 { 3, "Complex-ACK"},
2331 { 4, "Segment-ACK"},
2338 static const true_false_string segments_follow = {
2339 "Segmented Request",
2340 "Unsegmented Request"
2343 static const true_false_string more_follow = {
2344 "More Segments Follow",
2345 "No More Segments Follow"
2348 static const true_false_string segmented_accept = {
2349 "Segmented Response accepted",
2350 "Segmented Response not accepted"
2353 static const true_false_string
2355 "Context Specific Tag",
2359 static const value_string
2360 BACnetMaxSegmentsAccepted [] = {
2361 { 0, "Unspecified"},
2365 { 4, "16 segments"},
2366 { 5, "32 segments"},
2367 { 6, "64 segments"},
2368 { 7, "Greater than 64 segments"},
2372 static const value_string
2373 BACnetMaxAPDULengthAccepted [] = {
2374 { 0, "Up to MinimumMessageSize (50 octets)"},
2375 { 1, "Up to 128 octets"},
2376 { 2, "Up to 206 octets (fits in a LonTalk frame)"},
2377 { 3, "Up to 480 octets (fits in an ARCNET frame)"},
2378 { 4, "Up to 1024 octets"},
2379 { 5, "Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2380 { 6, "reserved by ASHRAE"},
2381 { 7, "reserved by ASHRAE"},
2382 { 8, "reserved by ASHRAE"},
2383 { 9, "reserved by ASHRAE"},
2384 { 10, "reserved by ASHRAE"},
2385 { 11, "reserved by ASHRAE"},
2386 { 12, "reserved by ASHRAE"},
2387 { 13, "reserved by ASHRAE"},
2388 { 14, "reserved by ASHRAE"},
2389 { 15, "reserved by ASHRAE"},
2393 static const value_string
2394 BACnetRejectReason [] = {
2396 {1, "buffer-overflow"},
2397 {2, "inconsistent-parameters"},
2398 {3, "invalid-parameter-data-type"},
2400 {5, "missing-required-parameter"},
2401 {6, "parameter-out-of-range"},
2402 {7, "too-many-arguments"},
2403 {8, "undefined-enumeration"},
2404 {9, "unrecognized-service"},
2408 static const value_string
2409 BACnetRestartReason [] = {
2413 { 3, "detected-power-lost"},
2414 { 4, "detected-powered-off"},
2415 { 5, "hardware-watchdog"},
2416 { 6, "software-watchdog"},
2421 static const value_string
2422 BACnetApplicationTagNumber [] = {
2425 { 2, "Unsigned Integer"},
2426 { 3, "Signed Integer (2's complement notation)"},
2427 { 4, "Real (ANSI/IEE-754 floating point)"},
2428 { 5, "Double (ANSI/IEE-754 double precision floating point)"},
2429 { 6, "Octet String"},
2430 { 7, "Character String"},
2435 { 12, "BACnetObjectIdentifier"},
2436 { 13, "reserved by ASHRAE"},
2437 { 14, "reserved by ASHRAE"},
2438 { 15, "reserved by ASHRAE"},
2442 static const value_string
2449 static const value_string
2450 BACnetAccessEvent [] = {
2454 { 3, "passback-detected"},
2457 { 6, "lockout-max-attempts"},
2458 { 7, "lockout-other"},
2459 { 8, "lockout-relinquished"},
2460 { 9, "lockout-by-higher-priority"},
2461 { 10, "out-of-service"},
2462 { 11, "out-of-service-relinquished"},
2463 { 12, "accompaniment-by"},
2464 { 13, "authentication-factor-read"},
2465 { 14, "authorization-delayed"},
2466 { 15, "verification-required"},
2467 /* Enumerated values 128-511 are used for events
2468 * which indicate that access has been denied. */
2469 { 128, "denied-deny-all"},
2470 { 129, "denied-unknown-credential"},
2471 { 130, "denied-authentication-unavailable"},
2472 { 131, "denied-authentication-factor-timeout"},
2473 { 132, "denied-incorrect-authentication-factor"},
2474 { 133, "denied-zone-no-access-rights"},
2475 { 134, "denied-point-no-access-rights"},
2476 { 135, "denied-no-access-rights"},
2477 { 136, "denied-out-of-time-range"},
2478 { 137, "denied-threat-level"},
2479 { 138, "denied-passback"},
2480 { 139, "denied-unexpected-location-usage"},
2481 { 140, "denied-max-attempts"},
2482 { 141, "denied-lower-occupancy-limit"},
2483 { 142, "denied-upper-occupancy-limit"},
2484 { 143, "denied-authentication-factor-lost"},
2485 { 144, "denied-authentication-factor-stolen"},
2486 { 145, "denied-authentication-factor-damaged"},
2487 { 146, "denied-authentication-factor-destroyed"},
2488 { 147, "denied-authentication-factor-disabled"},
2489 { 148, "denied-authentication-factor-error"},
2490 { 149, "denied-credential-unassigned"},
2491 { 150, "denied-credential-not-provisioned"},
2492 { 151, "denied-credential-not-yet-active"},
2493 { 152, "denied-credential-expired"},
2494 { 153, "denied-credential-manual-disable"},
2495 { 154, "denied-credential-lockout"},
2496 { 155, "denied-credential-max-days"},
2497 { 156, "denied-credential-max-uses"},
2498 { 157, "denied-credential-inactivity"},
2499 { 158, "denied-credential-disabled"},
2500 { 159, "denied-no-accompaniment"},
2501 { 160, "denied-incorrect-accompaniment"},
2502 { 161, "denied-lockout"},
2503 { 162, "denied-verification-failed"},
2504 { 163, "denied-verification-timeout"},
2505 { 164, "denied-other"},
2507 /* Enumerated values 0-512 are reserved for definition by ASHRAE.
2508 Enumerated values 512-65535 may be used by others subject to
2509 procedures and constraints described in Clause 23. */
2512 static const value_string
2513 BACnetFileAccessMethod [] = {
2514 { 0, "record-access"},
2515 { 1, "stream-access"},
2519 /* For some reason, BACnet defines the choice parameter
2520 in the file read and write services backwards from the
2521 BACnetFileAccessMethod enumeration.
2523 static const value_string
2524 BACnetFileAccessOption [] = {
2525 { 0, "stream access"},
2526 { 1, "record access"},
2530 static const value_string
2531 BACnetFileStartOption [] = {
2532 { 0, "File Start Position: "},
2533 { 1, "File Start Record: "},
2537 static const value_string
2538 BACnetFileRequestCount [] = {
2539 { 0, "Requested Octet Count: "},
2540 { 1, "Requested Record Count: "},
2544 static const value_string
2545 BACnetFileWriteInfo [] = {
2546 { 0, "File Data: "},
2547 { 1, "Record Count: "},
2551 static const value_string
2552 BACnetAbortReason [] = {
2554 { 1, "buffer-overflow"},
2555 { 2, "invalid-apdu-in-this-state"},
2556 { 3, "preempted-by-higher-priority-task"},
2557 { 4, "segmentation-not-supported"},
2561 static const value_string
2562 BACnetLifeSafetyMode [] = {
2573 { 10, "disconnected"},
2576 { 13, "atomic-release-disabled"},
2579 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2580 Enumerated values 256-65535 may be used by others subject to
2581 procedures and constraints described in Clause 23. */
2584 static const value_string
2585 BACnetLifeSafetyOperation [] = {
2588 { 2, "silence-audible"},
2589 { 3, "silence-visual"},
2591 { 5, "reset-alarm"},
2592 { 6, "reset-fault"},
2594 { 8, "unsilence-audible"},
2595 { 9, "unsilence-visual"},
2597 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2598 Enumerated values 64-65535 may be used by others subject to
2599 procedures and constraints described in Clause 23. */
2603 static const value_string
2604 BACnetLimitEnable [] = {
2605 { 0, "lowLimitEnable"},
2606 { 1, "highLimitEnable"},
2611 static const value_string
2612 BACnetLifeSafetyState [] = {
2617 { 4, "fault-pre-alarm"},
2618 { 5, "fault-alarm"},
2623 { 10, "test-active"},
2624 { 11, "test-fault"},
2625 { 12, "test-fault-alarm"},
2628 { 15, "tamper-alarm"},
2630 { 17, "emergency-power"},
2633 { 20, "local-alarm"},
2634 { 21, "general-alarm"},
2635 { 22, "supervisory"},
2636 { 23, "test-supervisory"},
2638 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2639 Enumerated values 256-65535 may be used by others subject to
2640 procedures and constraints described in Clause 23. */
2643 static const value_string
2644 BACnetConfirmedServiceChoice [] = {
2645 { 0, "acknowledgeAlarm"},
2646 { 1, "confirmedCOVNotification"},
2647 { 2, "confirmedEventNotification"},
2648 { 3, "getAlarmSummary"},
2649 { 4, "getEnrollmentSummary"},
2650 { 5, "subscribeCOV"},
2651 { 6, "atomicReadFile"},
2652 { 7, "atomicWriteFile"},
2653 { 8, "addListElement"},
2654 { 9, "removeListElement"},
2655 { 10, "createObject"},
2656 { 11, "deleteObject"},
2657 { 12, "readProperty"},
2658 { 13, "readPropertyConditional"},
2659 { 14, "readPropertyMultiple"},
2660 { 15, "writeProperty"},
2661 { 16, "writePropertyMultiple"},
2662 { 17, "deviceCommunicationControl"},
2663 { 18, "confirmedPrivateTransfer"},
2664 { 19, "confirmedTextMessage"},
2665 { 20, "reinitializeDevice"},
2669 { 24, "authenticate"},
2670 { 25, "requestKey"},
2672 { 27, "lifeSafetyOperation"},
2673 { 28, "subscribeCOVProperty"},
2674 { 29, "getEventInformation"},
2675 { 30, "reserved by ASHRAE"},
2679 static const value_string
2680 BACnetReliability [] = {
2681 { 0, "no-fault-detected"},
2684 { 3, "under-range"},
2686 { 5, "shorted-loop"},
2688 { 7, "unreliable-other"},
2689 { 8, "process-error"},
2690 { 9, "multi-state-fault"},
2691 { 10, "configuration-error"},
2692 /* enumeration value 11 is reserved for a future addendum */
2693 { 12, "communication-failure"},
2694 { 13, "member-fault"},
2698 static const value_string
2699 BACnetUnconfirmedServiceChoice [] = {
2702 { 2, "unconfirmedCOVNotification"},
2703 { 3, "unconfirmedEventNotification"},
2704 { 4, "unconfirmedPrivateTransfer"},
2705 { 5, "unconfirmedTextMessage"},
2706 { 6, "timeSynchronization"},
2709 { 9, "utcTimeSynchronization"},
2714 static const value_string
2715 BACnetUnconfirmedServiceRequest [] = {
2716 { 0, "i-Am-Request"},
2717 { 1, "i-Have-Request"},
2718 { 2, "unconfirmedCOVNotification-Request"},
2719 { 3, "unconfirmedEventNotification-Request"},
2720 { 4, "unconfirmedPrivateTransfer-Request"},
2721 { 5, "unconfirmedTextMessage-Request"},
2722 { 6, "timeSynchronization-Request"},
2723 { 7, "who-Has-Request"},
2724 { 8, "who-Is-Request"},
2725 { 9, "utcTimeSynchonization-Request"},
2730 static const value_string
2731 BACnetObjectType [] = {
2732 { 0, "analog-input"},
2733 { 1, "analog-output"},
2734 { 2, "analog-value"},
2735 { 3, "binary-input"},
2736 { 4, "binary-output"},
2737 { 5, "binary-value"},
2741 { 9, "event-enrollment"},
2745 { 13, "multi-state-input"},
2746 { 14, "multi-state-output"},
2747 { 15, "notification-class"},
2751 { 19, "multi-state-value"},
2753 { 21, "life-safety-point"},
2754 { 22, "life-safety-zone"},
2755 { 23, "accumulator"},
2756 { 24, "pulse-converter"},
2758 { 26, "global-group"},
2759 { 27, "trend-log-multiple"},
2760 { 28, "load-control"},
2761 { 29, "structured-view"},
2762 { 30, "access-door"}, /* 30-37 added with addanda 135-2008j */
2763 /* value 31 is unassigned */
2764 { 32, "access-credential"},
2765 { 33, "access-point"},
2766 { 34, "access-rights"},
2767 { 35, "access-user"},
2768 { 36, "access-zone"},
2769 { 37, "credential-data-input"},
2770 { 38, "network-security"},
2771 { 39, "bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2772 { 40, "characterstring-value"},
2773 { 41, "date-pattern-value"},
2774 { 42, "date-value"},
2775 { 43, "datetime-pattern-value"},
2776 { 44, "datetime-value"},
2777 { 45, "integer-value"},
2778 { 46, "large-analog-value"},
2779 { 47, "octetstring-value"},
2780 { 48, "positive-integer-value"},
2781 { 49, "time-pattern-value"},
2782 { 50, "time-value"},
2784 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2785 Enumerated values 128-1023 may be used by others subject to
2786 the procedures and constraints described in Clause 23. */
2789 static const value_string
2790 BACnetEngineeringUnits [] = {
2793 { 2, "Milliamperes"},
2799 { 8, "Volt Amperes"},
2800 { 9, "Kilovolt Amperes"},
2801 { 10, "Megavolt Amperes"},
2802 { 11, "Volt Amperes Reactive"},
2803 { 12, "Kilovolt Amperes Reactive"},
2804 { 13, "Megavolt Amperes Reactive"},
2805 { 14, "Degrees Phase"},
2806 { 15, "Power Factor"},
2808 { 17, "Kilojoules"},
2809 { 18, "Watt Hours"},
2810 { 19, "Kilowatt Hours"},
2814 { 23, "Joules Per Kg Dry Air"},
2815 { 24, "BTUs Per Pound Dry Air"},
2816 { 25, "Cycles Per Hour"},
2817 { 26, "Cycles Per Minute"},
2819 { 28, "Grams Of Water Per Kilogram Dry Air"},
2820 { 29, "Relative Humidity"},
2821 { 30, "Millimeters"},
2825 { 34, "Watts Per Sq Foot"},
2826 { 35, "Watts Per Sq meter"},
2829 { 38, "Foot Candles"},
2831 { 40, "Pounds Mass"},
2833 { 42, "Kgs per Second"},
2834 { 43, "Kgs Per Minute"},
2835 { 44, "Kgs Per Hour"},
2836 { 45, "Pounds Mass Per Minute"},
2837 { 46, "Pounds Mass Per Hour"},
2841 { 50, "BTUs Per Hour"},
2842 { 51, "Horsepower"},
2843 { 52, "Tons Refrigeration"},
2845 { 54, "Kilopascals"},
2847 { 56, "Pounds Force Per Square Inch"},
2848 { 57, "Centimeters Of Water"},
2849 { 58, "Inches Of Water"},
2850 { 59, "Millimeters Of Mercury"},
2851 { 60, "Centimeters Of Mercury"},
2852 { 61, "Inches Of Mercury"},
2853 { 62, "Degrees Celsius"},
2854 { 63, "Degrees Kelvin"},
2855 { 64, "Degrees Fahrenheit"},
2856 { 65, "Degree Days Celsius"},
2857 { 66, "Degree Days Fahrenheit"},
2865 { 74, "Meters Per Second"},
2866 { 75, "Kilometers Per Hour"},
2867 { 76, "Feed Per Second"},
2868 { 77, "Feet Per Minute"},
2869 { 78, "Miles Per Hour"},
2870 { 79, "Cubic Feet"},
2871 { 80, "Cubic Meters"},
2872 { 81, "Imperial Gallons"},
2874 { 83, "US Gallons"},
2875 { 84, "Cubic Feet Per Minute"},
2876 { 85, "Cubic Meters Per Second"},
2877 { 86, "Imperial Gallons Per Minute"},
2878 { 87, "Liters Per Second"},
2879 { 88, "Liters Per Minute"},
2880 { 89, "US Gallons Per Minute"},
2881 { 90, "Degrees Angular"},
2882 { 91, "Degrees Celsius Per Hour"},
2883 { 92, "Degrees Celsius Per Minute"},
2884 { 93, "Degrees Fahrenheit Per Hour"},
2885 { 94, "Degrees Fahrenheit Per Minute"},
2887 { 96, "Parts Per Million"},
2888 { 97, "Parts Per Billion"},
2890 { 99, "Pecent Per Second"},
2891 { 100, "Per Minute"},
2892 { 101, "Per Second"},
2893 { 102, "Psi Per Degree Fahrenheit"},
2895 { 104, "Revolutions Per Min"},
2896 { 105, "Currency1"},
2897 { 106, "Currency2"},
2898 { 107, "Currency3"},
2899 { 108, "Currency4"},
2900 { 109, "Currency5"},
2901 { 110, "Currency6"},
2902 { 111, "Currency7"},
2903 { 112, "Currency8"},
2904 { 113, "Currency9"},
2905 { 114, "Currency10"},
2906 { 115, "Sq Inches"},
2907 { 116, "Sq Centimeters"},
2908 { 117, "BTUs Per Pound"},
2909 { 118, "Centimeters"},
2910 { 119, "Pounds Mass Per Second"},
2911 { 120, "Delta Degrees Fahrenheit"},
2912 { 121, "Delta Degrees Kelvin"},
2915 { 124, "Millivolts"},
2916 { 125, "Kilojoules Per Kg"},
2917 { 126, "Megajoules"},
2918 { 127, "Joules Per Degree Kelvin"},
2919 { 128, "Joules Per Kg Degree Kelvin"},
2920 { 129, "Kilohertz"},
2921 { 130, "Megahertz"},
2923 { 132, "Milliwatts"},
2924 { 133, "Hectopascals"},
2925 { 134, "Millibars"},
2926 { 135, "Cubic Meters Per Hour"},
2927 { 136, "Liters Per Hour"},
2928 { 137, "KWatt Hours Per Square Meter"},
2929 { 138, "KWatt Hours Per Square Foot"},
2930 { 139, "Megajoules Per Square Meter"},
2931 { 140, "Megajoules Per Square Foot"},
2932 { 141, "Watts Per Sq Meter Degree Kelvin"},
2933 { 142, "Cubic Feet Per Second"},
2934 { 143, "Percent Obstruction Per Foot"},
2935 { 144, "Percent Obstruction Per Meter"},
2936 { 145, "milliohms"},
2937 { 146, "megawatt-hours"},
2938 { 147, "kilo-btus"},
2939 { 148, "mega-btus"},
2940 { 149, "kilojoules-per-kilogram-dry-air"},
2941 { 150, "megajoules-per-kilogram-dry-air"},
2942 { 151, "kilojoules-per-degree-Kelvin"},
2943 { 152, "megajoules-per-degree-Kelvin"},
2945 { 154, "grams-per-second"},
2946 { 155, "grams-per-minute"},
2947 { 156, "tons-per-hour"},
2948 { 157, "kilo-btus-per-hour"},
2949 { 158, "hundredths-seconds"},
2950 { 159, "milliseconds"},
2951 { 160, "newton-meters"},
2952 { 161, "millimeters-per-second"},
2953 { 162, "millimeters-per-minute"},
2954 { 163, "meters-per-minute"},
2955 { 164, "meters-per-hour"},
2956 { 165, "cubic-meters-per-minute"},
2957 { 166, "meters-per-second-per-second"},
2958 { 167, "amperes-per-meter"},
2959 { 168, "amperes-per-square-meter"},
2960 { 169, "ampere-square-meters"},
2963 { 172, "ohm-meters"},
2965 { 174, "siemens-per-meter"},
2967 { 176, "volts-per-degree-Kelvin"},
2968 { 177, "volts-per-meter"},
2971 { 180, "candelas-per-square-meter"},
2972 { 181, "degrees-Kelvin-per-hour"},
2973 { 182, "degrees-Kelvin-per-minute"},
2974 { 183, "joule-seconds"},
2975 { 184, "radians-per-second"},
2976 { 185, "square-meters-per-Newton"},
2977 { 186, "kilograms-per-cubic-meter"},
2978 { 187, "newton-seconds"},
2979 { 188, "newtons-per-meter"},
2980 { 189, "watts-per-meter-per-degree-Kelvin"},
2981 { 190, "micro-siemens"},
2982 { 191, "cubic-feet-per-hour"},
2983 { 192, "us-gallons-per-hour"},
2984 { 193, "kilometers"},
2985 { 194, "micrometers"},
2987 { 196, "milligrams"},
2988 { 197, "milliliters"},
2989 { 198, "milliliters-per-second"},
2991 { 200, "decibels-millivolt"},
2992 { 201, "decibels-volt"},
2993 { 202, "millisiemens"},
2994 { 203, "watt-hours-reactive"},
2995 { 204, "kilowatt-hours-reactive"},
2996 { 205, "megawatt-hours-reactive"},
2997 { 206, "millimeters-of-water"},
2998 { 207, "per-mille"},
2999 { 208, "grams-per-gram"},
3000 { 209, "kilograms-per-kilogram"},
3001 { 210, "grams-per-kilogram"},
3002 { 211, "milligrams-per-gram"},
3003 { 212, "milligrams-per-kilogram"},
3004 { 213, "grams-per-milliliter"},
3005 { 214, "grams-per-liter"},
3006 { 215, "milligrams-per-liter"},
3007 { 216, "micrograms-per-liter"},
3008 { 217, "grams-per-cubic-meter"},
3009 { 218, "milligrams-per-cubic-meter"},
3010 { 219, "micrograms-per-cubic-meter"},
3011 { 220, "nanograms-per-cubic-meter"},
3012 { 221, "grams-per-cubic-centimeter"},
3013 { 222, "becquerels"},
3014 { 223, "kilobecquerels"},
3015 { 224, "megabecquerels"},
3017 { 226, "milligray"},
3018 { 227, "microgray"},
3020 { 229, "millisieverts"},
3021 { 230, "microsieverts"},
3022 { 231, "microsieverts-per-hour"},
3023 { 232, "decibels-a"},
3024 { 233, "nephelometric-turbidity-unit"},
3026 { 235, "grams-per-square-meter"},
3027 { 236, "minutes-per-degree-kelvin"},
3029 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
3030 Enumerated values 256-65535 may be used by others subject to
3031 the procedures and constraints described in Clause 23. */
3034 static const value_string
3035 BACnetErrorCode [] = {
3037 { 1, "authentication-failed"},
3038 { 2, "configuration-in-progress"},
3039 { 3, "device-busy"},
3040 { 4, "dynamic-creation-not-supported"},
3041 { 5, "file-access-denied"},
3042 { 6, "incompatible-security-levels"},
3043 { 7, "inconsistent-parameters"},
3044 { 8, "inconsistent-selection-criterion"},
3045 { 9, "invalid-data-type"},
3046 { 10, "invalid-file-access-method"},
3047 { 11, "invalid-file-start-position"},
3048 { 12, "invalid-operator-name"},
3049 { 13, "invalid-parameter-data-type"},
3050 { 14, "invalid-time-stamp"},
3051 { 15, "key-generation-error"},
3052 { 16, "missing-required-parameter"},
3053 { 17, "no-objects-of-specified-type"},
3054 { 18, "no-space-for-object"},
3055 { 19, "no-space-to-add-list-element"},
3056 { 20, "no-space-to-write-property"},
3057 { 21, "no-vt-sessions-available"},
3058 { 22, "property-is-not-a-list"},
3059 { 23, "object-deletion-not-permitted"},
3060 { 24, "object-identifier-already-exists"},
3061 { 25, "operational-problem"},
3062 { 26, "password-failure"},
3063 { 27, "read-access-denied"},
3064 { 28, "security-not-supported"},
3065 { 29, "service-request-denied"},
3067 { 31, "unknown-object"},
3068 { 32, "unknown-property"},
3069 { 33, "removed enumeration"},
3070 { 34, "unknown-vt-class"},
3071 { 35, "unknown-vt-session"},
3072 { 36, "unsupported-object-type"},
3073 { 37, "value-out-of-range"},
3074 { 38, "vt-session-already-closed"},
3075 { 39, "vt-session-termination-failure"},
3076 { 40, "write-access-denied"},
3077 { 41, "character-set-not-supported"},
3078 { 42, "invalid-array-index"},
3079 { 43, "cov-subscription-failed"},
3080 { 44, "not-cov-property"},
3081 { 45, "optional-functionality-not-supported"},
3082 { 46, "invalid-configuration-data"},
3083 { 47, "datatype-not-supported"},
3084 { 48, "duplicate-name"},
3085 { 49, "duplicate-object-id"},
3086 { 50, "property-is-not-an-array"},
3087 { 73, "invalid-event-state"},
3088 { 74, "no-alarm-configured"},
3089 { 75, "log-buffer-full"},
3090 { 76, "logged-value-purged"},
3091 { 77, "no-property-specified"},
3092 { 78, "not-configured-for-triggered-logging"},
3093 { 79, "unknown-subscription"},
3094 { 80, "parameter-out-of-range"},
3095 { 81, "list-element-not-found"},
3097 { 83, "communication-disabled"},
3099 { 85, "access-denied"},
3100 { 86, "bad-destination-address"},
3101 { 87, "bad-destination-device-id"},
3102 { 88, "bad-signature"},
3103 { 89, "bad-source-address"},
3104 { 90, "bad-timestamp"},
3105 { 91, "cannot-use-key"},
3106 { 92, "cannot-verify-message-id"},
3107 { 93, "correct-key-revision"},
3108 { 94, "destination-device-id-required"},
3109 { 95, "duplicate-message"},
3110 { 96, "encryption-not-configured"},
3111 { 97, "encryption-required"},
3112 { 98, "incorrect-key"},
3113 { 99, "invalid-key-data"},
3114 { 100, "key-update-in-progress"},
3115 { 101, "malformed-message"},
3116 { 102, "not-key-server"},
3117 { 103, "security-not-configured"},
3118 { 104, "source-security-required"},
3119 { 105, "too-many-keys"},
3120 { 106, "unknown-authentication-type"},
3121 { 107, "unknown-key"},
3122 { 108, "unknown-key-revision"},
3123 { 109, "unknown-source-message"},
3124 { 110, "not-router-to-dnet"},
3125 { 111, "router-busy"},
3126 { 112, "unknown-network-message"},
3127 { 113, "message-too-long"},
3128 { 114, "security-error"},
3129 { 115, "addressing-error"},
3130 { 116, "write-bdt-failed"},
3131 { 117, "read-bdt-failed"},
3132 { 118, "register-foreign-device-failed"},
3133 { 119, "read-fdt-failed"},
3134 { 120, "delete-fdt-entry-failed"},
3135 { 121, "distribute-broadcast-failed"},
3136 { 122, "unknown-file-size"},
3137 { 123, "abort-apdu-too-long"},
3138 { 124, "abort-application-exceeded-reply-time"},
3139 { 125, "abort-out-of-resources"},
3140 { 126, "abort-tsm-timeout"},
3141 { 127, "abort-window-size-out-of-range"},
3142 { 128, "file-full"},
3143 { 129, "inconsistent-configuration"},
3144 { 130, "inconsistent-object-type"},
3145 { 131, "internal-error"},
3146 { 132, "not-configured"},
3147 { 133, "out-of-memory"},
3148 { 134, "value-too-long"},
3149 { 135, "abort-insufficient-security"},
3150 { 136, "abort-security-error"},
3152 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
3153 Enumerated values 256-65535 may be used by others subject to the
3154 procedures and constraints described in Clause 23. */
3157 static const value_string
3158 BACnetPropertyIdentifier [] = {
3159 { 0, "acked-transition"},
3160 { 1, "ack-required"},
3162 { 3, "action-text"},
3163 { 4, "active-text"},
3164 { 5, "active-vt-session"},
3165 { 6, "alarm-value"},
3166 { 7, "alarm-values"},
3168 { 9, "all-write-successful"},
3169 { 10, "apdu-segment-timeout"},
3170 { 11, "apdu-timeout"},
3171 { 12, "application-software-version"},
3174 { 15, "change-of-state-count"},
3175 { 16, "change-of-state-time"},
3176 { 17, "notification-class"},
3177 { 18, "the property in this place was deleted"},
3178 { 19, "controlled-variable-reference"},
3179 { 20, "controlled-variable-units"},
3180 { 21, "controlled-variable-value"},
3181 { 22, "cov-increment"},
3183 { 24, "daylights-savings-status"},
3185 { 26, "derivative-constant"},
3186 { 27, "derivative-constant-units"},
3187 { 28, "description"},
3188 { 29, "description-of-halt"},
3189 { 30, "device-address-binding"},
3190 { 31, "device-type"},
3191 { 32, "effective-period"},
3192 { 33, "elapsed-active-time"},
3193 { 34, "error-limit"},
3194 { 35, "event-enable"},
3195 { 36, "event-state"},
3196 { 37, "event-type"},
3197 { 38, "exception-schedule"},
3198 { 39, "fault-values"},
3199 { 40, "feedback-value"},
3200 { 41, "file-access-method"},
3203 { 44, "firmware-revision"},
3204 { 45, "high-limit"},
3205 { 46, "inactive-text"},
3206 { 47, "in-progress"},
3207 { 48, "instance-of"},
3208 { 49, "integral-constant"},
3209 { 50, "integral-constant-units"},
3210 { 51, "issue-confirmed-notifications"},
3211 { 52, "limit-enable"},
3212 { 53, "list-of-group-members"},
3213 { 54, "list-of-object-property-references"},
3214 { 55, "list-of-session-keys"},
3215 { 56, "local-date"},
3216 { 57, "local-time"},
3219 { 60, "manipulated-variable-reference"},
3220 { 61, "maximum-output"},
3221 { 62, "max-apdu-length-accepted"},
3222 { 63, "max-info-frames"},
3223 { 64, "max-master"},
3224 { 65, "max-pres-value"},
3225 { 66, "minimum-off-time"},
3226 { 67, "minimum-on-time"},
3227 { 68, "minimum-output"},
3228 { 69, "min-pres-value"},
3229 { 70, "model-name"},
3230 { 71, "modification-date"},
3231 { 72, "notify-type"},
3232 { 73, "number-of-APDU-retries"},
3233 { 74, "number-of-states"},
3234 { 75, "object-identifier"},
3235 { 76, "object-list"},
3236 { 77, "object-name"},
3237 { 78, "object-property-reference"},
3238 { 79, "object-type"},
3240 { 81, "out-of-service"},
3241 { 82, "output-units"},
3242 { 83, "event-parameters"},
3244 { 85, "present-value"},
3246 { 87, "priority-array"},
3247 { 88, "priority-for-writing"},
3248 { 89, "process-identifier"},
3249 { 90, "program-change"},
3250 { 91, "program-location"},
3251 { 92, "program-state"},
3252 { 93, "proportional-constant"},
3253 { 94, "proportional-constant-units"},
3254 { 95, "protocol-conformance-class"},
3255 { 96, "protocol-object-types-supported"},
3256 { 97, "protocol-services-supported"},
3257 { 98, "protocol-version"},
3259 { 100, "reason-for-halt"},
3260 { 101, "recipient"},
3261 { 102, "recipient-list"},
3262 { 103, "reliability"},
3263 { 104, "relinquish-default"},
3265 { 106, "resolution"},
3266 { 107, "segmentation-supported"},
3268 { 109, "setpoint-reference"},
3269 { 110, "state-text"},
3270 { 111, "status-flags"},
3271 { 112, "system-status"},
3272 { 113, "time-delay"},
3273 { 114, "time-of-active-time-reset"},
3274 { 115, "time-of-state-count-reset"},
3275 { 116, "time-synchronization-recipients"},
3277 { 118, "update-interval"},
3278 { 119, "utc-offset"},
3279 { 120, "vendor-identifier"},
3280 { 121, "vendor-name"},
3281 { 122, "vt-class-supported"},
3282 { 123, "weekly-schedule"},
3283 { 124, "attempted-samples"},
3284 { 125, "average-value"},
3285 { 126, "buffer-size"},
3286 { 127, "client-cov-increment"},
3287 { 128, "cov-resubscription-interval"},
3288 { 129, "current-notify-time"},
3289 { 130, "event-time-stamp"},
3290 { 131, "log-buffer"},
3291 { 132, "log-device-object-property"},
3292 { 133, "enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
3293 { 134, "log-interval"},
3294 { 135, "maximum-value"},
3295 { 136, "minimum-value"},
3296 { 137, "notification-threshold"},
3297 { 138, "previous-notify-time"},
3298 { 139, "protocol-revision"},
3299 { 140, "records-since-notification"},
3300 { 141, "record-count"},
3301 { 142, "start-time"},
3302 { 143, "stop-time"},
3303 { 144, "stop-when-full"},
3304 { 145, "total-record-count"},
3305 { 146, "valid-samples"},
3306 { 147, "window-interval"},
3307 { 148, "window-samples"},
3308 { 149, "maximum-value-time-stamp"},
3309 { 150, "minimum-value-time-stamp"},
3310 { 151, "variance-value"},
3311 { 152, "active-cov-subscriptions"},
3312 { 153, "backup-failure-timeout"},
3313 { 154, "configuration-files"},
3314 { 155, "database-revision"},
3315 { 156, "direct-reading"},
3316 { 157, "last-restore-time"},
3317 { 158, "maintenance-required"},
3318 { 159, "member-of"},
3320 { 161, "operation-expected"},
3323 { 164, "tracking-value"},
3324 { 165, "zone-members"},
3325 { 166, "life-safety-alarm-values"},
3326 { 167, "max-segments-accepted"},
3327 { 168, "profile-name"},
3328 { 169, "auto-slave-discovery"},
3329 { 170, "manual-slave-address-binding"},
3330 { 171, "slave-address-binding"},
3331 { 172, "slave-proxy-enable"},
3332 { 173, "last-notify-record"}, /* bug 4117 */
3333 { 174, "schedule-default"},
3334 { 175, "accepted-modes"},
3335 { 176, "adjust-value"},
3337 { 178, "count-before-change"},
3338 { 179, "count-change-time"},
3339 { 180, "cov-period"},
3340 { 181, "input-reference"},
3341 { 182, "limit-monitoring-interval"},
3342 { 183, "logging-device"},
3343 { 184, "logging-record"},
3345 { 186, "pulse-rate"},
3347 { 188, "scale-factor"},
3348 { 189, "update-time"},
3349 { 190, "value-before-change"},
3350 { 191, "value-set"},
3351 { 192, "value-change-time"},
3352 { 193, "align-intervals"},
3353 { 194, "group-member-names"},
3354 { 195, "interval-offset"},
3355 { 196, "last-restart-reason"},
3356 { 197, "logging-type"},
3357 { 198, "member-status-flags"},
3358 { 199, "notification-period"},
3359 { 200, "previous-notify-record"},
3360 { 201, "requested-update-interval"},
3361 { 202, "restart-notification-recipients"},
3362 { 203, "time-of-device-restart"},
3363 { 204, "time-synchronization-interval"},
3365 { 206, "UTC-time-synchronization-recipients"},
3366 { 207, "node-subtype"},
3367 { 208, "node-type"},
3368 { 209, "structured-object-list"},
3369 { 210, "subordinate-annotations"},
3370 { 211, "subordinate-list"},
3371 { 212, "actual-shed-level"},
3372 { 213, "duty-window"},
3373 { 214, "expected-shed-level"},
3374 { 215, "full-duty-baseline"},
3375 { 216, "node-subtype"},
3376 { 217, "node-type"},
3377 { 218, "requested-shed-level"},
3378 { 219, "shed-duration"},
3379 { 220, "shed-level-descriptions"},
3380 { 221, "shed-levels"},
3381 { 222, "state-description"},
3382 /* enumeration values 223-225 are unassigned */
3383 { 226, "door-alarm-state"},
3384 { 227, "door-extended-pulse-time"},
3385 { 228, "door-members"},
3386 { 229, "door-open-too-long-time"},
3387 { 230, "door-pulse-time"},
3388 { 231, "door-status"},
3389 { 232, "door-unlock-delay-time"},
3390 { 233, "lock-status"},
3391 { 234, "masked-alarm-values"},
3392 { 235, "secured-status"},
3393 /* enumeration values 236-243 are unassigned */
3394 { 244, "absentee-limit"}, /* added with addenda 135-2008j */
3395 { 245, "access-alarm-events"},
3396 { 246, "access-doors"},
3397 { 247, "access-event"},
3398 { 248, "access-event-authentication-factor"},
3399 { 249, "access-event-credential"},
3400 { 250, "access-event-time"},
3401 { 251, "access-transaction-events"},
3402 { 252, "accompaniment"},
3403 { 253, "accompaniment-time"},
3404 { 254, "activation-time"},
3405 { 255, "active-authentication-policy"},
3406 { 256, "assigned-access-rights"},
3407 { 257, "authentication-factors"},
3408 { 258, "authentication-policy-list"},
3409 { 259, "authentication-policy-names"},
3410 { 260, "authentication-status"},
3411 { 261, "authorization-mode"},
3412 { 262, "belongs-to"},
3413 { 263, "credential-disable"},
3414 { 264, "credential-status"},
3415 { 265, "credentials"},
3416 { 266, "credentials-in-zone"},
3417 { 267, "days-remaining"},
3418 { 268, "entry-points"},
3419 { 269, "exit-points"},
3420 { 270, "expiry-time"},
3421 { 271, "extended-time-enable"},
3422 { 272, "failed-attempt-events"},
3423 { 273, "failed-attempts"},
3424 { 274, "failed-attempts-time"},
3425 { 275, "last-access-event"},
3426 { 276, "last-access-point"},
3427 { 277, "last-credential-added"},
3428 { 278, "last-credential-added-time"},
3429 { 279, "last-credential-removed"},
3430 { 280, "last-credential-removed-time"},
3431 { 281, "last-use-time"},
3433 { 283, "lockout-relinquish-time"},
3434 { 284, "master-exemption"},
3435 { 285, "max-failed-attempts"},
3437 { 287, "muster-point"},
3438 { 288, "negative-access-rules"},
3439 { 289, "number-of-authentication-policies"},
3440 { 290, "occupancy-count"},
3441 { 291, "occupancy-count-adjust"},
3442 { 292, "occupancy-count-enable"},
3443 { 293, "occupancy-exemption"},
3444 { 294, "occupancy-lower-limit"},
3445 { 295, "occupancy-lower-limit-enforced"},
3446 { 296, "occupancy-state"},
3447 { 297, "occupancy-upper-limit"},
3448 { 298, "occupancy-upper-limit-enforced"},
3449 { 299, "passback-exemption"},
3450 { 300, "passback-mode"},
3451 { 301, "passback-timeout"},
3452 { 302, "positive-access-rules"},
3453 { 303, "reason-for-disable"},
3454 { 304, "supported-formats"},
3455 { 305, "supported-format-classes"},
3456 { 306, "threat-authority"},
3457 { 307, "threat-level"},
3458 { 308, "trace-flag"},
3459 { 309, "transaction-notification-class"},
3460 { 310, "user-external-identifier"},
3461 { 311, "user-information-reference"},
3462 /* enumeration values 312-316 are unassigned */
3463 { 317, "user-name"},
3464 { 318, "user-type"},
3465 { 319, "uses-remaining"},
3466 { 320, "zone-from"},
3468 { 322, "access-event-tag"},
3469 { 323, "global-identifier"},
3470 /* enumeration values 324-325 reserved for future addenda */
3471 { 326, "verification-time"},
3472 { 327, "base-device-security-policy"},
3473 { 328, "distribution-key-revision"},
3474 { 329, "do-not-hide"},
3476 { 331, "last-key-server"},
3477 { 332, "network-access-security-policies"},
3478 { 333, "packet-reorder-time"},
3479 { 334, "security-pdu-timeout"},
3480 { 335, "security-time-window"},
3481 { 336, "supported-security-algorithms"},
3482 { 337, "update-key-set-timeout"},
3483 { 338, "backup-and-restore-state"},
3484 { 339, "backup-preparation-time"},
3485 { 340, "restore-completion-time"},
3486 { 341, "restore-preparation-time"},
3487 { 342, "bit-mask"}, /* addenda 135-2008w */
3490 { 345, "group-members"},
3491 { 346, "group-member-names"},
3492 { 347, "member-status-flags"},
3493 { 348, "requested-update-interval"},
3494 { 349, "covu-period"},
3495 { 350, "covu-recipients"},
3496 { 351, "event-message-texts"},
3498 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3499 Enumerated values 512-4194303 may be used by others subject to
3500 the procedures and constraints described in Clause 23. */
3503 static const value_string
3504 BACnetBinaryPV [] = {
3511 #define ANSI_X3_4 0 /* ANSI X3.4, a/k/a "ASCII"; full UTF-8 since 2010 */
3512 /* See, for example, ANSI/ASHRAE Addendum k to ANSI/ASHRAE Standard 135-2008 */
3513 /* XXX - I've seen captures using this for ISO 8859-1 */
3514 #define IBM_MS_DBCS 1 /* "IBM/Microsoft DBCS"; was there only one such DBCS? */
3515 #define JIS_C_6226 2 /* JIS C 6226 */
3516 #define ISO_10646_UCS4 3 /* ISO 10646 (UCS-4) - 4-byte Unicode */
3517 #define ISO_10646_UCS2 4 /* ISO 10646 (UCS-2) - 2-byte Unicode Basic Multilingual Plane (not UTF-16, presumably) */
3518 #define ISO_8859_1 5 /* ISO 8859-1 */
3519 static const value_string
3520 BACnetCharacterSet [] = {
3521 { ANSI_X3_4, "ANSI X3.4 / UTF-8 (since 2010)"},
3522 { IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3523 { JIS_C_6226, "JIS C 6226"},
3524 { ISO_10646_UCS4, "ISO 10646 (UCS-4)"},
3525 { ISO_10646_UCS2, "ISO 10646 (UCS-2)"},
3526 { ISO_8859_1, "ISO 8859-1"},
3530 static const value_string
3531 BACnetStatusFlags [] = {
3535 { 3, "out-of-service"},
3539 static const value_string
3540 BACnetMessagePriority [] = {
3546 static const value_string
3547 BACnetAcknowledgementFilter [] = {
3554 static const value_string
3555 BACnetResultFlags [] = {
3562 static const value_string
3563 BACnetRelationSpecifier [] = {
3567 { 3, "greater-than"},
3568 { 4, "less-than-or-equal"},
3569 { 5, "greater-than-or-equal"},
3573 static const value_string
3574 BACnetSelectionLogic [] = {
3581 static const value_string
3582 BACnetEventStateFilter [] = {
3591 static const value_string
3592 BACnetEventTransitionBits [] = {
3593 { 0, "to-offnormal"},
3599 static const value_string
3600 BACnetSegmentation [] = {
3601 { 0, "segmented-both"},
3602 { 1, "segmented-transmit"},
3603 { 2, "segmented-receive"},
3604 { 3, "no-segmentation"},
3608 static const value_string
3609 BACnetSilencedState [] = {
3611 { 1, "audible-silenced"},
3612 { 2, "visible-silenced"},
3613 { 3, "all-silenced"},
3617 static const value_string
3618 BACnetDeviceStatus [] = {
3619 { 0, "operational"},
3620 { 1, "operational-read-only"},
3621 { 2, "download-required"},
3622 { 3, "download-in-progress"},
3623 { 4, "non-operational"},
3624 { 5, "backup-in-progress"},
3628 static const value_string
3629 BACnetEnableDisable [] = {
3632 { 2, "disable-initiation"},
3636 static const value_string
3650 { 255, "any month" },
3654 static const value_string
3656 { 1, "days numbered 1-7" },
3657 { 2, "days numbered 8-14" },
3658 { 3, "days numbered 15-21" },
3659 { 4, "days numbered 22-28" },
3660 { 5, "days numbered 29-31" },
3661 { 6, "last 7 days of this month" },
3662 { 255, "any week of this month" },
3666 /* note: notification class object recipient-list uses
3667 different day-of-week enum */
3668 static const value_string
3677 { 255, "any day of week" },
3681 static const value_string
3682 BACnetErrorClass [] = {
3690 { 7, "communication" },
3692 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3693 Enumerated values64-65535 may be used by others subject to
3694 the procedures and constraints described in Clause 23. */
3697 static const value_string
3698 BACnetVTClass [] = {
3699 { 0, "default-terminal" },
3700 { 1, "ansi-x3-64" },
3709 static const value_string
3710 BACnetEventType [] = {
3711 { 0, "change-of-bitstring" },
3712 { 1, "change-of-state" },
3713 { 2, "change-of-value" },
3714 { 3, "command-failure" },
3715 { 4, "floating-limit" },
3716 { 5, "out-of-range" },
3717 { 6, "complex-event-type" },
3718 { 7, "(deprecated)buffer-ready" },
3719 { 8, "change-of-life-safety" },
3721 { 10, "buffer-ready" },
3722 { 11, "unsigned-range" },
3723 { 14, "double-out-of-range"}, /* added with addenda 135-2008w */
3724 { 15, "signed-out-of-range"},
3725 { 16, "unsigned-out-of-range"},
3726 { 17, "change-of-characterstring"},
3727 { 18, "change-of-status-flags"},
3729 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3730 Enumerated values 64-65535 may be used by others subject to
3731 the procedures and constraints described in Clause 23.
3732 It is expected that these enumerated values will correspond
3733 to the use of the complex-event-type CHOICE [6] of the
3734 BACnetNotificationParameters production. */
3737 static const value_string
3738 BACnetEventState [] = {
3742 { 3, "high-limit" },
3744 { 5, "life-safety-alarm" },
3746 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3747 Enumerated values 64-65535 may be used by others subject to
3748 the procedures and constraints described in Clause 23. */
3751 static const value_string
3752 BACnetLogStatus [] = {
3753 { 0, "log-disabled" },
3754 { 1, "buffer-purged" },
3755 { 2, "log-interrupted"},
3759 static const value_string
3760 BACnetMaintenance [] = {
3762 { 1, "periodic-test" },
3763 { 2, "need-service-operational" },
3764 { 3, "need-service-inoperative" },
3768 static const value_string
3769 BACnetNotifyType [] = {
3772 { 2, "ack-notification" },
3776 static const value_string
3777 BACnetServicesSupported [] = {
3778 { 0, "acknowledgeAlarm"},
3779 { 1, "confirmedCOVNotification"},
3780 { 2, "confirmedEventNotification"},
3781 { 3, "getAlarmSummary"},
3782 { 4, "getEnrollmentSummary"},
3783 { 5, "subscribeCOV"},
3784 { 6, "atomicReadFile"},
3785 { 7, "atomicWriteFile"},
3786 { 8, "addListElement"},
3787 { 9, "removeListElement"},
3788 { 10, "createObject"},
3789 { 11, "deleteObject"},
3790 { 12, "readProperty"},
3791 { 13, "readPropertyConditional"},
3792 { 14, "readPropertyMultiple"},
3793 { 15, "writeProperty"},
3794 { 16, "writePropertyMultiple"},
3795 { 17, "deviceCommunicationControl"},
3796 { 18, "confirmedPrivateTransfer"},
3797 { 19, "confirmedTextMessage"},
3798 { 20, "reinitializeDevice"},
3802 { 24, "authenticate"},
3803 { 25, "requestKey"},
3806 { 28, "unconfirmedCOVNotification"},
3807 { 29, "unconfirmedEventNotification"},
3808 { 30, "unconfirmedPrivateTransfer"},
3809 { 31, "unconfirmedTextMessage"},
3810 { 32, "timeSynchronization"},
3814 { 36, "utcTimeSynchronization"},
3815 { 37, "lifeSafetyOperation"},
3816 { 38, "subscribeCOVProperty"},
3817 { 39, "getEventInformation"},
3821 static const value_string
3822 BACnetPropertyStates [] = {
3823 { 0, "boolean-value"},
3824 { 1, "binary-value"},
3827 { 4, "program-change"},
3828 { 5, "program-state"},
3829 { 6, "reason-for-halt"},
3830 { 7, "reliability"},
3832 { 9, "system-status"},
3834 { 11, "unsigned-value"},
3835 { 12, "life-safety-mode"},
3836 { 13, "life-safety-state"},
3837 { 14, "restart-reason"},
3838 { 15, "door-alarm-state"},
3840 { 17, "door-secured-status"},
3841 { 18, "door-status"},
3842 { 19, "door-value"},
3843 { 20, "file-access-method"},
3844 { 21, "lock-status"},
3845 { 22, "life-safety-operation"},
3846 { 23, "maintenance"},
3848 { 25, "notify-type"},
3849 { 26, "security-level"},
3850 { 27, "shed-state"},
3851 { 28, "silenced-state"},
3852 /* context tag 29 reserved for future addenda */
3853 { 29, "unknown-29"},
3854 { 30, "access-event"},
3855 { 31, "zone-occupancy-state"},
3856 { 32, "access-credential-disable-reason"},
3857 { 33, "access-credential-disable"},
3858 { 34, "authentication-status"},
3859 { 35, "unknown-35"},
3860 { 36, "backup-state"},
3862 /* Tag values 0-63 are reserved for definition by ASHRAE.
3863 Tag values of 64-254 may be used by others to accommodate
3864 vendor specific properties that have discrete or enumerated values,
3865 subject to the constraints described in Clause 23. */
3868 static const value_string
3869 BACnetProgramError [] = {
3871 { 1, "load-failed"},
3876 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3877 Enumerated values 64-65535 may be used by others subject to
3878 the procedures and constraints described in Clause 23. */
3881 static const value_string
3882 BACnetProgramRequest [] = {
3892 static const value_string
3893 BACnetProgramState [] = {
3903 static const value_string
3904 BACnetReinitializedStateOfDevice [] = {
3907 { 2, "startbackup"},
3909 { 4, "startrestore"},
3911 { 6, "abortrestore"},
3915 static const value_string
3916 BACnetPolarity [] = {
3922 static const value_string
3923 BACnetTagNames[] = {
3924 { 5, "Extended Value" },
3925 { 6, "Opening Tag" },
3926 { 7, "Closing Tag" },
3930 static const value_string
3931 BACnetReadRangeOptions[] = {
3932 { 3, "range byPosition" },
3933 { 4, "range byTime" },
3934 { 5, "range timeRange" },
3935 { 6, "range bySequenceNumber" },
3936 { 7, "range byTime" },
3940 /* Present_Value for Load Control Object */
3941 static const value_string
3942 BACnetShedState[] = {
3943 { 0, "shed-inactive" },
3944 { 1, "shed-request-pending" },
3945 { 2, "shed-compliant" },
3946 { 3, "shed-non-compliant" },
3950 static const value_string
3951 BACnetNodeType [] = {
3956 { 4, "organizational" },
3960 { 8, "collection" },
3962 { 10, "functional" },
3967 static const value_string
3968 BACnetLoggingType [] = {
3975 static const value_string
3976 BACnetDoorStatus [] = {
3983 static const value_string
3984 BACnetLockStatus [] = {
3992 static const value_string
3993 BACnetDoorSecuredStatus [] = {
4000 static const value_string
4001 BACnetDoorAlarmState [] = {
4004 { 2, "door-open-too-long" },
4005 { 3, "forced-open" },
4007 { 5, "door-fault" },
4009 { 7, "free-access" },
4010 { 8, "egress-open" },
4014 static const value_string
4015 BACnetAccumulatorStatus [] = {
4024 /* These values are (manually) transferred from
4025 * http://www.bacnet.org/VendorID/BACnet Vendor IDs.htm
4026 * Version: "As of September 16, 2013"
4029 static const value_string
4030 BACnetVendorIdentifiers [] = {
4033 { 2, "The Trane Company" },
4034 { 3, "McQuay International" },
4036 { 5, "Johnson Controls, Inc." },
4037 { 6, "American Auto-Matrix" },
4038 { 7, "Siemens Schweiz AG (Formerly: Landis & Staefa Division Europe)" },
4039 { 8, "Delta Controls" },
4040 { 9, "Siemens Schweiz AG" },
4041 { 10, "Schneider Electric" },
4043 { 12, "Orion Analysis Corporation" },
4044 { 13, "Teletrol Systems Inc." },
4045 { 14, "Cimetrics Technology" },
4046 { 15, "Cornell University" },
4047 { 16, "United Technologies Carrier" },
4048 { 17, "Honeywell Inc." },
4049 { 18, "Alerton / Honeywell" },
4051 { 20, "Hewlett-Packard Company" },
4052 { 21, "Dorsette's Inc." },
4053 { 22, "Siemens Schweiz AG (Formerly: Cerberus AG)" },
4054 { 23, "York Controls Group" },
4055 { 24, "Automated Logic Corporation" },
4056 { 25, "CSI Control Systems International" },
4057 { 26, "Phoenix Controls Corporation" },
4058 { 27, "Innovex Technologies, Inc." },
4059 { 28, "KMC Controls, Inc." },
4060 { 29, "Xn Technologies, Inc." },
4061 { 30, "Hyundai Information Technology Co., Ltd." },
4062 { 31, "Tokimec Inc." },
4064 { 33, "North Building Technologies Limited" },
4066 { 35, "Reliable Controls Corporation" },
4067 { 36, "Tridium Inc." },
4068 { 37, "Sierra Monitor Corporation/FieldServer Technologies" },
4069 { 38, "Silicon Energy" },
4070 { 39, "Kieback & Peter GmbH & Co KG" },
4071 { 40, "Anacon Systems, Inc." },
4072 { 41, "Systems Controls & Instruments, LLC" },
4073 { 42, "Lithonia Lighting" },
4074 { 43, "Micropower Manufacturing" },
4075 { 44, "Matrix Controls" },
4076 { 45, "METALAIRE" },
4077 { 46, "ESS Engineering" },
4078 { 47, "Sphere Systems Pty Ltd." },
4079 { 48, "Walker Technologies Corporation" },
4080 { 49, "H I Solutions, Inc." },
4082 { 51, "SAMSON AG" },
4083 { 52, "Badger Meter Inc." },
4084 { 53, "DAIKIN Industries Ltd." },
4085 { 54, "NARA Controls Inc." },
4086 { 55, "Mammoth Inc." },
4087 { 56, "Liebert Corporation" },
4088 { 57, "SEMCO Incorporated" },
4089 { 58, "Air Monitor Corporation" },
4090 { 59, "TRIATEK, LLC" },
4092 { 61, "Multistack" },
4093 { 62, "TSI Incorporated" },
4094 { 63, "Weather-Rite, Inc." },
4095 { 64, "Dunham-Bush" },
4096 { 65, "Reliance Electric" },
4098 { 67, "Regulator Australia PTY Ltd." },
4099 { 68, "Touch-Plate Lighting Controls" },
4100 { 69, "Amann GmbH" },
4101 { 70, "RLE Technologies" },
4102 { 71, "Cardkey Systems" },
4103 { 72, "SECOM Co., Ltd." },
4104 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
4105 { 74, "KNX Association cvba" },
4106 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
4107 { 76, "Nohmi Bosai, Ltd." },
4108 { 77, "Carel S.p.A." },
4109 { 78, "AirSense Technology, Inc." },
4110 { 79, "Hochiki Corporation" },
4111 { 80, "Fr. Sauter AG" },
4112 { 81, "Matsushita Electric Works, Ltd." },
4113 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
4114 { 83, "Mitsubishi Heavy Industries, Ltd." },
4115 { 84, "ITT Bell & Gossett" },
4116 { 85, "Yamatake Building Systems Co., Ltd." },
4117 { 86, "The Watt Stopper, Inc." },
4118 { 87, "Aichi Tokei Denki Co., Ltd." },
4119 { 88, "Activation Technologies, LLC" },
4120 { 89, "Saia-Burgess Controls, Ltd." },
4121 { 90, "Hitachi, Ltd." },
4122 { 91, "Novar Corp./Trend Control Systems Ltd." },
4123 { 92, "Mitsubishi Electric Lighting Corporation" },
4124 { 93, "Argus Control Systems, Ltd." },
4125 { 94, "Kyuki Corporation" },
4126 { 95, "Richards-Zeta Building Intelligence, Inc." },
4127 { 96, "Scientech R&D, Inc." },
4128 { 97, "VCI Controls, Inc." },
4129 { 98, "Toshiba Corporation" },
4130 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
4131 { 100, "Custom Mechanical Equipment, LLC" },
4132 { 101, "ClimateMaster" },
4133 { 102, "ICP Panel-Tec, Inc." },
4134 { 103, "D-Tek Controls" },
4135 { 104, "NEC Engineering, Ltd." },
4136 { 105, "PRIVA BV" },
4137 { 106, "Meidensha Corporation" },
4138 { 107, "JCI Systems Integration Services" },
4139 { 108, "Freedom Corporation" },
4140 { 109, "Neuberger Gebaudeautomation GmbH" },
4141 { 110, "Sitronix" },
4142 { 111, "Leviton Manufacturing" },
4143 { 112, "Fujitsu Limited" },
4144 { 113, "Emerson Network Power" },
4145 { 114, "S. A. Armstrong, Ltd." },
4146 { 115, "Visonet AG" },
4147 { 116, "M&M Systems, Inc." },
4148 { 117, "Custom Software Engineering" },
4149 { 118, "Nittan Company, Limited" },
4150 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
4151 { 120, "Pacom Systems Pty., Ltd." },
4152 { 121, "Unico, Inc." },
4153 { 122, "Ebtron, Inc." },
4154 { 123, "Scada Engine" },
4155 { 124, "AC Technology Corporation" },
4156 { 125, "Eagle Technology" },
4157 { 126, "Data Aire, Inc." },
4158 { 127, "ABB, Inc." },
4159 { 128, "Transbit Sp. z o. o." },
4160 { 129, "Toshiba Carrier Corporation" },
4161 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
4162 { 131, "Tokai Soft" },
4163 { 132, "Blue Ridge Technologies" },
4164 { 133, "Veris Industries" },
4165 { 134, "Centaurus Prime" },
4166 { 135, "Sand Network Systems" },
4167 { 136, "Regulvar, Inc." },
4168 { 137, "AFDtek Division of Fastek International Inc." },
4169 { 138, "PowerCold Comfort Air Solutions, Inc." },
4170 { 139, "I Controls" },
4171 { 140, "Viconics Electronics, Inc." },
4172 { 141, "Yaskawa America, Inc." },
4173 { 142, "DEOS control systems GmbH" },
4174 { 143, "Digitale Mess- und Steuersysteme AG" },
4175 { 144, "Fujitsu General Limited" },
4176 { 145, "Project Engineering S.r.l." },
4177 { 146, "Sanyo Electric Co., Ltd." },
4178 { 147, "Integrated Information Systems, Inc." },
4179 { 148, "Temco Controls, Ltd." },
4180 { 149, "Airtek International Inc." },
4181 { 150, "Advantech Corporation" },
4182 { 151, "Titan Products, Ltd." },
4183 { 152, "Regel Partners" },
4184 { 153, "National Environmental Product" },
4185 { 154, "Unitec Corporation" },
4186 { 155, "Kanden Engineering Company" },
4187 { 156, "Messner Gebaudetechnik GmbH" },
4188 { 157, "Integrated.CH" },
4189 { 158, "Price Industries" },
4190 { 159, "SE-Elektronic GmbH" },
4191 { 160, "Rockwell Automation" },
4192 { 161, "Enflex Corp." },
4193 { 162, "ASI Controls" },
4194 { 163, "SysMik GmbH Dresden" },
4195 { 164, "HSC Regelungstechnik GmbH" },
4196 { 165, "Smart Temp Australia Pty. Ltd." },
4197 { 166, "Cooper Controls" },
4198 { 167, "Duksan Mecasys Co., Ltd." },
4199 { 168, "Fuji IT Co., Ltd." },
4200 { 169, "Vacon Plc" },
4201 { 170, "Leader Controls" },
4202 { 171, "Cylon Controls, Ltd." },
4204 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
4205 { 174, "Building Control Integrators" },
4206 { 175, "ITG Worldwide (M) Sdn Bhd" },
4207 { 176, "Lutron Electronics Co., Inc." },
4208 { 178, "LOYTEC Electronics GmbH" },
4210 { 180, "Mega Controls Limited" },
4211 { 181, "Micro Control Systems, Inc." },
4212 { 182, "Kiyon, Inc." },
4213 { 183, "Dust Networks" },
4214 { 184, "Advanced Building Automation Systems" },
4215 { 185, "Hermos AG" },
4218 { 188, "Lynxspring" },
4219 { 189, "Schneider Toshiba Inverter Europe" },
4220 { 190, "Danfoss Drives A/S" },
4221 { 191, "Eaton Corporation" },
4222 { 192, "Matyca S.A." },
4223 { 193, "Botech AB" },
4224 { 194, "Noveo, Inc." },
4226 { 196, "Yokogawa Electric Corporation" },
4227 { 197, "GFR Gesellschaft fur Regelungstechnik" },
4228 { 198, "Exact Logic" },
4229 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
4230 { 200, "Kandenko Co., Ltd." },
4231 { 201, "DTF, Daten-Technik Fries" },
4232 { 202, "Klimasoft, Ltd." },
4233 { 203, "Toshiba Schneider Inverter Corporation" },
4234 { 204, "Control Applications, Ltd." },
4235 { 205, "KDT Systems Co., Ltd." },
4236 { 206, "Onicon Incorporated" },
4237 { 207, "Automation Displays, Inc." },
4238 { 208, "Control Solutions, Inc." },
4239 { 209, "Remsdaq Limited" },
4240 { 210, "NTT Facilities, Inc." },
4241 { 211, "VIPA GmbH" },
4242 { 212, "TSC21 Association of Japan" },
4243 { 213, "Strato Automation" },
4244 { 214, "HRW Limited" },
4245 { 215, "Lighting Control & Design, Inc." },
4246 { 216, "Mercy Electronic and Electrical Industries" },
4247 { 217, "Samsung SDS Co., Ltd" },
4248 { 218, "Impact Facility Solutions, Inc." },
4249 { 219, "Aircuity" },
4250 { 220, "Control Techniques, Ltd." },
4251 { 221, "OpenGeneral Pty., Ltd." },
4252 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
4253 { 223, "Cerus Industrial" },
4254 { 224, "Chloride Power Protection Company" },
4255 { 225, "Computrols, Inc." },
4256 { 226, "Phoenix Contact GmbH & Co. KG" },
4257 { 227, "Grundfos Management A/S" },
4258 { 228, "Ridder Drive Systems" },
4259 { 229, "Soft Device SDN BHD" },
4260 { 230, "Integrated Control Technology Limited" },
4261 { 231, "AIRxpert Systems, Inc." },
4262 { 232, "Microtrol Limited" },
4263 { 233, "Red Lion Controls" },
4264 { 234, "Digital Electronics Corporation" },
4265 { 235, "Ennovatis GmbH" },
4266 { 236, "Serotonin Software Technologies, Inc." },
4267 { 237, "LS Industrial Systems Co., Ltd." },
4268 { 238, "Square D Company" },
4269 { 239, "S Squared Innovations, Inc." },
4270 { 240, "Aricent Ltd." },
4271 { 241, "EtherMetrics, LLC" },
4272 { 242, "Industrial Control Communications, Inc." },
4273 { 243, "Paragon Controls, Inc." },
4274 { 244, "A. O. Smith Corporation" },
4275 { 245, "Contemporary Control Systems, Inc." },
4276 { 246, "Intesis Software SL" },
4277 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
4278 { 248, "Heat-Timer Corporation" },
4279 { 249, "Ingrasys Technology, Inc." },
4280 { 250, "Costerm Building Automation" },
4282 { 252, "Embedia Technologies Corp." },
4283 { 253, "Technilog" },
4284 { 254, "HR Controls Ltd. & Co. KG" },
4285 { 255, "Lennox International, Inc." },
4286 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
4287 { 257, "Thermomax, Ltd." },
4288 { 258, "ELCON Electronic Control, Ltd." },
4289 { 259, "Larmia Control AB" },
4290 { 260, "BACnet Stack at SourceForge" },
4291 { 261, "G4S Security Services A/S" },
4292 { 262, "Exor International S.p.A." },
4293 { 263, "Cristal Controles" },
4294 { 264, "Regin AB" },
4295 { 265, "Dimension Software, Inc." },
4296 { 266, "SynapSense Corporation" },
4297 { 267, "Beijing Nantree Electronic Co., Ltd." },
4298 { 268, "Camus Hydronics Ltd." },
4299 { 269, "Kawasaki Heavy Industries, Ltd." },
4300 { 270, "Critical Environment Technologies" },
4301 { 271, "ILSHIN IBS Co., Ltd." },
4302 { 272, "ELESTA Energy Control AG" },
4303 { 273, "KROPMAN Installatietechniek" },
4304 { 274, "Baldor Electric Company" },
4305 { 275, "INGA mbH" },
4306 { 276, "GE Consumer & Industrial" },
4307 { 277, "Functional Devices, Inc." },
4309 { 279, "M-System Co., Ltd." },
4310 { 280, "Yokota Co., Ltd." },
4311 { 281, "Hitranse Technology Co., LTD" },
4312 { 282, "Federspiel Controls" },
4313 { 283, "Kele, Inc." },
4314 { 284, "Opera Electronics, Inc." },
4316 { 286, "Embedded Science Labs, LLC" },
4317 { 287, "Parker Hannifin Corporation" },
4318 { 288, "MaCaPS International Limited" },
4319 { 289, "Link4 Corporation" },
4320 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
4321 { 291, "Pribusin, Inc." },
4322 { 292, "Advantage Controls" },
4323 { 293, "Critical Room Control" },
4325 { 295, "Tongdy Control Technology Co., Ltd." },
4326 { 296, "ISSARO Integrierte Systemtechnik" },
4327 { 297, "Pro-Dev Industries" },
4328 { 298, "DRI-STEEM" },
4329 { 299, "Creative Electronic GmbH" },
4330 { 300, "Swegon AB" },
4331 { 301, "Jan Brachacek" },
4332 { 302, "Hitachi Appliances, Inc." },
4333 { 303, "Real Time Automation, Inc." },
4334 { 304, "ITEC Hankyu-Hanshin Co." },
4335 { 305, "Cyrus E&M Engineering Co., Ltd." },
4336 { 306, "Racine Federated, Inc." },
4337 { 307, "Cirrascale Corporation" },
4338 { 308, "Elesta GmbH Building Automation" },
4339 { 309, "Securiton" },
4340 { 310, "OSlsoft, Inc." },
4341 { 311, "Hanazeder Electronic GmbH" },
4342 { 312, "Honeywell Security Deutschland, Novar GmbH" },
4343 { 313, "Siemens Energy & Automation, Inc." },
4344 { 314, "ETM Professional Control GmbH" },
4345 { 315, "Meitav-tec, Ltd." },
4346 { 316, "Janitza Electronics GmbH" },
4347 { 317, "MKS Nordhausen" },
4348 { 318, "De Gier Drive Systems B.V." },
4349 { 319, "Cypress Envirosystems" },
4350 { 320, "SMARTron s.r.o." },
4351 { 321, "Verari Systems, Inc." },
4352 { 322, "K-W Electronic Service, Inc." },
4353 { 323, "ALFA-SMART Energy Management" },
4354 { 324, "Telkonet, Inc." },
4355 { 325, "Securiton GmbH" },
4356 { 326, "Cemtrex, Inc." },
4357 { 327, "Performance Technologies, Inc." },
4358 { 328, "Xtralis (Aust) Pty Ltd" },
4359 { 329, "TROX GmbH" },
4360 { 330, "Beijing Hysine Technology Co., Ltd" },
4361 { 331, "RCK Controls, Inc." },
4362 { 332, "Distech Controls SAS" },
4363 { 333, "Novar/Honeywell" },
4364 { 334, "The S4 Group, Inc." },
4365 { 335, "Schneider Electric" },
4366 { 336, "LHA Systems" },
4367 { 337, "GHM engineering Group, Inc." },
4368 { 338, "Cllimalux S.A." },
4369 { 339, "VAISALA Oyj" },
4370 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
4371 { 341, "SCADAmetrics" },
4372 { 342, "POWERPEG NSI Limited" },
4373 { 343, "BACnet Interoperability Testing Services, Inc." },
4374 { 344, "Teco a.s." },
4375 { 345, "Plexus Technology, Inc." },
4376 { 346, "Energy Focus, Inc." },
4377 { 347, "Powersmiths International Corp." },
4378 { 348, "Nichibei Co., Ltd." },
4379 { 349, "HKC Technology Ltd." },
4380 { 350, "Ovation Networks, Inc." },
4381 { 351, "Setra Systems" },
4382 { 352, "AVG Automation" },
4383 { 353, "ZXC Ltd." },
4384 { 354, "Byte Sphere" },
4385 { 355, "Generiton Co., Ltd." },
4386 { 356, "Holter Regelarmaturen GmbH & Co. KG" },
4387 { 357, "Bedford Instruments, LLC" },
4388 { 358, "Standair Inc." },
4389 { 359, "WEG Automation - R&D" },
4390 { 360, "Prolon Control Systems ApS" },
4391 { 361, "Inneasoft" },
4392 { 362, "ConneXSoft GmbH" },
4393 { 363, "CEAG Notlichtsysteme GmbH" },
4394 { 364, "Distech Controls Inc." },
4395 { 365, "Industrial Technology Research Institute" },
4396 { 366, "ICONICS, Inc." },
4397 { 367, "IQ Controls s.c." },
4398 { 368, "OJ Electronics A/S" },
4399 { 369, "Rolbit Ltd." },
4400 { 370, "Synapsys Solutions Ltd." },
4401 { 371, "ACME Engineering Prod. Ltd." },
4402 { 372, "Zener Electric Pty, Ltd." },
4403 { 373, "Selectronix, Inc." },
4404 { 374, "Gorbet & Banerjee, LLC." },
4406 { 376, "Stephen H. Dawson Computer Service" },
4407 { 377, "Accutrol, LLC" },
4408 { 378, "Schneider Elektronik GmbH" },
4409 { 379, "Alpha-Inno Tec GmbH" },
4410 { 380, "ADMMicro, Inc." },
4411 { 381, "Greystone Energy Systems, Inc." },
4412 { 382, "CAP Technologie" },
4413 { 383, "KeRo Systems" },
4414 { 384, "Domat Control System s.r.o." },
4415 { 385, "Efektronics Pty. Ltd." },
4416 { 386, "Hekatron Vertriebs GmbH" },
4417 { 387, "Securiton AG" },
4418 { 388, "Carlo Gavazzi Controls SpA" },
4419 { 389, "Chipkin Automation Systems" },
4420 { 390, "Savant Systems, LLC" },
4421 { 391, "Simmtronic Lighting Controls" },
4422 { 392, "Abelko Innovation AB" },
4423 { 393, "Seresco Technologies Inc." },
4424 { 394, "IT Watchdogs" },
4425 { 395, "Automation Assist Japan Corp." },
4426 { 396, "Thermokon Sensortechnik GmbH" },
4427 { 397, "EGauge Systems, LLC" },
4428 { 398, "Quantum Automation (ASIA) PTE, Ltd." },
4429 { 399, "Toshiba Lighting & Technology Corp." },
4430 { 400, "SPIN Engenharia de Automaca Ltda." },
4431 { 401, "Logistics Systems & Software Services India PVT. Ltd." },
4432 { 402, "Delta Controls Integration Products" },
4433 { 403, "Focus Media" },
4434 { 404, "LUMEnergi Inc." },
4435 { 405, "Kara Systems" },
4436 { 406, "RF Code, Inc." },
4437 { 407, "Fatek Automation Corp." },
4438 { 408, "JANDA Software Company, LLC" },
4439 { 409, "Open System Solutions Limited" },
4440 { 410, "Intelec Systems PTY Ltd." },
4441 { 411, "Ecolodgix, LLC" },
4442 { 412, "Douglas Lighting Controls" },
4443 { 413, "iSAtech GmbH" },
4445 { 415, "Beckhoff Automation GmbH" },
4446 { 416, "IPAS GmbH" },
4447 { 417, "KE2 Therm Solutions" },
4448 { 418, "Base2Products" },
4449 { 419, "DTL Controls, LLC" },
4450 { 420, "INNCOM International, Inc." },
4451 { 421, "BTR Netcom GmbH" },
4452 { 422, "Greentrol Automation, Inc" },
4453 { 423, "BELIMO Automation AG" },
4454 { 424, "Samsung Heavy Industries Co, Ltd" },
4455 { 425, "Triacta Power Technologies, Inc." },
4456 { 426, "Globestar Systems" },
4457 { 427, "MLB Advanced Media, LP" },
4458 { 428, "SWG Stuckmann Wirtschaftliche Gebaudesysteme GmbH" },
4459 { 429, "SensorSwitch" },
4460 { 430, "Multitek Power Limited" },
4461 { 431, "Aquametro AG" },
4462 { 432, "LG Electronics Inc." },
4463 { 433, "Electronic Theatre Controls, Inc." },
4464 { 434, "Mitsubishi Electric Corporation Nagoya Works" },
4465 { 435, "Delta Electronics, Inc." },
4466 { 436, "Elma Kurtalj, Ltd." },
4467 { 437, "ADT Fire and Security Sp. A.o.o." },
4468 { 438, "Nedap Security Management" },
4469 { 439, "ESC Automation Inc." },
4470 { 440, "DSP4YOU Ltd." },
4471 { 441, "GE Sensing and Inspection Technologies" },
4472 { 442, "Embedded Systems SIA" },
4473 { 443, "BEFEGA GmbH" },
4474 { 444, "Baseline Inc." },
4475 { 445, "M2M Systems Integrators" },
4477 { 447, "Clarkson Controls Limited" },
4478 { 448, "Rogerwell Control System Limited" },
4479 { 449, "SCL Elements" },
4480 { 450, "Hitachi Ltd." },
4481 { 451, "Newron System SA" },
4482 { 452, "BEVECO Gebouwautomatisering BV" },
4483 { 453, "Streamside Solutions" },
4484 { 454, "Yellowstone Soft" },
4485 { 455, "Oztech Intelligent Systems Pty Ltd." },
4486 { 456, "Novelan GmbH" },
4487 { 457, "Flexim Americas Corporation" },
4488 { 458, "ICP DAS Co., Ltd." },
4489 { 459, "CARMA Industries Inc." },
4490 { 460, "Log-One Ltd." },
4491 { 461, "TECO Electric & Machinery Co., Ltd." },
4492 { 462, "ConnectEx, Inc." },
4493 { 463, "Turbo DDC Sudwest" },
4494 { 464, "Quatrosense Environmental Ltd." },
4495 { 465, "Fifth Light Technology Ltd." },
4496 { 466, "Scientific Solutions, Ltd." },
4497 { 467, "Controller Area Network Solutions (M) Sdn Bhd" },
4498 { 468, "RESOL - Elektronische Regelungen GmbH" },
4499 { 469, "RPBUS LLC" },
4500 { 470, "BRS Sistemas Eletronicos" },
4501 { 471, "WindowMaster A/S" },
4502 { 472, "Sunlux Technologies Ltd." },
4503 { 473, "Measurlogic" },
4504 { 474, "Frimat GmbH" },
4505 { 475, "Spirax Sarco" },
4507 { 477, "Raypak Inc" },
4508 { 478, "Air Monitor Corporation" },
4509 { 479, "Regler Och Webbteknik Sverige (ROWS)" },
4510 { 480, "Intelligent Lighting Controls Inc." },
4511 { 481, "Sanyo Electric Industry Co., Ltd" },
4512 { 482, "E-Mon Energy Monitoring Products" },
4513 { 483, "Digital Control Systems" },
4514 { 484, "ATI Airtest Technologies, Inc." },
4516 { 486, "HMS Industrial Networks AB" },
4517 { 487, "Shenzhen Universal Intellisys Co Ltd" },
4518 { 488, "EK Intellisys Sdn Bhd" },
4520 { 490, "Firecom, Inc." },
4521 { 491, "ESA Elektroschaltanlagen Grimma GmbH" },
4522 { 492, "Kumahira Co Ltd" },
4524 { 494, "SABO Elektronik GmbH" },
4525 { 495, "Equip'Trans" },
4526 { 496, "TCS Basys Controls" },
4527 { 497, "FlowCon International A/S" },
4528 { 498, "ThyssenKrupp Elevator Americas" },
4529 { 499, "Abatement Technologies" },
4530 { 500, "Continental Control Systems, LLC" },
4531 { 501, "WISAG Automatisierungstechnik GmbH & Co KG" },
4533 { 503, "EAP-Electric GmbH" },
4534 { 504, "Hardmeier" },
4535 { 505, "Mircom Group of Companies" },
4536 { 506, "Quest Controls" },
4537 { 507, "Mestek, Inc" },
4538 { 508, "Pulse Energy" },
4539 { 509, "Tachikawa Corporation" },
4540 { 510, "University of Nebraska-Lincoln" },
4541 { 511, "Redwood Systems" },
4542 { 512, "PASStec Industrie-Elektronik GmbH" },
4543 { 513, "NgEK, Inc." },
4544 { 514, "FAW Electronics Ltd" },
4545 { 515, "Jireh Energy Tech Co., Ltd." },
4546 { 516, "Enlighted Inc." },
4547 { 517, "El-Piast Sp. Z o.o" },
4548 { 518, "NetxAutomation Software GmbH" },
4549 { 519, "Invertek Drives" },
4550 { 520, "Deutschmann Automation GmbH & Co. KG" },
4551 { 521, "EMU Electronic AG" },
4552 { 522, "Phaedrus Limited" },
4553 { 523, "Sigmatek GmbH & Co KG" },
4554 { 524, "Marlin Controls" },
4555 { 525, "Circutor, SA" },
4556 { 526, "UTC Fire & Security" },
4557 { 527, "DENT Instruments, Inc." },
4558 { 528, "FHP Manufacturing Company - Bosch Group" },
4559 { 529, "GE Intelligent Platforms" },
4560 { 530, "Inner Range Pty Ltd" },
4561 { 531, "GLAS Energy Technology" },
4562 { 532, "MSR-Electronic-GmbH" },
4563 { 533, "Energy Control Systems, Inc." },
4564 { 534, "EMT Controls" },
4565 { 535, "Daintree Networks Inc." },
4566 { 536, "EURO ICC d.o.o" },
4567 { 537, "TE Connectivity Energy" },
4568 { 538, "GEZE GmbH" },
4569 { 539, "NEC Corporation" },
4570 { 540, "Ho Cheung International Company Limited" },
4571 { 541, "Sharp Manufacturing Systems Corporation" },
4572 { 542, "DOT CONTROLS a.s." },
4573 { 543, "BeaconMedaes" },
4574 { 544, "Midea Commercial Aircon" },
4575 { 545, "WattMaster Controls" },
4576 { 546, "Kamstrup A/S" },
4577 { 547, "CA Computer Automation GmbH" },
4578 { 548, "Laars Heating Systems Company" },
4579 { 549, "Hitachi Systems, Ltd." },
4580 { 550, "Fushan AKE Electronic Engineering Co., Ltd." },
4581 { 551, "Toshiba International Corporation" },
4582 { 552, "Starman Systems, LLC" },
4583 { 553, "Samsung Techwin Co., Ltd." },
4584 { 554, "ISAS-Integrated Switchgear and Systems P/L" },
4586 { 557, "Marek Guzik" },
4587 { 558, "Vortek Instruments, LLC" },
4588 { 559, "Universal Lighting Technologies" },
4589 { 560, "Myers Power Products, Inc." },
4590 { 561, "Vector Controls GmbH" },
4591 { 562, "Crestron Electronics, Inc." },
4592 { 563, "A&E Controls Limited" },
4593 { 564, "Projektomontaza A.D." },
4594 { 565, "Freeaire Refrigeration" },
4595 { 566, "Aqua Cooler Pty Limited" },
4596 { 567, "Basic Controls" },
4597 { 568, "GE Measurement and Control Solutions Advanced Sensors" },
4598 { 569, "EQUAL Networks" },
4599 { 570, "Millennial Net" },
4600 { 571, "APLI Ltd" },
4601 { 572, "Electro Industries/GaugeTech" },
4602 { 573, "SangMyung University" },
4603 { 574, "Coppertree Analytics, Inc." },
4604 { 575, "CoreNetiX GmbH" },
4605 { 576, "Acutherm" },
4606 { 577, "Dr. Riedel Automatisierungstechnik GmbH" },
4607 { 578, "Shina System Co., Ltd" },
4608 { 579, "Iqapertus" },
4609 { 580, "PSE Technology" },
4610 { 581, "BA Systems" },
4612 { 583, "Monico, Inc." },
4614 { 585, "tekmar Control Systems Ltd." },
4615 { 586, "Control Technology Corporation" },
4616 { 587, "GFAE GmbH" },
4617 { 588, "BeKa Software GmbH" },
4618 { 589, "Isoil Industria SpA" },
4619 { 590, "Home Systems Consulting SpA" },
4621 { 592, "Everex Communications, Inc." },
4622 { 593, "Ceiec Electric Technology" },
4623 { 594, "Atrila GmbH" },
4624 { 595, "WingTechs" },
4625 { 596, "Shenzhen Mek Intellisys Pte Ltd." },
4626 { 597, "Nestfield Co., Ltd." },
4627 { 598, "Swissphone Telecom AG" },
4628 { 599, "PNTECH JSC" },
4629 { 600, "Horner APG, LLC" },
4630 { 601, "PVI Industries, LLC" },
4631 { 602, "Ela-compil" },
4632 { 603, "Pegasus Automation International LLC" },
4633 { 604, "Wight Electronic Services Ltd." },
4635 { 606, "Exhausto A/S" },
4636 { 607, "Dwyer Instruments, Inc." },
4637 { 608, "Link GmbH" },
4638 { 609, "Oppermann Regelgerate GmbH" },
4639 { 610, "NuAire, Inc." },
4640 { 611, "Nortec Humidity, Inc." },
4641 { 612, "Bigwood Systems, Inc." },
4642 { 613, "Enbala Power Networks" },
4643 { 614, "Inter Energy Co., Ltd." },
4645 { 616, "COMELEC S.A.R.L" },
4646 { 617, "Pythia Technologies" },
4647 { 618, "TrendPoint Systems, Inc." },
4650 { 621, "Kongsberg E-lon AS" },
4651 { 622, "FlaktWoods" },
4652 { 623, "E + E Elektronik GES M.B.H." },
4653 { 624, "ARC Informatique" },
4654 { 625, "SKIDATA AG" },
4655 { 626, "WSW Solutions" },
4656 { 627, "Trefon Electronic GmbH" },
4657 { 628, "Dongseo System" },
4658 { 629, "Kanontec Intelligence Technology Co., Ltd." },
4659 { 630, "EVCO S.p.A." },
4660 { 631, "Accuenergy (CANADA) Inc." },
4662 { 633, "Orion Energy Systems, Inc." },
4663 { 634, "Roboticsware" },
4664 { 635, "DOMIQ Sp. z o.o." },
4665 { 636, "Solidyne" },
4666 { 637, "Elecsys Corporation" },
4667 { 638, "Conditionaire International Pty. Limited" },
4668 { 639, "Quebec, Inc." },
4669 { 640, "Homerun Holdings" },
4670 { 641, "RFM, Inc." },
4672 { 643, "Westco Systems, Inc." },
4673 { 644, "Advancis Software & Services GmbH" },
4674 { 645, "Intergrid, LLC" },
4675 { 646, "Markerr Controls, Inc." },
4676 { 647, "Toshiba Elevator and Building Systems Corporation" },
4677 { 648, "Spectrum Controls, Inc." },
4678 { 649, "Mkservice" },
4679 { 650, "Fox Thermal Instruments" },
4680 { 651, "SyxthSense Ltd" },
4681 { 652, "DUHA System S R.O." },
4683 { 654, "Melink Corporation" },
4684 { 655, "Fritz-Haber-Institut" },
4685 { 656, "MTU Onsite Energy GmbH, Gas Power Systems" },
4686 { 657, "Omega Engineering, Inc." },
4688 { 659, "Ywire Technologies, Inc." },
4689 { 660, "M.R. Engineering Co., Ltd." },
4690 { 661, "Lochinvar, LLC" },
4691 { 662, "Sontay Limited" },
4692 { 663, "GRUPA Slawomir Chelminski" },
4693 { 664, "Arch Meter Corporation" },
4694 { 665, "Senva, Inc." },
4696 { 668, "Systems Specialists, Inc." },
4697 { 669, "SenseAir" },
4698 { 670, "AB IndustrieTechnik Srl" },
4699 { 671, "Cortland Research, LLC" },
4700 { 672, "MediaView" },
4701 { 673, "VDA Elettronica" },
4702 { 674, "CSS, Inc." },
4703 { 675, "Tek-Air Systems, Inc." },
4705 { 677, "The Armstrong Monitoring Corporation" },
4706 { 678, "DIXELL S.r.l" },
4707 { 679, "Lead System, Inc." },
4708 { 680, "ISM EuroCenter S.A." },
4710 { 682, "Trade FIDES" },
4711 { 683, "Knurr GmbH (Emerson Network Power)" },
4712 { 684, "Resource Data Management" },
4713 { 685, "Abies Technology, Inc." },
4715 { 687, "MIRAE Electrical Mfg. Co., Ltd." },
4716 { 688, "HunterDouglas Architectural Projects Scandinavia ApS" },
4717 { 689, "RUNPAQ Group Co., Ltd" },
4718 { 690, "Unicard SA" },
4719 { 691, "IE Technologies" },
4720 { 692, "Ruskin Manufacturing" },
4721 { 693, "Calon Associates Limited" },
4722 { 694, "Contec Co., Ltd." },
4724 { 696, "Autani Corporation"},
4725 { 697, "Christian Fortin"},
4727 { 699, "IPID Sp. Z.O.O Limited"},
4728 { 700, "Fuji Electric Co., Ltd"},
4729 { 701, "View, Inc."},
4730 { 702, "Samsung S1 Corporation"},
4732 { 704, "VRT Systems"},
4735 static value_string_ext BACnetVendorIdentifiers_ext = VALUE_STRING_EXT_INIT(BACnetVendorIdentifiers);
4737 static int proto_bacapp = -1;
4738 static int hf_bacapp_type = -1;
4739 static int hf_bacapp_pduflags = -1;
4740 static int hf_bacapp_SEG = -1;
4741 static int hf_bacapp_MOR = -1;
4742 static int hf_bacapp_SA = -1;
4743 static int hf_bacapp_response_segments = -1;
4744 static int hf_bacapp_max_adpu_size = -1;
4745 static int hf_bacapp_invoke_id = -1;
4746 static int hf_bacapp_objectType = -1;
4747 static int hf_bacapp_instanceNumber = -1;
4748 static int hf_bacapp_sequence_number = -1;
4749 static int hf_bacapp_window_size = -1;
4750 static int hf_bacapp_service = -1;
4751 static int hf_bacapp_NAK = -1;
4752 static int hf_bacapp_SRV = -1;
4753 static int hf_Device_Instance_Range_Low_Limit = -1;
4754 static int hf_Device_Instance_Range_High_Limit = -1;
4755 static int hf_BACnetRejectReason = -1;
4756 static int hf_BACnetAbortReason = -1;
4757 static int hf_BACnetApplicationTagNumber = -1;
4758 static int hf_BACnetContextTagNumber = -1;
4759 static int hf_BACnetExtendedTagNumber = -1;
4760 static int hf_BACnetNamedTag = -1;
4761 static int hf_BACnetTagClass = -1;
4762 static int hf_BACnetCharacterSet = -1;
4763 static int hf_bacapp_tag_lvt = -1;
4764 static int hf_bacapp_tag_ProcessId = -1;
4765 static int hf_bacapp_uservice = -1;
4766 static int hf_BACnetPropertyIdentifier = -1;
4767 static int hf_BACnetVendorIdentifier = -1;
4768 static int hf_BACnetRestartReason = -1;
4769 static int hf_bacapp_tag_IPV4 = -1;
4770 static int hf_bacapp_tag_IPV6 = -1;
4771 static int hf_bacapp_tag_PORT = -1;
4772 /* some more variables for segmented messages */
4773 static int hf_msg_fragments = -1;
4774 static int hf_msg_fragment = -1;
4775 static int hf_msg_fragment_overlap = -1;
4776 static int hf_msg_fragment_overlap_conflicts = -1;
4777 static int hf_msg_fragment_multiple_tails = -1;
4778 static int hf_msg_fragment_too_long_fragment = -1;
4779 static int hf_msg_fragment_error = -1;
4780 static int hf_msg_fragment_count = -1;
4781 static int hf_msg_reassembled_in = -1;
4782 static int hf_msg_reassembled_length = -1;
4784 static gint ett_msg_fragment = -1;
4785 static gint ett_msg_fragments = -1;
4787 static gint ett_bacapp = -1;
4788 static gint ett_bacapp_control = -1;
4789 static gint ett_bacapp_tag = -1;
4790 static gint ett_bacapp_list = -1;
4791 static gint ett_bacapp_value = -1;
4793 static expert_field ei_bacapp_bad_length = EI_INIT;
4795 static gint32 propertyIdentifier = -1;
4796 static gint32 propertyArrayIndex = -1;
4797 static guint32 object_type = 4096;
4799 static guint8 bacapp_flags = 0;
4800 static guint8 bacapp_seq = 0;
4802 /* Defined to allow vendor identifier registration of private transfer dissectors */
4803 static dissector_table_t bacapp_dissector_table;
4806 /* Stat: BACnet Packets sorted by IP */
4807 bacapp_info_value_t bacinfo;
4809 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
4810 static const gchar* st_str_packets_by_ip_dst = "By Destination";
4811 static const gchar* st_str_packets_by_ip_src = "By Source";
4812 static int st_node_packets_by_ip = -1;
4813 static int st_node_packets_by_ip_dst = -1;
4814 static int st_node_packets_by_ip_src = -1;
4817 bacapp_packet_stats_tree_init(stats_tree* st)
4819 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4820 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4821 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4825 bacapp_get_address_label(const char *tag, address *addr)
4827 gchar *addr_str, *label_str;
4829 addr_str = address_to_str(NULL, addr);
4830 label_str = wmem_strconcat(NULL, tag, addr_str, NULL);
4831 wmem_free(NULL, addr_str);
4836 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4838 int packets_for_this_dst;
4839 int packets_for_this_src;
4840 int service_for_this_dst;
4841 int service_for_this_src;
4842 int src_for_this_dst;
4843 int dst_for_this_src;
4844 int objectid_for_this_dst;
4845 int objectid_for_this_src;
4846 int instanceid_for_this_dst;
4847 int instanceid_for_this_src;
4850 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4852 srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
4853 dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
4855 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4856 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4857 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4858 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4859 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4860 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4861 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4862 if (binfo->service_type) {
4863 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4864 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4865 if (binfo->object_ident) {
4866 instanceid_for_this_dst = tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4867 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4868 instanceid_for_this_src = tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4869 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4873 wmem_free(NULL, srcstr);
4874 wmem_free(NULL, dststr);
4879 /* Stat: BACnet Packets sorted by Service */
4880 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4881 static int st_node_packets_by_service = -1;
4884 bacapp_service_stats_tree_init(stats_tree* st)
4886 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4890 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4899 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4901 srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
4902 dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
4904 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4905 if (binfo->service_type) {
4906 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4907 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4908 dst = tick_stat_node(st, dststr, src, TRUE);
4909 if (binfo->object_ident) {
4910 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4911 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4915 wmem_free(NULL, srcstr);
4916 wmem_free(NULL, dststr);
4921 /* Stat: BACnet Packets sorted by Object Type */
4922 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
4923 static int st_node_packets_by_objectid = -1;
4926 bacapp_objectid_stats_tree_init(stats_tree* st)
4928 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
4932 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4940 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4942 srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
4943 dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
4945 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
4946 if (binfo->object_ident) {
4947 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
4948 src = tick_stat_node(st, srcstr, objectid, TRUE);
4949 dst = tick_stat_node(st, dststr, src, TRUE);
4950 if (binfo->service_type) {
4951 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4952 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
4956 wmem_free(NULL, srcstr);
4957 wmem_free(NULL, dststr);
4962 /* Stat: BACnet Packets sorted by Instance No */
4963 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
4964 static int st_node_packets_by_instanceid = -1;
4967 bacapp_instanceid_stats_tree_init(stats_tree* st)
4969 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
4973 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4981 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4983 srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
4984 dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
4986 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
4987 if (binfo->object_ident) {
4988 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
4989 src = tick_stat_node(st, srcstr, instanceid, TRUE);
4990 dst = tick_stat_node(st, dststr, src, TRUE);
4991 if (binfo->service_type) {
4992 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4993 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
4997 wmem_free(NULL, srcstr);
4998 wmem_free(NULL, dststr);
5004 /* register all BACnet Ststistic trees */
5006 register_bacapp_stat_trees(void)
5008 stats_tree_register("bacapp", "bacapp_ip", "BACnet/Packets sorted by IP", 0,
5009 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
5010 stats_tree_register("bacapp", "bacapp_service", "BACnet/Packets sorted by Service", 0,
5011 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
5012 stats_tree_register("bacapp", "bacapp_objectid", "BACnet/Packets sorted by Object Type", 0,
5013 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
5014 stats_tree_register("bacapp", "bacapp_instanceid", "BACnet/Packets sorted by Instance ID", 0,
5015 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
5018 /* 'data' must be ep_ allocated */
5020 updateBacnetInfoValue(gint whichval, const gchar *data)
5022 if (whichval == BACINFO_SERVICE) {
5023 bacinfo.service_type = data;
5026 if (whichval == BACINFO_INVOKEID) {
5027 bacinfo.invoke_id = data;
5030 if (whichval == BACINFO_OBJECTID) {
5031 bacinfo.object_ident = data;
5034 if (whichval == BACINFO_INSTANCEID) {
5035 bacinfo.instance_ident = data;
5041 static const fragment_items msg_frag_items = {
5042 /* Fragment subtrees */
5045 /* Fragment fields */
5048 &hf_msg_fragment_overlap,
5049 &hf_msg_fragment_overlap_conflicts,
5050 &hf_msg_fragment_multiple_tails,
5051 &hf_msg_fragment_too_long_fragment,
5052 &hf_msg_fragment_error,
5053 &hf_msg_fragment_count,
5054 /* Reassembled in field */
5055 &hf_msg_reassembled_in,
5056 /* Reassembled length field */
5057 &hf_msg_reassembled_length,
5058 /* Reassembled data field */
5065 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
5066 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
5067 static const guint MaxAPDUSize [] = { 50, 128, 206, 480, 1024, 1476 };
5070 fGetMaxAPDUSize(guint8 idx)
5072 /* only 16 values are defined, so use & 0x0f */
5073 /* check the size of the Array, deliver either the entry
5074 or the first entry if idx is outside of the array (bug 3736 comment#7) */
5076 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
5077 return MaxAPDUSize[0];
5079 return MaxAPDUSize[idx & 0x0f];
5084 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
5085 const char *fmt, const char *split_fmt)
5087 G_GNUC_PRINTF(5, 0);
5089 /* Used when there are ranges of reserved and proprietary enumerations */
5091 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
5092 const char *fmt, const char *split_fmt)
5094 if (val < split_val)
5095 return val_to_str(val, vs, fmt);
5097 return val_to_str(val, vs, split_fmt);
5100 /* from clause 20.2.1.3.2 Constructed Data */
5101 /* returns true if the extended value is used */
5103 tag_is_extended_value(guint8 tag)
5105 return (tag & 0x07) == 5;
5109 tag_is_opening(guint8 tag)
5111 return (tag & 0x07) == 6;
5115 tag_is_closing(guint8 tag)
5117 return (tag & 0x07) == 7;
5120 /* from clause 20.2.1.1 Class
5121 class bit shall be one for context specific tags */
5122 /* returns true if the tag is context specific */
5124 tag_is_context_specific(guint8 tag)
5126 return (tag & 0x08) != 0;
5130 tag_is_extended_tag_number(guint8 tag)
5132 return ((tag & 0xF0) == 0xF0);
5136 object_id_type(guint32 object_identifier)
5138 return ((object_identifier >> 22) & 0x3FF);
5142 object_id_instance(guint32 object_identifier)
5144 return (object_identifier & 0x3FFFFF);
5148 fTagNo(tvbuff_t *tvb, guint offset)
5150 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
5154 fUnsigned32(tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
5156 gboolean valid = TRUE;
5160 *val = tvb_get_guint8(tvb, offset);
5163 *val = tvb_get_ntohs(tvb, offset);
5166 *val = tvb_get_ntoh24(tvb, offset);
5169 *val = tvb_get_ntohl(tvb, offset);
5180 fUnsigned64(tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
5182 gboolean valid = FALSE;
5186 if (lvt && (lvt <= 8)) {
5188 for (i = 0; i < lvt; i++) {
5189 data = tvb_get_guint8(tvb, offset+i);
5190 value = (value << 8) + data;
5198 /* BACnet Signed Value uses 2's complement notation, but with a twist:
5199 All signed integers shall be encoded in the smallest number of octets
5200 possible. That is, the first octet of any multi-octet encoded value
5201 shall not be X'00' if the most significant bit (bit 7) of the second
5202 octet is 0, and the first octet shall not be X'FF' if the most
5203 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
5205 fSigned64(tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
5207 gboolean valid = FALSE;
5212 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
5213 if (lvt && (lvt <= 7)) {
5215 data = tvb_get_guint8(tvb, offset);
5216 if ((data & 0x80) != 0)
5217 value = (-1 << 8) | data;
5220 for (i = 1; i < lvt; i++) {
5221 data = tvb_get_guint8(tvb, offset+i);
5222 value = (value << 8) + data;
5231 fTagHeaderTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5232 guint offset, guint8 *tag_no, guint8* tag_info, guint32 *lvt)
5234 proto_item *ti = NULL;
5238 guint lvt_len = 1; /* used for tree display of lvt */
5239 guint lvt_offset; /* used for tree display of lvt */
5241 lvt_offset = offset;
5242 tag = tvb_get_guint8(tvb, offset);
5246 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
5247 /* can mean open/close tag or length of 6/7 after the length is */
5248 /* computed below - store whole tag info, not just context bit. */
5249 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
5251 if (tag_is_extended_tag_number(tag)) {
5252 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
5254 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
5255 lvt_offset += tag_len;
5256 value = tvb_get_guint8(tvb, lvt_offset);
5258 if (value == 254) { /* length is encoded with 16 Bits */
5259 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
5262 } else if (value == 255) { /* length is encoded with 32 Bits */
5263 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
5271 proto_tree *subtree;
5272 if (tag_is_opening(tag))
5273 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
5274 else if (tag_is_closing(tag))
5275 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
5276 else if (tag_is_context_specific(tag)) {
5277 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
5278 "Context Tag: %u, Length/Value/Type: %u",
5281 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
5282 "Application Tag: %s, Length/Value/Type: %u",
5284 BACnetApplicationTagNumber,
5285 ASHRAE_Reserved_Fmt),
5288 /* details if needed */
5289 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5290 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
5291 if (tag_is_extended_tag_number(tag)) {
5292 proto_tree_add_uint_format(subtree,
5293 hf_BACnetContextTagNumber,
5294 tvb, offset, 1, tag,
5295 "Extended Tag Number");
5296 proto_tree_add_item(subtree,
5297 hf_BACnetExtendedTagNumber,
5298 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
5300 if (tag_is_context_specific(tag))
5301 proto_tree_add_item(subtree,
5302 hf_BACnetContextTagNumber,
5303 tvb, offset, 1, ENC_BIG_ENDIAN);
5305 proto_tree_add_item(subtree,
5306 hf_BACnetApplicationTagNumber,
5307 tvb, offset, 1, ENC_BIG_ENDIAN);
5309 if (tag_is_closing(tag) || tag_is_opening(tag))
5310 proto_tree_add_item(subtree,
5312 tvb, offset, 1, ENC_BIG_ENDIAN);
5313 else if (tag_is_extended_value(tag)) {
5314 proto_tree_add_item(subtree,
5316 tvb, offset, 1, ENC_BIG_ENDIAN);
5317 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
5318 tvb, lvt_offset, lvt_len, *lvt);
5320 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
5321 tvb, lvt_offset, lvt_len, *lvt);
5324 if (*lvt > tvb_length(tvb)) {
5325 expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
5326 "LVT length too long: %d > %d", *lvt,
5335 fTagHeader(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* tag_info,
5338 return fTagHeaderTree(tvb, pinfo, NULL, offset, tag_no, tag_info, lvt);
5342 fNullTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5344 guint8 tag_no, tag_info;
5346 proto_tree *subtree;
5348 subtree = proto_tree_add_subtree_format(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "%sNULL", label);
5349 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5355 fBooleanTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5357 guint8 tag_no, tag_info;
5359 proto_tree *subtree;
5362 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5363 if (tag_info && lvt == 1) {
5364 lvt = tvb_get_guint8(tvb, offset+1);
5368 subtree = proto_tree_add_subtree_format(tree, tvb, offset, bool_len,
5369 ett_bacapp_tag, NULL, "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
5370 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5372 return offset + bool_len;
5376 fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5379 guint8 tag_no, tag_info;
5382 proto_tree *subtree;
5384 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5385 /* only support up to an 8 byte (64-bit) integer */
5386 if (fUnsigned64(tvb, offset + tag_len, lvt, &val))
5387 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5388 ett_bacapp_tag, NULL, "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
5390 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5391 ett_bacapp_tag, NULL, "%s - %u octets (Unsigned)", label, lvt);
5392 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5394 return offset+tag_len+lvt;
5398 fDevice_Instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, int hf)
5400 guint8 tag_no, tag_info;
5401 guint32 lvt, safe_lvt;
5404 proto_tree *subtree;
5406 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5413 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, safe_lvt, ENC_BIG_ENDIAN);
5415 if (lvt != safe_lvt)
5416 expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
5417 "This field claims to be an impossible %u bytes, while the max is %u", lvt, safe_lvt);
5419 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5420 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5422 return offset+tag_len+lvt;
5425 /* set split_val to zero when not needed */
5427 fEnumeratedTagSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5428 guint offset, const gchar *label, const value_string *vs, guint32 split_val)
5431 guint8 tag_no, tag_info;
5434 proto_tree *subtree;
5436 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5437 /* only support up to a 4 byte (32-bit) enumeration */
5438 if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) {
5440 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5441 ett_bacapp_tag, NULL, "%s %s", label, val_to_split_str(val, split_val, vs,
5442 ASHRAE_Reserved_Fmt, Vendor_Proprietary_Fmt));
5444 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5445 ett_bacapp_tag, NULL, "%s %u", label, val);
5447 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5448 ett_bacapp_tag, NULL, "%s - %u octets (enumeration)", label, lvt);
5451 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5453 return offset+tag_len+lvt;
5457 fEnumeratedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5458 guint offset, const gchar *label, const value_string *vs)
5460 return fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, vs, 0);
5464 fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5467 guint8 tag_no, tag_info;
5470 proto_tree *subtree;
5472 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5473 if (fSigned64(tvb, offset + tag_len, lvt, &val))
5474 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5475 ett_bacapp_tag, NULL, "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
5477 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5478 ett_bacapp_tag, NULL, "%s - %u octets (Signed)", label, lvt);
5479 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5481 return offset+tag_len+lvt;
5485 fRealTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5487 guint8 tag_no, tag_info;
5491 proto_tree *subtree;
5493 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5494 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
5495 subtree = proto_tree_add_subtree_format(tree, tvb, offset, 4+tag_len,
5496 ett_bacapp_tag, NULL, "%s%f (Real)", label, f_val);
5497 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5499 return offset+tag_len+4;
5503 fDoubleTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5505 guint8 tag_no, tag_info;
5509 proto_tree *subtree;
5511 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5512 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
5513 subtree = proto_tree_add_subtree_format(tree, tvb, offset, 8+tag_len,
5514 ett_bacapp_tag, NULL, "%s%f (Double)", label, d_val);
5515 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5517 return offset+tag_len+8;
5521 fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5523 guint32 val = 0, lvt;
5524 guint8 tag_no, tag_info;
5526 proto_tree *subtree;
5529 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5530 if (fUnsigned32(tvb, offset+tag_len, lvt, &val))
5532 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
5533 tvb, offset, lvt+tag_len, val);
5534 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5538 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5539 ett_bacapp_tag, NULL, "Process Identifier - %u octets (Signed)", lvt);
5541 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5542 offset += tag_len + lvt;
5548 fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5550 guint32 val = 0, lvt;
5551 guint8 tag_no, tag_info;
5552 proto_tree *subtree;
5555 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5556 if (fUnsigned32(tvb, offset+tag_len, lvt, &val))
5557 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5558 ett_bacapp_tag, NULL,
5559 "%s (hh.mm.ss): %d.%02d.%02d%s",
5561 (val / 3600), ((val % 3600) / 60), (val % 60),
5562 val == 0 ? " (indefinite)" : "");
5564 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5565 ett_bacapp_tag, NULL,
5566 "%s - %u octets (Signed)", label, lvt);
5567 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5569 return offset+tag_len+lvt;
5573 fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5575 guint32 month, weekOfMonth, dayOfWeek;
5576 guint8 tag_no, tag_info;
5579 proto_tree *subtree;
5581 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5582 month = tvb_get_guint8(tvb, offset+tag_len);
5583 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
5584 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
5585 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5586 ett_bacapp_tag, NULL, "%s %s, %s",
5587 val_to_str(month, months, "month (%d) not found"),
5588 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
5589 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
5590 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5592 return offset+tag_len+lvt;
5596 fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5598 guint32 year, month, day, weekday;
5599 guint8 tag_no, tag_info;
5602 proto_tree *subtree;
5604 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5605 year = tvb_get_guint8(tvb, offset+tag_len);
5606 month = tvb_get_guint8(tvb, offset+tag_len+1);
5607 day = tvb_get_guint8(tvb, offset+tag_len+2);
5608 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
5609 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
5610 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5611 ett_bacapp_tag, NULL,
5614 else if (year != 255) {
5616 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5617 ett_bacapp_tag, NULL,
5618 "%s%s %d, %d, (Day of Week = %s)",
5619 label, val_to_str(month,
5621 "month (%d) not found"),
5622 day, year, val_to_str(weekday,
5626 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5627 ett_bacapp_tag, NULL,
5628 "%s%s %d, any year, (Day of Week = %s)",
5629 label, val_to_str(month, months, "month (%d) not found"),
5630 day, val_to_str(weekday, day_of_week, "(%d) not found"));
5632 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5634 return offset+tag_len+lvt;
5638 fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5640 guint32 hour, minute, second, msec, lvt;
5641 guint8 tag_no, tag_info;
5643 proto_tree *subtree;
5645 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5646 hour = tvb_get_guint8(tvb, offset+tag_len);
5647 minute = tvb_get_guint8(tvb, offset+tag_len+1);
5648 second = tvb_get_guint8(tvb, offset+tag_len+2);
5649 msec = tvb_get_guint8(tvb, offset+tag_len+3);
5650 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
5651 subtree = proto_tree_add_subtree_format(tree, tvb, offset,
5652 lvt+tag_len, ett_bacapp_tag, NULL,
5655 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5656 ett_bacapp_tag, NULL,
5657 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
5659 hour > 12 ? hour - 12 : hour,
5660 minute, second, msec,
5661 hour >= 12 ? "P.M." : "A.M.",
5662 hour, minute, second, msec);
5663 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5665 return offset+tag_len+lvt;
5669 fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5671 proto_tree *subtree = tree;
5673 if (label != NULL) {
5674 subtree = proto_tree_add_subtree(subtree, tvb, offset, 10, ett_bacapp_value, NULL, label);
5676 offset = fDate(tvb, pinfo, subtree, offset, "Date: ");
5677 return fTime(tvb, pinfo, subtree, offset, "Time: ");
5681 fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5683 guint lastoffset = 0;
5684 guint8 tag_no, tag_info;
5687 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5688 lastoffset = offset;
5689 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5690 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
5693 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
5694 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
5696 if (offset == lastoffset) break; /* exit loop if nothing happens inside */
5702 fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5704 guint8 tag_no, tag_info;
5707 switch (fTagNo(tvb, offset)) {
5709 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
5711 case 1: /* dateRange */
5712 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5713 offset = fDateRange(tvb, pinfo, tree, offset);
5714 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5716 case 2: /* BACnetWeekNDay */
5717 offset = fWeekNDay(tvb, pinfo, tree, offset);
5727 fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
5730 proto_tree* subtree = tree;
5732 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5733 subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventTimeStamps");
5735 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: ");
5736 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: ");
5737 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: ");
5743 fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5745 guint8 tag_no = 0, tag_info = 0;
5748 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
5749 switch (fTagNo(tvb, offset)) {
5751 offset = fTime(tvb, pinfo, tree, offset, label?label:"time: ");
5753 case 1: /* sequenceNumber */
5754 offset = fUnsignedTag(tvb, pinfo, tree, offset,
5755 label?label:"sequence number: ");
5757 case 2: /* dateTime */
5758 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5759 offset = fDateTime(tvb, pinfo, tree, offset, label?label:"date time: ");
5760 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5772 fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5774 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5775 offset = fApplicationTypes(tvb, pinfo, tree, offset, "increment: ");
5780 static const value_string
5781 BACnetDaysOfWeek [] = {
5793 fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5795 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5796 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
5797 "valid Days: ", BACnetDaysOfWeek);
5798 offset = fTime(tvb, pinfo, tree, offset, "from time: ");
5799 offset = fTime(tvb, pinfo, tree, offset, "to time: ");
5800 offset = fRecipient(tvb, pinfo, tree, offset);
5801 offset = fProcessId(tvb, pinfo, tree, offset);
5802 offset = fApplicationTypes(tvb, pinfo, tree, offset,
5803 "issue confirmed notifications: ");
5804 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
5805 "transitions: ", BACnetEventTransitionBits);
5812 fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5815 guint start = offset;
5816 guint8 tag_no, tag_info;
5817 proto_tree *subtree = tree;
5819 offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5822 tmp = tvb_bytes_to_ep_str(tvb, offset, lvt);
5823 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt,
5824 ett_bacapp_tag, NULL, "%s %s", label, tmp);
5828 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5834 fMacAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5836 guint start = offset;
5837 guint8 tag_no, tag_info;
5838 proto_tree* subtree = tree;
5840 offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5842 subtree = proto_tree_add_subtree(tree, tvb, offset, 6, ett_bacapp_tag, NULL, label); /* just add the label, with the tagHeader information in its subtree */
5845 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
5847 proto_tree_add_item(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ENC_BIG_ENDIAN);
5848 proto_tree_add_item(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, ENC_BIG_ENDIAN);
5851 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
5853 proto_tree_add_item(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, ENC_NA);
5854 proto_tree_add_item(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, ENC_BIG_ENDIAN);
5856 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
5857 subtree = proto_tree_add_subtree(tree, tvb, offset, lvt,
5858 ett_bacapp_tag, NULL, tvb_bytes_to_ep_str(tvb, offset, lvt));
5864 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5870 fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5872 guint8 tag_no, tag_info;
5876 offset = fUnsignedTag(tvb, pinfo, tree, offset, "network-number");
5877 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5879 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5882 offset = fMacAddress(tvb, pinfo, tree, offset, "MAC-address: ", lvt);
5888 fSessionKey(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5890 offset = fOctetString(tvb, pinfo, tree, offset, "session key: ", 8);
5891 return fAddress(tvb, pinfo, tree, offset);
5895 fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5897 guint8 tag_no, tag_info;
5900 proto_tree *subtree;
5903 tag_length = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5904 object_id = tvb_get_ntohl(tvb, offset+tag_length);
5905 object_type = object_id_type(object_id);
5906 subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_length + 4,
5907 ett_bacapp_tag, NULL, "ObjectIdentifier: %s, %u",
5908 val_to_split_str(object_type,
5911 ASHRAE_Reserved_Fmt,
5912 Vendor_Proprietary_Fmt),
5913 object_id_instance(object_id));
5915 if (col_get_writable(pinfo->cinfo))
5916 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5917 val_to_split_str(object_type,
5920 ASHRAE_Reserved_Fmt,
5921 Vendor_Proprietary_Fmt),
5922 object_id_instance(object_id));
5924 /* update BACnet Statistics */
5925 updateBacnetInfoValue(BACINFO_OBJECTID,
5926 wmem_strdup(wmem_packet_scope(),
5927 val_to_split_str(object_type, 128,
5928 BACnetObjectType, ASHRAE_Reserved_Fmt,
5929 Vendor_Proprietary_Fmt)));
5930 updateBacnetInfoValue(BACINFO_INSTANCEID,
5931 wmem_strdup_printf(wmem_packet_scope(),
5933 object_id_instance(object_id)));
5935 /* here are the details of how we arrived at the above text */
5936 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5937 offset += tag_length;
5938 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
5939 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
5946 fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5948 guint8 tag_no, tag_info;
5951 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5953 if (tag_no == 0) { /* device */
5954 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
5956 else { /* address */
5957 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5958 offset = fAddress(tvb, pinfo, tree, offset);
5959 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5966 fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5968 guint lastoffset = 0;
5969 guint8 tag_no, tag_info;
5971 proto_tree *orgtree = tree;
5972 proto_tree *subtree;
5974 /* beginning of new item - indent and label */
5975 tree = proto_tree_add_subtree(orgtree, tvb, offset, 1, ett_bacapp_value, NULL, "Recipient Process" );
5977 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5978 lastoffset = offset;
5980 switch (fTagNo(tvb, offset)) {
5981 case 0: /* recipient */
5982 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5983 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "Recipient"); /* add tree label and indent */
5984 offset = fRecipient(tvb, pinfo, subtree, offset);
5985 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5987 case 1: /* processId */
5988 offset = fProcessId(tvb, pinfo, tree, offset);
5989 lastoffset = offset;
5994 if (offset == lastoffset) break; /* nothing happened, exit loop */
6000 fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6002 guint lastoffset = 0;
6003 guint8 tag_no, tag_info;
6005 proto_tree *subtree;
6006 proto_tree *orgtree = tree;
6009 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6010 lastoffset = offset;
6011 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6012 if (tag_is_closing(tag_info) ) {
6017 case 0: /* recipient */
6018 /* beginning of new item in list */
6019 tree = proto_tree_add_subtree_format(orgtree, tvb, offset, 1,
6020 ett_bacapp_value, NULL, "Subscription %d",itemno); /* add tree label and indent */
6021 itemno = itemno + 1;
6023 subtree = proto_tree_add_subtree(tree, tvb, offset, 1,
6024 ett_bacapp_value, NULL, "Recipient"); /* add tree label and indent */
6025 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
6026 offset = fRecipientProcess(tvb, pinfo, subtree, offset);
6027 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
6029 case 1: /* MonitoredPropertyReference */
6030 subtree = proto_tree_add_subtree(tree, tvb, offset, 1,
6031 ett_bacapp_value, NULL, "Monitored Property Reference");
6032 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6033 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
6034 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6036 case 2: /* IssueConfirmedNotifications - boolean */
6037 offset = fBooleanTag(tvb, pinfo, tree, offset, "Issue Confirmed Notifications: ");
6039 case 3: /* TimeRemaining */
6040 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Time Remaining: ");
6042 case 4: /* COVIncrement */
6043 offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
6048 if (offset == lastoffset) break; /* nothing happened, exit loop */
6054 fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6056 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
6057 return fAddress(tvb, pinfo, tree, offset);
6061 fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
6063 guint lastoffset = 0, len;
6064 guint8 tag_no, tag_info;
6066 proto_tree *subtree = tree;
6068 /* set the optional global properties to indicate not-used */
6069 propertyArrayIndex = -1;
6070 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6071 lastoffset = offset;
6072 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6073 if (tag_is_closing(tag_info) ) {
6074 if (tag_no == tag_match) {
6083 case 0: /* deviceIdentifier */
6084 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
6086 case 1: /* objectIdentifier */
6087 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
6089 case 2: /* propertyIdentifier */
6090 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
6092 case 3: /* propertyArrayIndex */
6093 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
6095 case 4: /* propertyValue */
6096 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
6098 case 5: /* priority */
6099 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
6101 case 6: /* postDelay */
6102 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Post Delay: ");
6104 case 7: /* quitOnFailure */
6105 offset = fBooleanTag(tvb, pinfo, subtree, offset,
6106 "Quit On Failure: ");
6108 case 8: /* writeSuccessful */
6109 offset = fBooleanTag(tvb, pinfo, subtree, offset,
6110 "Write Successful: ");
6115 if (offset == lastoffset) break; /* nothing happened, exit loop */
6120 /* BACnetActionList ::= SEQUENCE{
6121 action [0] SEQUENCE OF BACnetActionCommand
6125 fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6127 guint lastoffset = 0, len;
6128 guint8 tag_no, tag_info;
6130 proto_tree *subtree = tree;
6132 while (tvb_reported_length_remaining(tvb, offset) > 0) {
6133 lastoffset = offset;
6134 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6135 if (tag_is_closing(tag_info)) {
6137 if ( tag_no != 0 ) /* don't eat the closing property tag, just return */
6142 if (tag_is_opening(tag_info)) {
6143 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "Action List");
6144 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
6145 &tag_no, &tag_info, &lvt);
6148 case 0: /* BACnetActionCommand */
6149 offset = fActionCommand(tvb, pinfo, subtree, offset, tag_no);
6154 if (offset == lastoffset) break; /* nothing happened, exit loop */
6160 fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6162 guint8 tag_no, tag_info;
6165 proto_tree *subtree;
6166 const gchar *label = "Property Identifier";
6168 propertyIdentifier = 0; /* global Variable */
6169 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6170 /* can we decode this value? */
6171 if (fUnsigned32(tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
6172 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
6173 ett_bacapp_tag, NULL,
6174 "%s: %s (%u)", label,
6175 val_to_split_str(propertyIdentifier, 512,
6176 BACnetPropertyIdentifier,
6177 ASHRAE_Reserved_Fmt,
6178 Vendor_Proprietary_Fmt), propertyIdentifier);
6179 if (col_get_writable(pinfo->cinfo))
6180 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
6181 val_to_split_str(propertyIdentifier, 512,
6182 BACnetPropertyIdentifier,
6183 ASHRAE_Reserved_Fmt,
6184 Vendor_Proprietary_Fmt));
6186 /* property identifiers cannot be larger than 22-bits */
6190 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6191 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
6192 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6194 return offset+tag_len+lvt;
6198 fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6200 guint8 tag_no, tag_info;
6203 proto_tree *subtree;
6205 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6206 if (fUnsigned32(tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
6207 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
6208 ett_bacapp_tag, NULL, "property Array Index (Unsigned) %u", propertyArrayIndex);
6210 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
6211 ett_bacapp_tag, NULL, "property Array Index - %u octets (Unsigned)", lvt);
6212 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6214 return offset+tag_len+lvt;
6218 fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6220 guint8 tag_no, tag_info, character_set;
6222 guint offs, extra = 1;
6225 proto_tree *subtree;
6226 guint start = offset;
6228 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6230 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6232 character_set = tvb_get_guint8(tvb, offset+offs);
6233 /* Account for code page if DBCS */
6234 if (character_set == 1) {
6237 offset += (offs+extra);
6243 * XXX - are we guaranteed that these encoding
6244 * names correspond, on *all* platforms with
6245 * iconv(), to the encodings we want?
6246 * If not (and perhaps even if so), we should
6247 * perhaps have our own iconv() implementation,
6248 * with a different name, so that we control the
6249 * encodings it supports and the names of those
6252 * We should also handle that in the general
6253 * string handling code, rather than making it
6254 * specific to the BACAPP dissector, as many
6255 * other dissectors need to handle various
6256 * character encodings.
6258 /** this decoding may be not correct for multi-byte characters, Lka */
6259 switch (character_set) {
6261 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UTF_8);
6265 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
6266 coding = "IBM MS DBCS";
6269 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
6270 coding = "JIS C 6226";
6272 case ISO_10646_UCS4:
6273 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UCS_4|ENC_BIG_ENDIAN);
6274 coding = "ISO 10646 UCS-4";
6276 case ISO_10646_UCS2:
6277 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UCS_2|ENC_BIG_ENDIAN);
6278 coding = "ISO 10646 UCS-2";
6281 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ISO_8859_1);
6282 coding = "ISO 8859-1";
6285 /* Assume this is some form of extended ASCII, with one-byte code points for ASCII characters */
6286 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
6290 subtree = proto_tree_add_subtree_format(tree, tvb, offset, l, ett_bacapp_tag, NULL,
6291 "%s%s '%s'", label, coding, out);
6296 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6297 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
6299 if (character_set == 1) {
6300 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
6302 /* XXX - put the string value here */
6308 fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
6309 const value_string *src)
6311 guint8 tag_no, tag_info, tmp;
6312 gint j, unused, skip;
6313 guint start = offset;
6315 guint32 lvt, i, numberOfBytes;
6317 proto_tree* subtree = tree;
6319 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6320 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
6322 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
6323 subtree = proto_tree_add_subtree_format(tree, tvb, start, offs+lvt,
6324 ett_bacapp_tag, NULL,
6325 "%s(Bit String)", label);
6327 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6328 proto_tree_add_text(subtree, tvb, offset, 1,
6329 "Unused bits: %u", unused);
6330 memset(bf_arr, 0, 256);
6332 for (i = 0; i < numberOfBytes; i++) {
6333 tmp = tvb_get_guint8(tvb, (offset)+i+1);
6334 if (i == numberOfBytes-1) { skip = unused; }
6335 for (j = 0; j < 8-skip; j++) {
6337 if (tmp & (1 << (7 - j)))
6338 proto_tree_add_text(subtree, tvb,
6341 val_to_str((guint) (i*8 +j),
6343 ASHRAE_Reserved_Fmt));
6345 proto_tree_add_text(subtree, tvb,
6348 val_to_str((guint) (i*8 +j),
6350 ASHRAE_Reserved_Fmt));
6352 bf_arr[MIN(255, (i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
6358 bf_arr[MIN(255, numberOfBytes*8-unused)] = 0;
6359 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
6368 fBitStringTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6370 return fBitStringTagVS(tvb, pinfo, tree, offset, label, NULL);
6373 /* handles generic application types, as well as enumerated and enumerations
6374 with reserved and proprietarty ranges (split) */
6376 fApplicationTypesEnumeratedSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6377 const gchar *label, const value_string *src, guint32 split_val)
6379 guint8 tag_no, tag_info;
6383 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6385 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6386 if (!tag_is_context_specific(tag_info)) {
6388 case 0: /** NULL 20.2.2 */
6389 offset = fNullTag(tvb, pinfo, tree, offset, label);
6391 case 1: /** BOOLEAN 20.2.3 */
6392 offset = fBooleanTag(tvb, pinfo, tree, offset, label);
6394 case 2: /** Unsigned Integer 20.2.4 */
6395 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
6397 case 3: /** Signed Integer 20.2.5 */
6398 offset = fSignedTag(tvb, pinfo, tree, offset, label);
6400 case 4: /** Real 20.2.6 */
6401 offset = fRealTag(tvb, pinfo, tree, offset, label);
6403 case 5: /** Double 20.2.7 */
6404 offset = fDoubleTag(tvb, pinfo, tree, offset, label);
6406 case 6: /** Octet String 20.2.8 */
6407 offset = fOctetString(tvb, pinfo, tree, offset, label, lvt);
6409 case 7: /** Character String 20.2.9 */
6410 offset = fCharacterString(tvb, pinfo, tree, offset, label);
6412 case 8: /** Bit String 20.2.10 */
6413 offset = fBitStringTagVS(tvb, pinfo, tree, offset, label, src);
6415 case 9: /** Enumerated 20.2.11 */
6416 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, src, split_val);
6418 case 10: /** Date 20.2.12 */
6419 offset = fDate(tvb, pinfo, tree, offset, label);
6421 case 11: /** Time 20.2.13 */
6422 offset = fTime(tvb, pinfo, tree, offset, label);
6424 case 12: /** BACnetObjectIdentifier 20.2.14 */
6425 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
6427 case 13: /* reserved for ASHRAE */
6430 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
6431 offset += lvt + tag_len;
6443 fShedLevel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6445 guint lastoffset = 0;
6447 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6448 lastoffset = offset;
6450 switch (fTagNo(tvb, offset)) {
6451 case 0: /* percent */
6452 offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed percent: ");
6455 offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed level: ");
6457 case 2: /* amount */
6458 offset = fRealTag(tvb, pinfo, tree, offset, "shed amount: ");
6463 if (offset == lastoffset) break; /* nothing happened, exit loop */
6469 fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6470 const gchar *label, const value_string *vs)
6472 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
6476 fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6479 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
6483 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6485 guint8 tag_no, tag_info;
6488 proto_tree *subtree;
6492 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6493 /* cap the the suggested length in case of bad data */
6494 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
6495 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
6498 subtree = proto_tree_add_subtree_format(tree, tvb, offset+tag_len, lvt,
6499 ett_bacapp_tag, NULL, "Context Value (as %u DATA octets)", lvt);
6501 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6503 return offset + tag_len + lvt;
6506 BACnetPrescale ::= SEQUENCE {
6507 multiplier [0] Unsigned,
6508 moduloDivide [1] Unsigned
6512 fPrescale(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6514 guint8 tag_no, tag_info;
6516 guint lastoffset = 0;
6518 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6519 lastoffset = offset;
6520 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6521 if (tag_is_closing(tag_info) ) {
6525 case 0: /* multiplier */
6526 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Multiplier: ");
6528 case 1: /* moduloDivide */
6529 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Modulo Divide: ");
6534 if (offset == lastoffset) break; /* nothing happened, exit loop */
6540 BACnetScale ::= CHOICE {
6541 floatScale [0] REAL,
6542 integerScale [1] INTEGER
6546 fScale(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6548 guint8 tag_no, tag_info;
6550 guint lastoffset = 0;
6552 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6553 lastoffset = offset;
6554 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6555 if (tag_is_closing(tag_info) ) {
6559 case 0: /* floatScale */
6560 offset = fRealTag(tvb, pinfo, tree, offset, "Float Scale: ");
6562 case 1: /* integerScale */
6563 offset = fSignedTag(tvb, pinfo, tree, offset, "Integer Scale: ");
6568 if (offset == lastoffset) break; /* nothing happened, exit loop */
6573 BACnetAccumulatorRecord ::= SEQUENCE {
6574 timestamp [0] BACnetDateTime,
6575 presentValue [1] Unsigned,
6576 accumulatedValue [2] Unsigned,
6577 accumulatortStatus [3] ENUMERATED {
6587 fLoggingRecord(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6589 guint8 tag_no, tag_info;
6591 guint lastoffset = 0;
6593 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6594 lastoffset = offset;
6595 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6596 if (tag_is_closing(tag_info) ) {
6600 case 0: /* timestamp */
6601 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6602 offset = fDateTime(tvb, pinfo, tree, offset, "Timestamp: ");
6603 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6605 case 1: /* presentValue */
6606 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Present Value: ");
6608 case 2: /* accumulatedValue */
6609 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Accumulated Value: ");
6611 case 3: /* accumulatorStatus */
6612 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus);
6617 if (offset == lastoffset) break; /* nothing happened, exit loop */
6623 SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState
6626 fSequenceOfEnums(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, const value_string *vs)
6628 guint8 tag_no, tag_info;
6630 guint lastoffset = 0;
6632 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6633 lastoffset = offset;
6634 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6635 if (tag_is_closing(tag_info) ) {
6638 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs);
6639 if ( offset == lastoffset ) break;
6645 SEQ OF BACnetDeviceObjectReference (accessed as an array)
6649 fDoorMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6651 guint8 tag_no, tag_info;
6653 guint lastoffset = 0;
6655 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6656 lastoffset = offset;
6657 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6658 if (tag_is_closing(tag_info) ) {
6661 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6662 if (offset == lastoffset) break;
6668 SEQ OF ReadAccessSpecification
6671 fListOfGroupMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6673 guint8 tag_no, tag_info;
6675 guint lastoffset = 0;
6677 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6678 lastoffset = offset;
6679 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6680 if (tag_is_closing(tag_info) ) {
6683 offset = fReadAccessSpecification(tvb, pinfo, tree, offset);
6684 if ( offset == lastoffset ) break;
6690 fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6692 guint8 tag_no, tag_info;
6694 guint lastoffset = 0, depth = 0;
6696 guint32 save_object_type;
6698 if (propertyIdentifier >= 0) {
6699 g_snprintf(ar, sizeof(ar), "%s: ",
6700 val_to_split_str(propertyIdentifier, 512,
6701 BACnetPropertyIdentifier,
6702 ASHRAE_Reserved_Fmt,
6703 Vendor_Proprietary_Fmt));
6705 g_snprintf(ar, sizeof(ar), "Abstract Type: ");
6707 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6708 lastoffset = offset;
6709 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6710 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
6711 if (depth <= 0) return offset;
6714 /* Application Tags */
6715 switch (propertyIdentifier) {
6716 case 2: /* action */
6717 /* loop object is application tagged,
6718 command object is context tagged */
6719 if (tag_is_context_specific(tag_info)) {
6720 /* BACnetActionList */
6721 offset = fActionList(tvb, pinfo, tree, offset);
6724 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6728 case 30: /* BACnetAddressBinding */
6729 offset = fAddressBinding(tvb, pinfo, tree, offset);
6731 case 54: /* list of object property reference */
6732 offset = fLOPR(tvb, pinfo, tree, offset);
6734 case 55: /* list-of-session-keys */
6735 fSessionKey(tvb, pinfo, tree, offset);
6737 case 79: /* object-type */
6738 case 96: /* protocol-object-types-supported */
6739 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar,
6740 BACnetObjectType, 128);
6742 case 97: /* Protocol-Services-Supported */
6743 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6744 BACnetServicesSupported);
6746 case 102: /* recipient-list */
6747 offset = fDestination(tvb, pinfo, tree, offset);
6749 case 107: /* segmentation-supported */
6750 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6751 BACnetSegmentation);
6753 case 111: /* Status-Flags */
6754 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6757 case 112: /* System-Status */
6758 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6759 BACnetDeviceStatus);
6761 case 117: /* units */
6762 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6763 BACnetEngineeringUnits);
6765 case 87: /* priority-array -- accessed as a BACnetARRAY */
6766 if (propertyArrayIndex == 0) {
6767 /* BACnetARRAY index 0 refers to the length
6768 of the array, not the elements of the array */
6769 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6771 offset = fPriorityArray(tvb, pinfo, tree, offset);
6774 case 38: /* exception-schedule */
6775 if (object_type < 128) {
6776 if (propertyArrayIndex == 0) {
6777 /* BACnetARRAY index 0 refers to the length
6778 of the array, not the elements of the array */
6779 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6781 offset = fSpecialEvent(tvb, pinfo, tree, offset);
6785 case 19: /* controlled-variable-reference */
6786 case 60: /* manipulated-variable-reference */
6787 case 132: /* log-device-object-property */
6788 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
6790 case 109: /* Setpoint-Reference */
6791 /* setpoint-Reference is actually BACnetSetpointReference which is a SEQ of [0] */
6792 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6793 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
6794 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6796 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
6797 if (object_type < 128) {
6798 if (propertyArrayIndex == 0) {
6799 /* BACnetARRAY index 0 refers to the length
6800 of the array, not the elements of the array */
6801 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6803 offset = fWeeklySchedule(tvb, pinfo, tree, offset);
6807 case 127: /* client COV increment */
6808 offset = fClientCOV(tvb, pinfo, tree, offset);
6810 case 131: /* log-buffer */
6811 if ( object_type == 25 )
6812 offset = fEventLogRecord(tvb, pinfo, tree, offset);
6813 else if ( object_type == 27 )
6814 offset = fLogMultipleRecord(tvb, pinfo, tree, offset);
6816 offset = fLogRecord(tvb, pinfo, tree, offset);
6818 case 159: /* member-of */
6819 case 165: /* zone-members */
6820 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6822 case 196: /* last-restart-reason */
6823 offset = fRestartReason(tvb, pinfo, tree, offset);
6825 case 212: /* actual-shed-level */
6826 case 214: /* expected-shed-level */
6827 case 218: /* requested-shed-level */
6828 offset = fShedLevel(tvb, pinfo, tree, offset);
6830 case 152: /* active-cov-subscriptions */
6831 offset = fCOVSubscription(tvb, pinfo, tree, offset);
6833 case 23: /* date-list */
6834 offset = fCalendarEntry(tvb, pinfo, tree, offset);
6836 case 116: /* time-sychronization-recipients */
6837 offset = fRecipient(tvb, pinfo, tree, offset);
6839 case 83: /* event-parameters */
6840 offset = fEventParameter(tvb, pinfo, tree, offset);
6842 case 211: /* subordinate-list */
6843 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6845 case 130: /* event-time-stamp */
6846 offset = fEventTimeStamps(tvb, pinfo, tree, offset);
6848 case 197: /* logging-type */
6849 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType);
6851 case 36: /* event-state */
6852 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64);
6854 case 103: /* reliability */
6855 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability);
6857 case 72: /* notify-type */
6858 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNotifyType);
6860 case 208: /* node-type */
6861 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType);
6863 case 231: /* door-status */
6864 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus);
6866 case 233: /* lock-status */
6867 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus);
6869 case 235: /* secured-status */
6870 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus);
6872 case 158: /* maintenance-required */
6873 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance);
6875 case 92: /* program-state */
6876 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState);
6878 case 90: /* program-change */
6879 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest);
6881 case 100: /* reason-for-halt */
6882 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError);
6884 case 160: /* mode */
6885 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode);
6887 case 163: /* silenced */
6888 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState);
6890 case 161: /* operation-expected */
6891 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation);
6893 case 164: /* tracking-value */
6894 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState);
6896 case 41: /* file-access-method */
6897 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod);
6899 case 185: /* prescale */
6900 offset = fPrescale(tvb, pinfo, tree, offset);
6902 case 187: /* scale */
6903 offset = fScale(tvb, pinfo, tree, offset);
6905 case 184: /* logging-record */
6906 offset = fLoggingRecord(tvb, pinfo, tree, offset);
6908 case 228: /* door-members */
6909 offset = fDoorMembers(tvb, pinfo, tree, offset);
6911 case 181: /* input-reference */
6912 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6914 case 78: /* object-property-reference */
6915 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6917 case 234: /* masked-alarm-values */
6918 offset = fSequenceOfEnums(tvb, pinfo, tree, offset, "masked-alarm-value: ", BACnetDoorAlarmState);
6920 case 53: /* list-of-group-members */
6921 save_object_type = object_type;
6922 offset = fListOfGroupMembers(tvb, pinfo, tree, offset);
6923 object_type = save_object_type;
6925 case 85: /* present-value */
6926 if ( object_type == 11 ) /* group object handling of present-value */
6928 offset = fReadAccessResult(tvb, pinfo, tree, offset);
6931 /* intentially fall through here so don't reorder this case statement */
6934 if (tag_is_opening(tag_info)) {
6936 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6937 } else if (tag_is_closing(tag_info)) {
6939 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6941 offset = fContextTaggedValue(tvb, pinfo, tree, offset, ar);
6944 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6948 if (offset == lastoffset) break; /* nothing happened, exit loop */
6955 fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
6960 if (tag_is_opening(tag_info)) {
6961 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
6962 &tag_no, &tag_info, &lvt);
6963 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
6964 if (tvb_length_remaining(tvb, offset) > 0) {
6965 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
6966 &tag_no, &tag_info, &lvt);
6969 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
6970 "expected Opening Tag!");
6971 offset = tvb_length(tvb);
6979 fPropertyIdentifierValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
6981 guint lastoffset = offset;
6982 guint8 tag_no, tag_info;
6985 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
6986 if (offset > lastoffset) {
6987 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6988 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
6989 offset = fPropertyValue(tvb, pinfo, tree, offset, tag_info);
6996 fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6998 guint lastoffset = 0;
6999 guint8 tag_no, tag_info;
7002 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7003 lastoffset = offset;
7004 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
7005 if (offset > lastoffset) {
7006 /* detect optional priority
7007 by looking to see if the next tag is context tag number 3 */
7008 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7009 if (tag_is_context_specific(tag_info) && (tag_no == 3))
7010 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: ");
7012 if (offset == lastoffset) break; /* nothing happened, exit loop */
7018 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7020 guint lastoffset = 0, len;
7021 guint8 tag_no, tag_info;
7023 proto_tree *subtree = tree;
7025 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7026 lastoffset = offset;
7027 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7028 if (tag_is_closing(tag_info)) {
7035 case 0: /* ProcessId */
7036 offset = fUnsignedTag(tvb, pinfo, tree, offset, "subscriber Process Id: ");
7038 case 1: /* monitored ObjectId */
7039 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7041 case 2: /* issueConfirmedNotifications */
7042 offset = fBooleanTag(tvb, pinfo, tree, offset, "issue Confirmed Notifications: ");
7044 case 3: /* life time */
7045 offset = fTimeSpan(tvb, pinfo, tree, offset, "life time");
7047 case 4: /* monitoredPropertyIdentifier */
7048 if (tag_is_opening(tag_info)) {
7049 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "monitoredPropertyIdentifier");
7050 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7051 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
7056 case 5: /* covIncrement */
7057 offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
7062 if (offset == lastoffset) break; /* nothing happened, exit loop */
7068 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7070 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
7074 fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7076 guint lastoffset = 0;
7078 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7079 lastoffset = offset;
7081 switch (fTagNo(tvb, offset)) {
7082 case 0: /* deviceInstanceLowLimit */
7083 offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance Low Limit: ");
7085 case 1: /* deviceInstanceHighLimit */
7086 offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance High Limit: ");
7088 case 2: /* BACnetObjectId */
7089 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7091 case 3: /* messageText */
7092 offset = fCharacterString(tvb, pinfo, tree, offset, "Object Name: ");
7097 if (offset == lastoffset) break; /* nothing happened, exit loop */
7104 fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7106 guint lastoffset = 0;
7107 guint8 tag_no, tag_info;
7110 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7111 if (tag_is_opening(tag_info) && tag_no == 0) {
7112 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
7113 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7114 lastoffset = offset;
7115 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7116 if (tag_is_closing(tag_info)) {
7117 /* should be closing context tag 0 */
7118 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7122 offset = fTimeValue(tvb, pinfo, subtree, offset);
7123 if (offset == lastoffset) break; /* nothing happened, exit loop */
7125 } else if ((tag_no == 0) && (lvt == 0)) {
7126 /* not sure null (empty array element) is legal */
7127 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7133 fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7135 guint lastoffset = 0;
7136 guint8 tag_no, tag_info;
7138 guint i = 1; /* day of week array index */
7139 proto_tree *subtree = tree;
7141 if (propertyArrayIndex > 0) {
7142 /* BACnetARRAY index 0 refers to the length
7143 of the array, not the elements of the array.
7144 BACnetARRAY index -1 is our internal flag that
7145 the optional index was not used.
7146 BACnetARRAY refers to this as all elements of the array.
7147 If the optional index is specified for a BACnetARRAY,
7148 then that specific array element is referenced. */
7149 i = propertyArrayIndex;
7151 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7152 lastoffset = offset;
7153 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7154 if (tag_is_closing(tag_info)) {
7155 return offset; /* outer encoding will print out closing tag */
7157 subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_bacapp_value, NULL,
7158 val_to_str(i++, day_of_week, "day of week (%d) not found"));
7159 offset = fDailySchedule(tvb, pinfo, subtree, offset);
7160 if (offset == lastoffset) break; /* nothing happened, exit loop */
7167 fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7169 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7172 return fDateTime(tvb, pinfo, tree, offset, "UTC-Time: ");
7176 fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7178 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7181 return fDateTime(tvb, pinfo, tree, offset, NULL);
7185 fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7187 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7189 offset = fDate(tvb, pinfo, tree, offset, "Start Date: ");
7190 return fDate(tvb, pinfo, tree, offset, "End Date: ");
7194 fVendorIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7197 guint8 tag_no, tag_info;
7201 proto_tree *subtree;
7202 const gchar *label = "Vendor ID";
7204 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7205 if (fUnsigned32(tvb, offset + tag_len, lvt, &val))
7206 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7209 val_to_str_ext_const(val, &BACnetVendorIdentifiers_ext, "Unknown Vendor"),
7212 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7213 "%s - %u octets (Unsigned)", label, lvt);
7214 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7215 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7217 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
7218 proto_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
7219 "Wrong length indicated. Expected 1 or 2, got %u", lvt);
7220 return offset+tag_len+lvt;
7223 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
7224 offset+tag_len, lvt, ENC_BIG_ENDIAN);
7226 return offset+tag_len+lvt;
7230 fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7233 guint8 tag_no, tag_info;
7237 proto_tree *subtree;
7238 const gchar *label = "Restart Reason";
7240 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7241 if (fUnsigned32(tvb, offset + tag_len, lvt, &val))
7242 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7243 "%s: %s (%u)", label,
7244 val_to_str_const(val, BACnetRestartReason, "Unknown reason"), val);
7246 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7247 "%s - %u octets (Unsigned)", label, lvt);
7248 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7249 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7252 proto_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
7253 "Wrong length indicated. Expected 1, got %u", lvt);
7254 return offset+tag_len+lvt;
7257 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
7258 offset+tag_len, lvt, ENC_BIG_ENDIAN);
7260 return offset+tag_len+lvt;
7264 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7266 guint lastoffset = 0;
7268 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7269 lastoffset = offset;
7270 switch (fTagNo(tvb, offset)) {
7272 case 0: /* textMessageSourceDevice */
7273 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7275 case 1: /* messageClass */
7276 switch (fTagNo(tvb, offset)) {
7277 case 0: /* numeric */
7278 offset = fUnsignedTag(tvb, pinfo, tree, offset, "message Class: ");
7280 case 1: /* character */
7281 offset = fCharacterString(tvb, pinfo, tree, offset, "message Class: ");
7285 case 2: /* messagePriority */
7286 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "message Priority: ",
7287 BACnetMessagePriority);
7289 case 3: /* message */
7290 offset = fCharacterString(tvb, pinfo, tree, offset, "message: ");
7295 if (offset == lastoffset) break; /* nothing happened, exit loop */
7301 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7303 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
7307 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7309 guint lastoffset, len;
7310 guint8 tag_no, tag_info;
7312 proto_tree *subtree = tree;
7314 guint vendor_identifier = 0;
7315 guint service_number = 0;
7317 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7318 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
7319 if (col_get_writable(pinfo->cinfo))
7320 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
7321 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
7323 next_tvb = tvb_new_subset_remaining(tvb, offset);
7324 if (dissector_try_uint(bacapp_dissector_table,
7325 vendor_identifier, next_tvb, pinfo, tree)) {
7326 /* we parsed it so skip over length and we are done */
7327 offset += tvb_length(next_tvb);
7331 /* Not handled by vendor dissector */
7333 /* exit loop if nothing happens inside */
7334 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7335 lastoffset = offset;
7336 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7337 if (tag_is_closing(tag_info)) {
7338 if (tag_no == 2) { /* Make sure it's the expected tag */
7343 break; /* End loop if incorrect closing tag */
7348 /* vendorID is now parsed above */
7349 case 1: /* serviceNumber */
7350 fUnsigned32(tvb, offset+len, lvt, &service_number);
7351 if (col_get_writable(pinfo->cinfo))
7352 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
7353 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: ");
7355 case 2: /*serviceParameters */
7356 if (tag_is_opening(tag_info)) {
7357 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1,
7358 ett_bacapp_value, NULL, "service Parameters");
7359 propertyIdentifier = -1;
7360 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7368 if (offset == lastoffset) break; /* nothing happened, exit loop */
7375 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7377 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7381 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7383 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7387 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
7389 guint lastoffset = 0;
7390 guint8 tag_no, tag_info;
7392 proto_tree *subtree = tree;
7394 if (label != NULL) {
7395 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, label);
7398 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7399 lastoffset = offset;
7400 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7403 case 0: /* subscriberProcessId */
7404 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "requesting Process Id: ");
7406 case 1: /* requestingSource */
7407 offset = fCharacterString(tvb, pinfo, tree, offset, "requesting Source: ");
7409 case 2: /* request */
7410 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
7411 "request: ", BACnetLifeSafetyOperation, 64);
7413 case 3: /* objectId */
7414 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
7419 if (offset == lastoffset) break; /* nothing happened, exit loop */
7424 typedef struct _value_string_enum {
7425 const value_string *valstr;
7426 } value_string_enum;
7428 static const value_string_enum
7429 BACnetPropertyStatesEnums[] = {
7434 {BACnetProgramRequest },
7435 {BACnetProgramState },
7436 {BACnetProgramError },
7437 {BACnetReliability },
7438 {BACnetEventState },
7439 {BACnetDeviceStatus },
7440 {BACnetEngineeringUnits },
7442 {BACnetLifeSafetyMode },
7443 {BACnetLifeSafetyState },
7444 {BACnetRestartReason },
7445 {BACnetDoorAlarmState },
7447 {BACnetDoorSecuredStatus },
7448 {BACnetDoorStatus },
7449 { NULL }, /* {BACnetDoorValue }, */
7450 {BACnetFileAccessMethod },
7451 {BACnetLockStatus },
7452 {BACnetLifeSafetyOperation },
7453 {BACnetMaintenance },
7455 {BACnetNotifyType },
7456 { NULL }, /* {BACnetSecurityLevel }, */
7458 {BACnetSilencedState },
7460 { NULL }, /* {BACnetAccessEvent }, */
7461 { NULL }, /* {BACnetZoneOccupancyState }, */
7462 { NULL }, /* {BACnetAccessCredentialDisableReason }, */
7463 { NULL }, /* {BACnetAccessCredentialDisable }, */
7464 { NULL }, /* {BACnetAuthenticationStatus }, */
7466 { NULL }, /* {BACnetBackupState }, */
7468 #define BACnetPropertyStatesEnums_Size 36
7471 fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
7473 guint8 tag_no, tag_info;
7477 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7478 label = wmem_strdup_printf(wmem_packet_scope(), "%s: ",
7479 val_to_str_const( tag_no, VALS(BACnetPropertyStates), "Unknown State" ));
7483 offset = fBooleanTag(tvb, pinfo, tree, offset, label);
7486 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
7489 if ( (tag_no > BACnetPropertyStatesEnums_Size) ||
7490 VALS(BACnetPropertyStatesEnums[tag_no].valstr) == NULL)
7492 offset = fEnumeratedTag(tvb, pinfo, tree, offset, label, NULL);
7493 /* don't use Abstract type here because it is context tagged and therefore we don't know app type */
7497 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label,
7498 VALS(BACnetPropertyStatesEnums[tag_no].valstr), 64);
7507 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
7508 deviceIdentifier [0] BACnetObjectIdentifier,
7509 objectIdentifier [1] BACnetObjectIdentifier,
7510 propertyIdentifier [2] BACnetPropertyIdentifier,
7511 arrayIndex [3] Unsigned OPTIONAL,
7512 value [4] ABSTRACT-SYNTAX.&Type
7516 fDeviceObjectPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7518 guint lastoffset = 0;
7519 guint8 tag_no, tag_info;
7522 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7523 lastoffset = offset;
7524 /* check the tag. A closing tag means we are done */
7525 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7526 if (tag_is_closing(tag_info)) {
7530 case 0: /* deviceIdentifier */
7531 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7533 case 1: /* objectIdentifier */
7534 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7536 case 2: /* propertyIdentifier */
7537 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
7539 case 3: /* arrayIndex - OPTIONAL */
7540 offset = fUnsignedTag(tvb, pinfo, tree, offset,
7544 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7545 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
7546 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7551 if (offset == lastoffset) break; /* nothing happened, exit loop */
7557 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7558 objectIdentifier [0] BACnetObjectIdentifier,
7559 propertyIdentifier [1] BACnetPropertyIdentifier,
7560 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7561 -- if omitted with an array then
7562 -- the entire array is referenced
7563 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7567 fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7569 return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7573 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7574 objectIdentifier [0] BACnetObjectIdentifier,
7575 propertyIdentifier [1] BACnetPropertyIdentifier,
7576 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7577 -- if omitted with an array then
7578 -- the entire array is referenced
7579 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7583 fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7585 guint lastoffset = 0;
7586 guint8 tag_no, tag_info;
7589 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7590 lastoffset = offset;
7591 /* check the tag. A closing tag means we are done */
7592 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7593 if (tag_is_closing(tag_info)) {
7597 case 0: /* objectIdentifier */
7598 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7600 case 1: /* propertyIdentifier */
7601 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
7603 case 2: /* arrayIndex - OPTIONAL */
7604 offset = fUnsignedTag(tvb, pinfo, tree, offset,
7607 case 3: /* deviceIdentifier - OPTIONAL */
7608 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7613 if (offset == lastoffset) break; /* nothing happened, exit loop */
7619 fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7621 guint lastoffset = offset;
7622 guint8 tag_no, tag_info;
7624 proto_tree *subtree = tree;
7626 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7627 subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0,
7628 ett_bacapp_value, NULL, "notification parameters (%d) %s",
7629 tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
7630 /* Opening tag for parameter choice */
7631 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7634 case 0: /* change-of-bitstring */
7635 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7636 lastoffset = offset;
7637 switch (fTagNo(tvb, offset)) {
7639 offset = fBitStringTag(tvb, pinfo, subtree, offset,
7640 "referenced-bitstring: ");
7643 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7644 "status-flags: ", BACnetStatusFlags);
7645 lastoffset = offset;
7650 if (offset == lastoffset) break; /* nothing happened, exit loop */
7653 case 1: /* change-of-state */
7654 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7655 lastoffset = offset;
7656 switch (fTagNo(tvb, offset)) {
7658 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7659 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7660 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7663 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7664 "status-flags: ", BACnetStatusFlags);
7665 lastoffset = offset;
7670 if (offset == lastoffset) break; /* nothing happened, exit loop */
7673 case 2: /* change-of-value */
7674 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7675 lastoffset = offset;
7676 switch (fTagNo(tvb, offset)) {
7678 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7679 switch (fTagNo(tvb, offset)) {
7681 offset = fBitStringTag(tvb, pinfo, subtree, offset,
7685 offset = fRealTag(tvb, pinfo, subtree, offset,
7691 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7694 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7695 "status-flags: ", BACnetStatusFlags);
7696 lastoffset = offset;
7701 if (offset == lastoffset) break; /* nothing happened, exit loop */
7704 case 3: /* command-failure */
7705 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7706 lastoffset = offset;
7707 switch (fTagNo(tvb, offset)) {
7708 case 0: /* "command-value: " */
7709 /* from BACnet Table 13-3,
7710 Standard Object Property Values Returned in Notifications */
7711 propertyIdentifier = 85; /* PRESENT_VALUE */
7712 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7713 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7714 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7717 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7718 "status-flags: ", BACnetStatusFlags);
7720 case 2: /* "feedback-value: " */
7721 propertyIdentifier = 40; /* FEEDBACK_VALUE */
7722 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7723 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7724 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7725 lastoffset = offset;
7730 if (offset == lastoffset) break; /* nothing happened, exit loop */
7733 case 4: /* floating-limit */
7734 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7735 lastoffset = offset;
7736 switch (fTagNo(tvb, offset)) {
7738 offset = fRealTag(tvb, pinfo, subtree, offset, "reference-value: ");
7741 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7742 "status-flags: ", BACnetStatusFlags);
7745 offset = fRealTag(tvb, pinfo, subtree, offset, "setpoint-value: ");
7748 offset = fRealTag(tvb, pinfo, subtree, offset, "error-limit: ");
7749 lastoffset = offset;
7754 if (offset == lastoffset) break; /* nothing happened, exit loop */
7757 case 5: /* out-of-range */
7758 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7759 lastoffset = offset;
7760 switch (fTagNo(tvb, offset)) {
7762 offset = fRealTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7765 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7766 "status-flags: ", BACnetStatusFlags);
7769 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
7772 offset = fRealTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
7773 lastoffset = offset;
7778 if (offset == lastoffset) break; /* nothing happened, exit loop */
7782 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7783 lastoffset = offset;
7784 offset =fBACnetPropertyValue(tvb, pinfo, subtree, offset);
7785 if (offset == lastoffset) break; /* nothing happened, exit loop */
7788 case 7: /* deprecated (was 'buffer-ready', changed and moved to [10]) */
7789 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7790 lastoffset = offset;
7791 switch (fTagNo(tvb, offset)) {
7793 offset = fObjectIdentifier(tvb, pinfo, subtree, offset); /* buffer-device */
7796 offset = fObjectIdentifier(tvb, pinfo, subtree, offset); /* buffer-object */
7799 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7800 offset = fDateTime(tvb, pinfo, subtree, offset, "previous-notification: ");
7801 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7804 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7805 offset = fDateTime(tvb, pinfo, subtree, offset, "current-notification: ");
7806 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7807 lastoffset = offset;
7812 if (offset == lastoffset) break; /* nothing happened, exit loop */
7815 case 8: /* change-of-life-safety */
7816 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7817 lastoffset = offset;
7818 switch (fTagNo(tvb, offset)) {
7820 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7821 "new-state: ", BACnetLifeSafetyState, 256);
7824 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7825 "new-mode: ", BACnetLifeSafetyMode, 256);
7828 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7829 "status-flags: ", BACnetStatusFlags);
7832 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7833 "operation-expected: ", BACnetLifeSafetyOperation, 64);
7834 lastoffset = offset;
7839 if (offset == lastoffset) break; /* nothing happened, exit loop */
7842 case 9: /* extended */
7843 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7844 lastoffset = offset;
7845 switch (fTagNo(tvb, offset)) {
7847 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
7850 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7851 "extended-event-type: ");
7853 case 2: /* parameters */
7854 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7855 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
7856 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
7857 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7858 lastoffset = offset;
7863 if (offset == lastoffset) break; /* nothing happened, exit loop */
7866 case 10: /* buffer ready */
7867 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7868 lastoffset = offset;
7869 switch (fTagNo(tvb, offset)) {
7870 case 0: /* buffer-property */
7871 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7872 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
7873 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7876 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7877 "previous-notification: ");
7880 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7881 "current-notification: ");
7882 lastoffset = offset;
7887 if (offset == lastoffset) break; /* nothing happened, exit loop */
7890 case 11: /* unsigned range */
7891 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7892 lastoffset = offset;
7893 switch (fTagNo(tvb, offset)) {
7895 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7896 "exceeding-value: ");
7899 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7900 "status-flags: ", BACnetStatusFlags);
7903 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7904 "exceeded-limit: ");
7905 lastoffset = offset;
7910 if (offset == lastoffset) break; /* nothing happened, exit loop */
7914 case 13: /* access-event */
7916 case 14: /* double-out-of-range */
7917 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7918 lastoffset = offset;
7919 switch (fTagNo(tvb, offset)) {
7921 offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7924 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7925 "status-flags: ", BACnetStatusFlags);
7928 offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: ");
7931 offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
7932 lastoffset = offset;
7937 if (offset == lastoffset) break; /* nothing happened, exit loop */
7940 case 15: /* signed-out-of-range */
7941 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7942 lastoffset = offset;
7943 switch (fTagNo(tvb, offset)) {
7945 offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7948 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7949 "status-flags: ", BACnetStatusFlags);
7952 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
7955 offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
7956 lastoffset = offset;
7961 if (offset == lastoffset) break; /* nothing happened, exit loop */
7964 case 16: /* unsigned-out-of-range */
7965 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7966 lastoffset = offset;
7967 switch (fTagNo(tvb, offset)) {
7969 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7972 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7973 "status-flags: ", BACnetStatusFlags);
7976 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
7979 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
7980 lastoffset = offset;
7985 if (offset == lastoffset) break; /* nothing happened, exit loop */
7988 case 17: /* change-of-characterstring */
7990 case 18: /* change-of-status-flags */
7992 /* todo: add new parameters here ... */
7994 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7998 /* Closing tag for parameter choice */
7999 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8005 fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8007 guint lastoffset = offset;
8008 guint8 tag_no, tag_info;
8010 proto_tree *subtree = tree;
8012 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8013 subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0,
8014 ett_bacapp_value, NULL, "event parameters (%d) %s",
8015 tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
8017 /* Opening tag for parameter choice */
8018 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8021 case 0: /* change-of-bitstring */
8022 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8023 lastoffset = offset;
8024 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8025 if (tag_is_closing(tag_info)) {
8030 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8033 offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: ");
8035 case 2: /* SEQUENCE OF BIT STRING */
8036 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8037 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8038 lastoffset = offset;
8039 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8040 if (tag_is_closing(tag_info)) {
8043 offset = fBitStringTag(tvb, pinfo, subtree, offset,
8044 "bitstring value: ");
8046 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8053 case 1: /* change-of-state */
8054 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8055 lastoffset = offset;
8056 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8057 if (tag_is_closing(tag_info)) {
8062 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8064 case 1: /* SEQUENCE OF BACnetPropertyStates */
8065 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8066 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8067 lastoffset = offset;
8068 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8069 if (tag_is_closing(tag_info)) {
8072 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
8074 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8081 case 2: /* change-of-value */
8082 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8083 lastoffset = offset;
8084 switch (fTagNo(tvb, offset)) {
8086 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8088 case 1: /* don't loop it, it's a CHOICE */
8089 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8090 switch (fTagNo(tvb, offset)) {
8092 offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: ");
8095 offset = fRealTag(tvb, pinfo, subtree, offset,
8096 "referenced Property Increment: ");
8101 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8108 case 3: /* command-failure */
8109 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8110 lastoffset = offset;
8111 tag_no = fTagNo(tvb, offset);
8114 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8117 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8118 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8119 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8126 case 4: /* floating-limit */
8127 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8128 lastoffset = offset;
8129 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8130 if (tag_is_closing(tag_info)) {
8135 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8138 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8139 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8140 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8143 offset = fRealTag(tvb, pinfo, subtree, offset, "low diff limit: ");
8146 offset = fRealTag(tvb, pinfo, subtree, offset, "high diff limit: ");
8149 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
8156 case 5: /* out-of-range */
8157 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8158 lastoffset = offset;
8159 switch (fTagNo(tvb, offset)) {
8161 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8164 offset = fRealTag(tvb, pinfo, subtree, offset, "low limit: ");
8167 offset = fRealTag(tvb, pinfo, subtree, offset, "high limit: ");
8170 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
8179 offset = fBACnetPropertyValue (tvb, pinfo, tree, offset);
8183 case 7: /* buffer-ready */
8186 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
8187 lastoffset = offset;
8188 switch (fTagNo(tvb, offset)) {
8190 offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification threshold");
8193 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8194 "previous notification count: ");
8202 case 8: /* change-of-life-safety */
8203 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8204 lastoffset = offset;
8205 switch (fTagNo(tvb, offset)) {
8207 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8210 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8211 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8212 lastoffset = offset;
8213 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8214 if (tag_is_closing(tag_info)) {
8217 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8218 "life safety alarm value: ", BACnetLifeSafetyState, 256);
8220 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8223 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8224 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8225 lastoffset = offset;
8226 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8227 if (tag_is_closing(tag_info)) {
8230 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8231 "alarm value: ", BACnetLifeSafetyState, 256);
8233 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8236 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8237 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8238 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8245 case 9: /* extended */
8246 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8247 lastoffset = offset;
8248 switch (fTagNo(tvb, offset)) {
8250 offset = fVendorIdentifier(tvb, pinfo, tree, offset);
8253 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8254 "extended-event-type: ");
8256 case 2: /* parameters */
8257 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8258 offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
8259 offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
8260 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8261 lastoffset = offset;
8266 if (offset == lastoffset) break; /* nothing happened, exit loop */
8269 case 10: /* buffer-ready */
8270 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8271 lastoffset = offset;
8272 switch (fTagNo(tvb, offset)) {
8274 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
8275 "notification-threshold: ");
8278 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
8279 "previous-notification-count: ");
8286 case 11: /* unsigned-range */
8287 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8288 lastoffset = offset;
8289 switch (fTagNo(tvb, offset)) {
8291 offset = fTimeSpan(tvb, pinfo, tree, offset, "Time Delay");
8294 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8298 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8306 case 13: /* access-event */
8307 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8308 lastoffset = offset;
8309 switch (fTagNo(tvb, offset)) {
8311 /* TODO: [0] SEQUENCE OF BACnetAccessEvent */
8312 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8313 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8314 lastoffset = offset;
8315 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8316 if (tag_is_closing(tag_info)) {
8319 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8320 "access event: ", BACnetAccessEvent, 512);
8322 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8325 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8326 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8327 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8334 case 14: /* double-out-of-range */
8335 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8336 lastoffset = offset;
8337 switch (fTagNo(tvb, offset)) {
8339 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8342 offset = fDoubleTag(tvb, pinfo, subtree, offset, "low limit: ");
8345 offset = fDoubleTag(tvb, pinfo, subtree, offset, "high limit: ");
8348 offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: ");
8355 case 15: /* signed-out-of-range */
8356 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8357 lastoffset = offset;
8358 switch (fTagNo(tvb, offset)) {
8360 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8363 offset = fSignedTag(tvb, pinfo, subtree, offset, "low limit: ");
8366 offset = fSignedTag(tvb, pinfo, subtree, offset, "high limit: ");
8369 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8376 case 16: /* unsigned-out-of-range */
8377 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8378 lastoffset = offset;
8379 switch (fTagNo(tvb, offset)) {
8381 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8384 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "low limit: ");
8387 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "high limit: ");
8390 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8397 case 17: /* change-of-characterstring */
8398 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8399 lastoffset = offset;
8400 switch (fTagNo(tvb, offset)) {
8402 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8404 case 1: /* SEQUENCE OF CharacterString */
8405 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8406 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8407 lastoffset = offset;
8408 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8409 if (tag_is_closing(tag_info)) {
8412 offset = fCharacterString(tvb, pinfo, tree, offset, "alarm value: ");
8414 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8421 case 18: /* change-of-status-flags */
8422 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8423 lastoffset = offset;
8424 switch (fTagNo(tvb, offset)) {
8426 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8429 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
8430 "selected flags: ", BACnetStatusFlags);
8437 /* todo: add new event-parameter cases here */
8442 /* Closing tag for parameter choice */
8443 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8448 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8450 guint lastoffset = 0;
8451 guint8 tag_no, tag_info;
8453 proto_tree *subtree = tree;
8455 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8456 lastoffset = offset;
8457 switch (fTagNo(tvb, offset)) {
8458 case 0: /* timestamp */
8459 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8460 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8461 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8462 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8464 case 1: /* logDatum: don't loop, it's a CHOICE */
8465 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8466 switch (fTagNo(tvb, offset)) {
8467 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8468 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8470 case 1: /* todo: move this to new method fConfirmedEventNotificationRequestTag... */
8471 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "notification: ");
8472 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8473 offset = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset);
8474 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8477 offset = fRealTag(tvb, pinfo, tree, offset, "time-change: ");
8482 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8487 if (offset == lastoffset) break; /* nothing happened, exit loop */
8493 fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8495 guint lastoffset = 0;
8496 guint8 tag_no, tag_info;
8499 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8500 lastoffset = offset;
8501 switch (fTagNo(tvb, offset)) {
8502 case 0: /* timestamp */
8503 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8504 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8505 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8506 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8508 case 1: /* logDatum: don't loop, it's a CHOICE */
8509 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8510 switch (fTagNo(tvb, offset)) {
8511 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8512 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8515 offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: ");
8518 offset = fRealTag(tvb, pinfo, tree, offset, "real value: ");
8521 offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: ");
8524 offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: ");
8527 offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: ");
8530 offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: ");
8533 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8536 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8537 offset = fError(tvb, pinfo, tree, offset);
8538 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8541 offset = fRealTag(tvb, pinfo, tree, offset, "time change: ");
8543 case 10: /* any Value */
8544 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8545 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
8546 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8551 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8554 /* Changed this to BitString per BACnet Spec. */
8555 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "Status Flags:", BACnetStatusFlags);
8560 if (offset == lastoffset) break; /* nothing happened, exit loop */
8566 fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8568 guint lastoffset = 0;
8569 guint8 tag_no, tag_info;
8572 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8573 lastoffset = offset;
8574 switch (fTagNo(tvb, offset)) {
8575 case 0: /* timestamp */
8576 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8577 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8578 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8579 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8581 case 1: /* logData: don't loop, it's a CHOICE */
8582 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8583 switch (fTagNo(tvb, offset)) {
8584 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8585 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8587 case 1: /* log-data: SEQUENCE OF CHOICE */
8588 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8589 while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset != lastoffset)) { /* exit loop if nothing happens inside */
8590 lastoffset = offset;
8591 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8592 if (tag_is_closing(tag_info)) {
8593 lastoffset = offset;
8598 offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: ");
8601 offset = fRealTag(tvb, pinfo, tree, offset, "real value: ");
8604 offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: ");
8607 offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: ");
8610 offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: ");
8613 offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: ");
8616 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8619 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8620 offset = fError(tvb, pinfo, tree, offset);
8621 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8623 case 8: /* any Value */
8624 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8625 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
8626 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8632 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8635 offset = fRealTag(tvb, pinfo, tree, offset, "time-change: ");
8640 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8645 if (offset == lastoffset) break; /* nothing happened, exit loop */
8652 fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8654 guint lastoffset = 0;
8655 guint8 tag_no, tag_info;
8658 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8659 lastoffset = offset;
8660 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8661 if (tag_is_closing(tag_info)) {
8666 case 0: /* ProcessId */
8667 offset = fProcessId(tvb, pinfo, tree, offset);
8669 case 1: /* initiating ObjectId */
8670 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8672 case 2: /* event ObjectId */
8673 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8675 case 3: /* time stamp */
8676 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8677 offset = fTimeStamp(tvb, pinfo, tree, offset, NULL);
8678 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8680 case 4: /* notificationClass */
8681 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: ");
8683 case 5: /* Priority */
8684 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: ");
8686 case 6: /* EventType */
8687 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8688 "Event Type: ", BACnetEventType, 64);
8690 case 7: /* messageText */
8691 offset = fCharacterString(tvb, pinfo, tree, offset, "message Text: ");
8693 case 8: /* NotifyType */
8694 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8695 "Notify Type: ", BACnetNotifyType);
8697 case 9: /* ackRequired */
8698 offset = fBooleanTag(tvb, pinfo, tree, offset, "ack Required: ");
8700 case 10: /* fromState */
8701 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8702 "from State: ", BACnetEventState, 64);
8704 case 11: /* toState */
8705 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8706 "to State: ", BACnetEventState, 64);
8708 case 12: /* NotificationParameters */
8709 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8710 offset = fNotificationParameters(tvb, pinfo, tree, offset);
8711 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8716 if (offset == lastoffset) break; /* nothing happened, exit loop */
8722 fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8724 return fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
8728 fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8730 guint lastoffset = 0, len;
8731 guint8 tag_no, tag_info;
8733 proto_tree *subtree = tree;
8735 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8736 lastoffset = offset;
8737 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8738 if (tag_is_closing(tag_info)) {
8745 case 0: /* ProcessId */
8746 offset = fProcessId(tvb, pinfo, tree, offset);
8748 case 1: /* initiating DeviceId */
8749 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
8751 case 2: /* monitored ObjectId */
8752 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
8754 case 3: /* time remaining */
8755 offset = fTimeSpan(tvb, pinfo, tree, offset, "Time remaining");
8757 case 4: /* List of Values */
8758 if (tag_is_opening(tag_info)) {
8759 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "list of Values");
8760 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8761 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
8769 if (offset == lastoffset) break; /* nothing happened, exit loop */
8775 fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8777 return fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
8781 fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8783 guint lastoffset = 0;
8784 guint8 tag_no = 0, tag_info = 0;
8787 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8788 lastoffset = offset;
8789 switch (fTagNo(tvb, offset)) {
8790 case 0: /* acknowledgingProcessId */
8791 offset = fUnsignedTag(tvb, pinfo, tree, offset, "acknowledging Process Id: ");
8793 case 1: /* eventObjectId */
8794 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8796 case 2: /* eventStateAcknowledged */
8797 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8798 "event State Acknowledged: ", BACnetEventState, 64);
8800 case 3: /* timeStamp */
8801 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8802 offset = fTimeStamp(tvb, pinfo, tree, offset, NULL);
8803 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8805 case 4: /* acknowledgementSource */
8806 offset = fCharacterString(tvb, pinfo, tree, offset, "acknowledgement Source: ");
8808 case 5: /* timeOfAcknowledgement */
8809 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8810 offset = fTimeStamp(tvb, pinfo, tree, offset, "acknowledgement timestamp: ");
8811 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8816 if (offset == lastoffset) break; /* nothing happened, exit loop */
8822 fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8824 guint lastoffset = 0;
8826 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8827 lastoffset = offset;
8828 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
8829 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
8830 "alarm State: ", BACnetEventState, 64);
8831 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
8832 "acknowledged Transitions: ", BACnetEventTransitionBits);
8833 if (offset == lastoffset) break; /* nothing happened, exit loop */
8839 fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8841 guint lastoffset = 0;
8842 guint8 tag_no, tag_info;
8845 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8846 lastoffset = offset;
8847 switch (fTagNo(tvb, offset)) {
8848 case 0: /* acknowledgmentFilter */
8849 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8850 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
8852 case 1: /* eventObjectId - OPTIONAL */
8853 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8854 offset = fRecipientProcess(tvb, pinfo, tree, offset);
8855 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8857 case 2: /* eventStateFilter */
8858 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8859 "event State Filter: ", BACnetEventStateFilter);
8861 case 3: /* eventTypeFilter - OPTIONAL */
8862 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8863 "event Type Filter: ", BACnetEventType);
8865 case 4: /* priorityFilter */
8866 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8867 offset = fUnsignedTag(tvb, pinfo, tree, offset, "min Priority: ");
8868 offset = fUnsignedTag(tvb, pinfo, tree, offset, "max Priority: ");
8869 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8871 case 5: /* notificationClassFilter - OPTIONAL */
8872 offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification Class Filter: ");
8877 if (offset == lastoffset) break; /* nothing happened, exit loop */
8883 fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8885 guint lastoffset = 0;
8887 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8888 lastoffset = offset;
8889 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
8890 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
8891 "event Type: ", BACnetEventType, 64);
8892 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
8893 "event State: ", BACnetEventState);
8894 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Priority: ");
8895 if (tvb_reported_length_remaining(tvb, offset) > 0 && fTagNo(tvb, offset) == 2) /* Notification Class - OPTIONAL */
8896 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: ");
8897 if (offset == lastoffset) break; /* nothing happened, exit loop */
8904 fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8906 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8907 if (fTagNo(tvb, offset) == 0) {
8908 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8915 flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8917 guint lastoffset = 0;
8918 guint8 tag_no, tag_info;
8920 proto_tree* subtree = tree;
8922 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8923 lastoffset = offset;
8924 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8925 /* we are finished here if we spot a closing tag */
8926 if (tag_is_closing(tag_info)) {
8930 case 0: /* ObjectId */
8931 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8933 case 1: /* eventState */
8934 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8935 "event State: ", BACnetEventState);
8937 case 2: /* acknowledgedTransitions */
8938 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
8939 "acknowledged Transitions: ", BACnetEventTransitionBits);
8941 case 3: /* eventTimeStamps */
8942 subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventTimeStamps");
8943 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8944 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: ");
8945 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: ");
8946 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: ");
8947 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8949 case 4: /* notifyType */
8950 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8951 "Notify Type: ", BACnetNotifyType);
8953 case 5: /* eventEnable */
8954 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
8955 "event Enable: ", BACnetEventTransitionBits);
8957 case 6: /* eventPriorities */
8958 subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventPriorities");
8959 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8960 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-OFFNORMAL Priority: ");
8961 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-FAULT Priority: ");
8962 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-NORMAL Priority: ");
8963 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8968 if (offset == lastoffset) break; /* nothing happened, exit loop */
8974 fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8976 guint lastoffset = 0;
8977 guint8 tag_no, tag_info;
8980 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
8981 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8982 lastoffset = offset;
8983 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8984 /* we are finished here if we spot a closing tag */
8985 if (tag_is_closing(tag_info)) {
8988 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
8989 if (offset == lastoffset) break; /* nothing happened, exit loop */
8995 fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8997 guint lastoffset = 0;
8998 guint8 tag_no, tag_info;
9001 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9002 lastoffset = offset;
9003 switch (fTagNo(tvb, offset)) {
9004 case 0: /* listOfEventSummaries */
9005 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9006 offset = flistOfEventSummaries(tvb, pinfo, tree, offset);
9007 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9009 case 1: /* moreEvents */
9010 offset = fBooleanTag(tvb, pinfo, tree, offset, "more Events: ");
9015 if (offset == lastoffset) break; /* nothing happened, exit loop */
9021 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9023 guint lastoffset = 0, len;
9024 guint8 tag_no, tag_info;
9026 proto_tree *subtree = tree;
9028 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9030 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9031 lastoffset = offset;
9032 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9033 if (tag_is_closing(tag_info)) {
9040 case 0: /* ObjectId */
9041 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9043 case 3: /* listOfElements */
9044 if (tag_is_opening(tag_info)) {
9045 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfElements");
9046 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9047 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
9055 if (offset == lastoffset) break; /* nothing happened, exit loop */
9061 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9063 return fObjectIdentifier(tvb, pinfo, tree, offset);
9067 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9069 guint lastoffset = 0;
9071 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9072 lastoffset = offset;
9074 switch (fTagNo(tvb, offset)) {
9075 case 0: /* timeDuration */
9076 offset = fUnsignedTag(tvb, pinfo, tree, offset, "time Duration: ");
9078 case 1: /* enable-disable */
9079 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "enable-disable: ",
9080 BACnetEnableDisable);
9082 case 2: /* password - OPTIONAL */
9083 offset = fCharacterString(tvb, pinfo, tree, offset, "Password: ");
9088 if (offset == lastoffset) break; /* nothing happened, exit loop */
9094 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9096 guint lastoffset = 0;
9098 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9099 lastoffset = offset;
9101 switch (fTagNo(tvb, offset)) {
9102 case 0: /* reinitializedStateOfDevice */
9103 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
9104 "reinitialized State Of Device: ",
9105 BACnetReinitializedStateOfDevice);
9107 case 1: /* password - OPTIONAL */
9108 offset = fCharacterString(tvb, pinfo, tree, offset, "Password: ");
9113 if (offset == lastoffset) break; /* nothing happened, exit loop */
9119 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9121 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
9122 "vtClass: ", BACnetVTClass);
9123 return fApplicationTypes(tvb, pinfo, tree, offset, "local VT Session ID: ");
9127 fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9129 return fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: ");
9133 fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9135 guint lastoffset = 0;
9137 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9138 lastoffset = offset;
9139 offset= fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: ");
9140 if (offset == lastoffset) break; /* nothing happened, exit loop */
9146 fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9148 offset= fApplicationTypes(tvb, pinfo, tree, offset, "VT Session ID: ");
9149 offset = fApplicationTypes(tvb, pinfo, tree, offset, "VT New Data: ");
9150 return fApplicationTypes(tvb, pinfo, tree, offset, "VT Data Flag: ");
9154 fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9156 guint lastoffset = 0;
9158 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9159 lastoffset = offset;
9161 switch (fTagNo(tvb, offset)) {
9162 case 0: /* BOOLEAN */
9163 offset = fBooleanTag(tvb, pinfo, tree, offset, "all New Data Accepted: ");
9165 case 1: /* Unsigned OPTIONAL */
9166 offset = fUnsignedTag(tvb, pinfo, tree, offset, "accepted Octet Count: ");
9171 if (offset == lastoffset) break; /* nothing happened, exit loop */
9177 fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9179 guint lastoffset = 0;
9181 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9182 lastoffset = offset;
9184 switch (fTagNo(tvb, offset)) {
9185 case 0: /* Unsigned32 */
9186 offset = fUnsignedTag(tvb, pinfo, tree, offset, "pseudo Random Number: ");
9188 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
9189 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
9191 case 2: /* Chararacter String OPTIONAL */
9192 offset = fCharacterString(tvb, pinfo, tree, offset, "operator Name: ");
9194 case 3: /* Chararacter String OPTIONAL */
9195 offset = fCharacterString(tvb, pinfo, tree, offset, "operator Password: ");
9197 case 4: /* Boolean OPTIONAL */
9198 offset = fBooleanTag(tvb, pinfo, tree, offset, "start Encyphered Session: ");
9203 if (offset == lastoffset) break; /* nothing happened, exit loop */
9209 fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9211 return fApplicationTypes(tvb, pinfo, tree, offset, "modified Random Number: ");
9215 fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9217 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* Requesting Device Identifier */
9218 offset = fAddress(tvb, pinfo, tree, offset);
9219 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* Remote Device Identifier */
9220 return fAddress(tvb, pinfo, tree, offset);
9224 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9226 /* Same as AddListElement request after service choice */
9227 return fAddListElementRequest(tvb, pinfo, tree, offset);
9231 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9233 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
9237 fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9239 guint lastoffset = 0, len;
9240 guint8 tag_no, tag_info;
9242 proto_tree *subtree = tree;
9244 /* set the optional global properties to indicate not-used */
9245 propertyArrayIndex = -1;
9246 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9247 lastoffset = offset;
9248 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9249 if (tag_is_closing(tag_info)) {
9255 case 0: /* objectIdentifier */
9256 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9258 case 1: /* propertyIdentifier */
9259 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9261 case 2: /* propertyArrayIndex */
9262 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
9264 case 3: /* propertyValue */
9265 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9270 if (offset == lastoffset) break; /* nothing happened, exit loop */
9276 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9278 guint lastoffset = 0;
9279 guint8 tag_no, tag_info;
9281 proto_tree *subtree = tree;
9283 /* set the optional global properties to indicate not-used */
9284 propertyArrayIndex = -1;
9285 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9286 lastoffset = offset;
9287 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9288 /* quit loop if we spot a closing tag */
9289 if (tag_is_closing(tag_info)) {
9294 case 0: /* objectIdentifier */
9295 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9297 case 1: /* propertyIdentifier */
9298 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9300 case 2: /* propertyArrayIndex */
9301 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
9303 case 3: /* propertyValue */
9304 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9306 case 4: /* Priority (only used for write) */
9307 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
9312 if (offset == lastoffset) break; /* nothing happened, exit loop */
9318 fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9320 guint lastoffset = 0, len;
9321 guint8 tag_no, tag_info;
9324 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9325 lastoffset = offset;
9326 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9327 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
9328 if (tag_is_closing(tag_info)) {
9334 case 0: /* objectIdentifier */
9335 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9337 case 1: /* listOfPropertyValues */
9338 if (tag_is_opening(tag_info)) {
9339 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9340 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
9348 if (offset == lastoffset) break; /* nothing happened, exit loop */
9354 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9356 if (offset >= tvb_reported_length(tvb))
9359 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9360 return fWriteAccessSpecification(tvb, pinfo, tree, offset);
9364 fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
9366 guint lastoffset = 0;
9367 guint8 tag_no, tag_info;
9370 /* set the optional global properties to indicate not-used */
9371 propertyArrayIndex = -1;
9372 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9373 lastoffset = offset;
9374 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9375 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
9377 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
9380 switch (tag_no-tagoffset) {
9381 case 0: /* PropertyIdentifier */
9382 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
9384 case 1: /* propertyArrayIndex */
9385 offset = fPropertyArrayIndex(tvb, pinfo, tree, offset);
9386 if (list != 0) break; /* Continue decoding if this may be a list */
9388 lastoffset = offset; /* Set loop end condition */
9391 if (offset == lastoffset) break; /* nothing happened, exit loop */
9397 fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
9399 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9400 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
9404 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9406 guint lastoffset = 0;
9408 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9409 lastoffset = offset;
9411 switch (fTagNo(tvb, offset)) {
9412 case 0: /* ObjectIdentifier */
9413 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9415 case 1: /* PropertyIdentifier and propertyArrayIndex */
9416 offset = fPropertyReference(tvb, pinfo, tree, offset, 1, 0);
9417 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9419 lastoffset = offset; /* Set loop end condition */
9422 if (offset == lastoffset) break; /* nothing happened, exit loop */
9429 fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, guint offset)
9431 guint lastoffset = 0;
9432 guint8 tag_no, tag_info;
9434 proto_tree* subtree = tree;
9437 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
9438 lastoffset = offset;
9439 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9440 if (tag_is_closing(tag_info)) {
9441 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
9442 &tag_no, &tag_info, &lvt);
9446 case 0: /* ObjectIdentifier */
9447 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9449 case 1: /* PropertyIdentifier */
9450 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9452 case 2: /* propertyArrayIndex */
9453 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "property Array Index: ");
9456 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9458 case 4: /* Priority */
9459 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
9470 fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9472 char i = 1, ar[256];
9473 guint lastoffset = 0;
9475 if (propertyArrayIndex > 0) {
9476 /* BACnetARRAY index 0 refers to the length
9477 of the array, not the elements of the array.
9478 BACnetARRAY index -1 is our internal flag that
9479 the optional index was not used.
9480 BACnetARRAY refers to this as all elements of the array.
9481 If the optional index is specified for a BACnetARRAY,
9482 then that specific array element is referenced. */
9483 i = propertyArrayIndex;
9485 while (tvb_reported_length_remaining(tvb, offset) > 0) {
9486 /* exit loop if nothing happens inside */
9487 lastoffset = offset;
9488 g_snprintf(ar, sizeof(ar), "%s[%d]: ",
9489 val_to_split_str(87 , 512,
9490 BACnetPropertyIdentifier,
9491 ASHRAE_Reserved_Fmt,
9492 Vendor_Proprietary_Fmt),
9494 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
9495 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
9496 /* there are only 16 priority array elements */
9500 if (offset == lastoffset) break; /* nothing happened, exit loop */
9507 fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9509 guint lastoffset = 0;
9511 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9512 lastoffset = offset;
9514 switch (fTagNo(tvb, offset)) {
9515 case 0: /* deviceIdentifier - OPTIONAL */
9516 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9518 case 1: /* ObjectIdentifier */
9519 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9524 if (offset == lastoffset) break; /* nothing happened, exit loop */
9530 fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9532 guint8 tag_no, tag_info;
9534 guint lastoffset = 0, len;
9535 gboolean closing_found = FALSE; /* tracks when we are done decoding the fSpecialEvent entries */
9537 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9538 lastoffset = offset;
9539 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9540 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
9541 if (tag_is_closing(tag_info)) {
9542 /* if we find 2 closing tags in succession we need to exit without incrementing the offset again */
9543 /* This handles the special case where we have a special event entry in an RPM-ACK msg */
9544 if ( closing_found == TRUE )
9547 closing_found = TRUE;
9552 case 0: /* calendarEntry */
9553 if (tag_is_opening(tag_info)) {
9554 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9555 offset = fCalendarEntry(tvb, pinfo, subtree, offset);
9556 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9559 case 1: /* calendarReference */
9560 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9562 case 2: /* list of BACnetTimeValue */
9563 if (tag_is_opening(tag_info)) {
9564 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9565 offset = fTimeValue(tvb, pinfo, subtree, offset);
9566 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9571 case 3: /* eventPriority */
9572 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "event priority: ");
9577 closing_found = FALSE; /* reset our closing tag status, we processed another open tag */
9578 if (offset == lastoffset) break; /* nothing happened, exit loop */
9584 fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9586 guint lastoffset = 0, len;
9587 guint8 tag_no, tag_info;
9590 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9591 lastoffset = offset;
9592 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9593 /* maybe a listOfSelectionCriteria if we spot a closing tag */
9594 if (tag_is_closing(tag_info)) {
9599 switch (fTagNo(tvb, offset)) {
9600 case 0: /* propertyIdentifier */
9601 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
9603 case 1: /* propertyArrayIndex */
9604 offset = fPropertyArrayIndex(tvb, pinfo, tree, offset);
9606 case 2: /* relationSpecifier */
9607 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
9608 "relation Specifier: ", BACnetRelationSpecifier);
9610 case 3: /* comparisonValue */
9611 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9612 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
9613 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9618 if (offset == lastoffset) break; /* nothing happened, exit loop */
9624 fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9626 guint lastoffset = 0;
9627 guint8 tag_no, tag_info;
9630 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9631 lastoffset = offset;
9632 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9633 /* quit loop if we spot a closing tag */
9634 if (tag_is_closing(tag_info)) {
9639 case 0: /* selectionLogic */
9640 offset = fEnumeratedTag(tvb, pinfo, subtree, offset,
9641 "selection Logic: ", BACnetSelectionLogic);
9643 case 1: /* listOfSelectionCriteria */
9644 if (tag_is_opening(tag_info)) {
9645 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9646 offset = fSelectionCriteria(tvb, pinfo, subtree, offset);
9647 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9655 if (offset == lastoffset) break; /* nothing happened, exit loop */
9662 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
9664 guint lastoffset = 0;
9665 guint8 tag_no, tag_info;
9668 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9669 lastoffset = offset;
9670 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9672 if (tag_is_opening(tag_info) && tag_no < 2) {
9673 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9675 case 0: /* objectSelectionCriteria */
9676 offset = fObjectSelectionCriteria(tvb, pinfo, subtree, offset);
9678 case 1: /* listOfPropertyReferences */
9679 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
9684 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9686 if (offset == lastoffset) break; /* nothing happened, exit loop */
9692 fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9694 guint lastoffset = 0;
9695 guint8 tag_no, tag_info;
9697 proto_tree *subtree = tree;
9699 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9700 lastoffset = offset;
9701 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9703 case 0: /* objectIdentifier */
9704 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9706 case 1: /* listOfPropertyReferences */
9707 if (tag_is_opening(tag_info)) {
9708 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfPropertyReferences");
9709 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9710 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
9711 } else if (tag_is_closing(tag_info)) {
9712 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
9713 &tag_no, &tag_info, &lvt);
9716 /* error condition: let caller handle */
9723 if (offset == lastoffset) break; /* nothing happened, exit loop */
9729 fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9731 guint lastoffset = 0, len;
9735 proto_tree *subtree = tree;
9737 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9738 lastoffset = offset;
9739 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9740 /* maybe a listOfReadAccessResults if we spot a closing tag here */
9741 if (tag_is_closing(tag_info)) {
9743 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
9748 case 0: /* objectSpecifier */
9749 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9751 case 1: /* list of Results */
9752 if (tag_is_opening(tag_info)) {
9753 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfResults");
9754 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9759 case 2: /* propertyIdentifier */
9760 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
9762 case 5: /* propertyAccessError */
9763 if (tag_is_opening(tag_info)) {
9764 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "propertyAccessError");
9765 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9766 /* Error Code follows */
9767 offset = fError(tvb, pinfo, subtree, offset);
9775 if (offset == lastoffset) break; /* nothing happened, exit loop */
9782 fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9784 /* listOfReadAccessResults */
9785 return fReadAccessResult(tvb, pinfo, tree, offset);
9790 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9792 guint lastoffset = 0;
9793 guint8 tag_no, tag_info;
9796 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9797 lastoffset = offset;
9798 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9801 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9803 case 0: /* objectSpecifier */
9804 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
9805 case 0: /* objectType */
9806 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, "Object Type: ", BACnetObjectType, 128);
9808 case 1: /* objectIdentifier */
9809 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9815 case 1: /* propertyValue */
9816 if (tag_is_opening(tag_info)) {
9817 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
9825 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9827 if (offset == lastoffset) break; /* nothing happened, exit loop */
9833 fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9835 return fObjectIdentifier(tvb, pinfo, tree, offset);
9839 fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9841 guint8 tag_no, tag_info;
9843 proto_tree *subtree = tree;
9845 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9847 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9848 /* optional range choice */
9849 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9850 if (tag_is_opening(tag_info)) {
9851 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL,
9852 val_to_str_const(tag_no, BACnetReadRangeOptions, "unknown range option"));
9853 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9855 case 3: /* range byPosition */
9856 case 6: /* range bySequenceNumber, 2004 spec */
9857 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Index: ");
9858 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: ");
9860 case 4: /* range byTime - deprecated in 2004 */
9861 case 7: /* 2004 spec */
9862 offset = fDateTime(tvb, pinfo, subtree, offset, "reference Date/Time: ");
9863 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: ");
9865 case 5: /* range timeRange - deprecated in 2004 */
9866 offset = fDateTime(tvb, pinfo, subtree, offset, "beginning Time: ");
9867 offset = fDateTime(tvb, pinfo, subtree, offset, "ending Time: ");
9872 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9879 fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9881 guint8 tag_no, tag_info;
9883 proto_tree *subtree = tree;
9885 /* set the optional global properties to indicate not-used */
9886 propertyArrayIndex = -1;
9887 /* objectIdentifier, propertyIdentifier, and
9888 OPTIONAL propertyArrayIndex */
9889 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9890 /* resultFlags => BACnetResultFlags ::= BIT STRING */
9891 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
9895 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "item Count: ");
9897 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9898 if (tag_is_opening(tag_info)) {
9899 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9900 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "itemData");
9901 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9902 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
9903 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9905 /* firstSequenceNumber - OPTIONAL */
9906 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9907 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "first Sequence Number: ");
9914 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9916 guint lastoffset = 0;
9918 guint8 tag_no, tag_info;
9919 proto_tree* subtree = NULL;
9921 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9923 if (tag_is_opening(tag_info)) {
9924 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL,
9925 val_to_str_const(tag_no, BACnetFileAccessOption, "invalid access method"));
9926 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9927 offset = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "invalid option"));
9928 offset = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileWriteInfo, "unknown option"));
9931 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
9932 /* exit loop if nothing happens inside */
9933 lastoffset = offset;
9934 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "Record Data: ");
9938 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
9939 /* More Flag is not set, so we can look for closing tag in this segment */
9940 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9941 if (tag_is_closing(tag_info)) {
9942 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9950 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9952 guint8 tag_no, tag_info;
9954 proto_tree *subtree = tree;
9956 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9958 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9960 if (tag_is_opening(tag_info)) {
9961 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL,
9962 val_to_str_const(tag_no, BACnetFileAccessOption, "unknown access method"));
9963 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9964 offset = fSignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
9965 offset = fUnsignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileRequestCount, "unknown option"));
9966 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9972 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9975 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* file Identifier */
9976 offset = fAccessMethod(tvb, pinfo, tree, offset);
9982 fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9984 guint tag_no = fTagNo(tvb, offset);
9985 return fSignedTag(tvb, pinfo, tree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
9989 fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9991 offset = fApplicationTypes(tvb, pinfo, tree, offset, "End Of File: ");
9992 offset = fAccessMethod(tvb, pinfo, tree, offset);
9998 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
10000 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10001 return fReadAccessSpecification(tvb, pinfo, subtree, offset);
10005 fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10007 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10008 return fReadAccessResult(tvb, pinfo, tree, offset);
10012 fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10014 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10017 switch (service_choice) {
10018 case 0: /* acknowledgeAlarm */
10019 offset = fAcknowledgeAlarmRequest(tvb, pinfo, tree, offset);
10021 case 1: /* confirmedCOVNotification */
10022 offset = fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
10024 case 2: /* confirmedEventNotification */
10025 offset = fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
10027 case 3: /* confirmedGetAlarmSummary conveys no parameters */
10029 case 4: /* getEnrollmentSummaryRequest */
10030 offset = fGetEnrollmentSummaryRequest(tvb, pinfo, tree, offset);
10032 case 5: /* subscribeCOVRequest */
10033 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
10035 case 6: /* atomicReadFile-Request */
10036 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
10038 case 7: /* atomicWriteFile-Request */
10039 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
10041 case 8: /* AddListElement-Request */
10042 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
10044 case 9: /* removeListElement-Request */
10045 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
10047 case 10: /* createObjectRequest */
10048 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
10050 case 11: /* deleteObject */
10051 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
10054 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
10057 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
10060 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
10063 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
10066 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
10069 offset = fDeviceCommunicationControlRequest(tvb, pinfo, tree, offset);
10072 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
10075 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
10078 offset = fReinitializeDeviceRequest(tvb, pinfo, tree, offset);
10081 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
10084 offset = fVtCloseRequest(tvb, pinfo, tree, offset);
10087 offset = fVtDataRequest(tvb, pinfo, tree, offset);
10090 offset = fAuthenticateRequest(tvb, pinfo, tree, offset);
10093 offset = fRequestKeyRequest(tvb, pinfo, tree, offset);
10096 offset = fReadRangeRequest(tvb, pinfo, tree, offset);
10099 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
10102 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
10105 offset = fGetEventInformationRequest(tvb, pinfo, tree, offset);
10114 fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10116 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10119 switch (service_choice) {
10120 case 3: /* confirmedEventNotificationAck */
10121 offset = fGetAlarmSummaryAck(tvb, pinfo, tree, offset);
10123 case 4: /* getEnrollmentSummaryAck */
10124 offset = fGetEnrollmentSummaryAck(tvb, pinfo, tree, offset);
10126 case 6: /* atomicReadFile */
10127 offset = fAtomicReadFileAck(tvb, pinfo, tree, offset);
10129 case 7: /* atomicReadFileAck */
10130 offset = fAtomicWriteFileAck(tvb, pinfo, tree, offset);
10132 case 10: /* createObject */
10133 offset = fCreateObjectAck(tvb, pinfo, tree, offset);
10136 offset = fReadPropertyAck(tvb, pinfo, tree, offset);
10139 offset = fReadPropertyConditionalAck(tvb, pinfo, tree, offset);
10142 offset = fReadPropertyMultipleAck(tvb, pinfo, tree, offset);
10145 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
10148 offset = fVtOpenAck(tvb, pinfo, tree, offset);
10151 offset = fVtDataAck(tvb, pinfo, tree, offset);
10154 offset = fAuthenticateAck(tvb, pinfo, tree, offset);
10157 offset = fReadRangeAck(tvb, pinfo, tree, offset);
10160 offset = fGetEventInformationACK(tvb, pinfo, tree, offset);
10169 fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10171 /* BACnetObjectIdentifier */
10172 offset = fApplicationTypes(tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
10174 /* MaxAPDULengthAccepted */
10175 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
10177 /* segmentationSupported */
10178 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
10179 "Segmentation Supported: ", BACnetSegmentation);
10182 return fVendorIdentifier(tvb, pinfo, tree, offset);
10186 fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10188 /* BACnetDeviceIdentifier */
10189 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Device Identifier: ");
10191 /* BACnetObjectIdentifier */
10192 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
10195 return fApplicationTypes(tvb, pinfo, tree, offset, "Object Name: ");
10200 fWhoIsRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
10202 guint lastoffset = 0;
10206 guint8 tag_no, tag_info;
10209 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10210 lastoffset = offset;
10212 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10216 /* DeviceInstanceRangeLowLimit Optional */
10217 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
10218 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
10219 offset = fDevice_Instance(tvb, pinfo, tree, offset,
10220 hf_Device_Instance_Range_Low_Limit);
10223 /* DeviceInstanceRangeHighLimit Optional but
10224 required if DeviceInstanceRangeLowLimit is there */
10225 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
10226 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
10227 offset = fDevice_Instance(tvb, pinfo, tree, offset,
10228 hf_Device_Instance_Range_High_Limit);
10233 if (offset == lastoffset) break; /* nothing happened, exit loop */
10239 fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10241 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10244 switch (service_choice) {
10245 case 0: /* I-Am-Request */
10246 offset = fIAmRequest(tvb, pinfo, tree, offset);
10248 case 1: /* i-Have Request */
10249 offset = fIHaveRequest(tvb, pinfo, tree, offset);
10251 case 2: /* unconfirmedCOVNotification */
10252 offset = fUnconfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
10254 case 3: /* unconfirmedEventNotification */
10255 offset = fUnconfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
10257 case 4: /* unconfirmedPrivateTransfer */
10258 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
10260 case 5: /* unconfirmedTextMessage */
10261 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
10263 case 206: /* utc-time-synchronization-recipients */
10264 case 6: /* timeSynchronization */
10265 offset = fTimeSynchronizationRequest(tvb, pinfo, tree, offset);
10267 case 7: /* who-Has */
10268 offset = fWhoHas(tvb, pinfo, tree, offset);
10270 case 8: /* who-Is */
10271 offset = fWhoIsRequest(tvb, pinfo, tree, offset);
10273 case 9: /* utcTimeSynchronization */
10274 offset = fUTCTimeSynchronizationRequest(tvb, pinfo, tree, offset);
10283 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
10284 gint *svc, proto_item **tt)
10287 proto_tree *bacapp_tree_control;
10292 tmp = (gint) tvb_get_guint8(tvb, offset);
10293 bacapp_flags = tmp & 0x0f;
10298 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
10299 if (bacapp_flags & 0x08)
10300 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
10302 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10303 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
10304 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
10306 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
10307 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
10308 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
10309 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
10310 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
10311 offset, 1, ENC_BIG_ENDIAN);
10312 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
10313 offset, 1, ENC_BIG_ENDIAN);
10316 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
10317 if (bacapp_flags & 0x08) {
10318 bacapp_seq = tvb_get_guint8(tvb, offset);
10319 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
10320 offset++, 1, ENC_BIG_ENDIAN);
10321 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
10322 offset++, 1, ENC_BIG_ENDIAN);
10324 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
10325 offset++, 1, ENC_BIG_ENDIAN);
10330 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
10331 { /* BACnet-Confirmed-Request */
10332 /* ASHRAE 135-2001 20.1.2 */
10334 return fConfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, svc);
10338 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10339 { /* BACnet-Confirmed-Request */
10340 /* ASHRAE 135-2001 20.1.2 */
10342 proto_item *tt = 0;
10344 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
10345 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
10349 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10350 { /* BACnet-Unconfirmed-Request-PDU */
10351 /* ASHRAE 135-2001 20.1.3 */
10355 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10357 tmp = tvb_get_guint8(tvb, offset);
10358 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
10359 offset++, 1, ENC_BIG_ENDIAN);
10360 /* Service Request follows... Variable Encoding 20.2ff */
10361 return fUnconfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, tmp);
10365 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10366 { /* BACnet-Simple-Ack-PDU */
10367 /* ASHRAE 135-2001 20.1.4 */
10369 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10371 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
10372 offset++, 1, ENC_BIG_ENDIAN);
10373 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
10374 offset++, 1, ENC_BIG_ENDIAN);
10380 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
10381 { /* BACnet-Complex-Ack-PDU */
10382 /* ASHRAE 135-2001 20.1.5 */
10384 /* Service ACK follows... */
10385 return fConfirmedServiceAck(tvb, pinfo, bacapp_tree, offset, svc);
10389 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10390 { /* BACnet-Complex-Ack-PDU */
10391 /* ASHRAE 135-2001 20.1.5 */
10393 proto_item *tt = 0;
10395 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
10396 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
10400 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10401 { /* BACnet-SegmentAck-PDU */
10402 /* ASHRAE 135-2001 20.1.6 */
10405 proto_tree *bacapp_tree_control;
10407 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10408 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10410 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
10411 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10412 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10413 offset++, 1, ENC_BIG_ENDIAN);
10414 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
10415 offset++, 1, ENC_BIG_ENDIAN);
10416 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
10417 offset++, 1, ENC_BIG_ENDIAN);
10422 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10424 guint8 tag_info = 0;
10425 guint8 parsed_tag = 0;
10428 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
10429 offset = fError(tvb, pinfo, tree, offset);
10430 return offset + fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
10434 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10436 guint lastoffset = 0;
10437 guint8 tag_no = 0, tag_info = 0;
10439 proto_tree *subtree = tree;
10441 guint vendor_identifier = 0;
10442 guint service_number = 0;
10443 guint8 tag_len = 0;
10445 while (tvb_reported_length_remaining(tvb, offset) > 0) {
10446 /* exit loop if nothing happens inside */
10447 lastoffset = offset;
10448 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10450 case 0: /* errorType */
10451 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
10453 case 1: /* vendorID */
10454 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
10455 if (col_get_writable(pinfo->cinfo))
10456 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
10457 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
10459 case 2: /* serviceNumber */
10460 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
10461 if (col_get_writable(pinfo->cinfo))
10462 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
10463 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: ");
10465 case 3: /* errorParameters */
10466 if (tag_is_opening(tag_info)) {
10467 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1,
10468 ett_bacapp_value, NULL, "error Parameters");
10469 propertyIdentifier = -1;
10470 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10471 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
10472 } else if (tag_is_closing(tag_info)) {
10473 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
10474 &tag_no, &tag_info, &lvt);
10477 /* error condition: let caller handle */
10484 if (offset == lastoffset) break; /* nothing happened, exit loop */
10490 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10492 guint lastoffset = 0;
10494 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10495 lastoffset = offset;
10496 switch (fTagNo(tvb, offset)) {
10497 case 0: /* errorType */
10498 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10500 case 1: /* firstFailedElementNumber */
10501 offset = fUnsignedTag(tvb, pinfo, tree, offset, "first failed element number: ");
10506 if (offset == lastoffset) break; /* nothing happened, exit loop */
10512 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10514 /* Identical to CreateObjectError */
10515 return fCreateObjectError(tvb, pinfo, tree, offset);
10519 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10521 guint8 tag_no = 0, tag_info = 0;
10524 if (fTagNo(tvb, offset) == 0) {
10526 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10527 if (fTagNo(tvb, offset) == 1) {
10528 /* listOfVTSessionIdentifiers [OPTIONAL] */
10529 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10530 offset = fVtCloseRequest(tvb, pinfo, tree, offset);
10531 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10534 /* should report bad packet if initial tag wasn't 0 */
10539 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10541 guint lastoffset = 0;
10542 guint8 tag_no = 0, tag_info = 0;
10545 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10546 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10547 lastoffset = offset;
10548 switch (fTagNo(tvb, offset)) {
10549 case 0: /* errorType */
10550 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10552 case 1: /* firstFailedWriteAttempt */
10553 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10554 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
10555 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10560 if (offset == lastoffset) break; /* nothing happened, exit loop */
10566 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10568 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
10569 "error Class: ", BACnetErrorClass, 64);
10570 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
10571 "error Code: ", BACnetErrorCode, 256);
10575 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
10578 case 8: /* no break here !!!! */
10580 offset = fChangeListError(tvb, pinfo, tree, offset);
10583 offset = fCreateObjectError(tvb, pinfo, tree, offset);
10586 offset = fWritePropertyMultipleError(tvb, pinfo, tree, offset);
10589 offset = fConfirmedPrivateTransferError(tvb, pinfo, tree, offset);
10592 offset = fVTCloseError(tvb, pinfo, tree, offset);
10595 return fError(tvb, pinfo, tree, offset);
10601 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10602 { /* BACnet-Error-PDU */
10603 /* ASHRAE 135-2001 20.1.7 */
10606 proto_tree *bacapp_tree_control;
10609 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10610 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10612 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10613 offset++, 1, ENC_BIG_ENDIAN);
10614 tmp = tvb_get_guint8(tvb, offset);
10615 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
10616 offset++, 1, ENC_BIG_ENDIAN);
10617 /* Error Handling follows... */
10618 return fBACnetError(tvb, pinfo, bacapp_tree, offset, tmp);
10622 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10623 { /* BACnet-Reject-PDU */
10624 /* ASHRAE 135-2001 20.1.8 */
10627 proto_tree *bacapp_tree_control;
10629 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10630 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10632 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10633 offset++, 1, ENC_BIG_ENDIAN);
10634 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
10635 offset++, 1, ENC_BIG_ENDIAN);
10640 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10641 { /* BACnet-Abort-PDU */
10642 /* ASHRAE 135-2001 20.1.9 */
10645 proto_tree *bacapp_tree_control;
10647 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10648 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10650 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10651 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10652 offset++, 1, ENC_BIG_ENDIAN);
10653 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
10654 offset++, 1, ENC_BIG_ENDIAN);
10659 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10661 guint8 flag, bacapp_type;
10664 flag = (gint) tvb_get_guint8(tvb, 0);
10665 bacapp_type = (flag >> 4) & 0x0f;
10671 /* ASHRAE 135-2001 20.1.1 */
10672 switch (bacapp_type) {
10673 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
10674 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
10676 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
10677 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
10679 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
10680 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
10682 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
10683 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
10685 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
10686 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
10688 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
10689 offset = fErrorPDU(tvb, pinfo, tree, offset);
10691 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
10692 offset = fRejectPDU(tvb, pinfo, tree, offset);
10694 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
10695 offset = fAbortPDU(tvb, pinfo, tree, offset);
10702 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10704 guint8 flag, bacapp_type;
10705 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
10706 tvbuff_t *new_tvb = NULL;
10708 guint8 bacapp_seqno = 0;
10709 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
10710 guint8 bacapp_invoke_id = 0;
10712 proto_tree *bacapp_tree = NULL;
10715 proto_item *tt = 0;
10718 /* Strings for BACnet Statistics */
10719 const gchar errstr[] = "ERROR: ";
10720 const gchar rejstr[] = "REJECTED: ";
10721 const gchar abortstr[] = "ABORTED: ";
10722 const gchar sackstr[] = " (SimpleAck)";
10723 const gchar cackstr[] = " (ComplexAck)";
10724 const gchar uconfsreqstr[] = " (Unconfirmed Service Request)";
10725 const gchar confsreqstr[] = " (Confirmed Service Request)";
10727 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
10728 col_clear(pinfo->cinfo, COL_INFO);
10730 flag = tvb_get_guint8(tvb, 0);
10731 bacapp_type = (flag >> 4) & 0x0f;
10733 /* show some descriptive text in the INFO column */
10734 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
10735 val_to_str_const(bacapp_type, BACnetTypeName, "# unknown APDU #"));
10737 bacinfo.service_type = NULL;
10738 bacinfo.invoke_id = NULL;
10739 bacinfo.instance_ident = NULL;
10740 bacinfo.object_ident = NULL;
10742 switch (bacapp_type) {
10743 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10744 /* segmented messages have 2 additional bytes */
10745 if (flag & BACAPP_SEGMENTED_REQUEST) {
10748 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
10749 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10750 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
10751 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
10752 bacapp_service = tvb_get_guint8(tvb, offset + 5);
10755 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10756 bacapp_service = tvb_get_guint8(tvb, offset + 3);
10758 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
10759 val_to_str_const(bacapp_service,
10760 BACnetConfirmedServiceChoice,
10761 bacapp_unknown_service_str),
10764 updateBacnetInfoValue(BACINFO_INVOKEID,
10765 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10767 updateBacnetInfoValue(BACINFO_SERVICE,
10768 wmem_strconcat(wmem_packet_scope(),
10769 val_to_str_const(bacapp_service,
10770 BACnetConfirmedServiceChoice,
10771 bacapp_unknown_service_str),
10772 confsreqstr, NULL));
10774 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
10775 bacapp_service = tvb_get_guint8(tvb, offset + 1);
10776 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
10777 val_to_str_const(bacapp_service,
10778 BACnetUnconfirmedServiceChoice,
10779 bacapp_unknown_service_str));
10781 updateBacnetInfoValue(BACINFO_SERVICE,
10782 wmem_strconcat(wmem_packet_scope(),
10783 val_to_str_const(bacapp_service,
10784 BACnetUnconfirmedServiceChoice,
10785 bacapp_unknown_service_str),
10786 uconfsreqstr, NULL));
10788 case BACAPP_TYPE_SIMPLE_ACK:
10789 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10790 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10791 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10792 val_to_str_const(bacapp_service,
10793 BACnetConfirmedServiceChoice,
10794 bacapp_unknown_service_str),
10797 updateBacnetInfoValue(BACINFO_INVOKEID,
10798 wmem_strdup_printf(wmem_packet_scope(),
10799 "Invoke ID: %d", bacapp_invoke_id));
10801 updateBacnetInfoValue(BACINFO_SERVICE,
10802 wmem_strconcat(wmem_packet_scope(),
10803 val_to_str_const(bacapp_service,
10804 BACnetConfirmedServiceChoice,
10805 bacapp_unknown_service_str),
10808 case BACAPP_TYPE_COMPLEX_ACK:
10809 /* segmented messages have 2 additional bytes */
10810 if (flag & BACAPP_SEGMENTED_REQUEST) {
10813 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
10814 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10815 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
10816 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
10817 bacapp_service = tvb_get_guint8(tvb, offset + 4);
10820 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10821 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10823 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10824 val_to_str_const(bacapp_service,
10825 BACnetConfirmedServiceChoice,
10826 bacapp_unknown_service_str),
10829 updateBacnetInfoValue(BACINFO_INVOKEID,
10830 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10832 updateBacnetInfoValue(BACINFO_SERVICE,
10833 wmem_strconcat(wmem_packet_scope(),
10834 val_to_str_const(bacapp_service,
10835 BACnetConfirmedServiceChoice,
10836 bacapp_unknown_service_str),
10839 case BACAPP_TYPE_SEGMENT_ACK:
10840 /* nothing more to add */
10842 case BACAPP_TYPE_ERROR:
10843 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10844 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10845 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10846 val_to_str_const(bacapp_service,
10847 BACnetConfirmedServiceChoice,
10848 bacapp_unknown_service_str),
10851 updateBacnetInfoValue(BACINFO_INVOKEID,
10852 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10854 updateBacnetInfoValue(BACINFO_SERVICE,
10855 wmem_strconcat(wmem_packet_scope(),
10857 val_to_str_const(bacapp_service,
10858 BACnetConfirmedServiceChoice,
10859 bacapp_unknown_service_str),
10862 case BACAPP_TYPE_REJECT:
10863 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10864 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10865 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10866 val_to_split_str(bacapp_reason,
10868 BACnetRejectReason,
10869 ASHRAE_Reserved_Fmt,
10870 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10872 updateBacnetInfoValue(BACINFO_INVOKEID,
10873 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10875 updateBacnetInfoValue(BACINFO_SERVICE,
10876 wmem_strconcat(wmem_packet_scope(), rejstr,
10877 val_to_split_str(bacapp_reason, 64,
10878 BACnetRejectReason,
10879 ASHRAE_Reserved_Fmt,
10880 Vendor_Proprietary_Fmt),
10883 case BACAPP_TYPE_ABORT:
10884 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10885 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10886 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10887 val_to_split_str(bacapp_reason,
10890 ASHRAE_Reserved_Fmt,
10891 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10893 updateBacnetInfoValue(BACINFO_INVOKEID,
10894 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10896 updateBacnetInfoValue(BACINFO_SERVICE,
10897 wmem_strconcat(wmem_packet_scope(), abortstr,
10898 val_to_split_str(bacapp_reason,
10901 ASHRAE_Reserved_Fmt,
10902 Vendor_Proprietary_Fmt),
10907 /* nothing more to add */
10911 save_fragmented = pinfo->fragmented;
10913 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA);
10914 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
10917 do_the_dissection(tvb, pinfo, bacapp_tree);
10919 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
10920 /* not resetting the offset so the remaining can be done */
10922 if (fragment) { /* fragmented */
10923 fragment_head *frag_msg;
10925 pinfo->fragmented = TRUE;
10927 frag_msg = fragment_add_seq_check(&msg_reassembly_table,
10930 bacapp_invoke_id, /* ID for fragments belonging together */
10932 bacapp_seqno, /* fragment sequence number */
10933 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
10934 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
10935 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
10936 "Reassembled BACapp", frag_msg, &msg_frag_items,
10939 if (new_tvb) { /* Reassembled */
10940 col_append_str(pinfo->cinfo, COL_INFO,
10941 " (Message Reassembled)");
10942 } else { /* Not last packet of reassembled Short Message */
10943 col_append_fstr(pinfo->cinfo, COL_INFO,
10944 " (Message fragment %u)", bacapp_seqno);
10946 if (new_tvb) { /* take it all */
10947 switch (bacapp_type) {
10948 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10949 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10951 case BACAPP_TYPE_COMPLEX_ACK:
10952 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
10961 pinfo->fragmented = save_fragmented;
10964 tap_queue_packet(bacapp_tap, pinfo, &bacinfo);
10968 bacapp_init_routine(void)
10970 reassembly_table_init(&msg_reassembly_table,
10971 &addresses_reassembly_table_functions);
10975 proto_register_bacapp(void)
10977 static hf_register_info hf[] = {
10979 { "APDU Type", "bacapp.type",
10980 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
10982 { &hf_bacapp_pduflags,
10983 { "PDU Flags", "bacapp.pduflags",
10984 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
10987 { "Segmented Request", "bacapp.segmented_request",
10988 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
10991 { "More Segments", "bacapp.more_segments",
10992 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
10995 { "SA", "bacapp.SA",
10996 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
10998 { &hf_bacapp_max_adpu_size,
10999 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
11000 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
11002 { &hf_bacapp_response_segments,
11003 { "Max Response Segments accepted", "bacapp.response_segments",
11004 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
11006 { &hf_bacapp_objectType,
11007 { "Object Type", "bacapp.objectType",
11008 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
11010 { &hf_bacapp_instanceNumber,
11011 { "Instance Number", "bacapp.instance_number",
11012 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
11014 { &hf_BACnetPropertyIdentifier,
11015 { "Property Identifier", "bacapp.property_identifier",
11016 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
11018 { &hf_BACnetVendorIdentifier,
11019 { "Vendor Identifier", "bacapp.vendor_identifier",
11020 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &BACnetVendorIdentifiers_ext, 0, NULL, HFILL }
11022 { &hf_BACnetRestartReason,
11023 { "Restart Reason", "bacapp.restart_reason",
11024 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
11026 { &hf_bacapp_invoke_id,
11027 { "Invoke ID", "bacapp.invoke_id",
11028 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11030 { &hf_bacapp_sequence_number,
11031 { "Sequence Number", "bacapp.sequence_number",
11032 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11034 { &hf_bacapp_window_size,
11035 { "Proposed Window Size", "bacapp.window_size",
11036 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11038 { &hf_bacapp_service,
11039 { "Service Choice", "bacapp.confirmed_service",
11040 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
11042 { &hf_bacapp_uservice,
11043 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
11044 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
11047 { "NAK", "bacapp.NAK",
11048 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
11051 { "SRV", "bacapp.SRV",
11052 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
11054 { &hf_Device_Instance_Range_Low_Limit,
11055 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
11056 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
11058 { &hf_Device_Instance_Range_High_Limit,
11059 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
11060 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
11062 { &hf_BACnetRejectReason,
11063 { "Reject Reason", "bacapp.reject_reason",
11064 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
11066 { &hf_BACnetAbortReason,
11067 { "Abort Reason", "bacapp.abort_reason",
11068 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
11070 { &hf_BACnetApplicationTagNumber,
11071 { "Application Tag Number",
11072 "bacapp.application_tag_number",
11073 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
11076 { &hf_BACnetContextTagNumber,
11077 { "Context Tag Number",
11078 "bacapp.context_tag_number",
11079 FT_UINT8, BASE_DEC, NULL, 0xF0,
11082 { &hf_BACnetExtendedTagNumber,
11083 { "Extended Tag Number",
11084 "bacapp.extended_tag_number",
11085 FT_UINT8, BASE_DEC, NULL, 0,
11088 { &hf_BACnetNamedTag,
11090 "bacapp.named_tag",
11091 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
11094 { &hf_BACnetCharacterSet,
11095 { "String Character Set",
11096 "bacapp.string_character_set",
11097 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet), 0,
11100 { &hf_BACnetTagClass,
11101 { "Tag Class", "bacapp.tag_class",
11102 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
11104 { &hf_bacapp_tag_lvt,
11105 { "Length Value Type",
11107 FT_UINT8, BASE_DEC, NULL, 0,
11110 { &hf_bacapp_tag_ProcessId,
11111 { "ProcessIdentifier", "bacapp.processId",
11112 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
11114 { &hf_bacapp_tag_IPV4,
11115 { "IPV4", "bacapp.IPV4",
11116 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
11118 { &hf_bacapp_tag_IPV6,
11119 { "IPV6", "bacapp.IPV6",
11120 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
11122 { &hf_bacapp_tag_PORT,
11123 { "Port", "bacapp.Port",
11124 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
11126 {&hf_msg_fragments,
11127 {"Message fragments", "bacapp.fragments",
11128 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11130 {"Message fragment", "bacapp.fragment",
11131 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11132 {&hf_msg_fragment_overlap,
11133 {"Message fragment overlap", "bacapp.fragment.overlap",
11134 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11135 {&hf_msg_fragment_overlap_conflicts,
11136 {"Message fragment overlapping with conflicting data",
11137 "bacapp.fragment.overlap.conflicts",
11138 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11139 {&hf_msg_fragment_multiple_tails,
11140 {"Message has multiple tail fragments",
11141 "bacapp.fragment.multiple_tails",
11142 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11143 {&hf_msg_fragment_too_long_fragment,
11144 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
11145 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11146 {&hf_msg_fragment_error,
11147 {"Message defragmentation error", "bacapp.fragment.error",
11148 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11149 {&hf_msg_fragment_count,
11150 {"Message fragment count", "bacapp.fragment.count",
11151 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
11152 {&hf_msg_reassembled_in,
11153 {"Reassembled in", "bacapp.reassembled.in",
11154 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11155 {&hf_msg_reassembled_length,
11156 {"Reassembled BACapp length", "bacapp.reassembled.length",
11157 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
11159 static gint *ett[] = {
11161 &ett_bacapp_control,
11170 static ei_register_info ei[] = {
11171 { &ei_bacapp_bad_length, { "bacapp.bad_length", PI_MALFORMED, PI_ERROR, "Wrong length indicated", EXPFILL }},
11174 expert_module_t* expert_bacapp;
11176 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
11177 "BACapp", "bacapp");
11179 proto_register_field_array(proto_bacapp, hf, array_length(hf));
11180 proto_register_subtree_array(ett, array_length(ett));
11181 expert_bacapp = expert_register_protocol(proto_bacapp);
11182 expert_register_field_array(expert_bacapp, ei, array_length(ei));
11183 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
11184 register_init_routine(&bacapp_init_routine);
11186 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
11187 "BACapp Vendor Identifier",
11188 FT_UINT8, BASE_HEX);
11190 /* Register BACnet Statistic trees */
11191 register_bacapp_stat_trees();
11192 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
11196 * Editor modelines - http://www.wireshark.org/tools/modelines.html
11199 * c-basic-offset: 4
11201 * indent-tabs-mode: nil
11204 * vi: set shiftwidth=4 tabstop=8 expandtab:
11205 * :indentSize=4:tabSize=8:noTabs=true: