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.
30 #include <epan/packet.h>
31 #include <epan/to_str.h>
32 #include <epan/reassemble.h>
33 #include <epan/expert.h>
34 #include <epan/stats_tree.h>
35 #include "packet-bacapp.h"
37 static int bacapp_tap = -1;
39 /* formerly bacapp.h contains definitions and forward declarations */
42 #define FAULT proto_tree_add_text(subtree, tvb, offset, tvb_reported_length(tvb) - offset, "something is going wrong here !!"); \
43 offset = tvb_reported_length(tvb);
46 /* BACnet PDU Types */
47 #define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0
48 #define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1
49 #define BACAPP_TYPE_SIMPLE_ACK 2
50 #define BACAPP_TYPE_COMPLEX_ACK 3
51 #define BACAPP_TYPE_SEGMENT_ACK 4
52 #define BACAPP_TYPE_ERROR 5
53 #define BACAPP_TYPE_REJECT 6
54 #define BACAPP_TYPE_ABORT 7
55 #define MAX_BACAPP_TYPE 8
57 #define BACAPP_SEGMENTED_REQUEST 0x08
58 #define BACAPP_MORE_SEGMENTS 0x04
59 #define BACAPP_SEGMENTED_RESPONSE 0x02
60 #define BACAPP_SEGMENT_NAK 0x02
61 #define BACAPP_SENT_BY 0x01
65 * dissect_bacapp ::= CHOICE {
66 * confirmed-request-PDU [0] BACnet-Confirmed-Request-PDU,
67 * unconfirmed-request-PDU [1] BACnet-Unconfirmed-Request-PDU,
68 * simpleACK-PDU [2] BACnet-SimpleACK-PDU,
69 * complexACK-PDU [3] BACnet-ComplexACK-PDU,
70 * segmentACK-PDU [4] BACnet-SegmentACK-PDU,
71 * error-PDU [5] BACnet-Error-PDU,
72 * reject-PDU [6] BACnet-Reject-PDU,
73 * abort-PDU [7] BACnet-Abort-PDU
75 * @param tvb the tv buffer of the current data
76 * @param pinfo the packet info of the current data
77 * @param tree the tree to append this item to
80 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
83 * ConfirmedRequest-PDU ::= SEQUENCE {
84 * pdu-type [0] Unsigned (0..15), -- 0 for this PDU Type
85 * segmentedMessage [1] BOOLEAN,
86 * moreFollows [2] BOOLEAN,
87 * segmented-response-accepted [3] BOOLEAN,
88 * reserved [4] Unsigned (0..3), -- must be set zero
89 * max-segments-accepted [5] Unsigned (0..7), -- as per 20.1.2.4
90 * max-APDU-length-accepted [5] Unsigned (0..15), -- as per 20.1.2.5
91 * invokeID [6] Unsigned (0..255),
92 * sequence-number [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
93 * proposed-window-size [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
94 * service-choice [9] BACnetConfirmedServiceChoice,
95 * service-request [10] BACnet-Confirmed-Service-Request OPTIONAL
97 * @param tvb the tv buffer of the current data
98 * @param pinfo the packet info of the current data
99 * @param tree the tree to append this item to
100 * @param offset the offset in the tvb
101 * @return modified offset
104 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
107 * @param tvb the tv buffer of the current data
108 * @param pinfo the packet info of the current data
109 * @param tree the tree to append this item to
110 * @param offset the offset in the tvb
111 * @param ack - indocates whether working on request or ack
112 * @param svc - output variable to return service choice
113 * @param tt - output varable to return service choice item
114 * @return modified offset
117 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 ack,
118 gint *svc, proto_item **tt);
121 * Unconfirmed-Request-PDU ::= SEQUENCE {
122 * pdu-type [0] Unsigned (0..15), -- 1 for this PDU type
123 * reserved [1] Unsigned (0..15), -- must be set zero
124 * service-choice [2] BACnetUnconfirmedServiceChoice,
125 * service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
127 * @param tvb the tv buffer of the current data
128 * @param pinfo the packet info of the current data
129 * @param tree the tree to append this item to
130 * @param offset the offset in the tvb
131 * @return modified offset
134 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
137 * SimpleACK-PDU ::= SEQUENCE {
138 * pdu-type [0] Unsigned (0..15), -- 2 for this PDU type
139 * reserved [1] Unsigned (0..15), -- must be set zero
140 * invokeID [2] Unsigned (0..255),
141 * service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
143 * @param tvb the tv buffer of the current data
144 * @param pinfo the packet info of the current data
145 * @param tree the tree to append this item to
146 * @param offset the offset in the tvb
147 * @return modified offset
150 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
153 * ComplexACK-PDU ::= SEQUENCE {
154 * pdu-type [0] Unsigned (0..15), -- 3 for this PDU Type
155 * segmentedMessage [1] BOOLEAN,
156 * moreFollows [2] BOOLEAN,
157 * reserved [3] Unsigned (0..3), -- must be set zero
158 * invokeID [4] Unsigned (0..255),
159 * sequence-number [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
160 * proposed-window-size [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
161 * service-ACK-choice [7] BACnetConfirmedServiceChoice,
162 * service-ACK [8] BACnet-Confirmed-Service-Request -- Context-specific tags 0..8 are NOT used in header encoding
164 * @param tvb the tv buffer of the current data
165 * @param pinfo the packet info of the current data
166 * @param tree the tree to append this item to
167 * @param offset the offset in the tvb
168 * @return modified offset
171 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
174 * SegmentACK-PDU ::= SEQUENCE {
175 * pdu-type [0] Unsigned (0..15), -- 4 for this PDU Type
176 * reserved [1] Unsigned (0..3), -- must be set zero
177 * negative-ACK [2] BOOLEAN,
178 * server [3] BOOLEAN,
179 * original-invokeID [4] Unsigned (0..255),
180 * sequence-number [5] Unsigned (0..255),
181 * actual-window-size [6] Unsigned (0..127)
183 * @param tvb the tv buffer of the current data
184 * @param pinfo the packet info of the current data
185 * @param tree the tree to append this item to
186 * @param offset the offset in the tvb
187 * @return modified offset
190 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
193 * Error-PDU ::= SEQUENCE {
194 * pdu-type [0] Unsigned (0..15), -- 5 for this PDU Type
195 * reserved [1] Unsigned (0..3), -- must be set zero
196 * original-invokeID [2] Unsigned (0..255),
197 * error-choice [3] BACnetConfirmedServiceChoice,
198 * error [4] BACnet-Error
200 * @param tvb the tv buffer of the current data
201 * @param pinfo the packet info of the current data
202 * @param tree the tree to append this item to
203 * @param offset the offset in the tvb
204 * @return modified offset
207 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
210 * Reject-PDU ::= SEQUENCE {
211 * pdu-type [0] Unsigned (0..15), -- 6 for this PDU Type
212 * reserved [1] Unsigned (0..3), -- must be set zero
213 * original-invokeID [2] Unsigned (0..255),
214 * reject-reason [3] BACnetRejectReason
216 * @param tvb the tv buffer of the current data
217 * @param pinfo the packet info of the current data
218 * @param tree the tree to append this item to
219 * @param offset the offset in the tvb
220 * @return modified offset
223 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
226 * Abort-PDU ::= SEQUENCE {
227 * pdu-type [0] Unsigned (0..15), -- 7 for this PDU Type
228 * reserved [1] Unsigned (0..3), -- must be set zero
229 * server [2] BOOLEAN,
230 * original-invokeID [3] Unsigned (0..255),
231 * abort-reason [4] BACnetAbortReason
233 * @param tvb the tv buffer of the current data
234 * @param pinfo the packet info of the current data
235 * @param tree the tree to append this item to
236 * @param offset the offset in the tvb
237 * @return modified offset
240 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
243 * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree
244 * @param tvb the tv buffer of the current data
245 * @param pinfo the packet info of the current data
246 * @param tree the tree to append this item to
247 * @param offset the offset in the tvb
248 * @param label the label of this item
249 * @return modified offset
252 fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
255 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
256 * @param tvb the tv buffer of the current data
257 * @param pinfo the packet info of the current data
258 * @param tree the tree to append this item to
259 * @param offset the offset in the tvb
260 * @param label the label of this item
261 * @return modified offset
264 fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
267 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
268 * @param tvb the tv buffer of the current data
269 * @param pinfo the packet info of the current data
270 * @param tree the tree to append this item to
271 * @param offset the offset in the tvb
272 * @param label the label of this item
273 * @param lvt length of String
274 * @return modified offset
277 fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
280 * 20.2.12, adds the label with Date Value to tree
281 * @param tvb the tv buffer of the current data
282 * @param pinfo the packet info of the current data
283 * @param tree the tree to append this item to
284 * @param offset the offset in the tvb
285 * @param label the label of this item
286 * @return modified offset
289 fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
292 * 20.2.13, adds the label with Time Value to tree
293 * @param tvb the tv buffer of the current data
294 * @param pinfo the packet info of the current data
295 * @param tree the tree to append this item to
296 * @param offset the offset in the tvb
297 * @param label the label of this item
298 * @return modified offset
301 fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
304 * 20.2.14, adds Object Identifier to tree
305 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
306 * @param tvb the tv buffer of the current data
307 * @param pinfo the packet info of the current data
308 * @param tree the tree to append this item to
309 * @param offset the offset in the tvb
310 * @return modified offset
313 fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
316 * BACnet-Confirmed-Service-Request ::= CHOICE {
318 * @param tvb the tv buffer of the current data
319 * @param pinfo the packet info of the current data
320 * @param tree the tree to append this item to
321 * @param offset the offset in the tvb
322 * @param service_choice the service choice
326 fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
329 * BACnet-Confirmed-Service-ACK ::= CHOICE {
331 * @param tvb the tv buffer of the current data
332 * @param pinfo the packet info of the current data
333 * @param tree the tree to append this item to
334 * @param offset the offset in the tvb
335 * @param service_choice the service choice
339 fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
342 * AcknowledgeAlarm-Request ::= SEQUENCE {
343 * acknowledgingProcessIdentifier [0] Unsigned32,
344 * eventObjectIdentifier [1] BACnetObjectIdentifer,
345 * eventStateAcknowledge [2] BACnetEventState,
346 * timeStamp [3] BACnetTimeStamp,
347 * acknowledgementSource [4] Character String,
348 * timeOfAcknowledgement [5] BACnetTimeStamp
350 * @param tvb the tv buffer of the current data
351 * @param pinfo the packet info of the current data
352 * @param tree the tree to append this item to
353 * @param offset the offset in the tvb
354 * @return modified offset
357 fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
360 * ConfirmedCOVNotification-Request ::= SEQUENCE {
361 * subscriberProcessIdentifier [0] Unsigned32,
362 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
363 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
364 * timeRemaining [3] unsigned,
365 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
367 * @param tvb the tv buffer of the current data
368 * @param pinfo the packet info of the current data
369 * @param tree the tree to append this item to
370 * @param offset the offset in the tvb
371 * @return modified offset
374 fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
377 * ConfirmedEventNotification-Request ::= SEQUENCE {
378 * ProcessIdentifier [0] Unsigned32,
379 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
380 * eventObjectIdentifier [2] BACnetObjectIdentifer,
381 * timeStamp [3] BACnetTimeStamp,
382 * notificationClass [4] unsigned,
383 * priority [5] unsigned8,
384 * eventType [6] BACnetEventType,
385 * messageText [7] CharacterString OPTIONAL,
386 * notifyType [8] BACnetNotifyType,
387 * ackRequired [9] BOOLEAN OPTIONAL,
388 * fromState [10] BACnetEventState OPTIONAL,
389 * toState [11] BACnetEventState,
390 * eventValues [12] BACnetNotificationParameters OPTIONAL
392 * @param tvb the tv buffer of the current data
393 * @param pinfo the packet info of the current data
394 * @param tree the tree to append this item to
395 * @param offset the offset in the tvb
396 * @return modified offset
399 fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
402 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
403 * objectIdentifier BACnetObjectIdentifer,
404 * alarmState BACnetEventState,
405 * acknowledgedTransitions BACnetEventTransitionBits
407 * @param tvb the tv buffer of the current data
408 * @param pinfo the packet info of the current data
409 * @param tree the tree to append this item to
410 * @param offset the offset in the tvb
411 * @return modified offset
414 fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
417 * GetEnrollmentSummary-Request ::= SEQUENCE {
418 * acknowledgmentFilter [0] ENUMERATED {
423 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
424 * eventStateFilter [2] ENUMERATED {
431 * eventTypeFilter [3] BACnetEventType OPTIONAL,
432 * priorityFilter [4] SEQUENCE {
433 * minPriority [0] Unsigned8,
434 * maxPriority [1] Unsigned8
436 * notificationClassFilter [5] Unsigned OPTIONAL
438 * @param tvb the tv buffer of the current data
439 * @param pinfo the packet info of the current data
440 * @param tree the tree to append this item to
441 * @param offset the offset in the tvb
442 * @return modified offset
445 fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
448 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
449 * objectIdentifier BACnetObjectIdentifer,
450 * eventType BACnetEventType,
451 * eventState BACnetEventState,
452 * priority Unsigned8,
453 * notificationClass Unsigned OPTIONAL
455 * @param tvb the tv buffer of the current data
456 * @param pinfo the packet info of the current data
457 * @param tree the tree to append this item to
458 * @param offset the offset in the tvb
459 * @return modified offset
462 fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
465 * GetEventInformation-Request ::= SEQUENCE {
466 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
468 * @param tvb the tv buffer of the current data
469 * @param pinfo the packet info of the current data
470 * @param tree the tree to append this item to
471 * @param offset the offset in the tvb
472 * @return modified offset
475 fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
478 * GetEventInformation-ACK ::= SEQUENCE {
479 * listOfEventSummaries [0] listOfEventSummaries,
480 * moreEvents [1] BOOLEAN
482 * @param tvb the tv buffer of the current data
483 * @param pinfo the packet info of the current data
484 * @param tree the tree to append this item to
485 * @param offset the offset in the tvb
486 * @return modified offset
489 fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
492 * LifeSafetyOperation-Request ::= SEQUENCE {
493 * requestingProcessIdentifier [0] Unsigned32
494 * requestingSource [1] CharacterString
495 * request [2] BACnetLifeSafetyOperation
496 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
498 * @param tvb the tv buffer of the current data
499 * @param pinfo the packet info of the current data
500 * @param tree the tree to append this item to
501 * @param offset the offset in the tvb
502 * @return modified offset
505 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
508 * SubscribeCOV-Request ::= SEQUENCE {
509 * subscriberProcessIdentifier [0] Unsigned32
510 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
511 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
512 * lifetime [3] Unsigned OPTIONAL
514 * @param tvb the tv buffer of the current data
515 * @param pinfo the packet info of the current data
516 * @param tree the tree to append this item to
517 * @param offset the offset in the tvb
518 * @return modified offset
521 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
524 * SubscribeCOVProperty-Request ::= SEQUENCE {
525 * subscriberProcessIdentifier [0] Unsigned32
526 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
527 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
528 * lifetime [3] Unsigned OPTIONAL
529 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
530 * covIncrement [5] Unsigned OPTIONAL
532 * @param tvb the tv buffer of the current data
533 * @param pinfo the packet info of the current data
534 * @param tree the tree to append this item to
535 * @param offset the offset in the tvb
536 * @return modified offset
539 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
542 * AtomicReadFile-Request ::= SEQUENCE {
543 * fileIdentifier BACnetObjectIdentifier,
544 * accessMethod CHOICE {
545 * streamAccess [0] SEQUENCE {
546 * fileStartPosition INTEGER,
547 * requestedOctetCount Unsigned
549 * recordAccess [1] SEQUENCE {
550 * fileStartRecord INTEGER,
551 * requestedRecordCount Unsigned
555 * @param tvb the tv buffer of the current data
556 * @param pinfo the packet info of the current data
557 * @param tree the tree to append this item to
558 * @param offset the offset in the tvb
559 * @return modified offset
562 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
565 * AtomicWriteFile-ACK ::= SEQUENCE {
567 * accessMethod CHOICE {
568 * streamAccess [0] SEQUENCE {
569 * fileStartPosition INTEGER,
570 * fileData OCTET STRING
572 * recordAccess [1] SEQUENCE {
573 * fileStartRecord INTEGER,
574 * returnedRecordCount Unsigned,
575 * fileRecordData SEQUENCE OF OCTET STRING
579 * @param tvb the tv buffer of the current data
580 * @param pinfo the packet info of the current data
581 * @param tree the tree to append this item to
582 * @param offset the offset in the tvb
583 * @return modified offset
586 fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
589 * AtomicWriteFile-Request ::= SEQUENCE {
590 * fileIdentifier BACnetObjectIdentifier,
591 * accessMethod CHOICE {
592 * streamAccess [0] SEQUENCE {
593 * fileStartPosition INTEGER,
594 * fileData OCTET STRING
596 * recordAccess [1] SEQUENCE {
597 * fileStartRecord INTEGER,
598 * recordCount Unsigned,
599 * fileRecordData SEQUENCE OF OCTET STRING
603 * @param tvb the tv buffer of the current data
604 * @param pinfo the packet info of the current data
605 * @param tree the tree to append this item to
606 * @param offset the offset in the tvb
607 * @return modified offset
610 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
613 * AtomicWriteFile-ACK ::= SEQUENCE {
614 * fileStartPosition [0] INTEGER,
615 * fileStartRecord [1] INTEGER,
617 * @param tvb the tv buffer of the current data
618 * @param pinfo the packet info of the current data
619 * @param tree the tree to append this item to
620 * @param offset the offset in the tvb
621 * @return modified offset
624 fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
627 * AddListElement-Request ::= SEQUENCE {
628 * objectIdentifier [0] BACnetObjectIdentifier,
629 * propertyIdentifier [1] BACnetPropertyIdentifier,
630 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
631 * listOfElements [3] ABSTRACT-SYNTAX.&Type
633 * @param tvb the tv buffer of the current data
634 * @param pinfo the packet info of the current data
635 * @param tree the tree to append this item to
636 * @param offset the offset in the tvb
637 * @return modified offset
640 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
643 * CreateObject-Request ::= SEQUENCE {
644 * objectSpecifier [0] ObjectSpecifier,
645 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
647 * @param tvb the tv buffer of the current data
648 * @param pinfo the packet info of the current data
649 * @param subtree the sub tree to append this item to
650 * @param offset the offset in the tvb
651 * @return modified offset
654 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
657 * CreateObject-Request ::= BACnetObjectIdentifier
658 * @param tvb the tv buffer of the current data
659 * @param pinfo the packet info of the current data
660 * @param tree the tree to append this item to
661 * @param offset the offset in the tvb
662 * @return modified offset
665 fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
668 * DeleteObject-Request ::= SEQUENCE {
669 * ObjectIdentifier BACnetObjectIdentifer
671 * @param tvb the tv buffer of the current data
672 * @param pinfo the packet info of the current data
673 * @param tree the tree to append this item to
674 * @param offset the offset in the tvb
675 * @return modified offset
678 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
681 * ReadProperty-Request ::= SEQUENCE {
682 * objectIdentifier [0] BACnetObjectIdentifier,
683 * propertyIdentifier [1] BACnetPropertyIdentifier,
684 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
686 * @param tvb the tv buffer of the current data
687 * @param pinfo the packet info of the current data
688 * @param tree the tree to append this item to
689 * @param offset the offset in the tvb
690 * @return modified offset
693 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
696 * ReadProperty-ACK ::= SEQUENCE {
697 * objectIdentifier [0] BACnetObjectIdentifier,
698 * propertyIdentifier [1] BACnetPropertyIdentifier,
699 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
700 * propertyValue [3] ABSTRACT-SYNTAX.&Type
702 * @param tvb the tv buffer of the current data
703 * @param pinfo the packet info of the current data
704 * @param tree the tree to append this item to
705 * @param offset the offset in the tvb
706 * @return modified offset
709 fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
712 * ReadPropertyConditional-Request ::= SEQUENCE {
713 * objectSelectionCriteria [0] objectSelectionCriteria,
714 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
716 * @param tvb the tv buffer of the current data
717 * @param pinfo the packet info of the current data
718 * @param subtree the sub tree to append this item to
719 * @param offset the offset in the tvb
720 * @return modified offset
723 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
726 * ReadPropertyConditional-ACK ::= SEQUENCE {
727 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
729 * @param tvb the tv buffer of the current data
730 * @param pinfo the packet info of the current data
731 * @param tree the tree to append this item to
732 * @param offset the offset in the tvb
733 * @return modified offset
736 fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
739 * ReadPropertyMultiple-Request ::= SEQUENCE {
740 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
742 * @param tvb the tv buffer of the current data
743 * @param pinfo the packet info of the current data
744 * @param subtree the sub tree to append this item to
745 * @param offset the offset in the tvb
746 * @return offset modified
749 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
752 * ReadPropertyMultiple-Ack ::= SEQUENCE {
753 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
755 * @param tvb the tv buffer of the current data
756 * @param pinfo the packet info of the current data
757 * @param tree the tree to append this item to
758 * @param offset the offset in the tvb
759 * @return offset modified
762 fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
765 * ReadRange-Request ::= SEQUENCE {
766 * objectIdentifier [0] BACnetObjectIdentifier,
767 * propertyIdentifier [1] BACnetPropertyIdentifier,
768 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
770 * byPosition [3] SEQUENCE {
771 * referencedIndex Unsigned,
774 * byTime [4] SEQUENCE {
775 * referenceTime BACnetDateTime,
778 * timeRange [5] SEQUENCE {
779 * beginningTime BACnetDateTime,
780 * endingTime BACnetDateTime
784 * @param tvb the tv buffer of the current data
785 * @param pinfo the packet info of the current data
786 * @param tree the tree to append this item to
787 * @param offset the offset in the tvb
788 * @return modified offset
791 fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
794 * ReadRange-ACK ::= SEQUENCE {
795 * objectIdentifier [0] BACnetObjectIdentifier,
796 * propertyIdentifier [1] BACnetPropertyIdentifier,
797 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
798 * resultFlags [3] BACnetResultFlags,
799 * itemCount [4] Unsigned,
800 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
802 * @param tvb the tv buffer of the current data
803 * @param pinfo the packet info of the current data
804 * @param tree the tree to append this item to
805 * @param offset the offset in the tvb
806 * @return modified offset
809 fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
812 * RemoveListElement-Request ::= SEQUENCE {
813 * objectIdentifier [0] BACnetObjectIdentifier,
814 * propertyIdentifier [1] BACnetPropertyIdentifier,
815 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
816 * listOfElements [3] ABSTRACT-SYNTAX.&Type
818 * @param tvb the tv buffer of the current data
819 * @param pinfo the packet info of the current data
820 * @param tree the tree to append this item to
821 * @param offset the offset in the tvb
822 * @return modified offset
825 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
828 * WriteProperty-Request ::= SEQUENCE {
829 * objectIdentifier [0] BACnetObjectIdentifier,
830 * propertyIdentifier [1] BACnetPropertyIdentifier,
831 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
832 * propertyValue [3] ABSTRACT-SYNTAX.&Type
833 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
835 * @param tvb the tv buffer of the current data
836 * @param pinfo the packet info of the current data
837 * @param tree the tree to append this item to
838 * @param offset the offset in the tvb
839 * @return modified offset
842 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
845 * WritePropertyMultiple-Request ::= SEQUENCE {
846 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
848 * @param tvb the tv buffer of the current data
849 * @param pinfo the packet info of the current data
850 * @param tree the tree to append this item to
851 * @param offset the offset in the tvb
852 * @return modified offset
855 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
858 * DeviceCommunicationControl-Request ::= SEQUENCE {
859 * timeDuration [0] Unsigned16 OPTIONAL,
860 * enable-disable [1] ENUMERATED {
864 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
866 * @param tvb the tv buffer of the current data
867 * @param pinfo the packet info of the current data
868 * @param tree the tree to append this item to
869 * @param offset the offset in the tvb
870 * @return modified offset
873 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
876 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
877 * vendorID [0] Unsigned,
878 * serviceNumber [1] Unsigned,
879 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
881 * @param tvb the tv buffer of the current data
882 * @param pinfo the packet info of the current data
883 * @param tree the tree to append this item to
884 * @param offset the offset in the tvb
885 * @return modified offset
888 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
891 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
892 * vendorID [0] Unsigned,
893 * serviceNumber [1] Unsigned,
894 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
896 * @param tvb the tv buffer of the current data
897 * @param pinfo the packet info of the current data
898 * @param tree the tree to append this item to
899 * @param offset the offset in the tvb
900 * @return modified offset
903 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
906 * ConfirmedTextMessage-Request ::= SEQUENCE {
907 * textMessageSourceDevice [0] BACnetObjectIdentifier,
908 * messageClass [1] CHOICE {
909 * numeric [0] Unsigned,
910 * character [1] CharacterString
912 * messagePriority [2] ENUMERATED {
916 * message [3] CharacterString
918 * @param tvb the tv buffer of the current data
919 * @param pinfo the packet info of the current data
920 * @param tree the tree to append this item to
921 * @param offset the offset in the tvb
922 * @return modified offset
925 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
928 * ReinitializeDevice-Request ::= SEQUENCE {
929 * reinitializedStateOfDevice [0] ENUMERATED {
938 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
940 * @param tvb the tv buffer of the current data
941 * @param pinfo the packet info of the current data
942 * @param tree the tree to append this item to
943 * @param offset the offset in the tvb
944 * @return modified offset
947 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
950 * VTOpen-Request ::= SEQUENCE {
951 * vtClass BACnetVTClass,
952 * localVTSessionIdentifier Unsigned8
954 * @param tvb the tv buffer of the current data
955 * @param pinfo the packet info of the current data
956 * @param tree the tree to append this item to
957 * @param offset the offset in the tvb
958 * @return modified offset
961 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
964 * VTOpen-ACK ::= SEQUENCE {
965 * remoteVTSessionIdentifier Unsigned8
967 * @param tvb the tv buffer of the current data
968 * @param pinfo the packet info of the current data
969 * @param tree the tree to append this item to
970 * @param offset the offset in the tvb
971 * @return modified offset
974 fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
977 * VTClose-Request ::= SEQUENCE {
978 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
980 * @param tvb the tv buffer of the current data
981 * @param pinfo the packet info of the current data
982 * @param tree the tree to append this item to
983 * @param offset the offset in the tvb
984 * @return modified offset
987 fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
990 * VTData-Request ::= SEQUENCE {
991 * vtSessionIdentifier Unsigned8,
992 * vtNewData OCTET STRING,
993 * vtDataFlag Unsigned (0..1)
995 * @param tvb the tv buffer of the current data
996 * @param pinfo the packet info of the current data
997 * @param tree the tree to append this item to
998 * @param offset the offset in the tvb
999 * @return modified offset
1002 fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1005 * VTData-ACK ::= SEQUENCE {
1006 * allNewDataAccepted [0] BOOLEAN,
1007 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1009 * @param tvb the tv buffer of the current data
1010 * @param pinfo the packet info of the current data
1011 * @param tree the tree to append this item to
1012 * @param offset the offset in the tvb
1013 * @return modified offset
1016 fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1019 * Authenticate-Request ::= SEQUENCE {
1020 * pseudoRandomNumber [0] Unsigned32,
1021 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1022 * operatorName [2] CharacterString OPTIONAL,
1023 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1024 * startEncypheredSession [4] BOOLEAN OPTIONAL
1026 * @param tvb the tv buffer of the current data
1027 * @param pinfo the packet info of the current data
1028 * @param tree the tree to append this item to
1029 * @param offset the offset in the tvb
1030 * @return modified offset
1033 fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1036 * Authenticate-ACK ::= SEQUENCE {
1037 * modifiedRandomNumber Unsigned32,
1039 * @param tvb the tv buffer of the current data
1040 * @param pinfo the packet info of the current data
1041 * @param tree the tree to append this item to
1042 * @param offset the offset in the tvb
1043 * @return modified offset
1046 fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1049 * RequestKey-Request ::= SEQUENCE {
1050 * requestingDeviceIdentifier BACnetObjectIdentifier,
1051 * requestingDeviceAddress BACnetAddress,
1052 * remoteDeviceIdentifier BACnetObjectIdentifier,
1053 * remoteDeviceAddress BACnetAddress
1055 * @param tvb the tv buffer of the current data
1056 * @param pinfo the packet info of the current data
1057 * @param tree the tree to append this item to
1058 * @param offset the offset in the tvb
1059 * @return modified offset
1062 fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1065 * Unconfirmed-Service-Request ::= CHOICE {
1067 * @param tvb the tv buffer of the current data
1068 * @param pinfo the packet info of the current data
1069 * @param tree the tree to append this item to
1070 * @param offset the offset in the tvb
1071 * @param service_choice the service choice
1072 * @return modified offset
1075 fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1078 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1079 * subscriberProcessIdentifier [0] Unsigned32,
1080 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1081 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1082 * timeRemaining [3] unsigned,
1083 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1085 * @param tvb the tv buffer of the current data
1086 * @param pinfo the packet info of the current data
1087 * @param tree the tree to append this item to
1088 * @param offset the offset in the tvb
1089 * @return modified offset
1092 fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1095 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1096 * ProcessIdentifier [0] Unsigned32,
1097 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1098 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1099 * timeStamp [3] BACnetTimeStamp,
1100 * notificationClass [4] unsigned,
1101 * priority [5] unsigned8,
1102 * eventType [6] BACnetEventType,
1103 * messageText [7] CharacterString OPTIONAL,
1104 * notifyType [8] BACnetNotifyType,
1105 * ackRequired [9] BOOLEAN OPTIONAL,
1106 * fromState [10] BACnetEventState OPTIONAL,
1107 * toState [11] BACnetEventState,
1108 * eventValues [12] BACnetNotificationParameters OPTIONAL
1110 * @param tvb the tv buffer of the current data
1111 * @param pinfo the packet info of the current data
1112 * @param tree the tree to append this item to
1113 * @param offset the offset in the tvb
1114 * @return modified offset
1117 fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1120 * I-Am-Request ::= SEQUENCE {
1121 * aAmDeviceIdentifier BACnetObjectIdentifier,
1122 * maxAPDULengthAccepted Unsigned,
1123 * segmentationSupported BACnetSegmentation,
1126 * @param tvb the tv buffer of the current data
1127 * @param pinfo the packet info of the current data
1128 * @param tree the tree to append this item to
1129 * @param offset the offset in the tvb
1130 * @return modified offset
1133 fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1137 * I-Have-Request ::= SEQUENCE {
1138 * deviceIdentifier BACnetObjectIdentifier,
1139 * objectIdentifier BACnetObjectIdentifier,
1140 * objectName CharacterString
1142 * @param tvb the tv buffer of the current data
1143 * @param pinfo the packet info of the current data
1144 * @param tree the tree to append this item to
1145 * @param offset the offset in the tvb
1146 * @return modified offset
1149 fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1152 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1153 * vendorID [0] Unsigned,
1154 * serviceNumber [1] Unsigned,
1155 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1157 * @param tvb the tv buffer of the current data
1158 * @param pinfo the packet info of the current data
1159 * @param tree the tree to append this item to
1160 * @param offset the offset in the tvb
1161 * @return modified offset
1164 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1167 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1168 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1169 * messageClass [1] CHOICE {
1170 * numeric [0] Unsigned,
1171 * character [1] CharacterString
1173 * messagePriority [2] ENUMERATED {
1177 * message [3] CharacterString
1179 * @param tvb the tv buffer of the current data
1180 * @param pinfo the packet info of the current data
1181 * @param tree the tree to append this item to
1182 * @param offset the offset in the tvb
1183 * @return modified offset
1186 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1189 * TimeSynchronization-Request ::= SEQUENCE {
1192 * @param tvb the tv buffer of the current data
1193 * @param pinfo the packet info of the current data
1194 * @param tree the tree to append this item to
1195 * @param offset the offset in the tvb
1196 * @return modified offset
1199 fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1202 * UTCTimeSynchronization-Request ::= SEQUENCE {
1205 * @param tvb the tv buffer of the current data
1206 * @param pinfo the packet info of the current data
1207 * @param tree the tree to append this item to
1208 * @param offset the offset in the tvb
1209 * @return modified offset
1212 fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1215 * Who-Has-Request ::= SEQUENCE {
1217 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1218 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1221 * objectIdentifier [2] BACnetObjectIdentifier,
1222 * objectName [3] CharacterString
1225 * @param tvb the tv buffer of the current data
1226 * @param pinfo the packet info of the current data
1227 * @param tree the tree to append this item to
1228 * @param offset the offset in the tvb
1229 * @return modified offset
1232 fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1235 * Who-Is-Request ::= SEQUENCE {
1236 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1237 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1239 * @param tvb the tv buffer of the current data
1240 * @param tree the tree to append this item to
1241 * @param offset the offset in the tvb
1242 * @return modified offset
1245 fWhoIsRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1248 * BACnet-Error ::= CHOICE {
1249 * addListElement [8] ChangeList-Error,
1250 * removeListElement [9] ChangeList-Error,
1251 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1252 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1253 * vtClose [22] VTClose-Error,
1254 * readRange [26] ObjectAccessService-Error
1257 * @param tvb the tv buffer of the current data
1258 * @param pinfo the packet info of the current data
1259 * @param tree the tree to append this item to
1260 * @param offset the offset in the tvb
1261 * @param service the service
1262 * @return modified offset
1265 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1268 * Dissect a BACnetError in a context tag
1270 * @param tvb the tv buffer of the current data
1271 * @param pinfo the packet info of the current data
1272 * @param tree the tree to append this item to
1273 * @param offset the offset in the tvb
1274 * @return modified offset
1276 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1279 * ChangeList-Error ::= SEQUENCE {
1280 * errorType [0] Error,
1281 * firstFailedElementNumber [1] Unsigned
1284 * @param tvb the tv buffer of the current data
1285 * @param pinfo the packet info of the current data
1286 * @param tree the tree to append this item to
1287 * @param offset the offset in the tvb
1288 * @return modified offset
1291 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1294 * CreateObject-Error ::= SEQUENCE {
1295 * errorType [0] Error,
1296 * firstFailedElementNumber [1] Unsigned
1299 * @param tvb the tv buffer of the current data
1300 * @param pinfo the packet info of the current data
1301 * @param tree the tree to append this item to
1302 * @param offset the offset in the tvb
1303 * @return modified offset
1306 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1309 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1310 * errorType [0] Error,
1311 * vendorID [1] Unsigned,
1312 * serviceNumber [2] Unsigned,
1313 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1316 * @param tvb the tv buffer of the current data
1317 * @param pinfo the packet info of the current data
1318 * @param tree the tree to append this item to
1319 * @param offset the offset in the tvb
1320 * @return modified offset
1323 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1326 * WritePropertyMultiple-Error ::= SEQUENCE {
1327 * errorType [0] Error,
1328 * firstFailedWriteAttempt [1] Unsigned
1331 * @param tvb the tv buffer of the current data
1332 * @param pinfo the packet info of the current data
1333 * @param tree the tree to append this item to
1334 * @param offset the offset in the tvb
1335 * @return modified offset
1338 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1341 * VTClose-Error ::= SEQUENCE {
1342 * errorType [0] Error,
1343 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1346 * @param tvb the tv buffer of the current data
1347 * @param pinfo the packet info of the current data
1348 * @param tree the tree to append this item to
1349 * @param offset the offset in the tvb
1350 * @return modified offset
1353 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1356 * BACnet Application Types chapter 20.2.1
1357 * @param tvb the tv buffer of the current data
1358 * @param pinfo the packet info of the current data
1359 * @param tree the tree to append this item to
1360 * @param offset the offset in the tvb
1361 * @param label the label of this item
1362 * @return modified offset
1365 fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1368 * BACnetActionCommand ::= SEQUENCE {
1369 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1370 * objectIdentifier [1] BACnetObjectIdentifier,
1371 * propertyIdentifier [2] BACnetPropertyIdentifier,
1372 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1373 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1374 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1375 * postDelay [6] Unsigned OPTIONAL,
1376 * quitOnFailure [7] BOOLEAN,
1377 * writeSuccessful [8] BOOLEAN
1379 * @param tvb the tv buffer of the current data
1380 * @param pinfo the packet info of the current data
1381 * @param tree the tree to append this item to
1382 * @param offset the offset in the tvb
1383 * @param tag_match the tag number
1384 * @return modified offset
1387 fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1390 * BACnetActionList ::= SEQUENCE {
1391 * action [0] SEQUENCE of BACnetActionCommand
1393 * @param tvb the tv buffer of the current data
1394 * @param pinfo the packet info of the current data
1395 * @param tree the tree to append this item to
1396 * @param offset the offset in the tvb
1397 * @return modified offset
1400 fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1402 /** BACnetAddress ::= SEQUENCE {
1403 * network-number Unsigned16, -- A value 0 indicates the local network
1404 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1406 * @param tvb the tv buffer of the current data
1407 * @param pinfo the packet info of the current data
1408 * @param tree the tree to append this item to
1409 * @param offset the offset in the tvb
1410 * @return modified offset
1413 fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1416 * BACnetAddressBinding ::= SEQUENCE {
1417 * deviceObjectID BACnetObjectIdentifier
1418 * deviceAddress BacnetAddress
1420 * @param tvb the tv buffer of the current data
1421 * @param pinfo the packet info of the current data
1422 * @param tree the tree to append this item to
1423 * @param offset the offset in the tvb
1424 * @return modified offset
1427 fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1430 * BACnetCalendarEntry ::= CHOICE {
1432 * dateRange [1] BACnetDateRange,
1433 * weekNDay [2] BacnetWeekNday
1435 * @param tvb the tv buffer of the current data
1436 * @param pinfo the packet info of the current data
1437 * @param tree the tree to append this item to
1438 * @param offset the offset in the tvb
1439 * @return modified offset
1442 fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1445 * BACnetClientCOV ::= CHOICE {
1446 * real-increment REAL,
1447 * default-increment NULL
1449 * @param tvb the tv buffer of the current data
1450 * @param tree the tree to append this item to
1451 * @param offset the offset in the tvb
1452 * @return modified offset
1455 fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1459 * BACnetDailySchedule ::= SEQUENCE {
1460 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1462 * @param tvb the tv buffer of the current data
1463 * @param pinfo the packet info of the current data
1464 * @param tree the tree to append this item to
1465 * @param offset the offset in the tvb
1466 * @return modified offset
1469 fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1472 * BACnetWeeklySchedule ::= SEQUENCE {
1473 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1475 * @param tvb the tv buffer of the current data
1476 * @param pinfo the packet info of the current data
1477 * @param tree the tree to append this item to
1478 * @param offset the offset in the tvb
1479 * @return modified offset
1482 fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1485 * BACnetDateRange ::= SEQUENCE {
1489 * @param tvb the tv buffer of the current data
1490 * @param pinfo the packet info of the current data
1491 * @param tree the tree to append this item to
1492 * @param offset the offset in the tvb
1493 * @return modified offset
1496 fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1499 * BACnetDateTime ::= SEQUENCE {
1503 * @param tvb the tv buffer of the current data
1504 * @param pinfo the packet info of the current data
1505 * @param tree the tree to append this item to
1506 * @param offset the offset in the tvb
1507 * @param label the label of this item
1508 * @return modified offset
1511 fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1514 * BACnetDestination ::= SEQUENCE {
1515 * validDays BACnetDaysOfWeek,
1518 * recipient BACnetRecipient,
1519 * processIdentifier Unsigned32,
1520 * issueConfirmedNotifications BOOLEAN,
1521 * transitions BACnetEventTransitionBits
1523 * @param tvb the tv buffer of the current data
1524 * @param pinfo the packet info of the current data
1525 * @param tree the tree to append this item to
1526 * @param offset the offset in the tvb
1527 * @return modified offset
1530 fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1533 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1534 * objectIdentifier [0] BACnetObjectIdentifier,
1535 * propertyIdentifier [1] BACnetPropertyIdentifier,
1536 * propertyArrayIndex [2] Unsigend OPTIONAL,
1537 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1539 * @param tvb the tv buffer of the current data
1540 * @param pinfo the packet info of the current data
1541 * @param tree the tree to append this item to
1542 * @param offset the offset in the tvb
1543 * @return modified offset
1546 fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1549 * BACnetObjectPropertyReference ::= SEQUENCE {
1550 * objectIdentifier [0] BACnetObjectIdentifier,
1551 * propertyIdentifier [1] BACnetPropertyIdentifier,
1552 * propertyArrayIndex [2] Unsigend OPTIONAL,
1554 * @param tvb the tv buffer of the current data
1555 * @param pinfo the packet info of the current data
1556 * @param tree the tree to append this item to
1557 * @param offset the offset in the tvb
1558 * @return modified offset
1561 fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1564 * BACnetDeviceObjectReference ::= SEQUENCE {
1565 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1566 * objectIdentifier [1] BACnetObjectIdentifier
1568 * @param tvb the tv buffer of the current data
1569 * @param pinfo the packet info of the current data
1570 * @param tree the tree to append this item to
1571 * @param offset the offset in the tvb
1572 * @return modified offset
1575 fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1578 * BACnetEventParameter ::= CHOICE {
1579 * change-of-bitstring [0] SEQUENCE {
1580 * time-delay [0] Unsigned,
1581 * bitmask [1] BIT STRING,
1582 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1584 * change-of-state [1] SEQUENCE {
1585 * time-delay [0] Unsigned,
1586 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1588 * change-of-value [2] SEQUENCE {
1589 * time-delay [0] Unsigned,
1590 * cov-criteria [1] CHOICE {
1591 * bitmask [0] BIT STRING,
1592 * referenced-property-increment [1] REAL
1595 * command-failure [3] SEQUENCE {
1596 * time-delay [0] Unsigned,
1597 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1599 * floating-limit [4] SEQUENCE {
1600 * time-delay [0] Unsigned,
1601 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1602 * low-diff-limit [2] REAL,
1603 * high-diff-limit [3] REAL,
1606 * out-of-range [5] SEQUENCE {
1607 * time-delay [0] Unsigned,
1608 * low-limit [1] REAL,
1609 * high-limit [2] REAL,
1612 * -- context tag 7 is deprecated
1613 * change-of-life-safety [8] SEQUENCE {
1614 * time-delay [0] Unsigned,
1615 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1616 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1617 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1619 * extended [9] SEQUENCE {
1620 * vendor-id [0] Unsigned16,
1621 * extended-event-type [1] Unsigned,
1622 * parameters [2] SEQUENCE OF CHOICE {
1628 * octet OCTET STRING,
1629 * bitstring BIT STRING,
1631 * reference [0] BACnetDeviceObjectPropertyReference
1634 * buffer-ready [10] SEQUENCE {
1635 * notification-threshold [0] Unsigned,
1636 * previous-notification-count [1] Unsigned32
1638 * unsigned-range [11] SEQUENCE {
1639 * time-delay [0] Unsigned,
1640 * low-limit [1] Unsigned,
1641 * high-limit [2] Unsigned,
1643 * -- context tag 12 is reserved for future addenda
1644 * access-event [13] SEQUENCE {
1645 * list-of-access-events [0] SEQUENCE OF BACnetAccessEvent,
1646 * access-event-time-reference [1] BACnetDeviceObjectPropertyReference
1648 * double-out-of-range [14] SEQUENCE {
1649 * time-delay [0] Unsigned,
1650 * low-limit [1] Double,
1651 * high-limit [2] Double,
1652 * deadband [3] Double
1654 * signed-out-of-range [15] SEQUENCE {
1655 * time-delay [0] Unsigned,
1656 * low-limit [1] INTEGER,
1657 * high-limit [2] INTEGER,
1658 * deadband [3] Unsigned
1660 * unsigned-out-of-range [16] SEQUENCE {
1661 * time-delay [0] Unsigned,
1662 * low-limit [1] Unsigned,
1663 * high-limit [2] Unsigned,
1664 * deadband [3] Unsigned
1666 * change-of-characterstring [17] SEQUENCE {
1667 * time-delay [0] Unsigned,
1668 * list-of-alarm-values [1] SEQUENCE OF CharacterString,
1670 * change-of-status-flags [18] SEQUENCE {
1671 * time-delay [0] Unsigned,
1672 * selected-flags [1] BACnetStatusFlags
1675 * @param tvb the tv buffer of the current data
1676 * @param tree the tree to append this item to
1677 * @param offset the offset in the tvb
1678 * @return modified offset
1681 fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1686 * BACnetLogRecord ::= SEQUENCE {
1687 * timestamp [0] BACnetDateTime,
1688 * logDatum [1] CHOICE {
1689 * log-status [0] BACnetLogStatus,
1690 * boolean-value [1] BOOLEAN,
1691 * real-value [2] REAL,
1692 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1693 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1694 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1695 * bitstring-value [6] BIT STRING, -- Optionally limited to 32 bits
1696 * null-value [7] NULL,
1697 * failure [8] Error,
1698 * time-change [9] REAL,
1699 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1701 * statusFlags [2] BACnetStatusFlags OPTIONAL
1703 * @param tvb the tv buffer of the current data
1704 * @param pinfo the packet info of the current data
1705 * @param tree the tree to append this item to
1706 * @param offset the offset in the tvb
1707 * @return modified offset
1710 fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1713 * BACnetEventLogRecord ::= SEQUENCE {
1714 * timestamp [0] BACnetDateTime,
1715 * logDatum [1] CHOICE {
1716 * log-status [0] BACnetLogStatus,
1717 * notification [1] ConfirmedEventNotification-Request,
1718 * time-change [2] REAL,
1721 * @param tvb the tv buffer of the current data
1722 * @param pinfo the packet info of the current data
1723 * @param tree the tree to append this item to
1724 * @param offset the offset in the tvb
1725 * @return modified offset
1728 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1731 fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1734 * BACnetNotificationParameters ::= CHOICE {
1735 * change-of-bitstring [0] SEQUENCE {
1736 * referenced-bitstring [0] BIT STRING,
1737 * status-flags [1] BACnetStatusFlags
1739 * change-of-state [1] SEQUENCE {
1740 * new-state [0] BACnetPropertyStatus,
1741 * status-flags [1] BACnetStatusFlags
1743 * change-of-value [2] SEQUENCE {
1744 * new-value [0] CHOICE {
1745 * changed-bits [0] BIT STRING,
1746 * changed-value [1] REAL
1748 * status-flags [1] BACnetStatusFlags
1750 * command-failure [3] SEQUENCE {
1751 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1752 * status-flags [1] BACnetStatusFlags
1753 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1755 * floating-limit [4] SEQUENCE {
1756 * reference-value [0] REAL,
1757 * status-flags [1] BACnetStatusFlags
1758 * setpoint-value [2] REAL,
1759 * error-limit [3] REAL
1761 * out-of-range [5] SEQUENCE {
1762 * exceeding-value [0] REAL,
1763 * status-flags [1] BACnetStatusFlags
1764 * deadband [2] REAL,
1765 * exceeded-limit [3] REAL
1767 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1768 * -- complex tag 7 is deprecated
1769 * change-of-life-safety [8] SEQUENCE {
1770 * new-state [0] BACnetLifeSafetyState,
1771 * new-mode [1] BACnetLifeSafetyState
1772 * status-flags [2] BACnetStatusFlags,
1773 * operation-expected [3] BACnetLifeSafetyOperation
1775 * extended [9] SEQUENCE {
1776 * vendor-id [0] Unsigned16,
1777 * extended-event-type [1] Unsigned,
1778 * parameters [2] SEQUENCE OF CHOICE {
1784 * octet OCTET STRING,
1785 * bitstring BIT STRING,
1787 * propertyValue [0] BACnetDeviceObjectPropertyValue
1790 * buffer-ready [10] SEQUENCE {
1791 * buffer-property [0] BACnetDeviceObjectPropertyReference,
1792 * previous-notification[1] Unsigned32,
1793 * current-notification [2] BACneUnsigned32tDateTime
1795 * unsigned-range [11] SEQUENCE {
1796 * exceeding-value [0] Unsigned,
1797 * status-flags [1] BACnetStatusFlags,
1798 * exceeded-limit [2] Unsigned
1800 * -- context tag 12 is reserved for future addenda
1801 * access-event [13] SEQUENCE {
1802 * access-event [0] BACnetAccessEvent,
1803 * status-flags [1] BACnetStatusFlags,
1804 * access-event-tag [2] Unsigned,
1805 * access-event-time [3] BACnetTimeStamp,
1806 * access-credential [4] BACnetDeviceObjectReference,
1807 * authentication-factor [5] BACnetAuthenticationFactor OPTIONAL
1809 * double-out-of-range [14] SEQUENCE {
1810 * exceeding-value [0] Double,
1811 * status-flags [1] BACnetStatusFlags
1812 * deadband [2] Double,
1813 * exceeded-limit [3] Double
1815 * signed-out-of-range [15] SEQUENCE {
1816 * exceeding-value [0] INTEGER,
1817 * status-flags [1] BACnetStatusFlags
1818 * deadband [2] Unsigned,
1819 * exceeded-limit [3] INTEGER
1821 * unsigned-out-of-range [16] SEQUENCE {
1822 * exceeding-value [0] Unsigned,
1823 * status-flags [1] BACnetStatusFlags
1824 * deadband [2] Unsigned,
1825 * exceeded-limit [3] Unsigned
1827 * change-of-characterstring [17] SEQUENCE {
1828 * changed-value [0] CharacterString,
1829 * status-flags [1] BACnetStatusFlags
1830 * alarm-value [2] CharacterString
1832 * change-of-status-flags [18] SEQUENCE {
1833 * present-value [0] ABSTRACT-SYNTAX.&Type OPTIONAL,
1834 * -- depends on referenced property
1835 * referenced-flags [1] BACnetStatusFlags
1838 * @param tvb the tv buffer of the current data
1839 * @param pinfo the packet info of the current data
1840 * @param tree the tree to append this item to
1841 * @param offset the offset in the tvb
1842 * @return modified offset
1845 fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1848 * BACnetObjectPropertyReference ::= SEQUENCE {
1849 * objectIdentifier [0] BACnetObjectIdentifier,
1850 * propertyIdentifier [1] BACnetPropertyIdentifier,
1851 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1853 * @param tvb the tv buffer of the current data
1854 * @param pinfo the packet info of the current data
1855 * @param tree the tree to append this item to
1856 * @param offset the offset in the tvb
1857 * @return modified offset
1860 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1864 * BACnetObjectPropertyValue ::= SEQUENCE {
1865 * objectIdentifier [0] BACnetObjectIdentifier,
1866 * propertyIdentifier [1] BACnetPropertyIdentifier,
1867 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1868 * -- if omitted with an array the entire array is referenced
1869 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1870 * priority [4] Unsigned (1..16) OPTIONAL
1872 * @param tvb the tv buffer of the current data
1873 * @param tree the tree to append this item to
1874 * @param offset the offset in the tvb
1875 * @return modified offset
1878 fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, guint offset);
1882 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1883 * @param tvb the tv buffer of the current data
1884 * @param pinfo the packet info of the current data
1885 * @param tree the tree to append this item to
1886 * @param offset the offset in the tvb
1887 * @return modified offset
1890 fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1893 fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1896 * BACnetPropertyReference ::= SEQUENCE {
1897 * propertyIdentifier [0] BACnetPropertyIdentifier,
1898 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1900 * @param tvb the tv buffer of the current data
1901 * @param pinfo the packet info of the current data
1902 * @param tree the tree to append this item to
1903 * @param offset the offset in the tvb
1904 * @return modified offset
1907 fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1910 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1913 fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1916 fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1919 * BACnetPropertyValue ::= SEQUENCE {
1920 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1921 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1922 * -- if omitted with an array the entire array is referenced
1923 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1924 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1926 * @param tvb the tv buffer of the current data
1927 * @param pinfo the packet info of the current data
1928 * @param tree the tree to append this item to
1929 * @param offset the offset in the tvb
1930 * @return modified offset
1933 fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1936 fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1939 * BACnet Application PDUs chapter 21
1940 * BACnetRecipient::= CHOICE {
1941 * device [0] BACnetObjectIdentifier
1942 * address [1] BACnetAddress
1944 * @param tvb the tv buffer of the current data
1945 * @param pinfo the packet info of the current data
1946 * @param tree the tree to append this item to
1947 * @param offset the offset in the tvb
1948 * @return modified offset
1951 fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1954 * BACnet Application PDUs chapter 21
1955 * BACnetRecipientProcess::= SEQUENCE {
1956 * recipient [0] BACnetRecipient
1957 * processID [1] Unsigned32
1959 * @param tvb the tv buffer of the current data
1960 * @param pinfo the packet info of the current data
1961 * @param tree the tree to append this item to
1962 * @param offset the offset in the tvb
1963 * @return modified offset
1966 fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1969 fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1973 * BACnetSessionKey ::= SEQUENCE {
1974 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1975 * peerAddress BACnetAddress
1977 * @param tvb the tv buffer of the current data
1978 * @param tree the tree to append this item to
1979 * @param offset the offset in the tvb
1980 * @return modified offset
1981 * @todo check if checksum is displayed correctly
1984 fSessionKey(tvbuff_t *tvb, proto_tree *tree, guint offset);
1988 * BACnetSpecialEvent ::= SEQUENCE {
1990 * calendarEntry [0] BACnetCalendarEntry,
1991 * calendarRefernce [1] BACnetObjectIdentifier
1993 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1994 * eventPriority [3] Unsigned (1..16)
1996 * @param tvb the tv buffer of the current data
1997 * @param pinfo the packet info of the current data
1998 * @param tree the tree to append this item to
1999 * @param offset the offset in the tvb
2000 * @return modified offset
2003 fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2006 * BACnetTimeStamp ::= CHOICE {
2008 * sequenceNumber [1] Unsigned (0..65535),
2009 * dateTime [2] BACnetDateTime
2011 * @param tvb the tv buffer of the current data
2012 * @param pinfo the packet info of the current data
2013 * @param tree the tree to append this item to
2014 * @param offset the offset in the tvb
2015 * @param label the label of this item
2016 * @return modified offset
2019 fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2022 fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2025 * BACnetTimeValue ::= SEQUENCE {
2027 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
2029 * @param tvb the tv buffer of the current data
2030 * @param pinfo the packet info of the current data
2031 * @param tree the tree to append this item to
2032 * @param offset the offset in the tvb
2033 * @return modified offset
2036 fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2040 * BACnetVTSession ::= SEQUENCE {
2041 * local-vtSessionID Unsigned8,
2042 * remote-vtSessionID Unsigned8,
2043 * remote-vtAddress BACnetAddress
2045 * @param tvb the tv buffer of the current data
2046 * @param tree the tree to append this item to
2047 * @param offset the offset in the tvb
2048 * @return modified offset
2051 fVTSession(tvbuff_t *tvb, proto_tree *tree, guint offset);
2055 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
2056 * -- first octet month (1..12) January = 1, X'FF' = any month
2057 * -- second octet weekOfMonth where: 1 = days numbered 1-7
2058 * -- 2 = days numbered 8-14
2059 * -- 3 = days numbered 15-21
2060 * -- 4 = days numbered 22-28
2061 * -- 5 = days numbered 29-31
2062 * -- 6 = last 7 days of this month
2063 * -- X'FF' = any week of this month
2064 * -- third octet dayOfWeek (1..7) where 1 = Monday
2066 * -- X'FF' = any day of week
2067 * @param tvb the tv buffer of the current data
2068 * @param pinfo the packet info of the current data
2069 * @param tree the tree to append this item to
2070 * @param offset the offset in the tvb
2071 * @return modified offset
2074 fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2077 * ReadAccessResult ::= SEQUENCE {
2078 * objectIdentifier [0] BACnetObjectIdentifier,
2079 * listOfResults [1] SEQUENCE OF SEQUENCE {
2080 * propertyIdentifier [2] BACnetPropertyIdentifier,
2081 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
2082 * readResult CHOICE {
2083 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
2084 * propertyAccessError [5] Error
2088 * @param tvb the tv buffer of the current data
2089 * @param pinfo the packet info of the current data
2090 * @param tree the tree to append this item to
2091 * @param offset the offset in the tvb
2092 * @return modified offset
2095 fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2098 * ReadAccessSpecification ::= SEQUENCE {
2099 * objectIdentifier [0] BACnetObjectIdentifier,
2100 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
2102 * @param tvb the tv buffer of the current data
2103 * @param pinfo the packet info of the current data
2104 * @param subtree the subtree to append this item to
2105 * @param offset the offset in the tvb
2106 * @return modified offset
2109 fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2112 * WriteAccessSpecification ::= SEQUENCE {
2113 * objectIdentifier [0] BACnetObjectIdentifier,
2114 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
2116 * @param tvb the tv buffer of the current data
2117 * @param pinfo the packet info of the current data
2118 * @param subtree the sub tree to append this item to
2119 * @param offset the offset in the tvb
2120 * @return modified offset
2123 fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2126 /********************************************************* Helper functions *******************************************/
2129 * extracts the tag number from the tag header.
2130 * @param tvb the tv buffer of the current data "TestyVirtualBuffer"
2131 * @param offset the offset in the tvb in actual tvb
2132 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
2135 fTagNo(tvbuff_t *tvb, guint offset);
2138 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
2139 * @param tvb the tv buffer of the current data = "TestyVirtualBuffer"
2140 * @param pinfo the packet info of the current data = packet info
2141 * @param offset the offset in the tvb = offset in actual tvb
2142 * @return tag_no BACnet 20.2.1.2 Tag Number
2143 * @return class_tag BACnet 20.2.1.1 Class
2144 * @return lvt BACnet 20.2.1.3 Length/Value/Type
2145 * @return offs = length of this header
2149 fTagHeader(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
2153 * adds processID with max 32Bit unsigned Integer Value to tree
2154 * @param tvb the tv buffer of the current data
2155 * @param pinfo the packet info of the current data
2156 * @param tree the tree to append this item to
2157 * @param offset the offset in the tvb
2158 * @return modified offset
2161 fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2164 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2165 * @param tvb the tv buffer of the current data
2166 * @param pinfo the packet info of the current data
2167 * @param tree the tree to append this item to
2168 * @param offset the offset in the tvb
2169 * @return modified offset
2172 fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2175 * BACnet Application PDUs chapter 21
2176 * BACnetPropertyIdentifier::= ENUMERATED {
2177 * @see bacapp_property_identifier
2179 * @param tvb the tv buffer of the current data
2180 * @param pinfo the packet info of the current data
2181 * @param tree the tree to append this item to
2182 * @param offset the offset in the tvb
2183 * @return modified offset
2186 fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2189 * BACnet Application PDUs chapter 21
2190 * BACnetPropertyArrayIndex::= ENUMERATED {
2191 * @see bacapp_property_array_index
2193 * @param tvb the tv buffer of the current data
2194 * @param pinfo the packet info of the current data
2195 * @param tree the tree to append this item to
2196 * @param offset the offset in the tvb
2197 * @return modified offset
2200 fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2203 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2204 * objectIdentifier [0] BACnetObjectIdentifier,
2205 * eventState [1] BACnetEventState,
2206 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2207 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2208 * notifyType [4] BACnetNotifyType,
2209 * eventEnable [5] BACnetEventTransitionBits,
2210 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2212 * @param tvb the tv buffer of the current data
2213 * @param pinfo the packet info of the current data
2214 * @param tree the tree to append this item to
2215 * @param offset the offset in the tvb
2216 * @return modified offset
2219 flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2222 * SelectionCriteria ::= SEQUENCE {
2223 * propertyIdentifier [0] BACnetPropertyIdentifier,
2224 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2225 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2226 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2228 * @param tvb the tv buffer of the current data
2229 * @param pinfo the packet info of the current data
2230 * @param tree the tree to append this item to
2231 * @param offset the offset in the tvb
2232 * @return modified offset
2235 fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2238 * objectSelectionCriteria ::= SEQUENCE {
2239 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2240 * listOfSelectionCriteria [1] SelectionCriteria
2242 * @param tvb the tv buffer of the current data
2243 * @param pinfo the packet info of the current data
2244 * @param subtree the sub tree to append this item to
2245 * @param offset the offset in the tvb
2246 * @return modified offset
2249 fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2252 * BACnet-Error ::= SEQUENCE {
2253 * error-class ENUMERATED {},
2254 * error-code ENUMERATED {}
2257 * @param tvb the tv buffer of the current data
2258 * @param pinfo the packet info of the current data
2259 * @param tree the tree to append this item to
2260 * @param offset the offset in the tvb
2261 * @return modified offset
2264 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2267 * Generic handler for context tagged values. Mostly for handling
2268 * vendor-defined properties and services.
2269 * @param tvb the tv buffer of the current data
2270 * @param pinfo the packet info of the current data
2271 * @param tree the tree to append this item to
2272 * @param offset the offset in the tvb
2273 * @return modified offset
2274 * @todo beautify this ugly construct
2277 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2280 * realizes some ABSTRACT-SYNTAX.&Type
2281 * @param tvb the tv buffer of the current data
2282 * @param pinfo the packet info of the current data
2283 * @param tree the tree to append this item to
2284 * @param offset the offset in the tvb
2285 * @return modified offset
2286 * @todo beautify this ugly construct
2289 fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2293 fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
2294 const value_string *src);
2300 proto_register_bacapp(void);
2303 * proto_reg_handoff_bacapp
2306 proto_reg_handoff_bacapp(void);
2308 /* <<<< formerly bacapp.h */
2310 /* reassembly table for segmented messages */
2311 static reassembly_table msg_reassembly_table;
2313 /* some necessary forward function prototypes */
2315 fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2316 const gchar *label, const value_string *vs);
2318 static const char *bacapp_unknown_service_str = "unknown service"; /* Usage: no format specifiers */
2319 static const char ASHRAE_Reserved_Fmt[] = "(%d) Reserved for Use by ASHRAE";
2320 static const char Vendor_Proprietary_Fmt[] = "(%d) Vendor Proprietary Value";
2322 static const value_string
2323 BACnetTypeName[] = {
2324 { 0, "Confirmed-REQ"},
2325 { 1, "Unconfirmed-REQ"},
2327 { 3, "Complex-ACK"},
2328 { 4, "Segment-ACK"},
2335 static const true_false_string segments_follow = {
2336 "Segmented Request",
2337 "Unsegmented Request"
2340 static const true_false_string more_follow = {
2341 "More Segments Follow",
2342 "No More Segments Follow"
2345 static const true_false_string segmented_accept = {
2346 "Segmented Response accepted",
2347 "Segmented Response not accepted"
2350 static const true_false_string
2352 "Context Specific Tag",
2356 static const value_string
2357 BACnetMaxSegmentsAccepted [] = {
2358 { 0, "Unspecified"},
2362 { 4, "16 segments"},
2363 { 5, "32 segments"},
2364 { 6, "64 segments"},
2365 { 7, "Greater than 64 segments"},
2369 static const value_string
2370 BACnetMaxAPDULengthAccepted [] = {
2371 { 0, "Up to MinimumMessageSize (50 octets)"},
2372 { 1, "Up to 128 octets"},
2373 { 2, "Up to 206 octets (fits in a LonTalk frame)"},
2374 { 3, "Up to 480 octets (fits in an ARCNET frame)"},
2375 { 4, "Up to 1024 octets"},
2376 { 5, "Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2377 { 6, "reserved by ASHRAE"},
2378 { 7, "reserved by ASHRAE"},
2379 { 8, "reserved by ASHRAE"},
2380 { 9, "reserved by ASHRAE"},
2381 { 10, "reserved by ASHRAE"},
2382 { 11, "reserved by ASHRAE"},
2383 { 12, "reserved by ASHRAE"},
2384 { 13, "reserved by ASHRAE"},
2385 { 14, "reserved by ASHRAE"},
2386 { 15, "reserved by ASHRAE"},
2390 static const value_string
2391 BACnetRejectReason [] = {
2393 {1, "buffer-overflow"},
2394 {2, "inconsistent-parameters"},
2395 {3, "invalid-parameter-data-type"},
2397 {5, "missing-required-parameter"},
2398 {6, "parameter-out-of-range"},
2399 {7, "too-many-arguments"},
2400 {8, "undefined-enumeration"},
2401 {9, "unrecognized-service"},
2405 static const value_string
2406 BACnetRestartReason [] = {
2410 { 3, "detected-power-lost"},
2411 { 4, "detected-powered-off"},
2412 { 5, "hardware-watchdog"},
2413 { 6, "software-watchdog"},
2418 static const value_string
2419 BACnetApplicationTagNumber [] = {
2422 { 2, "Unsigned Integer"},
2423 { 3, "Signed Integer (2's complement notation)"},
2424 { 4, "Real (ANSI/IEE-754 floating point)"},
2425 { 5, "Double (ANSI/IEE-754 double precision floating point)"},
2426 { 6, "Octet String"},
2427 { 7, "Character String"},
2432 { 12, "BACnetObjectIdentifier"},
2433 { 13, "reserved by ASHRAE"},
2434 { 14, "reserved by ASHRAE"},
2435 { 15, "reserved by ASHRAE"},
2439 static const value_string
2446 static const value_string
2447 BACnetAccessEvent [] = {
2451 { 3, "passback-detected"},
2454 { 6, "lockout-max-attempts"},
2455 { 7, "lockout-other"},
2456 { 8, "lockout-relinquished"},
2457 { 9, "lockout-by-higher-priority"},
2458 { 10, "out-of-service"},
2459 { 11, "out-of-service-relinquished"},
2460 { 12, "accompaniment-by"},
2461 { 13, "authentication-factor-read"},
2462 { 14, "authorization-delayed"},
2463 { 15, "verification-required"},
2464 /* Enumerated values 128-511 are used for events
2465 * which indicate that access has been denied. */
2466 { 128, "denied-deny-all"},
2467 { 129, "denied-unknown-credential"},
2468 { 130, "denied-authentication-unavailable"},
2469 { 131, "denied-authentication-factor-timeout"},
2470 { 132, "denied-incorrect-authentication-factor"},
2471 { 133, "denied-zone-no-access-rights"},
2472 { 134, "denied-point-no-access-rights"},
2473 { 135, "denied-no-access-rights"},
2474 { 136, "denied-out-of-time-range"},
2475 { 137, "denied-threat-level"},
2476 { 138, "denied-passback"},
2477 { 139, "denied-unexpected-location-usage"},
2478 { 140, "denied-max-attempts"},
2479 { 141, "denied-lower-occupancy-limit"},
2480 { 142, "denied-upper-occupancy-limit"},
2481 { 143, "denied-authentication-factor-lost"},
2482 { 144, "denied-authentication-factor-stolen"},
2483 { 145, "denied-authentication-factor-damaged"},
2484 { 146, "denied-authentication-factor-destroyed"},
2485 { 147, "denied-authentication-factor-disabled"},
2486 { 148, "denied-authentication-factor-error"},
2487 { 149, "denied-credential-unassigned"},
2488 { 150, "denied-credential-not-provisioned"},
2489 { 151, "denied-credential-not-yet-active"},
2490 { 152, "denied-credential-expired"},
2491 { 153, "denied-credential-manual-disable"},
2492 { 154, "denied-credential-lockout"},
2493 { 155, "denied-credential-max-days"},
2494 { 156, "denied-credential-max-uses"},
2495 { 157, "denied-credential-inactivity"},
2496 { 158, "denied-credential-disabled"},
2497 { 159, "denied-no-accompaniment"},
2498 { 160, "denied-incorrect-accompaniment"},
2499 { 161, "denied-lockout"},
2500 { 162, "denied-verification-failed"},
2501 { 163, "denied-verification-timeout"},
2502 { 164, "denied-other"},
2504 /* Enumerated values 0-512 are reserved for definition by ASHRAE.
2505 Enumerated values 512-65535 may be used by others subject to
2506 procedures and constraints described in Clause 23. */
2509 static const value_string
2510 BACnetFileAccessMethod [] = {
2511 { 0, "record-access"},
2512 { 1, "stream-access"},
2516 /* For some reason, BACnet defines the choice parameter
2517 in the file read and write services backwards from the
2518 BACnetFileAccessMethod enumeration.
2520 static const value_string
2521 BACnetFileAccessOption [] = {
2522 { 0, "stream access"},
2523 { 1, "record access"},
2527 static const value_string
2528 BACnetFileStartOption [] = {
2529 { 0, "File Start Position: "},
2530 { 1, "File Start Record: "},
2534 static const value_string
2535 BACnetFileRequestCount [] = {
2536 { 0, "Requested Octet Count: "},
2537 { 1, "Requested Record Count: "},
2541 static const value_string
2542 BACnetFileWriteInfo [] = {
2543 { 0, "File Data: "},
2544 { 1, "Record Count: "},
2548 static const value_string
2549 BACnetAbortReason [] = {
2551 { 1, "buffer-overflow"},
2552 { 2, "invalid-apdu-in-this-state"},
2553 { 3, "preempted-by-higher-priority-task"},
2554 { 4, "segmentation-not-supported"},
2558 static const value_string
2559 BACnetLifeSafetyMode [] = {
2570 { 10, "disconnected"},
2573 { 13, "atomic-release-disabled"},
2576 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2577 Enumerated values 256-65535 may be used by others subject to
2578 procedures and constraints described in Clause 23. */
2581 static const value_string
2582 BACnetLifeSafetyOperation [] = {
2585 { 2, "silence-audible"},
2586 { 3, "silence-visual"},
2588 { 5, "reset-alarm"},
2589 { 6, "reset-fault"},
2591 { 8, "unsilence-audible"},
2592 { 9, "unsilence-visual"},
2594 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2595 Enumerated values 64-65535 may be used by others subject to
2596 procedures and constraints described in Clause 23. */
2600 static const value_string
2601 BACnetLimitEnable [] = {
2602 { 0, "lowLimitEnable"},
2603 { 1, "highLimitEnable"},
2608 static const value_string
2609 BACnetLifeSafetyState [] = {
2614 { 4, "fault-pre-alarm"},
2615 { 5, "fault-alarm"},
2620 { 10, "test-active"},
2621 { 11, "test-fault"},
2622 { 12, "test-fault-alarm"},
2625 { 15, "tamper-alarm"},
2627 { 17, "emergency-power"},
2630 { 20, "local-alarm"},
2631 { 21, "general-alarm"},
2632 { 22, "supervisory"},
2633 { 23, "test-supervisory"},
2635 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2636 Enumerated values 256-65535 may be used by others subject to
2637 procedures and constraints described in Clause 23. */
2640 static const value_string
2641 BACnetConfirmedServiceChoice [] = {
2642 { 0, "acknowledgeAlarm"},
2643 { 1, "confirmedCOVNotification"},
2644 { 2, "confirmedEventNotification"},
2645 { 3, "getAlarmSummary"},
2646 { 4, "getEnrollmentSummary"},
2647 { 5, "subscribeCOV"},
2648 { 6, "atomicReadFile"},
2649 { 7, "atomicWriteFile"},
2650 { 8, "addListElement"},
2651 { 9, "removeListElement"},
2652 { 10, "createObject"},
2653 { 11, "deleteObject"},
2654 { 12, "readProperty"},
2655 { 13, "readPropertyConditional"},
2656 { 14, "readPropertyMultiple"},
2657 { 15, "writeProperty"},
2658 { 16, "writePropertyMultiple"},
2659 { 17, "deviceCommunicationControl"},
2660 { 18, "confirmedPrivateTransfer"},
2661 { 19, "confirmedTextMessage"},
2662 { 20, "reinitializeDevice"},
2666 { 24, "authenticate"},
2667 { 25, "requestKey"},
2669 { 27, "lifeSafetyOperation"},
2670 { 28, "subscribeCOVProperty"},
2671 { 29, "getEventInformation"},
2672 { 30, "reserved by ASHRAE"},
2676 static const value_string
2677 BACnetReliability [] = {
2678 { 0, "no-fault-detected"},
2681 { 3, "under-range"},
2683 { 5, "shorted-loop"},
2685 { 7, "unreliable-other"},
2686 { 8, "process-error"},
2687 { 9, "multi-state-fault"},
2688 { 10, "configuration-error"},
2689 /* enumeration value 11 is reserved for a future addendum */
2690 { 12, "communication-failure"},
2691 { 13, "member-fault"},
2695 static const value_string
2696 BACnetUnconfirmedServiceChoice [] = {
2699 { 2, "unconfirmedCOVNotification"},
2700 { 3, "unconfirmedEventNotification"},
2701 { 4, "unconfirmedPrivateTransfer"},
2702 { 5, "unconfirmedTextMessage"},
2703 { 6, "timeSynchronization"},
2706 { 9, "utcTimeSynchronization"},
2711 static const value_string
2712 BACnetUnconfirmedServiceRequest [] = {
2713 { 0, "i-Am-Request"},
2714 { 1, "i-Have-Request"},
2715 { 2, "unconfirmedCOVNotification-Request"},
2716 { 3, "unconfirmedEventNotification-Request"},
2717 { 4, "unconfirmedPrivateTransfer-Request"},
2718 { 5, "unconfirmedTextMessage-Request"},
2719 { 6, "timeSynchronization-Request"},
2720 { 7, "who-Has-Request"},
2721 { 8, "who-Is-Request"},
2722 { 9, "utcTimeSynchonization-Request"},
2727 static const value_string
2728 BACnetObjectType [] = {
2729 { 0, "analog-input"},
2730 { 1, "analog-output"},
2731 { 2, "analog-value"},
2732 { 3, "binary-input"},
2733 { 4, "binary-output"},
2734 { 5, "binary-value"},
2738 { 9, "event-enrollment"},
2742 { 13, "multi-state-input"},
2743 { 14, "multi-state-output"},
2744 { 15, "notification-class"},
2748 { 19, "multi-state-value"},
2750 { 21, "life-safety-point"},
2751 { 22, "life-safety-zone"},
2752 { 23, "accumulator"},
2753 { 24, "pulse-converter"},
2755 { 26, "global-group"},
2756 { 27, "trend-log-multiple"},
2757 { 28, "load-control"},
2758 { 29, "structured-view"},
2759 { 30, "access-door"}, /* 30-37 added with addanda 135-2008j */
2760 /* value 31 is unassigned */
2761 { 32, "access-credential"},
2762 { 33, "access-point"},
2763 { 34, "access-rights"},
2764 { 35, "access-user"},
2765 { 36, "access-zone"},
2766 { 37, "credential-data-input"},
2767 { 38, "network-security"},
2768 { 39, "bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2769 { 40, "characterstring-value"},
2770 { 41, "date-pattern-value"},
2771 { 42, "date-value"},
2772 { 43, "datetime-pattern-value"},
2773 { 44, "datetime-value"},
2774 { 45, "integer-value"},
2775 { 46, "large-analog-value"},
2776 { 47, "octetstring-value"},
2777 { 48, "positive-integer-value"},
2778 { 49, "time-pattern-value"},
2779 { 50, "time-value"},
2781 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2782 Enumerated values 128-1023 may be used by others subject to
2783 the procedures and constraints described in Clause 23. */
2786 static const value_string
2787 BACnetEngineeringUnits [] = {
2790 { 2, "Milliamperes"},
2796 { 8, "Volt Amperes"},
2797 { 9, "Kilovolt Amperes"},
2798 { 10, "Megavolt Amperes"},
2799 { 11, "Volt Amperes Reactive"},
2800 { 12, "Kilovolt Amperes Reactive"},
2801 { 13, "Megavolt Amperes Reactive"},
2802 { 14, "Degrees Phase"},
2803 { 15, "Power Factor"},
2805 { 17, "Kilojoules"},
2806 { 18, "Watt Hours"},
2807 { 19, "Kilowatt Hours"},
2811 { 23, "Joules Per Kg Dry Air"},
2812 { 24, "BTUs Per Pound Dry Air"},
2813 { 25, "Cycles Per Hour"},
2814 { 26, "Cycles Per Minute"},
2816 { 28, "Grams Of Water Per Kilogram Dry Air"},
2817 { 29, "Relative Humidity"},
2818 { 30, "Millimeters"},
2822 { 34, "Watts Per Sq Foot"},
2823 { 35, "Watts Per Sq meter"},
2826 { 38, "Foot Candles"},
2828 { 40, "Pounds Mass"},
2830 { 42, "Kgs per Second"},
2831 { 43, "Kgs Per Minute"},
2832 { 44, "Kgs Per Hour"},
2833 { 45, "Pounds Mass Per Minute"},
2834 { 46, "Pounds Mass Per Hour"},
2838 { 50, "BTUs Per Hour"},
2839 { 51, "Horsepower"},
2840 { 52, "Tons Refrigeration"},
2842 { 54, "Kilopascals"},
2844 { 56, "Pounds Force Per Square Inch"},
2845 { 57, "Centimeters Of Water"},
2846 { 58, "Inches Of Water"},
2847 { 59, "Millimeters Of Mercury"},
2848 { 60, "Centimeters Of Mercury"},
2849 { 61, "Inches Of Mercury"},
2850 { 62, "Degrees Celsius"},
2851 { 63, "Degrees Kelvin"},
2852 { 64, "Degrees Fahrenheit"},
2853 { 65, "Degree Days Celsius"},
2854 { 66, "Degree Days Fahrenheit"},
2862 { 74, "Meters Per Second"},
2863 { 75, "Kilometers Per Hour"},
2864 { 76, "Feed Per Second"},
2865 { 77, "Feet Per Minute"},
2866 { 78, "Miles Per Hour"},
2867 { 79, "Cubic Feet"},
2868 { 80, "Cubic Meters"},
2869 { 81, "Imperial Gallons"},
2871 { 83, "US Gallons"},
2872 { 84, "Cubic Feet Per Minute"},
2873 { 85, "Cubic Meters Per Second"},
2874 { 86, "Imperial Gallons Per Minute"},
2875 { 87, "Liters Per Second"},
2876 { 88, "Liters Per Minute"},
2877 { 89, "US Gallons Per Minute"},
2878 { 90, "Degrees Angular"},
2879 { 91, "Degrees Celsius Per Hour"},
2880 { 92, "Degrees Celsius Per Minute"},
2881 { 93, "Degrees Fahrenheit Per Hour"},
2882 { 94, "Degrees Fahrenheit Per Minute"},
2884 { 96, "Parts Per Million"},
2885 { 97, "Parts Per Billion"},
2887 { 99, "Pecent Per Second"},
2888 { 100, "Per Minute"},
2889 { 101, "Per Second"},
2890 { 102, "Psi Per Degree Fahrenheit"},
2892 { 104, "Revolutions Per Min"},
2893 { 105, "Currency1"},
2894 { 106, "Currency2"},
2895 { 107, "Currency3"},
2896 { 108, "Currency4"},
2897 { 109, "Currency5"},
2898 { 110, "Currency6"},
2899 { 111, "Currency7"},
2900 { 112, "Currency8"},
2901 { 113, "Currency9"},
2902 { 114, "Currency10"},
2903 { 115, "Sq Inches"},
2904 { 116, "Sq Centimeters"},
2905 { 117, "BTUs Per Pound"},
2906 { 118, "Centimeters"},
2907 { 119, "Pounds Mass Per Second"},
2908 { 120, "Delta Degrees Fahrenheit"},
2909 { 121, "Delta Degrees Kelvin"},
2912 { 124, "Millivolts"},
2913 { 125, "Kilojoules Per Kg"},
2914 { 126, "Megajoules"},
2915 { 127, "Joules Per Degree Kelvin"},
2916 { 128, "Joules Per Kg Degree Kelvin"},
2917 { 129, "Kilohertz"},
2918 { 130, "Megahertz"},
2920 { 132, "Milliwatts"},
2921 { 133, "Hectopascals"},
2922 { 134, "Millibars"},
2923 { 135, "Cubic Meters Per Hour"},
2924 { 136, "Liters Per Hour"},
2925 { 137, "KWatt Hours Per Square Meter"},
2926 { 138, "KWatt Hours Per Square Foot"},
2927 { 139, "Megajoules Per Square Meter"},
2928 { 140, "Megajoules Per Square Foot"},
2929 { 141, "Watts Per Sq Meter Degree Kelvin"},
2930 { 142, "Cubic Feet Per Second"},
2931 { 143, "Percent Obstruction Per Foot"},
2932 { 144, "Percent Obstruction Per Meter"},
2933 { 145, "milliohms"},
2934 { 146, "megawatt-hours"},
2935 { 147, "kilo-btus"},
2936 { 148, "mega-btus"},
2937 { 149, "kilojoules-per-kilogram-dry-air"},
2938 { 150, "megajoules-per-kilogram-dry-air"},
2939 { 151, "kilojoules-per-degree-Kelvin"},
2940 { 152, "megajoules-per-degree-Kelvin"},
2942 { 154, "grams-per-second"},
2943 { 155, "grams-per-minute"},
2944 { 156, "tons-per-hour"},
2945 { 157, "kilo-btus-per-hour"},
2946 { 158, "hundredths-seconds"},
2947 { 159, "milliseconds"},
2948 { 160, "newton-meters"},
2949 { 161, "millimeters-per-second"},
2950 { 162, "millimeters-per-minute"},
2951 { 163, "meters-per-minute"},
2952 { 164, "meters-per-hour"},
2953 { 165, "cubic-meters-per-minute"},
2954 { 166, "meters-per-second-per-second"},
2955 { 167, "amperes-per-meter"},
2956 { 168, "amperes-per-square-meter"},
2957 { 169, "ampere-square-meters"},
2960 { 172, "ohm-meters"},
2962 { 174, "siemens-per-meter"},
2964 { 176, "volts-per-degree-Kelvin"},
2965 { 177, "volts-per-meter"},
2968 { 180, "candelas-per-square-meter"},
2969 { 181, "degrees-Kelvin-per-hour"},
2970 { 182, "degrees-Kelvin-per-minute"},
2971 { 183, "joule-seconds"},
2972 { 184, "radians-per-second"},
2973 { 185, "square-meters-per-Newton"},
2974 { 186, "kilograms-per-cubic-meter"},
2975 { 187, "newton-seconds"},
2976 { 188, "newtons-per-meter"},
2977 { 189, "watts-per-meter-per-degree-Kelvin"},
2978 { 190, "micro-siemens"},
2979 { 191, "cubic-feet-per-hour"},
2980 { 192, "us-gallons-per-hour"},
2981 { 193, "kilometers"},
2982 { 194, "micrometers"},
2984 { 196, "milligrams"},
2985 { 197, "milliliters"},
2986 { 198, "milliliters-per-second"},
2988 { 200, "decibels-millivolt"},
2989 { 201, "decibels-volt"},
2990 { 202, "millisiemens"},
2991 { 203, "watt-hours-reactive"},
2992 { 204, "kilowatt-hours-reactive"},
2993 { 205, "megawatt-hours-reactive"},
2994 { 206, "millimeters-of-water"},
2995 { 207, "per-mille"},
2996 { 208, "grams-per-gram"},
2997 { 209, "kilograms-per-kilogram"},
2998 { 210, "grams-per-kilogram"},
2999 { 211, "milligrams-per-gram"},
3000 { 212, "milligrams-per-kilogram"},
3001 { 213, "grams-per-milliliter"},
3002 { 214, "grams-per-liter"},
3003 { 215, "milligrams-per-liter"},
3004 { 216, "micrograms-per-liter"},
3005 { 217, "grams-per-cubic-meter"},
3006 { 218, "milligrams-per-cubic-meter"},
3007 { 219, "micrograms-per-cubic-meter"},
3008 { 220, "nanograms-per-cubic-meter"},
3009 { 221, "grams-per-cubic-centimeter"},
3010 { 222, "becquerels"},
3011 { 223, "kilobecquerels"},
3012 { 224, "megabecquerels"},
3014 { 226, "milligray"},
3015 { 227, "microgray"},
3017 { 229, "millisieverts"},
3018 { 230, "microsieverts"},
3019 { 231, "microsieverts-per-hour"},
3020 { 232, "decibels-a"},
3021 { 233, "nephelometric-turbidity-unit"},
3023 { 235, "grams-per-square-meter"},
3024 { 236, "minutes-per-degree-kelvin"},
3026 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
3027 Enumerated values 256-65535 may be used by others subject to
3028 the procedures and constraints described in Clause 23. */
3031 static const value_string
3032 BACnetErrorCode [] = {
3034 { 1, "authentication-failed"},
3035 { 2, "configuration-in-progress"},
3036 { 3, "device-busy"},
3037 { 4, "dynamic-creation-not-supported"},
3038 { 5, "file-access-denied"},
3039 { 6, "incompatible-security-levels"},
3040 { 7, "inconsistent-parameters"},
3041 { 8, "inconsistent-selection-criterion"},
3042 { 9, "invalid-data-type"},
3043 { 10, "invalid-file-access-method"},
3044 { 11, "invalid-file-start-position"},
3045 { 12, "invalid-operator-name"},
3046 { 13, "invalid-parameter-data-type"},
3047 { 14, "invalid-time-stamp"},
3048 { 15, "key-generation-error"},
3049 { 16, "missing-required-parameter"},
3050 { 17, "no-objects-of-specified-type"},
3051 { 18, "no-space-for-object"},
3052 { 19, "no-space-to-add-list-element"},
3053 { 20, "no-space-to-write-property"},
3054 { 21, "no-vt-sessions-available"},
3055 { 22, "property-is-not-a-list"},
3056 { 23, "object-deletion-not-permitted"},
3057 { 24, "object-identifier-already-exists"},
3058 { 25, "operational-problem"},
3059 { 26, "password-failure"},
3060 { 27, "read-access-denied"},
3061 { 28, "security-not-supported"},
3062 { 29, "service-request-denied"},
3064 { 31, "unknown-object"},
3065 { 32, "unknown-property"},
3066 { 33, "removed enumeration"},
3067 { 34, "unknown-vt-class"},
3068 { 35, "unknown-vt-session"},
3069 { 36, "unsupported-object-type"},
3070 { 37, "value-out-of-range"},
3071 { 38, "vt-session-already-closed"},
3072 { 39, "vt-session-termination-failure"},
3073 { 40, "write-access-denied"},
3074 { 41, "character-set-not-supported"},
3075 { 42, "invalid-array-index"},
3076 { 43, "cov-subscription-failed"},
3077 { 44, "not-cov-property"},
3078 { 45, "optional-functionality-not-supported"},
3079 { 46, "invalid-configuration-data"},
3080 { 47, "datatype-not-supported"},
3081 { 48, "duplicate-name"},
3082 { 49, "duplicate-object-id"},
3083 { 50, "property-is-not-an-array"},
3084 { 73, "invalid-event-state"},
3085 { 74, "no-alarm-configured"},
3086 { 75, "log-buffer-full"},
3087 { 76, "logged-value-purged"},
3088 { 77, "no-property-specified"},
3089 { 78, "not-configured-for-triggered-logging"},
3090 { 79, "unknown-subscription"},
3091 { 80, "parameter-out-of-range"},
3092 { 81, "list-element-not-found"},
3094 { 83, "communication-disabled"},
3096 { 85, "access-denied"},
3097 { 86, "bad-destination-address"},
3098 { 87, "bad-destination-device-id"},
3099 { 88, "bad-signature"},
3100 { 89, "bad-source-address"},
3101 { 90, "bad-timestamp"},
3102 { 91, "cannot-use-key"},
3103 { 92, "cannot-verify-message-id"},
3104 { 93, "correct-key-revision"},
3105 { 94, "destination-device-id-required"},
3106 { 95, "duplicate-message"},
3107 { 96, "encryption-not-configured"},
3108 { 97, "encryption-required"},
3109 { 98, "incorrect-key"},
3110 { 99, "invalid-key-data"},
3111 { 100, "key-update-in-progress"},
3112 { 101, "malformed-message"},
3113 { 102, "not-key-server"},
3114 { 103, "security-not-configured"},
3115 { 104, "source-security-required"},
3116 { 105, "too-many-keys"},
3117 { 106, "unknown-authentication-type"},
3118 { 107, "unknown-key"},
3119 { 108, "unknown-key-revision"},
3120 { 109, "unknown-source-message"},
3121 { 110, "not-router-to-dnet"},
3122 { 111, "router-busy"},
3123 { 112, "unknown-network-message"},
3124 { 113, "message-too-long"},
3125 { 114, "security-error"},
3126 { 115, "addressing-error"},
3127 { 116, "write-bdt-failed"},
3128 { 117, "read-bdt-failed"},
3129 { 118, "register-foreign-device-failed"},
3130 { 119, "read-fdt-failed"},
3131 { 120, "delete-fdt-entry-failed"},
3132 { 121, "distribute-broadcast-failed"},
3133 { 122, "unknown-file-size"},
3134 { 123, "abort-apdu-too-long"},
3135 { 124, "abort-application-exceeded-reply-time"},
3136 { 125, "abort-out-of-resources"},
3137 { 126, "abort-tsm-timeout"},
3138 { 127, "abort-window-size-out-of-range"},
3139 { 128, "file-full"},
3140 { 129, "inconsistent-configuration"},
3141 { 130, "inconsistent-object-type"},
3142 { 131, "internal-error"},
3143 { 132, "not-configured"},
3144 { 133, "out-of-memory"},
3145 { 134, "value-too-long"},
3146 { 135, "abort-insufficient-security"},
3147 { 136, "abort-security-error"},
3149 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
3150 Enumerated values 256-65535 may be used by others subject to the
3151 procedures and constraints described in Clause 23. */
3154 static const value_string
3155 BACnetPropertyIdentifier [] = {
3156 { 0, "acked-transition"},
3157 { 1, "ack-required"},
3159 { 3, "action-text"},
3160 { 4, "active-text"},
3161 { 5, "active-vt-session"},
3162 { 6, "alarm-value"},
3163 { 7, "alarm-values"},
3165 { 9, "all-writes-successful"},
3166 { 10, "apdu-segment-timeout"},
3167 { 11, "apdu-timeout"},
3168 { 12, "application-software-version"},
3171 { 15, "change-of-state-count"},
3172 { 16, "change-of-state-time"},
3173 { 17, "notification-class"},
3174 { 18, "the property in this place was deleted"},
3175 { 19, "controlled-variable-reference"},
3176 { 20, "controlled-variable-units"},
3177 { 21, "controlled-variable-value"},
3178 { 22, "cov-increment"},
3180 { 24, "daylights-savings-status"},
3182 { 26, "derivative-constant"},
3183 { 27, "derivative-constant-units"},
3184 { 28, "description"},
3185 { 29, "description-of-halt"},
3186 { 30, "device-address-binding"},
3187 { 31, "device-type"},
3188 { 32, "effective-period"},
3189 { 33, "elapsed-active-time"},
3190 { 34, "error-limit"},
3191 { 35, "event-enable"},
3192 { 36, "event-state"},
3193 { 37, "event-type"},
3194 { 38, "exception-schedule"},
3195 { 39, "fault-values"},
3196 { 40, "feedback-value"},
3197 { 41, "file-access-method"},
3200 { 44, "firmware-revision"},
3201 { 45, "high-limit"},
3202 { 46, "inactive-text"},
3203 { 47, "in-process"},
3204 { 48, "instance-of"},
3205 { 49, "integral-constant"},
3206 { 50, "integral-constant-units"},
3207 { 51, "issue-confirmed-notifications"},
3208 { 52, "limit-enable"},
3209 { 53, "list-of-group-members"},
3210 { 54, "list-of-object-property-references"},
3211 { 55, "list-of-session-keys"},
3212 { 56, "local-date"},
3213 { 57, "local-time"},
3216 { 60, "manipulated-variable-reference"},
3217 { 61, "maximum-output"},
3218 { 62, "max-apdu-length-accepted"},
3219 { 63, "max-info-frames"},
3220 { 64, "max-master"},
3221 { 65, "max-pres-value"},
3222 { 66, "minimum-off-time"},
3223 { 67, "minimum-on-time"},
3224 { 68, "minimum-output"},
3225 { 69, "min-pres-value"},
3226 { 70, "model-name"},
3227 { 71, "modification-date"},
3228 { 72, "notify-type"},
3229 { 73, "number-of-APDU-retries"},
3230 { 74, "number-of-states"},
3231 { 75, "object-identifier"},
3232 { 76, "object-list"},
3233 { 77, "object-name"},
3234 { 78, "object-property-reference"},
3235 { 79, "object-type"},
3237 { 81, "out-of-service"},
3238 { 82, "output-units"},
3239 { 83, "event-parameters"},
3241 { 85, "present-value"},
3243 { 87, "priority-array"},
3244 { 88, "priority-for-writing"},
3245 { 89, "process-identifier"},
3246 { 90, "program-change"},
3247 { 91, "program-location"},
3248 { 92, "program-state"},
3249 { 93, "proportional-constant"},
3250 { 94, "proportional-constant-units"},
3251 { 95, "protocol-conformance-class"},
3252 { 96, "protocol-object-types-supported"},
3253 { 97, "protocol-services-supported"},
3254 { 98, "protocol-version"},
3256 { 100, "reason-for-halt"},
3257 { 101, "recipient"},
3258 { 102, "recipient-list"},
3259 { 103, "reliability"},
3260 { 104, "relinquish-default"},
3262 { 106, "resolution"},
3263 { 107, "segmentation-supported"},
3265 { 109, "setpoint-reference"},
3266 { 110, "state-text"},
3267 { 111, "status-flags"},
3268 { 112, "system-status"},
3269 { 113, "time-delay"},
3270 { 114, "time-of-active-time-reset"},
3271 { 115, "time-of-state-count-reset"},
3272 { 116, "time-synchronization-recipients"},
3274 { 118, "update-interval"},
3275 { 119, "utc-offset"},
3276 { 120, "vendor-identifier"},
3277 { 121, "vendor-name"},
3278 { 122, "vt-class-supported"},
3279 { 123, "weekly-schedule"},
3280 { 124, "attempted-samples"},
3281 { 125, "average-value"},
3282 { 126, "buffer-size"},
3283 { 127, "client-cov-increment"},
3284 { 128, "cov-resubscription-interval"},
3285 { 129, "current-notify-time"},
3286 { 130, "event-time-stamp"},
3287 { 131, "log-buffer"},
3288 { 132, "log-device-object-property"},
3289 { 133, "enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
3290 { 134, "log-interval"},
3291 { 135, "maximum-value"},
3292 { 136, "minimum-value"},
3293 { 137, "notification-threshold"},
3294 { 138, "previous-notify-time"},
3295 { 139, "protocol-revision"},
3296 { 140, "records-since-notification"},
3297 { 141, "record-count"},
3298 { 142, "start-time"},
3299 { 143, "stop-time"},
3300 { 144, "stop-when-full"},
3301 { 145, "total-record-count"},
3302 { 146, "valid-samples"},
3303 { 147, "window-interval"},
3304 { 148, "window-samples"},
3305 { 149, "maximum-value-time-stamp"},
3306 { 150, "minimum-value-time-stamp"},
3307 { 151, "variance-value"},
3308 { 152, "active-cov-subscriptions"},
3309 { 153, "backup-failure-timeout"},
3310 { 154, "configuration-files"},
3311 { 155, "database-revision"},
3312 { 156, "direct-reading"},
3313 { 157, "last-restore-time"},
3314 { 158, "maintenance-required"},
3315 { 159, "member-of"},
3317 { 161, "operation-expected"},
3320 { 164, "tracking-value"},
3321 { 165, "zone-members"},
3322 { 166, "life-safety-alarm-values"},
3323 { 167, "max-segments-accepted"},
3324 { 168, "profile-name"},
3325 { 169, "auto-slave-discovery"},
3326 { 170, "manual-slave-address-binding"},
3327 { 171, "slave-address-binding"},
3328 { 172, "slave-proxy-enable"},
3329 { 173, "last-notify-record"}, /* bug 4117 */
3330 { 174, "schedule-default"},
3331 { 175, "accepted-modes"},
3332 { 176, "adjust-value"},
3334 { 178, "count-before-change"},
3335 { 179, "count-change-time"},
3336 { 180, "cov-period"},
3337 { 181, "input-reference"},
3338 { 182, "limit-monitoring-interval"},
3339 { 183, "logging-device"},
3340 { 184, "logging-record"},
3342 { 186, "pulse-rate"},
3344 { 188, "scale-factor"},
3345 { 189, "update-time"},
3346 { 190, "value-before-change"},
3347 { 191, "value-set"},
3348 { 192, "value-change-time"},
3349 { 193, "align-intervals"},
3350 { 194, "group-member-names"},
3351 { 195, "interval-offset"},
3352 { 196, "last-restart-reason"},
3353 { 197, "logging-type"},
3354 { 198, "member-status-flags"},
3355 { 199, "notification-period"},
3356 { 200, "previous-notify-record"},
3357 { 201, "requested-update-interval"},
3358 { 202, "restart-notification-recipients"},
3359 { 203, "time-of-device-restart"},
3360 { 204, "time-synchronization-interval"},
3362 { 206, "UTC-time-synchronization-recipients"},
3363 { 207, "node-subtype"},
3364 { 208, "node-type"},
3365 { 209, "structured-object-list"},
3366 { 210, "subordinate-annotations"},
3367 { 211, "subordinate-list"},
3368 { 212, "actual-shed-level"},
3369 { 213, "duty-window"},
3370 { 214, "expected-shed-level"},
3371 { 215, "full-duty-baseline"},
3372 { 216, "node-subtype"},
3373 { 217, "node-type"},
3374 { 218, "requested-shed-level"},
3375 { 219, "shed-duration"},
3376 { 220, "shed-level-descriptions"},
3377 { 221, "shed-levels"},
3378 { 222, "state-description"},
3379 /* enumeration values 223-225 are unassigned */
3380 { 226, "door-alarm-state"},
3381 { 227, "door-extended-pulse-time"},
3382 { 228, "door-members"},
3383 { 229, "door-open-too-long-time"},
3384 { 230, "door-pulse-time"},
3385 { 231, "door-status"},
3386 { 232, "door-unlock-delay-time"},
3387 { 233, "lock-status"},
3388 { 234, "masked-alarm-values"},
3389 { 235, "secured-status"},
3390 /* enumeration values 236-243 are unassigned */
3391 { 244, "absentee-limit"}, /* added with addenda 135-2008j */
3392 { 245, "access-alarm-events"},
3393 { 246, "access-doors"},
3394 { 247, "access-event"},
3395 { 248, "access-event-authentication-factor"},
3396 { 249, "access-event-credential"},
3397 { 250, "access-event-time"},
3398 { 251, "access-transaction-events"},
3399 { 252, "accompaniment"},
3400 { 253, "accompaniment-time"},
3401 { 254, "activation-time"},
3402 { 255, "active-authentication-policy"},
3403 { 256, "assigned-access-rights"},
3404 { 257, "authentication-factors"},
3405 { 258, "authentication-policy-list"},
3406 { 259, "authentication-policy-names"},
3407 { 260, "authentication-status"},
3408 { 261, "authorization-mode"},
3409 { 262, "belongs-to"},
3410 { 263, "credential-disable"},
3411 { 264, "credential-status"},
3412 { 265, "credentials"},
3413 { 266, "credentials-in-zone"},
3414 { 267, "days-remaining"},
3415 { 268, "entry-points"},
3416 { 269, "exit-points"},
3417 { 270, "expiry-time"},
3418 { 271, "extended-time-enable"},
3419 { 272, "failed-attempt-events"},
3420 { 273, "failed-attempts"},
3421 { 274, "failed-attempts-time"},
3422 { 275, "last-access-event"},
3423 { 276, "last-access-point"},
3424 { 277, "last-credential-added"},
3425 { 278, "last-credential-added-time"},
3426 { 279, "last-credential-removed"},
3427 { 280, "last-credential-removed-time"},
3428 { 281, "last-use-time"},
3430 { 283, "lockout-relinquish-time"},
3431 { 284, "master-exemption"},
3432 { 285, "max-failed-attempts"},
3434 { 287, "muster-point"},
3435 { 288, "negative-access-rules"},
3436 { 289, "number-of-authentication-policies"},
3437 { 290, "occupancy-count"},
3438 { 291, "occupancy-count-adjust"},
3439 { 292, "occupancy-count-enable"},
3440 { 293, "occupancy-exemption"},
3441 { 294, "occupancy-lower-limit"},
3442 { 295, "occupancy-lower-limit-enforced"},
3443 { 296, "occupancy-state"},
3444 { 297, "occupancy-upper-limit"},
3445 { 298, "occupancy-upper-limit-enforced"},
3446 { 299, "passback-exemption"},
3447 { 300, "passback-mode"},
3448 { 301, "passback-timeout"},
3449 { 302, "positive-access-rules"},
3450 { 303, "reason-for-disable"},
3451 { 304, "supported-formats"},
3452 { 305, "supported-format-classes"},
3453 { 306, "threat-authority"},
3454 { 307, "threat-level"},
3455 { 308, "trace-flag"},
3456 { 309, "transaction-notification-class"},
3457 { 310, "user-external-identifier"},
3458 { 311, "user-information-reference"},
3459 /* enumeration values 312-316 are unassigned */
3460 { 317, "user-name"},
3461 { 318, "user-type"},
3462 { 319, "uses-remaining"},
3463 { 320, "zone-from"},
3465 { 322, "access-event-tag"},
3466 { 323, "global-identifier"},
3467 /* enumeration values 324-325 reserved for future addenda */
3468 { 326, "verification-time"},
3469 { 327, "base-device-security-policy"},
3470 { 328, "distribution-key-revision"},
3471 { 329, "do-not-hide"},
3473 { 331, "last-key-server"},
3474 { 332, "network-access-security-policies"},
3475 { 333, "packet-reorder-time"},
3476 { 334, "security-pdu-timeout"},
3477 { 335, "security-time-window"},
3478 { 336, "supported-security-algorithms"},
3479 { 337, "update-key-set-timeout"},
3480 { 338, "backup-and-restore-state"},
3481 { 339, "backup-preparation-time"},
3482 { 340, "restore-completion-time"},
3483 { 341, "restore-preparation-time"},
3484 { 342, "bit-mask"}, /* addenda 135-2008w */
3487 { 345, "group-members"},
3488 { 346, "group-member-names"},
3489 { 347, "member-status-flags"},
3490 { 348, "requested-update-interval"},
3491 { 349, "covu-period"},
3492 { 350, "covu-recipients"},
3493 { 351, "event-message-texts"},
3495 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3496 Enumerated values 512-4194303 may be used by others subject to
3497 the procedures and constraints described in Clause 23. */
3500 static const value_string
3501 BACnetBinaryPV [] = {
3508 #define ANSI_X3_4 0 /* ANSI X3.4, a/k/a "ASCII"; full UTF-8 since 2010 */
3509 /* See, for example, ANSI/ASHRAE Addendum k to ANSI/ASHRAE Standard 135-2008 */
3510 /* XXX - I've seen captures using this for ISO 8859-1 */
3511 #define IBM_MS_DBCS 1 /* "IBM/Microsoft DBCS"; was there only one such DBCS? */
3512 #define JIS_C_6226 2 /* JIS C 6226 */
3513 #define ISO_10646_UCS4 3 /* ISO 10646 (UCS-4) - 4-byte Unicode */
3514 #define ISO_10646_UCS2 4 /* ISO 10646 (UCS-2) - 2-byte Unicode Basic Multilingual Plane (not UTF-16, presumably) */
3515 #define ISO_8859_1 5 /* ISO 8859-1 */
3516 static const value_string
3517 BACnetCharacterSet [] = {
3518 { ANSI_X3_4, "ANSI X3.4 / UTF-8 (since 2010)"},
3519 { IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3520 { JIS_C_6226, "JIS C 6226"},
3521 { ISO_10646_UCS4, "ISO 10646 (UCS-4)"},
3522 { ISO_10646_UCS2, "ISO 10646 (UCS-2)"},
3523 { ISO_8859_1, "ISO 8859-1"},
3527 static const value_string
3528 BACnetStatusFlags [] = {
3532 { 3, "out-of-service"},
3536 static const value_string
3537 BACnetMessagePriority [] = {
3543 static const value_string
3544 BACnetAcknowledgementFilter [] = {
3551 static const value_string
3552 BACnetResultFlags [] = {
3559 static const value_string
3560 BACnetRelationSpecifier [] = {
3564 { 3, "greater-than"},
3565 { 4, "less-than-or-equal"},
3566 { 5, "greater-than-or-equal"},
3570 static const value_string
3571 BACnetSelectionLogic [] = {
3578 static const value_string
3579 BACnetEventStateFilter [] = {
3588 static const value_string
3589 BACnetEventTransitionBits [] = {
3590 { 0, "to-offnormal"},
3596 static const value_string
3597 BACnetSegmentation [] = {
3598 { 0, "segmented-both"},
3599 { 1, "segmented-transmit"},
3600 { 2, "segmented-receive"},
3601 { 3, "no-segmentation"},
3605 static const value_string
3606 BACnetSilencedState [] = {
3608 { 1, "audible-silenced"},
3609 { 2, "visible-silenced"},
3610 { 3, "all-silenced"},
3614 static const value_string
3615 BACnetDeviceStatus [] = {
3616 { 0, "operational"},
3617 { 1, "operational-read-only"},
3618 { 2, "download-required"},
3619 { 3, "download-in-progress"},
3620 { 4, "non-operational"},
3621 { 5, "backup-in-progress"},
3625 static const value_string
3626 BACnetEnableDisable [] = {
3629 { 2, "disable-initiation"},
3633 static const value_string
3647 { 255, "any month" },
3651 static const value_string
3653 { 1, "days numbered 1-7" },
3654 { 2, "days numbered 8-14" },
3655 { 3, "days numbered 15-21" },
3656 { 4, "days numbered 22-28" },
3657 { 5, "days numbered 29-31" },
3658 { 6, "last 7 days of this month" },
3659 { 255, "any week of this month" },
3663 /* note: notification class object recipient-list uses
3664 different day-of-week enum */
3665 static const value_string
3674 { 255, "any day of week" },
3678 static const value_string
3679 BACnetErrorClass [] = {
3687 { 7, "communication" },
3689 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3690 Enumerated values64-65535 may be used by others subject to
3691 the procedures and constraints described in Clause 23. */
3694 static const value_string
3695 BACnetVTClass [] = {
3696 { 0, "default-terminal" },
3697 { 1, "ansi-x3-64" },
3706 static const value_string
3707 BACnetEventType [] = {
3708 { 0, "change-of-bitstring" },
3709 { 1, "change-of-state" },
3710 { 2, "change-of-value" },
3711 { 3, "command-failure" },
3712 { 4, "floating-limit" },
3713 { 5, "out-of-range" },
3714 { 6, "complex-event-type" },
3715 { 7, "(deprecated)buffer-ready" },
3716 { 8, "change-of-life-safety" },
3718 { 10, "buffer-ready" },
3719 { 11, "unsigned-range" },
3720 { 14, "double-out-of-range"}, /* added with addenda 135-2008w */
3721 { 15, "signed-out-of-range"},
3722 { 16, "unsigned-out-of-range"},
3723 { 17, "change-of-characterstring"},
3724 { 18, "change-of-status-flags"},
3726 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3727 Enumerated values 64-65535 may be used by others subject to
3728 the procedures and constraints described in Clause 23.
3729 It is expected that these enumerated values will correspond
3730 to the use of the complex-event-type CHOICE [6] of the
3731 BACnetNotificationParameters production. */
3734 static const value_string
3735 BACnetEventState [] = {
3739 { 3, "high-limit" },
3741 { 5, "life-safety-alarm" },
3743 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3744 Enumerated values 64-65535 may be used by others subject to
3745 the procedures and constraints described in Clause 23. */
3748 static const value_string
3749 BACnetLogStatus [] = {
3750 { 0, "log-disabled" },
3751 { 1, "buffer-purged" },
3752 { 2, "log-interrupted"},
3756 static const value_string
3757 BACnetMaintenance [] = {
3759 { 1, "periodic-test" },
3760 { 2, "need-service-operational" },
3761 { 3, "need-service-inoperative" },
3765 static const value_string
3766 BACnetNotifyType [] = {
3769 { 2, "ack-notification" },
3773 static const value_string
3774 BACnetServicesSupported [] = {
3775 { 0, "acknowledgeAlarm"},
3776 { 1, "confirmedCOVNotification"},
3777 { 2, "confirmedEventNotification"},
3778 { 3, "getAlarmSummary"},
3779 { 4, "getEnrollmentSummary"},
3780 { 5, "subscribeCOV"},
3781 { 6, "atomicReadFile"},
3782 { 7, "atomicWriteFile"},
3783 { 8, "addListElement"},
3784 { 9, "removeListElement"},
3785 { 10, "createObject"},
3786 { 11, "deleteObject"},
3787 { 12, "readProperty"},
3788 { 13, "readPropertyConditional"},
3789 { 14, "readPropertyMultiple"},
3790 { 15, "writeProperty"},
3791 { 16, "writePropertyMultiple"},
3792 { 17, "deviceCommunicationControl"},
3793 { 18, "confirmedPrivateTransfer"},
3794 { 19, "confirmedTextMessage"},
3795 { 20, "reinitializeDevice"},
3799 { 24, "authenticate"},
3800 { 25, "requestKey"},
3803 { 28, "unconfirmedCOVNotification"},
3804 { 29, "unconfirmedEventNotification"},
3805 { 30, "unconfirmedPrivateTransfer"},
3806 { 31, "unconfirmedTextMessage"},
3807 { 32, "timeSynchronization"},
3811 { 36, "utcTimeSynchronization"},
3812 { 37, "lifeSafetyOperation"},
3813 { 38, "subscribeCOVProperty"},
3814 { 39, "getEventInformation"},
3818 static const value_string
3819 BACnetPropertyStates [] = {
3820 { 0, "boolean-value"},
3821 { 1, "binary-value"},
3824 { 4, "program-change"},
3825 { 5, "program-state"},
3826 { 6, "reason-for-halt"},
3827 { 7, "reliability"},
3829 { 9, "system-status"},
3831 { 11, "unsigned-value"},
3832 { 12, "life-safety-mode"},
3833 { 13, "life-safety-state"},
3834 { 14, "restart-reason"},
3835 { 15, "door-alarm-state"},
3837 { 17, "door-secured-status"},
3838 { 18, "door-status"},
3839 { 19, "door-value"},
3840 { 20, "file-access-method"},
3841 { 21, "lock-status"},
3842 { 22, "life-safety-operation"},
3843 { 23, "maintenance"},
3845 { 25, "notify-type"},
3846 { 26, "security-level"},
3847 { 27, "shed-state"},
3848 { 28, "silenced-state"},
3849 /* context tag 29 reserved for future addenda */
3850 { 29, "unknown-29"},
3851 { 30, "access-event"},
3852 { 31, "zone-occupancy-state"},
3853 { 32, "access-credential-disable-reason"},
3854 { 33, "access-credential-disable"},
3855 { 34, "authentication-status"},
3856 { 35, "unknown-35"},
3857 { 36, "backup-state"},
3859 /* Tag values 0-63 are reserved for definition by ASHRAE.
3860 Tag values of 64-254 may be used by others to accommodate
3861 vendor specific properties that have discrete or enumerated values,
3862 subject to the constraints described in Clause 23. */
3865 static const value_string
3866 BACnetProgramError [] = {
3868 { 1, "load-failed"},
3873 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3874 Enumerated values 64-65535 may be used by others subject to
3875 the procedures and constraints described in Clause 23. */
3878 static const value_string
3879 BACnetProgramRequest [] = {
3889 static const value_string
3890 BACnetProgramState [] = {
3900 static const value_string
3901 BACnetReinitializedStateOfDevice [] = {
3904 { 2, "startbackup"},
3906 { 4, "startrestore"},
3908 { 6, "abortrestore"},
3912 static const value_string
3913 BACnetPolarity [] = {
3919 static const value_string
3920 BACnetTagNames[] = {
3921 { 5, "Extended Value" },
3922 { 6, "Opening Tag" },
3923 { 7, "Closing Tag" },
3927 static const value_string
3928 BACnetReadRangeOptions[] = {
3929 { 3, "range byPosition" },
3930 { 4, "range byTime" },
3931 { 5, "range timeRange" },
3932 { 6, "range bySequenceNumber" },
3933 { 7, "range byTime" },
3937 /* Present_Value for Load Control Object */
3938 static const value_string
3939 BACnetShedState[] = {
3940 { 0, "shed-inactive" },
3941 { 1, "shed-request-pending" },
3942 { 2, "shed-compliant" },
3943 { 3, "shed-non-compliant" },
3947 static const value_string
3948 BACnetNodeType [] = {
3953 { 4, "organizational" },
3957 { 8, "collection" },
3959 { 10, "functional" },
3964 static const value_string
3965 BACnetLoggingType [] = {
3972 static const value_string
3973 BACnetDoorStatus [] = {
3980 static const value_string
3981 BACnetLockStatus [] = {
3989 static const value_string
3990 BACnetDoorSecuredStatus [] = {
3997 static const value_string
3998 BACnetDoorAlarmState [] = {
4001 { 2, "door-open-too-long" },
4002 { 3, "forced-open" },
4004 { 5, "door-fault" },
4006 { 7, "free-access" },
4007 { 8, "egress-open" },
4011 static const value_string
4012 BACnetAccumulatorStatus [] = {
4021 /* These values are (manually) transferred from
4022 * http://www.bacnet.org/VendorID/BACnet Vendor IDs.htm
4023 * Version: "As of September 16, 2013"
4026 static const value_string
4027 BACnetVendorIdentifiers [] = {
4030 { 2, "The Trane Company" },
4031 { 3, "McQuay International" },
4033 { 5, "Johnson Controls, Inc." },
4034 { 6, "American Auto-Matrix" },
4035 { 7, "Siemens Schweiz AG (Formerly: Landis & Staefa Division Europe)" },
4036 { 8, "Delta Controls" },
4037 { 9, "Siemens Schweiz AG" },
4038 { 10, "Schneider Electric" },
4040 { 12, "Orion Analysis Corporation" },
4041 { 13, "Teletrol Systems Inc." },
4042 { 14, "Cimetrics Technology" },
4043 { 15, "Cornell University" },
4044 { 16, "United Technologies Carrier" },
4045 { 17, "Honeywell Inc." },
4046 { 18, "Alerton / Honeywell" },
4048 { 20, "Hewlett-Packard Company" },
4049 { 21, "Dorsette's Inc." },
4050 { 22, "Siemens Schweiz AG (Formerly: Cerberus AG)" },
4051 { 23, "York Controls Group" },
4052 { 24, "Automated Logic Corporation" },
4053 { 25, "CSI Control Systems International" },
4054 { 26, "Phoenix Controls Corporation" },
4055 { 27, "Innovex Technologies, Inc." },
4056 { 28, "KMC Controls, Inc." },
4057 { 29, "Xn Technologies, Inc." },
4058 { 30, "Hyundai Information Technology Co., Ltd." },
4059 { 31, "Tokimec Inc." },
4061 { 33, "North Building Technologies Limited" },
4063 { 35, "Reliable Controls Corporation" },
4064 { 36, "Tridium Inc." },
4065 { 37, "Sierra Monitor Corporation/FieldServer Technologies" },
4066 { 38, "Silicon Energy" },
4067 { 39, "Kieback & Peter GmbH & Co KG" },
4068 { 40, "Anacon Systems, Inc." },
4069 { 41, "Systems Controls & Instruments, LLC" },
4070 { 42, "Lithonia Lighting" },
4071 { 43, "Micropower Manufacturing" },
4072 { 44, "Matrix Controls" },
4073 { 45, "METALAIRE" },
4074 { 46, "ESS Engineering" },
4075 { 47, "Sphere Systems Pty Ltd." },
4076 { 48, "Walker Technologies Corporation" },
4077 { 49, "H I Solutions, Inc." },
4079 { 51, "SAMSON AG" },
4080 { 52, "Badger Meter Inc." },
4081 { 53, "DAIKIN Industries Ltd." },
4082 { 54, "NARA Controls Inc." },
4083 { 55, "Mammoth Inc." },
4084 { 56, "Liebert Corporation" },
4085 { 57, "SEMCO Incorporated" },
4086 { 58, "Air Monitor Corporation" },
4087 { 59, "TRIATEK, LLC" },
4089 { 61, "Multistack" },
4090 { 62, "TSI Incorporated" },
4091 { 63, "Weather-Rite, Inc." },
4092 { 64, "Dunham-Bush" },
4093 { 65, "Reliance Electric" },
4095 { 67, "Regulator Australia PTY Ltd." },
4096 { 68, "Touch-Plate Lighting Controls" },
4097 { 69, "Amann GmbH" },
4098 { 70, "RLE Technologies" },
4099 { 71, "Cardkey Systems" },
4100 { 72, "SECOM Co., Ltd." },
4101 { 73, "ABB Gebaeudetechnik AG Bereich NetServ" },
4102 { 74, "KNX Association cvba" },
4103 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
4104 { 76, "Nohmi Bosai, Ltd." },
4105 { 77, "Carel S.p.A." },
4106 { 78, "UTC Fire & Security Espana, S.L." },
4107 { 79, "Hochiki Corporation" },
4108 { 80, "Fr. Sauter AG" },
4109 { 81, "Matsushita Electric Works, Ltd." },
4110 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
4111 { 83, "Mitsubishi Heavy Industries, Ltd." },
4112 { 84, "ITT Bell & Gossett" },
4113 { 85, "Yamatake Building Systems Co., Ltd." },
4114 { 86, "The Watt Stopper, Inc." },
4115 { 87, "Aichi Tokei Denki Co., Ltd." },
4116 { 88, "Activation Technologies, LLC" },
4117 { 89, "Saia-Burgess Controls, Ltd." },
4118 { 90, "Hitachi, Ltd." },
4119 { 91, "Novar Corp./Trend Control Systems Ltd." },
4120 { 92, "Mitsubishi Electric Lighting Corporation" },
4121 { 93, "Argus Control Systems, Ltd." },
4122 { 94, "Kyuki Corporation" },
4123 { 95, "Richards-Zeta Building Intelligence, Inc." },
4124 { 96, "Scientech R&D, Inc." },
4125 { 97, "VCI Controls, Inc." },
4126 { 98, "Toshiba Corporation" },
4127 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
4128 { 100, "Custom Mechanical Equipment, LLC" },
4129 { 101, "ClimateMaster" },
4130 { 102, "ICP Panel-Tec, Inc." },
4131 { 103, "D-Tek Controls" },
4132 { 104, "NEC Engineering, Ltd." },
4133 { 105, "PRIVA BV" },
4134 { 106, "Meidensha Corporation" },
4135 { 107, "JCI Systems Integration Services" },
4136 { 108, "Freedom Corporation" },
4137 { 109, "Neuberger Gebaeudeautomation GmbH" },
4138 { 110, "Sitronix" },
4139 { 111, "Leviton Manufacturing" },
4140 { 112, "Fujitsu Limited" },
4141 { 113, "Emerson Network Power" },
4142 { 114, "S. A. Armstrong, Ltd." },
4143 { 115, "Visonet AG" },
4144 { 116, "M&M Systems, Inc." },
4145 { 117, "Custom Software Engineering" },
4146 { 118, "Nittan Company, Limited" },
4147 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
4148 { 120, "Pacom Systems Pty., Ltd." },
4149 { 121, "Unico, Inc." },
4150 { 122, "Ebtron, Inc." },
4151 { 123, "Scada Engine" },
4152 { 124, "AC Technology Corporation" },
4153 { 125, "Eagle Technology" },
4154 { 126, "Data Aire, Inc." },
4155 { 127, "ABB, Inc." },
4156 { 128, "Transbit Sp. z o. o." },
4157 { 129, "Toshiba Carrier Corporation" },
4158 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
4159 { 131, "Tokai Soft" },
4160 { 132, "Blue Ridge Technologies" },
4161 { 133, "Veris Industries" },
4162 { 134, "Centaurus Prime" },
4163 { 135, "Sand Network Systems" },
4164 { 136, "Regulvar, Inc." },
4165 { 137, "AFDtek Division of Fastek International Inc." },
4166 { 138, "PowerCold Comfort Air Solutions, Inc." },
4167 { 139, "I Controls" },
4168 { 140, "Viconics Electronics, Inc." },
4169 { 141, "Yaskawa America, Inc." },
4170 { 142, "DEOS control systems GmbH" },
4171 { 143, "Digitale Mess- und Steuersysteme AG" },
4172 { 144, "Fujitsu General Limited" },
4173 { 145, "Project Engineering S.r.l." },
4174 { 146, "Sanyo Electric Co., Ltd." },
4175 { 147, "Integrated Information Systems, Inc." },
4176 { 148, "Temco Controls, Ltd." },
4177 { 149, "Airtek International Inc." },
4178 { 150, "Advantech Corporation" },
4179 { 151, "Titan Products, Ltd." },
4180 { 152, "Regel Partners" },
4181 { 153, "National Environmental Product" },
4182 { 154, "Unitec Corporation" },
4183 { 155, "Kanden Engineering Company" },
4184 { 156, "Messner Gebaeudetechnik GmbH" },
4185 { 157, "Integrated.CH" },
4186 { 158, "Price Industries" },
4187 { 159, "SE-Elektronic GmbH" },
4188 { 160, "Rockwell Automation" },
4189 { 161, "Enflex Corp." },
4190 { 162, "ASI Controls" },
4191 { 163, "SysMik GmbH Dresden" },
4192 { 164, "HSC Regelungstechnik GmbH" },
4193 { 165, "Smart Temp Australia Pty. Ltd." },
4194 { 166, "Cooper Controls" },
4195 { 167, "Duksan Mecasys Co., Ltd." },
4196 { 168, "Fuji IT Co., Ltd." },
4197 { 169, "Vacon Plc" },
4198 { 170, "Leader Controls" },
4199 { 171, "Cylon Controls, Ltd." },
4201 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
4202 { 174, "Building Control Integrators" },
4203 { 175, "ITG Worldwide (M) Sdn Bhd" },
4204 { 176, "Lutron Electronics Co., Inc." },
4205 { 177, "Cooper-Atkins Corporation" },
4206 { 178, "LOYTEC Electronics GmbH" },
4208 { 180, "Mega Controls Limited" },
4209 { 181, "Micro Control Systems, Inc." },
4210 { 182, "Kiyon, Inc." },
4211 { 183, "Dust Networks" },
4212 { 184, "Advanced Building Automation Systems" },
4213 { 185, "Hermos AG" },
4216 { 188, "Lynxspring, Inc." },
4217 { 189, "Schneider Toshiba Inverter Europe" },
4218 { 190, "Danfoss Drives A/S" },
4219 { 191, "Eaton Corporation" },
4220 { 192, "Matyca S.A." },
4221 { 193, "Botech AB" },
4222 { 194, "Noveo, Inc." },
4224 { 196, "Yokogawa Electric Corporation" },
4225 { 197, "GFR Gesellschaft fuer Regelungstechnik" },
4226 { 198, "Exact Logic" },
4227 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
4228 { 200, "Kandenko Co., Ltd." },
4229 { 201, "DTF, Daten-Technik Fries" },
4230 { 202, "Klimasoft, Ltd." },
4231 { 203, "Toshiba Schneider Inverter Corporation" },
4232 { 204, "Control Applications, Ltd." },
4233 { 205, "KDT Systems Co., Ltd." },
4234 { 206, "Onicon Incorporated" },
4235 { 207, "Automation Displays, Inc." },
4236 { 208, "Control Solutions, Inc." },
4237 { 209, "Remsdaq Limited" },
4238 { 210, "NTT Facilities, Inc." },
4239 { 211, "VIPA GmbH" },
4240 { 212, "TSC21 Association of Japan" },
4241 { 213, "Strato Automation" },
4242 { 214, "HRW Limited" },
4243 { 215, "Lighting Control & Design, Inc." },
4244 { 216, "Mercy Electronic and Electrical Industries" },
4245 { 217, "Samsung SDS Co., Ltd" },
4246 { 218, "Impact Facility Solutions, Inc." },
4247 { 219, "Aircuity" },
4248 { 220, "Control Techniques, Ltd." },
4249 { 221, "OpenGeneral Pty., Ltd." },
4250 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
4251 { 223, "Cerus Industrial" },
4252 { 224, "Chloride Power Protection Company" },
4253 { 225, "Computrols, Inc." },
4254 { 226, "Phoenix Contact GmbH & Co. KG" },
4255 { 227, "Grundfos Management A/S" },
4256 { 228, "Ridder Drive Systems" },
4257 { 229, "Soft Device SDN BHD" },
4258 { 230, "Integrated Control Technology Limited" },
4259 { 231, "AIRxpert Systems, Inc." },
4260 { 232, "Microtrol Limited" },
4261 { 233, "Red Lion Controls" },
4262 { 234, "Digital Electronics Corporation" },
4263 { 235, "Ennovatis GmbH" },
4264 { 236, "Serotonin Software Technologies, Inc." },
4265 { 237, "LS Industrial Systems Co., Ltd." },
4266 { 238, "Square D Company" },
4267 { 239, "S Squared Innovations, Inc." },
4268 { 240, "Aricent Ltd." },
4269 { 241, "EtherMetrics, LLC" },
4270 { 242, "Industrial Control Communications, Inc." },
4271 { 243, "Paragon Controls, Inc." },
4272 { 244, "A. O. Smith Corporation" },
4273 { 245, "Contemporary Control Systems, Inc." },
4274 { 246, "Intesis Software SL" },
4275 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
4276 { 248, "Heat-Timer Corporation" },
4277 { 249, "Ingrasys Technology, Inc." },
4278 { 250, "Costerm Building Automation" },
4280 { 252, "Embedia Technologies Corp." },
4281 { 253, "Technilog" },
4282 { 254, "HR Controls Ltd. & Co. KG" },
4283 { 255, "Lennox International, Inc." },
4284 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
4285 { 257, "Thermomax, Ltd." },
4286 { 258, "ELCON Electronic Control, Ltd." },
4287 { 259, "Larmia Control AB" },
4288 { 260, "BACnet Stack at SourceForge" },
4289 { 261, "G4S Security Services A/S" },
4290 { 262, "Exor International S.p.A." },
4291 { 263, "Cristal Controles" },
4292 { 264, "Regin AB" },
4293 { 265, "Dimension Software, Inc." },
4294 { 266, "SynapSense Corporation" },
4295 { 267, "Beijing Nantree Electronic Co., Ltd." },
4296 { 268, "Camus Hydronics Ltd." },
4297 { 269, "Kawasaki Heavy Industries, Ltd." },
4298 { 270, "Critical Environment Technologies" },
4299 { 271, "ILSHIN IBS Co., Ltd." },
4300 { 272, "ELESTA Energy Control AG" },
4301 { 273, "KROPMAN Installatietechniek" },
4302 { 274, "Baldor Electric Company" },
4303 { 275, "INGA mbH" },
4304 { 276, "GE Consumer & Industrial" },
4305 { 277, "Functional Devices, Inc." },
4307 { 279, "M-System Co., Ltd." },
4308 { 280, "Yokota Co., Ltd." },
4309 { 281, "Hitranse Technology Co., LTD" },
4310 { 282, "Federspiel Controls" },
4311 { 283, "Kele, Inc." },
4312 { 284, "Opera Electronics, Inc." },
4314 { 286, "Embedded Science Labs, LLC" },
4315 { 287, "Parker Hannifin Corporation" },
4316 { 288, "MaCaPS International Limited" },
4317 { 289, "Link4 Corporation" },
4318 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
4319 { 291, "Pribusin, Inc." },
4320 { 292, "Advantage Controls" },
4321 { 293, "Critical Room Control" },
4323 { 295, "Tongdy Control Technology Co., Ltd." },
4324 { 296, "ISSARO Integrierte Systemtechnik" },
4325 { 297, "Pro-Dev Industries" },
4326 { 298, "DRI-STEEM" },
4327 { 299, "Creative Electronic GmbH" },
4328 { 300, "Swegon AB" },
4329 { 301, "Jan Brachacek" },
4330 { 302, "Hitachi Appliances, Inc." },
4331 { 303, "Real Time Automation, Inc." },
4332 { 304, "ITEC Hankyu-Hanshin Co." },
4333 { 305, "Cyrus E&M Engineering Co., Ltd." },
4334 { 306, "Badger Meter" },
4335 { 307, "Cirrascale Corporation" },
4336 { 308, "Elesta GmbH Building Automation" },
4337 { 309, "Securiton" },
4338 { 310, "OSlsoft, Inc." },
4339 { 311, "Hanazeder Electronic GmbH" },
4340 { 312, "Honeywell Security Deutschland, Novar GmbH" },
4341 { 313, "Siemens Energy & Automation, Inc." },
4342 { 314, "ETM Professional Control GmbH" },
4343 { 315, "Meitav-tec, Ltd." },
4344 { 316, "Janitza Electronics GmbH" },
4345 { 317, "MKS Nordhausen" },
4346 { 318, "De Gier Drive Systems B.V." },
4347 { 319, "Cypress Envirosystems" },
4348 { 320, "SMARTron s.r.o." },
4349 { 321, "Verari Systems, Inc." },
4350 { 322, "K-W Electronic Service, Inc." },
4351 { 323, "ALFA-SMART Energy Management" },
4352 { 324, "Telkonet, Inc." },
4353 { 325, "Securiton GmbH" },
4354 { 326, "Cemtrex, Inc." },
4355 { 327, "Performance Technologies, Inc." },
4356 { 328, "Xtralis (Aust) Pty Ltd" },
4357 { 329, "TROX GmbH" },
4358 { 330, "Beijing Hysine Technology Co., Ltd" },
4359 { 331, "RCK Controls, Inc." },
4360 { 332, "Distech Controls SAS" },
4361 { 333, "Novar/Honeywell" },
4362 { 334, "The S4 Group, Inc." },
4363 { 335, "Schneider Electric" },
4364 { 336, "LHA Systems" },
4365 { 337, "GHM engineering Group, Inc." },
4366 { 338, "Cllimalux S.A." },
4367 { 339, "VAISALA Oyj" },
4368 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
4369 { 341, "SCADAmetrics" },
4370 { 342, "POWERPEG NSI Limited" },
4371 { 343, "BACnet Interoperability Testing Services, Inc." },
4372 { 344, "Teco a.s." },
4373 { 345, "Plexus Technology, Inc." },
4374 { 346, "Energy Focus, Inc." },
4375 { 347, "Powersmiths International Corp." },
4376 { 348, "Nichibei Co., Ltd." },
4377 { 349, "HKC Technology Ltd." },
4378 { 350, "Ovation Networks, Inc." },
4379 { 351, "Setra Systems" },
4380 { 352, "AVG Automation" },
4381 { 353, "ZXC Ltd." },
4382 { 354, "Byte Sphere" },
4383 { 355, "Generiton Co., Ltd." },
4384 { 356, "Holter Regelarmaturen GmbH & Co. KG" },
4385 { 357, "Bedford Instruments, LLC" },
4386 { 358, "Standair Inc." },
4387 { 359, "WEG Automation - R&D" },
4388 { 360, "Prolon Control Systems ApS" },
4389 { 361, "Inneasoft" },
4390 { 362, "ConneXSoft GmbH" },
4391 { 363, "CEAG Notlichtsysteme GmbH" },
4392 { 364, "Distech Controls Inc." },
4393 { 365, "Industrial Technology Research Institute" },
4394 { 366, "ICONICS, Inc." },
4395 { 367, "IQ Controls s.c." },
4396 { 368, "OJ Electronics A/S" },
4397 { 369, "Rolbit Ltd." },
4398 { 370, "Synapsys Solutions Ltd." },
4399 { 371, "ACME Engineering Prod. Ltd." },
4400 { 372, "Zener Electric Pty, Ltd." },
4401 { 373, "Selectronix, Inc." },
4402 { 374, "Gorbet & Banerjee, LLC." },
4404 { 376, "Stephen H. Dawson Computer Service" },
4405 { 377, "Accutrol, LLC" },
4406 { 378, "Schneider Elektronik GmbH" },
4407 { 379, "Alpha-Inno Tec GmbH" },
4408 { 380, "ADMMicro, Inc." },
4409 { 381, "Greystone Energy Systems, Inc." },
4410 { 382, "CAP Technologie" },
4411 { 383, "KeRo Systems" },
4412 { 384, "Domat Control System s.r.o." },
4413 { 385, "Efektronics Pty. Ltd." },
4414 { 386, "Hekatron Vertriebs GmbH" },
4415 { 387, "Securiton AG" },
4416 { 388, "Carlo Gavazzi Controls SpA" },
4417 { 389, "Chipkin Automation Systems" },
4418 { 390, "Savant Systems, LLC" },
4419 { 391, "Simmtronic Lighting Controls" },
4420 { 392, "Abelko Innovation AB" },
4421 { 393, "Seresco Technologies Inc." },
4422 { 394, "IT Watchdogs" },
4423 { 395, "Automation Assist Japan Corp." },
4424 { 396, "Thermokon Sensortechnik GmbH" },
4425 { 397, "EGauge Systems, LLC" },
4426 { 398, "Quantum Automation (ASIA) PTE, Ltd." },
4427 { 399, "Toshiba Lighting & Technology Corp." },
4428 { 400, "SPIN Engenharia de Automacao Ltda." },
4429 { 401, "Logistics Systems & Software Services India PVT. Ltd." },
4430 { 402, "Delta Controls Integration Products" },
4431 { 403, "Focus Media" },
4432 { 404, "LUMEnergi Inc." },
4433 { 405, "Kara Systems" },
4434 { 406, "RF Code, Inc." },
4435 { 407, "Fatek Automation Corp." },
4436 { 408, "JANDA Software Company, LLC" },
4437 { 409, "Open System Solutions Limited" },
4438 { 410, "Intelec Systems PTY Ltd." },
4439 { 411, "Ecolodgix, LLC" },
4440 { 412, "Douglas Lighting Controls" },
4441 { 413, "iSAtech GmbH" },
4443 { 415, "Beckhoff Automation GmbH" },
4444 { 416, "IPAS GmbH" },
4445 { 417, "KE2 Therm Solutions" },
4446 { 418, "Base2Products" },
4447 { 419, "DTL Controls, LLC" },
4448 { 420, "INNCOM International, Inc." },
4449 { 421, "BTR Netcom GmbH" },
4450 { 422, "Greentrol Automation, Inc" },
4451 { 423, "BELIMO Automation AG" },
4452 { 424, "Samsung Heavy Industries Co, Ltd" },
4453 { 425, "Triacta Power Technologies, Inc." },
4454 { 426, "Globestar Systems" },
4455 { 427, "MLB Advanced Media, LP" },
4456 { 428, "SWG Stuckmann Wirtschaftliche Gebaeudesysteme GmbH" },
4457 { 429, "SensorSwitch" },
4458 { 430, "Multitek Power Limited" },
4459 { 431, "Aquametro AG" },
4460 { 432, "LG Electronics Inc." },
4461 { 433, "Electronic Theatre Controls, Inc." },
4462 { 434, "Mitsubishi Electric Corporation Nagoya Works" },
4463 { 435, "Delta Electronics, Inc." },
4464 { 436, "Elma Kurtalj, Ltd." },
4465 { 437, "ADT Fire and Security Sp. A.o.o." },
4466 { 438, "Nedap Security Management" },
4467 { 439, "ESC Automation Inc." },
4468 { 440, "DSP4YOU Ltd." },
4469 { 441, "GE Sensing and Inspection Technologies" },
4470 { 442, "Embedded Systems SIA" },
4471 { 443, "BEFEGA GmbH" },
4472 { 444, "Baseline Inc." },
4473 { 445, "M2M Systems Integrators" },
4475 { 447, "Clarkson Controls Limited" },
4476 { 448, "Rogerwell Control System Limited" },
4477 { 449, "SCL Elements" },
4478 { 450, "Hitachi Ltd." },
4479 { 451, "Newron System SA" },
4480 { 452, "BEVECO Gebouwautomatisering BV" },
4481 { 453, "Streamside Solutions" },
4482 { 454, "Yellowstone Soft" },
4483 { 455, "Oztech Intelligent Systems Pty Ltd." },
4484 { 456, "Novelan GmbH" },
4485 { 457, "Flexim Americas Corporation" },
4486 { 458, "ICP DAS Co., Ltd." },
4487 { 459, "CARMA Industries Inc." },
4488 { 460, "Log-One Ltd." },
4489 { 461, "TECO Electric & Machinery Co., Ltd." },
4490 { 462, "ConnectEx, Inc." },
4491 { 463, "Turbo DDC Suedwest" },
4492 { 464, "Quatrosense Environmental Ltd." },
4493 { 465, "Fifth Light Technology Ltd." },
4494 { 466, "Scientific Solutions, Ltd." },
4495 { 467, "Controller Area Network Solutions (M) Sdn Bhd" },
4496 { 468, "RESOL - Elektronische Regelungen GmbH" },
4497 { 469, "RPBUS LLC" },
4498 { 470, "BRS Sistemas Eletronicos" },
4499 { 471, "WindowMaster A/S" },
4500 { 472, "Sunlux Technologies Ltd." },
4501 { 473, "Measurlogic" },
4502 { 474, "Frimat GmbH" },
4503 { 475, "Spirax Sarco" },
4505 { 477, "Raypak Inc" },
4506 { 478, "Air Monitor Corporation" },
4507 { 479, "Regler Och Webbteknik Sverige (ROWS)" },
4508 { 480, "Intelligent Lighting Controls Inc." },
4509 { 481, "Sanyo Electric Industry Co., Ltd" },
4510 { 482, "E-Mon Energy Monitoring Products" },
4511 { 483, "Digital Control Systems" },
4512 { 484, "ATI Airtest Technologies, Inc." },
4514 { 486, "HMS Industrial Networks AB" },
4515 { 487, "Shenzhen Universal Intellisys Co Ltd" },
4516 { 488, "EK Intellisys Sdn Bhd" },
4518 { 490, "Firecom, Inc." },
4519 { 491, "ESA Elektroschaltanlagen Grimma GmbH" },
4520 { 492, "Kumahira Co Ltd" },
4522 { 494, "SABO Elektronik GmbH" },
4523 { 495, "Equip'Trans" },
4524 { 496, "TCS Basys Controls" },
4525 { 497, "FlowCon International A/S" },
4526 { 498, "ThyssenKrupp Elevator Americas" },
4527 { 499, "Abatement Technologies" },
4528 { 500, "Continental Control Systems, LLC" },
4529 { 501, "WISAG Automatisierungstechnik GmbH & Co KG" },
4531 { 503, "EAP-Electric GmbH" },
4532 { 504, "Hardmeier" },
4533 { 505, "Mircom Group of Companies" },
4534 { 506, "Quest Controls" },
4535 { 507, "Mestek, Inc" },
4536 { 508, "Pulse Energy" },
4537 { 509, "Tachikawa Corporation" },
4538 { 510, "University of Nebraska-Lincoln" },
4539 { 511, "Redwood Systems" },
4540 { 512, "PASStec Industrie-Elektronik GmbH" },
4541 { 513, "NgEK, Inc." },
4542 { 514, "FAW Electronics Ltd" },
4543 { 515, "Jireh Energy Tech Co., Ltd." },
4544 { 516, "Enlighted Inc." },
4545 { 517, "El-Piast Sp. Z o.o" },
4546 { 518, "NetxAutomation Software GmbH" },
4547 { 519, "Invertek Drives" },
4548 { 520, "Deutschmann Automation GmbH & Co. KG" },
4549 { 521, "EMU Electronic AG" },
4550 { 522, "Phaedrus Limited" },
4551 { 523, "Sigmatek GmbH & Co KG" },
4552 { 524, "Marlin Controls" },
4553 { 525, "Circutor, SA" },
4554 { 526, "UTC Fire & Security" },
4555 { 527, "DENT Instruments, Inc." },
4556 { 528, "FHP Manufacturing Company - Bosch Group" },
4557 { 529, "GE Intelligent Platforms" },
4558 { 530, "Inner Range Pty Ltd" },
4559 { 531, "GLAS Energy Technology" },
4560 { 532, "MSR-Electronic-GmbH" },
4561 { 533, "Energy Control Systems, Inc." },
4562 { 534, "EMT Controls" },
4563 { 535, "Daintree Networks Inc." },
4564 { 536, "EURO ICC d.o.o" },
4565 { 537, "TE Connectivity Energy" },
4566 { 538, "GEZE GmbH" },
4567 { 539, "NEC Corporation" },
4568 { 540, "Ho Cheung International Company Limited" },
4569 { 541, "Sharp Manufacturing Systems Corporation" },
4570 { 542, "DOT CONTROLS a.s." },
4571 { 543, "BeaconMedaes" },
4572 { 544, "Midea Commercial Aircon" },
4573 { 545, "WattMaster Controls" },
4574 { 546, "Kamstrup A/S" },
4575 { 547, "CA Computer Automation GmbH" },
4576 { 548, "Laars Heating Systems Company" },
4577 { 549, "Hitachi Systems, Ltd." },
4578 { 550, "Fushan AKE Electronic Engineering Co., Ltd." },
4579 { 551, "Toshiba International Corporation" },
4580 { 552, "Starman Systems, LLC" },
4581 { 553, "Samsung Techwin Co., Ltd." },
4582 { 554, "ISAS-Integrated Switchgear and Systems P/L" },
4584 { 557, "Marek Guzik" },
4585 { 558, "Vortek Instruments, LLC" },
4586 { 559, "Universal Lighting Technologies" },
4587 { 560, "Myers Power Products, Inc." },
4588 { 561, "Vector Controls GmbH" },
4589 { 562, "Crestron Electronics, Inc." },
4590 { 563, "A&E Controls Limited" },
4591 { 564, "Projektomontaza A.D." },
4592 { 565, "Freeaire Refrigeration" },
4593 { 566, "Aqua Cooler Pty Limited" },
4594 { 567, "Basic Controls" },
4595 { 568, "GE Measurement and Control Solutions Advanced Sensors" },
4596 { 569, "EQUAL Networks" },
4597 { 570, "Millennial Net" },
4598 { 571, "APLI Ltd" },
4599 { 572, "Electro Industries/GaugeTech" },
4600 { 573, "SangMyung University" },
4601 { 574, "Coppertree Analytics, Inc." },
4602 { 575, "CoreNetiX GmbH" },
4603 { 576, "Acutherm" },
4604 { 577, "Dr. Riedel Automatisierungstechnik GmbH" },
4605 { 578, "Shina System Co., Ltd" },
4606 { 579, "Iqapertus" },
4607 { 580, "PSE Technology" },
4608 { 581, "BA Systems" },
4610 { 583, "Monico, Inc." },
4612 { 585, "tekmar Control Systems Ltd." },
4613 { 586, "Control Technology Corporation" },
4614 { 587, "GFAE GmbH" },
4615 { 588, "BeKa Software GmbH" },
4616 { 589, "Isoil Industria SpA" },
4617 { 590, "Home Systems Consulting SpA" },
4619 { 592, "Everex Communications, Inc." },
4620 { 593, "Ceiec Electric Technology" },
4621 { 594, "Atrila GmbH" },
4622 { 595, "WingTechs" },
4623 { 596, "Shenzhen Mek Intellisys Pte Ltd." },
4624 { 597, "Nestfield Co., Ltd." },
4625 { 598, "Swissphone Telecom AG" },
4626 { 599, "PNTECH JSC" },
4627 { 600, "Horner APG, LLC" },
4628 { 601, "PVI Industries, LLC" },
4629 { 602, "Ela-compil" },
4630 { 603, "Pegasus Automation International LLC" },
4631 { 604, "Wight Electronic Services Ltd." },
4633 { 606, "Exhausto A/S" },
4634 { 607, "Dwyer Instruments, Inc." },
4635 { 608, "Link GmbH" },
4636 { 609, "Oppermann Regelgerate GmbH" },
4637 { 610, "NuAire, Inc." },
4638 { 611, "Nortec Humidity, Inc." },
4639 { 612, "Bigwood Systems, Inc." },
4640 { 613, "Enbala Power Networks" },
4641 { 614, "Inter Energy Co., Ltd." },
4643 { 616, "COMELEC S.A.R.L" },
4644 { 617, "Pythia Technologies" },
4645 { 618, "TrendPoint Systems, Inc." },
4648 { 621, "Kongsberg E-lon AS" },
4649 { 622, "FlaktWoods" },
4650 { 623, "E + E Elektronik GES M.B.H." },
4651 { 624, "ARC Informatique" },
4652 { 625, "SKIDATA AG" },
4653 { 626, "WSW Solutions" },
4654 { 627, "Trefon Electronic GmbH" },
4655 { 628, "Dongseo System" },
4656 { 629, "Kanontec Intelligence Technology Co., Ltd." },
4657 { 630, "EVCO S.p.A." },
4658 { 631, "Accuenergy (CANADA) Inc." },
4660 { 633, "Orion Energy Systems, Inc." },
4661 { 634, "Roboticsware" },
4662 { 635, "DOMIQ Sp. z o.o." },
4663 { 636, "Solidyne" },
4664 { 637, "Elecsys Corporation" },
4665 { 638, "Conditionaire International Pty. Limited" },
4666 { 639, "Quebec, Inc." },
4667 { 640, "Homerun Holdings" },
4668 { 641, "Murata Americas" },
4670 { 643, "Westco Systems, Inc." },
4671 { 644, "Advancis Software & Services GmbH" },
4672 { 645, "Intergrid, LLC" },
4673 { 646, "Markerr Controls, Inc." },
4674 { 647, "Toshiba Elevator and Building Systems Corporation" },
4675 { 648, "Spectrum Controls, Inc." },
4676 { 649, "Mkservice" },
4677 { 650, "Fox Thermal Instruments" },
4678 { 651, "SyxthSense Ltd" },
4679 { 652, "DUHA System S R.O." },
4681 { 654, "Melink Corporation" },
4682 { 655, "Fritz-Haber-Institut" },
4683 { 656, "MTU Onsite Energy GmbH, Gas Power Systems" },
4684 { 657, "Omega Engineering, Inc." },
4686 { 659, "Ywire Technologies, Inc." },
4687 { 660, "M.R. Engineering Co., Ltd." },
4688 { 661, "Lochinvar, LLC" },
4689 { 662, "Sontay Limited" },
4690 { 663, "GRUPA Slawomir Chelminski" },
4691 { 664, "Arch Meter Corporation" },
4692 { 665, "Senva, Inc." },
4694 { 668, "Systems Specialists, Inc." },
4695 { 669, "SenseAir" },
4696 { 670, "AB IndustrieTechnik Srl" },
4697 { 671, "Cortland Research, LLC" },
4698 { 672, "MediaView" },
4699 { 673, "VDA Elettronica" },
4700 { 674, "CSS, Inc." },
4701 { 675, "Tek-Air Systems, Inc." },
4703 { 677, "The Armstrong Monitoring Corporation" },
4704 { 678, "DIXELL S.r.l" },
4705 { 679, "Lead System, Inc." },
4706 { 680, "ISM EuroCenter S.A." },
4708 { 682, "Trade FIDES" },
4709 { 683, "Knuerr GmbH (Emerson Network Power)" },
4710 { 684, "Resource Data Management" },
4711 { 685, "Abies Technology, Inc." },
4713 { 687, "MIRAE Electrical Mfg. Co., Ltd." },
4714 { 688, "HunterDouglas Architectural Projects Scandinavia ApS" },
4715 { 689, "RUNPAQ Group Co., Ltd" },
4716 { 690, "Unicard SA" },
4717 { 691, "IE Technologies" },
4718 { 692, "Ruskin Manufacturing" },
4719 { 693, "Calon Associates Limited" },
4720 { 694, "Contec Co., Ltd." },
4722 { 696, "Autani Corporation" },
4723 { 697, "Christian Fortin" },
4725 { 699, "IPID Sp. Z.O.O Limited" },
4726 { 700, "Fuji Electric Co., Ltd" },
4727 { 701, "View, Inc." },
4728 { 702, "Samsung S1 Corporation" },
4729 { 703, "New Lift" },
4730 { 704, "VRT Systems" },
4731 { 705, "Motion Control Engineering, Inc." },
4732 { 706, "Weiss Klimatechnik GmbH" },
4734 { 708, "Eliwell Controls S.r.l." },
4735 { 709, "Japan Computer Technos Corp" },
4736 { 710, "Rational Network ehf" },
4737 { 711, "Magnum Energy Solutions, LLC" },
4739 { 713, "VAE Group" },
4741 { 715, "Berghof Automationstechnik GmbH" },
4742 { 716, "Quark Communications, Inc." },
4744 { 718, "mivune AG" },
4746 { 720, "Smart Controls, LLC" },
4747 { 721, "Compu-Aire, Inc." },
4749 { 723, "ProtoSense Technologies" },
4750 { 724, "Eltrac Technologies Pvt Ltd" },
4751 { 725, "Bektas Invisible Controls GmbH" },
4754 { 728, "Covenant" },
4755 { 729, "Davitor AB" },
4756 { 730, "TongFang Technovator" },
4757 { 731, "Building Robotics, Inc." },
4758 { 732, "HSS-MSR UG" },
4759 { 733, "FramTack LLC" },
4760 { 734, "B. L. Acoustics, Ltd." },
4761 { 735, "Traxxon Rock Drills, Ltd" },
4763 { 737, "Wurm GmbH & Co" },
4764 { 738, "AddENERGIE" },
4765 { 739, "Mirle Automation Corporation" },
4766 { 740, "Ibis Networks" },
4767 { 741, "ID-KARTA s.r.o." },
4768 { 742, "Anaren, Inc." },
4769 { 743, "Span, Incorporated" },
4770 { 744, "Bosch Thermotechnology Corp" },
4771 { 745, "DRC Technology S.A." },
4772 { 746, "Shanghai Energy Building Technology Co, Ltd" },
4773 { 747, "Fraport AG" },
4774 { 748, "Flowgroup" },
4775 { 749, "Skytron Energy, GmbH" },
4776 { 750, "ALTEL Wicha, Golda Sp. J." },
4778 { 752, "Axiomatic Technology, Ltd" },
4779 { 753, "Bohnke + Partner" },
4780 { 754, "Function 1" },
4781 { 755, "Optergy Pty, Ltd" },
4782 { 756, "LSI Virticus" },
4783 { 757, "Konzeptpark GmbH" },
4784 { 758, "Hubbell Building Automation, Inc." },
4785 { 759, "eCurv, Inc." },
4786 { 760, "Agnosys GmbH" },
4787 { 761, "Shanghai Sunfull Automation Co., LTD" },
4788 { 762, "Kurz Instruments, Inc." },
4789 { 763, "Cias Elettronica S.r.l." },
4790 { 764, "Multiaqua, Inc." },
4792 { 766, "Sensidyne" },
4793 { 767, "Viessmann Elektronik GmbH" },
4794 { 768, "ADFweb.com srl" },
4795 { 769, "Gaylord Industries" },
4796 { 770, "Majur Ltd." },
4797 { 771, "Shanghai Huilin Technology Co., Ltd." },
4798 { 772, "Exotronic" },
4799 { 773, "Safecontrol spol s.r.o." },
4801 { 775, "Universal Electric Corporation" },
4803 { 778, "Smartrise Engineering, Inc." },
4804 { 779, "Miratron, Inc." },
4805 { 780, "SmartEdge" },
4806 { 781, "Mitsubishi Electric Australia Pty Ltd" },
4807 { 782, "Triangle Research International Ptd Ltd" },
4808 { 783, "Produal Oy" },
4809 { 784, "Milestone Systems A/S" },
4810 { 785, "Trustbridge" },
4813 static value_string_ext BACnetVendorIdentifiers_ext = VALUE_STRING_EXT_INIT(BACnetVendorIdentifiers);
4815 static int proto_bacapp = -1;
4816 static int hf_bacapp_type = -1;
4817 static int hf_bacapp_pduflags = -1;
4818 static int hf_bacapp_SEG = -1;
4819 static int hf_bacapp_MOR = -1;
4820 static int hf_bacapp_SA = -1;
4821 static int hf_bacapp_response_segments = -1;
4822 static int hf_bacapp_max_adpu_size = -1;
4823 static int hf_bacapp_invoke_id = -1;
4824 static int hf_bacapp_objectType = -1;
4825 static int hf_bacapp_instanceNumber = -1;
4826 static int hf_bacapp_sequence_number = -1;
4827 static int hf_bacapp_window_size = -1;
4828 static int hf_bacapp_service = -1;
4829 static int hf_bacapp_NAK = -1;
4830 static int hf_bacapp_SRV = -1;
4831 static int hf_Device_Instance_Range_Low_Limit = -1;
4832 static int hf_Device_Instance_Range_High_Limit = -1;
4833 static int hf_BACnetRejectReason = -1;
4834 static int hf_BACnetAbortReason = -1;
4835 static int hf_BACnetApplicationTagNumber = -1;
4836 static int hf_BACnetContextTagNumber = -1;
4837 static int hf_BACnetExtendedTagNumber = -1;
4838 static int hf_BACnetNamedTag = -1;
4839 static int hf_BACnetTagClass = -1;
4840 static int hf_BACnetCharacterSet = -1;
4841 static int hf_bacapp_tag_lvt = -1;
4842 static int hf_bacapp_tag_ProcessId = -1;
4843 static int hf_bacapp_uservice = -1;
4844 static int hf_BACnetPropertyIdentifier = -1;
4845 static int hf_BACnetVendorIdentifier = -1;
4846 static int hf_BACnetRestartReason = -1;
4847 static int hf_bacapp_tag_IPV4 = -1;
4848 static int hf_bacapp_tag_IPV6 = -1;
4849 static int hf_bacapp_tag_PORT = -1;
4850 /* some more variables for segmented messages */
4851 static int hf_msg_fragments = -1;
4852 static int hf_msg_fragment = -1;
4853 static int hf_msg_fragment_overlap = -1;
4854 static int hf_msg_fragment_overlap_conflicts = -1;
4855 static int hf_msg_fragment_multiple_tails = -1;
4856 static int hf_msg_fragment_too_long_fragment = -1;
4857 static int hf_msg_fragment_error = -1;
4858 static int hf_msg_fragment_count = -1;
4859 static int hf_msg_reassembled_in = -1;
4860 static int hf_msg_reassembled_length = -1;
4862 static gint ett_msg_fragment = -1;
4863 static gint ett_msg_fragments = -1;
4865 static gint ett_bacapp = -1;
4866 static gint ett_bacapp_control = -1;
4867 static gint ett_bacapp_tag = -1;
4868 static gint ett_bacapp_list = -1;
4869 static gint ett_bacapp_value = -1;
4871 static expert_field ei_bacapp_bad_length = EI_INIT;
4873 static gint32 propertyIdentifier = -1;
4874 static gint32 propertyArrayIndex = -1;
4875 static guint32 object_type = 4096;
4877 static guint8 bacapp_flags = 0;
4878 static guint8 bacapp_seq = 0;
4880 /* Defined to allow vendor identifier registration of private transfer dissectors */
4881 static dissector_table_t bacapp_dissector_table;
4884 /* Stat: BACnet Packets sorted by IP */
4885 bacapp_info_value_t bacinfo;
4887 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
4888 static const gchar* st_str_packets_by_ip_dst = "By Destination";
4889 static const gchar* st_str_packets_by_ip_src = "By Source";
4890 static int st_node_packets_by_ip = -1;
4891 static int st_node_packets_by_ip_dst = -1;
4892 static int st_node_packets_by_ip_src = -1;
4895 bacapp_packet_stats_tree_init(stats_tree* st)
4897 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4898 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4899 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4903 bacapp_get_address_label(const char *tag, address *addr)
4905 gchar *addr_str, *label_str;
4907 addr_str = address_to_str(NULL, addr);
4908 label_str = wmem_strconcat(NULL, tag, addr_str, NULL);
4909 wmem_free(NULL, addr_str);
4914 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4916 int packets_for_this_dst;
4917 int packets_for_this_src;
4918 int service_for_this_dst;
4919 int service_for_this_src;
4920 int src_for_this_dst;
4921 int dst_for_this_src;
4922 int objectid_for_this_dst;
4923 int objectid_for_this_src;
4924 int instanceid_for_this_dst;
4925 int instanceid_for_this_src;
4928 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4930 srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
4931 dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
4933 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4934 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4935 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4936 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4937 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4938 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4939 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4940 if (binfo->service_type) {
4941 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4942 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4943 if (binfo->object_ident) {
4944 instanceid_for_this_dst = tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4945 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4946 instanceid_for_this_src = tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4947 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4951 wmem_free(NULL, srcstr);
4952 wmem_free(NULL, dststr);
4957 /* Stat: BACnet Packets sorted by Service */
4958 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4959 static int st_node_packets_by_service = -1;
4962 bacapp_service_stats_tree_init(stats_tree* st)
4964 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4968 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4977 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4979 srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
4980 dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
4982 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4983 if (binfo->service_type) {
4984 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4985 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4986 dst = tick_stat_node(st, dststr, src, TRUE);
4987 if (binfo->object_ident) {
4988 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4989 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4993 wmem_free(NULL, srcstr);
4994 wmem_free(NULL, dststr);
4999 /* Stat: BACnet Packets sorted by Object Type */
5000 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
5001 static int st_node_packets_by_objectid = -1;
5004 bacapp_objectid_stats_tree_init(stats_tree* st)
5006 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
5010 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
5018 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
5020 srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
5021 dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
5023 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
5024 if (binfo->object_ident) {
5025 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
5026 src = tick_stat_node(st, srcstr, objectid, TRUE);
5027 dst = tick_stat_node(st, dststr, src, TRUE);
5028 if (binfo->service_type) {
5029 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
5030 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
5034 wmem_free(NULL, srcstr);
5035 wmem_free(NULL, dststr);
5040 /* Stat: BACnet Packets sorted by Instance No */
5041 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
5042 static int st_node_packets_by_instanceid = -1;
5045 bacapp_instanceid_stats_tree_init(stats_tree* st)
5047 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
5051 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
5059 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
5061 srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
5062 dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
5064 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
5065 if (binfo->object_ident) {
5066 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
5067 src = tick_stat_node(st, srcstr, instanceid, TRUE);
5068 dst = tick_stat_node(st, dststr, src, TRUE);
5069 if (binfo->service_type) {
5070 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
5071 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
5075 wmem_free(NULL, srcstr);
5076 wmem_free(NULL, dststr);
5082 /* register all BACnet Ststistic trees */
5084 register_bacapp_stat_trees(void)
5086 stats_tree_register("bacapp", "bacapp_ip", "BACnet/Packets sorted by IP", 0,
5087 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
5088 stats_tree_register("bacapp", "bacapp_service", "BACnet/Packets sorted by Service", 0,
5089 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
5090 stats_tree_register("bacapp", "bacapp_objectid", "BACnet/Packets sorted by Object Type", 0,
5091 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
5092 stats_tree_register("bacapp", "bacapp_instanceid", "BACnet/Packets sorted by Instance ID", 0,
5093 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
5096 /* 'data' must be allocated with wmem packet scope */
5098 updateBacnetInfoValue(gint whichval, const gchar *data)
5100 if (whichval == BACINFO_SERVICE) {
5101 bacinfo.service_type = data;
5104 if (whichval == BACINFO_INVOKEID) {
5105 bacinfo.invoke_id = data;
5108 if (whichval == BACINFO_OBJECTID) {
5109 bacinfo.object_ident = data;
5112 if (whichval == BACINFO_INSTANCEID) {
5113 bacinfo.instance_ident = data;
5119 static const fragment_items msg_frag_items = {
5120 /* Fragment subtrees */
5123 /* Fragment fields */
5126 &hf_msg_fragment_overlap,
5127 &hf_msg_fragment_overlap_conflicts,
5128 &hf_msg_fragment_multiple_tails,
5129 &hf_msg_fragment_too_long_fragment,
5130 &hf_msg_fragment_error,
5131 &hf_msg_fragment_count,
5132 /* Reassembled in field */
5133 &hf_msg_reassembled_in,
5134 /* Reassembled length field */
5135 &hf_msg_reassembled_length,
5136 /* Reassembled data field */
5143 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
5144 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
5145 static const guint MaxAPDUSize [] = { 50, 128, 206, 480, 1024, 1476 };
5148 fGetMaxAPDUSize(guint8 idx)
5150 /* only 16 values are defined, so use & 0x0f */
5151 /* check the size of the Array, deliver either the entry
5152 or the first entry if idx is outside of the array (bug 3736 comment#7) */
5154 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
5155 return MaxAPDUSize[0];
5157 return MaxAPDUSize[idx & 0x0f];
5162 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
5163 const char *fmt, const char *split_fmt)
5165 G_GNUC_PRINTF(5, 0);
5167 /* Used when there are ranges of reserved and proprietary enumerations */
5169 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
5170 const char *fmt, const char *split_fmt)
5172 if (val < split_val)
5173 return val_to_str(val, vs, fmt);
5175 return val_to_str(val, vs, split_fmt);
5178 /* from clause 20.2.1.3.2 Constructed Data */
5179 /* returns true if the extended value is used */
5181 tag_is_extended_value(guint8 tag)
5183 return (tag & 0x07) == 5;
5187 tag_is_opening(guint8 tag)
5189 return (tag & 0x07) == 6;
5193 tag_is_closing(guint8 tag)
5195 return (tag & 0x07) == 7;
5198 /* from clause 20.2.1.1 Class
5199 class bit shall be one for context specific tags */
5200 /* returns true if the tag is context specific */
5202 tag_is_context_specific(guint8 tag)
5204 return (tag & 0x08) != 0;
5208 tag_is_extended_tag_number(guint8 tag)
5210 return ((tag & 0xF0) == 0xF0);
5214 object_id_type(guint32 object_identifier)
5216 return ((object_identifier >> 22) & 0x3FF);
5220 object_id_instance(guint32 object_identifier)
5222 return (object_identifier & 0x3FFFFF);
5226 fTagNo(tvbuff_t *tvb, guint offset)
5228 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
5232 fUnsigned32(tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
5234 gboolean valid = TRUE;
5238 *val = tvb_get_guint8(tvb, offset);
5241 *val = tvb_get_ntohs(tvb, offset);
5244 *val = tvb_get_ntoh24(tvb, offset);
5247 *val = tvb_get_ntohl(tvb, offset);
5258 fUnsigned64(tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
5260 gboolean valid = FALSE;
5264 if (lvt && (lvt <= 8)) {
5266 for (i = 0; i < lvt; i++) {
5267 data = tvb_get_guint8(tvb, offset+i);
5268 value = (value << 8) + data;
5276 /* BACnet Signed Value uses 2's complement notation, but with a twist:
5277 All signed integers shall be encoded in the smallest number of octets
5278 possible. That is, the first octet of any multi-octet encoded value
5279 shall not be X'00' if the most significant bit (bit 7) of the second
5280 octet is 0, and the first octet shall not be X'FF' if the most
5281 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
5283 fSigned64(tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
5285 gboolean valid = FALSE;
5290 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
5291 if (lvt && (lvt <= 7)) {
5293 data = tvb_get_guint8(tvb, offset);
5294 if ((data & 0x80) != 0)
5295 value = (-1 << 8) | data;
5298 for (i = 1; i < lvt; i++) {
5299 data = tvb_get_guint8(tvb, offset+i);
5300 value = (value << 8) + data;
5309 fTagHeaderTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5310 guint offset, guint8 *tag_no, guint8* tag_info, guint32 *lvt)
5312 proto_item *ti = NULL;
5316 guint lvt_len = 1; /* used for tree display of lvt */
5317 guint lvt_offset; /* used for tree display of lvt */
5319 lvt_offset = offset;
5320 tag = tvb_get_guint8(tvb, offset);
5324 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
5325 /* can mean open/close tag or length of 6/7 after the length is */
5326 /* computed below - store whole tag info, not just context bit. */
5327 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
5329 if (tag_is_extended_tag_number(tag)) {
5330 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
5332 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
5333 lvt_offset += tag_len;
5334 value = tvb_get_guint8(tvb, lvt_offset);
5336 if (value == 254) { /* length is encoded with 16 Bits */
5337 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
5340 } else if (value == 255) { /* length is encoded with 32 Bits */
5341 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
5349 proto_tree *subtree;
5350 if (tag_is_opening(tag))
5351 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
5352 else if (tag_is_closing(tag))
5353 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
5354 else if (tag_is_context_specific(tag)) {
5355 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
5356 "Context Tag: %u, Length/Value/Type: %u",
5359 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
5360 "Application Tag: %s, Length/Value/Type: %u",
5362 BACnetApplicationTagNumber,
5363 ASHRAE_Reserved_Fmt),
5366 /* details if needed */
5367 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5368 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
5369 if (tag_is_extended_tag_number(tag)) {
5370 proto_tree_add_uint_format(subtree,
5371 hf_BACnetContextTagNumber,
5372 tvb, offset, 1, tag,
5373 "Extended Tag Number");
5374 proto_tree_add_item(subtree,
5375 hf_BACnetExtendedTagNumber,
5376 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
5378 if (tag_is_context_specific(tag))
5379 proto_tree_add_item(subtree,
5380 hf_BACnetContextTagNumber,
5381 tvb, offset, 1, ENC_BIG_ENDIAN);
5383 proto_tree_add_item(subtree,
5384 hf_BACnetApplicationTagNumber,
5385 tvb, offset, 1, ENC_BIG_ENDIAN);
5387 if (tag_is_closing(tag) || tag_is_opening(tag))
5388 proto_tree_add_item(subtree,
5390 tvb, offset, 1, ENC_BIG_ENDIAN);
5391 else if (tag_is_extended_value(tag)) {
5392 proto_tree_add_item(subtree,
5394 tvb, offset, 1, ENC_BIG_ENDIAN);
5395 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
5396 tvb, lvt_offset, lvt_len, *lvt);
5398 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
5399 tvb, lvt_offset, lvt_len, *lvt);
5402 if (*lvt > tvb_reported_length(tvb)) {
5403 expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
5404 "LVT length too long: %d > %d", *lvt,
5405 tvb_reported_length(tvb));
5413 fTagHeader(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* tag_info,
5416 return fTagHeaderTree(tvb, pinfo, NULL, offset, tag_no, tag_info, lvt);
5420 fNullTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5422 guint8 tag_no, tag_info;
5424 proto_tree *subtree;
5426 subtree = proto_tree_add_subtree_format(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "%sNULL", label);
5427 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5433 fBooleanTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5435 guint8 tag_no, tag_info;
5437 proto_tree *subtree;
5440 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5441 if (tag_info && lvt == 1) {
5442 lvt = tvb_get_guint8(tvb, offset+1);
5446 subtree = proto_tree_add_subtree_format(tree, tvb, offset, bool_len,
5447 ett_bacapp_tag, NULL, "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
5448 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5450 return offset + bool_len;
5454 fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5457 guint8 tag_no, tag_info;
5460 proto_tree *subtree;
5462 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5463 /* only support up to an 8 byte (64-bit) integer */
5464 if (fUnsigned64(tvb, offset + tag_len, lvt, &val))
5465 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5466 ett_bacapp_tag, NULL, "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
5468 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5469 ett_bacapp_tag, NULL, "%s - %u octets (Unsigned)", label, lvt);
5470 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5472 return offset+tag_len+lvt;
5476 fDevice_Instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, int hf)
5478 guint8 tag_no, tag_info;
5479 guint32 lvt, safe_lvt;
5482 proto_tree *subtree;
5484 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5491 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, safe_lvt, ENC_BIG_ENDIAN);
5493 if (lvt != safe_lvt)
5494 expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
5495 "This field claims to be an impossible %u bytes, while the max is %u", lvt, safe_lvt);
5497 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5498 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5500 return offset+tag_len+lvt;
5503 /* set split_val to zero when not needed */
5505 fEnumeratedTagSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5506 guint offset, const gchar *label, const value_string *vs, guint32 split_val)
5509 guint8 tag_no, tag_info;
5512 proto_tree *subtree;
5514 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5515 /* only support up to a 4 byte (32-bit) enumeration */
5516 if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) {
5518 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5519 ett_bacapp_tag, NULL, "%s %s", label, val_to_split_str(val, split_val, vs,
5520 ASHRAE_Reserved_Fmt, Vendor_Proprietary_Fmt));
5522 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5523 ett_bacapp_tag, NULL, "%s %u", label, val);
5525 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5526 ett_bacapp_tag, NULL, "%s - %u octets (enumeration)", label, lvt);
5529 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5531 return offset+tag_len+lvt;
5535 fEnumeratedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5536 guint offset, const gchar *label, const value_string *vs)
5538 return fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, vs, 0);
5542 fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5545 guint8 tag_no, tag_info;
5548 proto_tree *subtree;
5550 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5551 if (fSigned64(tvb, offset + tag_len, lvt, &val))
5552 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5553 ett_bacapp_tag, NULL, "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
5555 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5556 ett_bacapp_tag, NULL, "%s - %u octets (Signed)", label, lvt);
5557 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5559 return offset+tag_len+lvt;
5563 fRealTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5565 guint8 tag_no, tag_info;
5569 proto_tree *subtree;
5571 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5572 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
5573 subtree = proto_tree_add_subtree_format(tree, tvb, offset, 4+tag_len,
5574 ett_bacapp_tag, NULL, "%s%f (Real)", label, f_val);
5575 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5577 return offset+tag_len+4;
5581 fDoubleTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5583 guint8 tag_no, tag_info;
5587 proto_tree *subtree;
5589 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5590 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
5591 subtree = proto_tree_add_subtree_format(tree, tvb, offset, 8+tag_len,
5592 ett_bacapp_tag, NULL, "%s%f (Double)", label, d_val);
5593 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5595 return offset+tag_len+8;
5599 fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5601 guint32 val = 0, lvt;
5602 guint8 tag_no, tag_info;
5604 proto_tree *subtree;
5607 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5608 if (fUnsigned32(tvb, offset+tag_len, lvt, &val))
5610 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
5611 tvb, offset, lvt+tag_len, val);
5612 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5616 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5617 ett_bacapp_tag, NULL, "Process Identifier - %u octets (Signed)", lvt);
5619 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5620 offset += tag_len + lvt;
5626 fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5628 guint32 val = 0, lvt;
5629 guint8 tag_no, tag_info;
5630 proto_tree *subtree;
5633 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5634 if (fUnsigned32(tvb, offset+tag_len, lvt, &val))
5635 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5636 ett_bacapp_tag, NULL,
5637 "%s (hh.mm.ss): %d.%02d.%02d%s",
5639 (val / 3600), ((val % 3600) / 60), (val % 60),
5640 val == 0 ? " (indefinite)" : "");
5642 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5643 ett_bacapp_tag, NULL,
5644 "%s - %u octets (Signed)", label, lvt);
5645 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5647 return offset+tag_len+lvt;
5651 fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5653 guint32 month, weekOfMonth, dayOfWeek;
5654 guint8 tag_no, tag_info;
5657 proto_tree *subtree;
5659 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5660 month = tvb_get_guint8(tvb, offset+tag_len);
5661 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
5662 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
5663 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5664 ett_bacapp_tag, NULL, "%s %s, %s",
5665 val_to_str(month, months, "month (%d) not found"),
5666 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
5667 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
5668 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5670 return offset+tag_len+lvt;
5674 fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5676 guint32 year, month, day, weekday;
5677 guint8 tag_no, tag_info;
5680 proto_tree *subtree;
5682 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5683 year = tvb_get_guint8(tvb, offset+tag_len);
5684 month = tvb_get_guint8(tvb, offset+tag_len+1);
5685 day = tvb_get_guint8(tvb, offset+tag_len+2);
5686 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
5687 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
5688 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5689 ett_bacapp_tag, NULL,
5692 else if (year != 255) {
5694 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5695 ett_bacapp_tag, NULL,
5696 "%s%s %d, %d, (Day of Week = %s)",
5697 label, val_to_str(month,
5699 "month (%d) not found"),
5700 day, year, val_to_str(weekday,
5704 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5705 ett_bacapp_tag, NULL,
5706 "%s%s %d, any year, (Day of Week = %s)",
5707 label, val_to_str(month, months, "month (%d) not found"),
5708 day, val_to_str(weekday, day_of_week, "(%d) not found"));
5710 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5712 return offset+tag_len+lvt;
5716 fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5718 guint32 hour, minute, second, msec, lvt;
5719 guint8 tag_no, tag_info;
5721 proto_tree *subtree;
5723 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5724 hour = tvb_get_guint8(tvb, offset+tag_len);
5725 minute = tvb_get_guint8(tvb, offset+tag_len+1);
5726 second = tvb_get_guint8(tvb, offset+tag_len+2);
5727 msec = tvb_get_guint8(tvb, offset+tag_len+3);
5728 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
5729 subtree = proto_tree_add_subtree_format(tree, tvb, offset,
5730 lvt+tag_len, ett_bacapp_tag, NULL,
5733 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
5734 ett_bacapp_tag, NULL,
5735 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
5737 hour > 12 ? hour - 12 : hour,
5738 minute, second, msec,
5739 hour >= 12 ? "P.M." : "A.M.",
5740 hour, minute, second, msec);
5741 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5743 return offset+tag_len+lvt;
5747 fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5749 proto_tree *subtree = tree;
5751 if (label != NULL) {
5752 subtree = proto_tree_add_subtree(subtree, tvb, offset, 10, ett_bacapp_value, NULL, label);
5754 offset = fDate(tvb, pinfo, subtree, offset, "Date: ");
5755 return fTime(tvb, pinfo, subtree, offset, "Time: ");
5759 fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5761 guint lastoffset = 0;
5762 guint8 tag_no, tag_info;
5765 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5766 lastoffset = offset;
5767 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5768 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
5771 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
5772 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
5774 if (offset == lastoffset) break; /* exit loop if nothing happens inside */
5780 fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5782 guint8 tag_no, tag_info;
5785 switch (fTagNo(tvb, offset)) {
5787 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
5789 case 1: /* dateRange */
5790 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5791 offset = fDateRange(tvb, pinfo, tree, offset);
5792 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5794 case 2: /* BACnetWeekNDay */
5795 offset = fWeekNDay(tvb, pinfo, tree, offset);
5805 fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
5808 proto_tree* subtree = tree;
5810 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5811 subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventTimeStamps");
5813 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: ");
5814 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: ");
5815 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: ");
5821 fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5823 guint8 tag_no = 0, tag_info = 0;
5826 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
5827 switch (fTagNo(tvb, offset)) {
5829 offset = fTime(tvb, pinfo, tree, offset, label?label:"time: ");
5831 case 1: /* sequenceNumber */
5832 offset = fUnsignedTag(tvb, pinfo, tree, offset,
5833 label?label:"sequence number: ");
5835 case 2: /* dateTime */
5836 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5837 offset = fDateTime(tvb, pinfo, tree, offset, label?label:"date time: ");
5838 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5850 fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5852 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5853 offset = fApplicationTypes(tvb, pinfo, tree, offset, "increment: ");
5858 static const value_string
5859 BACnetDaysOfWeek [] = {
5871 fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5873 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5874 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
5875 "valid Days: ", BACnetDaysOfWeek);
5876 offset = fTime(tvb, pinfo, tree, offset, "from time: ");
5877 offset = fTime(tvb, pinfo, tree, offset, "to time: ");
5878 offset = fRecipient(tvb, pinfo, tree, offset);
5879 offset = fProcessId(tvb, pinfo, tree, offset);
5880 offset = fApplicationTypes(tvb, pinfo, tree, offset,
5881 "issue confirmed notifications: ");
5882 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
5883 "transitions: ", BACnetEventTransitionBits);
5890 fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5893 guint start = offset;
5894 guint8 tag_no, tag_info;
5895 proto_tree *subtree = tree;
5897 offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5900 tmp = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, lvt);
5901 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt,
5902 ett_bacapp_tag, NULL, "%s %s", label, tmp);
5906 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5912 fMacAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5914 guint start = offset;
5915 guint8 tag_no, tag_info;
5916 proto_tree* subtree = tree;
5918 offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5920 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 */
5923 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
5925 proto_tree_add_item(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ENC_BIG_ENDIAN);
5926 proto_tree_add_item(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, ENC_BIG_ENDIAN);
5929 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
5931 proto_tree_add_item(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, ENC_NA);
5932 proto_tree_add_item(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, ENC_BIG_ENDIAN);
5934 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
5935 subtree = proto_tree_add_subtree(tree, tvb, offset, lvt,
5936 ett_bacapp_tag, NULL, tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, lvt));
5942 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5948 fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5950 guint8 tag_no, tag_info;
5954 offset = fUnsignedTag(tvb, pinfo, tree, offset, "network-number");
5955 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5957 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5960 offset = fMacAddress(tvb, pinfo, tree, offset, "MAC-address: ", lvt);
5966 fSessionKey(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5968 offset = fOctetString(tvb, pinfo, tree, offset, "session key: ", 8);
5969 return fAddress(tvb, pinfo, tree, offset);
5973 fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5975 guint8 tag_no, tag_info;
5978 proto_tree *subtree;
5981 tag_length = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5982 object_id = tvb_get_ntohl(tvb, offset+tag_length);
5983 object_type = object_id_type(object_id);
5984 subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_length + 4,
5985 ett_bacapp_tag, NULL, "ObjectIdentifier: %s, %u",
5986 val_to_split_str(object_type,
5989 ASHRAE_Reserved_Fmt,
5990 Vendor_Proprietary_Fmt),
5991 object_id_instance(object_id));
5993 if (col_get_writable(pinfo->cinfo))
5994 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5995 val_to_split_str(object_type,
5998 ASHRAE_Reserved_Fmt,
5999 Vendor_Proprietary_Fmt),
6000 object_id_instance(object_id));
6002 /* update BACnet Statistics */
6003 updateBacnetInfoValue(BACINFO_OBJECTID,
6004 wmem_strdup(wmem_packet_scope(),
6005 val_to_split_str(object_type, 128,
6006 BACnetObjectType, ASHRAE_Reserved_Fmt,
6007 Vendor_Proprietary_Fmt)));
6008 updateBacnetInfoValue(BACINFO_INSTANCEID,
6009 wmem_strdup_printf(wmem_packet_scope(),
6011 object_id_instance(object_id)));
6013 /* here are the details of how we arrived at the above text */
6014 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6015 offset += tag_length;
6016 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
6017 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
6024 fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6026 guint8 tag_no, tag_info;
6029 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6031 if (tag_no == 0) { /* device */
6032 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
6034 else { /* address */
6035 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6036 offset = fAddress(tvb, pinfo, tree, offset);
6037 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6044 fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6046 guint lastoffset = 0;
6047 guint8 tag_no, tag_info;
6049 proto_tree *orgtree = tree;
6050 proto_tree *subtree;
6052 /* beginning of new item - indent and label */
6053 tree = proto_tree_add_subtree(orgtree, tvb, offset, 1, ett_bacapp_value, NULL, "Recipient Process" );
6055 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6056 lastoffset = offset;
6058 switch (fTagNo(tvb, offset)) {
6059 case 0: /* recipient */
6060 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
6061 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "Recipient"); /* add tree label and indent */
6062 offset = fRecipient(tvb, pinfo, subtree, offset);
6063 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
6065 case 1: /* processId */
6066 offset = fProcessId(tvb, pinfo, tree, offset);
6067 lastoffset = offset;
6072 if (offset == lastoffset) break; /* nothing happened, exit loop */
6078 fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6080 guint lastoffset = 0;
6081 guint8 tag_no, tag_info;
6083 proto_tree *subtree;
6084 proto_tree *orgtree = tree;
6087 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6088 lastoffset = offset;
6089 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6090 if (tag_is_closing(tag_info) ) {
6095 case 0: /* recipient */
6096 /* beginning of new item in list */
6097 tree = proto_tree_add_subtree_format(orgtree, tvb, offset, 1,
6098 ett_bacapp_value, NULL, "Subscription %d",itemno); /* add tree label and indent */
6099 itemno = itemno + 1;
6101 subtree = proto_tree_add_subtree(tree, tvb, offset, 1,
6102 ett_bacapp_value, NULL, "Recipient"); /* add tree label and indent */
6103 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
6104 offset = fRecipientProcess(tvb, pinfo, subtree, offset);
6105 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
6107 case 1: /* MonitoredPropertyReference */
6108 subtree = proto_tree_add_subtree(tree, tvb, offset, 1,
6109 ett_bacapp_value, NULL, "Monitored Property Reference");
6110 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6111 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
6112 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6114 case 2: /* IssueConfirmedNotifications - boolean */
6115 offset = fBooleanTag(tvb, pinfo, tree, offset, "Issue Confirmed Notifications: ");
6117 case 3: /* TimeRemaining */
6118 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Time Remaining: ");
6120 case 4: /* COVIncrement */
6121 offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
6126 if (offset == lastoffset) break; /* nothing happened, exit loop */
6132 fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6134 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
6135 return fAddress(tvb, pinfo, tree, offset);
6139 fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
6141 guint lastoffset = 0, len;
6142 guint8 tag_no, tag_info;
6144 proto_tree *subtree = tree;
6146 /* set the optional global properties to indicate not-used */
6147 propertyArrayIndex = -1;
6148 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6149 lastoffset = offset;
6150 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6151 if (tag_is_closing(tag_info) ) {
6152 if (tag_no == tag_match) {
6161 case 0: /* deviceIdentifier */
6162 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
6164 case 1: /* objectIdentifier */
6165 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
6167 case 2: /* propertyIdentifier */
6168 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
6170 case 3: /* propertyArrayIndex */
6171 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
6173 case 4: /* propertyValue */
6174 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
6176 case 5: /* priority */
6177 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
6179 case 6: /* postDelay */
6180 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Post Delay: ");
6182 case 7: /* quitOnFailure */
6183 offset = fBooleanTag(tvb, pinfo, subtree, offset,
6184 "Quit On Failure: ");
6186 case 8: /* writeSuccessful */
6187 offset = fBooleanTag(tvb, pinfo, subtree, offset,
6188 "Write Successful: ");
6193 if (offset == lastoffset) break; /* nothing happened, exit loop */
6198 /* BACnetActionList ::= SEQUENCE{
6199 action [0] SEQUENCE OF BACnetActionCommand
6203 fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6205 guint lastoffset = 0, len;
6206 guint8 tag_no, tag_info;
6208 proto_tree *subtree = tree;
6210 while (tvb_reported_length_remaining(tvb, offset) > 0) {
6211 lastoffset = offset;
6212 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6213 if (tag_is_closing(tag_info)) {
6215 if ( tag_no != 0 ) /* don't eat the closing property tag, just return */
6220 if (tag_is_opening(tag_info)) {
6221 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "Action List");
6222 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
6223 &tag_no, &tag_info, &lvt);
6226 case 0: /* BACnetActionCommand */
6227 offset = fActionCommand(tvb, pinfo, subtree, offset, tag_no);
6232 if (offset == lastoffset) break; /* nothing happened, exit loop */
6238 fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6240 guint8 tag_no, tag_info;
6243 proto_tree *subtree;
6244 const gchar *label = "Property Identifier";
6246 propertyIdentifier = 0; /* global Variable */
6247 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6248 /* can we decode this value? */
6249 if (fUnsigned32(tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
6250 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
6251 ett_bacapp_tag, NULL,
6252 "%s: %s (%u)", label,
6253 val_to_split_str(propertyIdentifier, 512,
6254 BACnetPropertyIdentifier,
6255 ASHRAE_Reserved_Fmt,
6256 Vendor_Proprietary_Fmt), propertyIdentifier);
6257 if (col_get_writable(pinfo->cinfo))
6258 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
6259 val_to_split_str(propertyIdentifier, 512,
6260 BACnetPropertyIdentifier,
6261 ASHRAE_Reserved_Fmt,
6262 Vendor_Proprietary_Fmt));
6264 /* property identifiers cannot be larger than 22-bits */
6268 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6269 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
6270 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6272 return offset+tag_len+lvt;
6276 fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6278 guint8 tag_no, tag_info;
6281 proto_tree *subtree;
6283 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6284 if (fUnsigned32(tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
6285 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
6286 ett_bacapp_tag, NULL, "property Array Index (Unsigned) %u", propertyArrayIndex);
6288 subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
6289 ett_bacapp_tag, NULL, "property Array Index - %u octets (Unsigned)", lvt);
6290 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6292 return offset+tag_len+lvt;
6296 fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6298 guint8 tag_no, tag_info, character_set;
6300 guint offs, extra = 1;
6303 proto_tree *subtree;
6304 guint start = offset;
6306 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6308 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6310 character_set = tvb_get_guint8(tvb, offset+offs);
6311 /* Account for code page if DBCS */
6312 if (character_set == 1) {
6315 offset += (offs+extra);
6321 * XXX - are we guaranteed that these encoding
6322 * names correspond, on *all* platforms with
6323 * iconv(), to the encodings we want?
6324 * If not (and perhaps even if so), we should
6325 * perhaps have our own iconv() implementation,
6326 * with a different name, so that we control the
6327 * encodings it supports and the names of those
6330 * We should also handle that in the general
6331 * string handling code, rather than making it
6332 * specific to the BACAPP dissector, as many
6333 * other dissectors need to handle various
6334 * character encodings.
6336 /** this decoding may be not correct for multi-byte characters, Lka */
6337 switch (character_set) {
6339 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UTF_8);
6343 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
6344 coding = "IBM MS DBCS";
6347 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
6348 coding = "JIS C 6226";
6350 case ISO_10646_UCS4:
6351 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UCS_4|ENC_BIG_ENDIAN);
6352 coding = "ISO 10646 UCS-4";
6354 case ISO_10646_UCS2:
6355 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UCS_2|ENC_BIG_ENDIAN);
6356 coding = "ISO 10646 UCS-2";
6359 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ISO_8859_1);
6360 coding = "ISO 8859-1";
6363 /* Assume this is some form of extended ASCII, with one-byte code points for ASCII characters */
6364 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
6368 subtree = proto_tree_add_subtree_format(tree, tvb, offset, l, ett_bacapp_tag, NULL,
6369 "%s%s '%s'", label, coding, out);
6374 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6375 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
6377 if (character_set == 1) {
6378 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
6380 /* XXX - put the string value here */
6386 fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
6387 const value_string *src)
6389 guint8 tag_no, tag_info, tmp;
6390 gint j, unused, skip;
6391 guint start = offset;
6393 guint32 lvt, i, numberOfBytes;
6395 proto_tree* subtree = tree;
6397 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6398 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
6400 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
6401 subtree = proto_tree_add_subtree_format(tree, tvb, start, offs+lvt,
6402 ett_bacapp_tag, NULL,
6403 "%s(Bit String)", label);
6405 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6406 proto_tree_add_text(subtree, tvb, offset, 1,
6407 "Unused bits: %u", unused);
6408 memset(bf_arr, 0, 256);
6410 for (i = 0; i < numberOfBytes; i++) {
6411 tmp = tvb_get_guint8(tvb, (offset)+i+1);
6412 if (i == numberOfBytes-1) { skip = unused; }
6413 for (j = 0; j < 8-skip; j++) {
6415 if (tmp & (1 << (7 - j)))
6416 proto_tree_add_text(subtree, tvb,
6419 val_to_str((guint) (i*8 +j),
6421 ASHRAE_Reserved_Fmt));
6423 proto_tree_add_text(subtree, tvb,
6426 val_to_str((guint) (i*8 +j),
6428 ASHRAE_Reserved_Fmt));
6430 bf_arr[MIN(255, (i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
6436 bf_arr[MIN(255, numberOfBytes*8-unused)] = 0;
6437 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
6446 fBitStringTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6448 return fBitStringTagVS(tvb, pinfo, tree, offset, label, NULL);
6451 /* handles generic application types, as well as enumerated and enumerations
6452 with reserved and proprietarty ranges (split) */
6454 fApplicationTypesEnumeratedSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6455 const gchar *label, const value_string *src, guint32 split_val)
6457 guint8 tag_no, tag_info;
6461 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6463 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6464 if (!tag_is_context_specific(tag_info)) {
6466 case 0: /** NULL 20.2.2 */
6467 offset = fNullTag(tvb, pinfo, tree, offset, label);
6469 case 1: /** BOOLEAN 20.2.3 */
6470 offset = fBooleanTag(tvb, pinfo, tree, offset, label);
6472 case 2: /** Unsigned Integer 20.2.4 */
6473 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
6475 case 3: /** Signed Integer 20.2.5 */
6476 offset = fSignedTag(tvb, pinfo, tree, offset, label);
6478 case 4: /** Real 20.2.6 */
6479 offset = fRealTag(tvb, pinfo, tree, offset, label);
6481 case 5: /** Double 20.2.7 */
6482 offset = fDoubleTag(tvb, pinfo, tree, offset, label);
6484 case 6: /** Octet String 20.2.8 */
6485 offset = fOctetString(tvb, pinfo, tree, offset, label, lvt);
6487 case 7: /** Character String 20.2.9 */
6488 offset = fCharacterString(tvb, pinfo, tree, offset, label);
6490 case 8: /** Bit String 20.2.10 */
6491 offset = fBitStringTagVS(tvb, pinfo, tree, offset, label, src);
6493 case 9: /** Enumerated 20.2.11 */
6494 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, src, split_val);
6496 case 10: /** Date 20.2.12 */
6497 offset = fDate(tvb, pinfo, tree, offset, label);
6499 case 11: /** Time 20.2.13 */
6500 offset = fTime(tvb, pinfo, tree, offset, label);
6502 case 12: /** BACnetObjectIdentifier 20.2.14 */
6503 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
6505 case 13: /* reserved for ASHRAE */
6508 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
6509 offset += lvt + tag_len;
6521 fShedLevel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6523 guint lastoffset = 0;
6525 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6526 lastoffset = offset;
6528 switch (fTagNo(tvb, offset)) {
6529 case 0: /* percent */
6530 offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed percent: ");
6533 offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed level: ");
6535 case 2: /* amount */
6536 offset = fRealTag(tvb, pinfo, tree, offset, "shed amount: ");
6541 if (offset == lastoffset) break; /* nothing happened, exit loop */
6547 fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6548 const gchar *label, const value_string *vs)
6550 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
6554 fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6557 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
6561 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6563 guint8 tag_no, tag_info;
6566 proto_tree *subtree;
6570 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6571 /* cap the the suggested length in case of bad data */
6572 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
6573 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
6576 subtree = proto_tree_add_subtree_format(tree, tvb, offset+tag_len, lvt,
6577 ett_bacapp_tag, NULL, "Context Value (as %u DATA octets)", lvt);
6579 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6581 return offset + tag_len + lvt;
6584 BACnetPrescale ::= SEQUENCE {
6585 multiplier [0] Unsigned,
6586 moduloDivide [1] Unsigned
6590 fPrescale(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6592 guint8 tag_no, tag_info;
6594 guint lastoffset = 0;
6596 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6597 lastoffset = offset;
6598 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6599 if (tag_is_closing(tag_info) ) {
6603 case 0: /* multiplier */
6604 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Multiplier: ");
6606 case 1: /* moduloDivide */
6607 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Modulo Divide: ");
6612 if (offset == lastoffset) break; /* nothing happened, exit loop */
6618 BACnetScale ::= CHOICE {
6619 floatScale [0] REAL,
6620 integerScale [1] INTEGER
6624 fScale(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6626 guint8 tag_no, tag_info;
6628 guint lastoffset = 0;
6630 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6631 lastoffset = offset;
6632 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6633 if (tag_is_closing(tag_info) ) {
6637 case 0: /* floatScale */
6638 offset = fRealTag(tvb, pinfo, tree, offset, "Float Scale: ");
6640 case 1: /* integerScale */
6641 offset = fSignedTag(tvb, pinfo, tree, offset, "Integer Scale: ");
6646 if (offset == lastoffset) break; /* nothing happened, exit loop */
6651 BACnetAccumulatorRecord ::= SEQUENCE {
6652 timestamp [0] BACnetDateTime,
6653 presentValue [1] Unsigned,
6654 accumulatedValue [2] Unsigned,
6655 accumulatortStatus [3] ENUMERATED {
6665 fLoggingRecord(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6667 guint8 tag_no, tag_info;
6669 guint lastoffset = 0;
6671 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6672 lastoffset = offset;
6673 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6674 if (tag_is_closing(tag_info) ) {
6678 case 0: /* timestamp */
6679 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6680 offset = fDateTime(tvb, pinfo, tree, offset, "Timestamp: ");
6681 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6683 case 1: /* presentValue */
6684 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Present Value: ");
6686 case 2: /* accumulatedValue */
6687 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Accumulated Value: ");
6689 case 3: /* accumulatorStatus */
6690 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus);
6695 if (offset == lastoffset) break; /* nothing happened, exit loop */
6701 SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState
6704 fSequenceOfEnums(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, const value_string *vs)
6706 guint8 tag_no, tag_info;
6708 guint lastoffset = 0;
6710 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6711 lastoffset = offset;
6712 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6713 if (tag_is_closing(tag_info) ) {
6716 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs);
6717 if ( offset == lastoffset ) break;
6723 SEQ OF BACnetDeviceObjectReference (accessed as an array)
6727 fDoorMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6729 guint8 tag_no, tag_info;
6731 guint lastoffset = 0;
6733 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6734 lastoffset = offset;
6735 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6736 if (tag_is_closing(tag_info) ) {
6739 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6740 if (offset == lastoffset) break;
6746 SEQ OF ReadAccessSpecification
6749 fListOfGroupMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6751 guint8 tag_no, tag_info;
6753 guint lastoffset = 0;
6755 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6756 lastoffset = offset;
6757 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6758 if (tag_is_closing(tag_info) ) {
6761 offset = fReadAccessSpecification(tvb, pinfo, tree, offset);
6762 if ( offset == lastoffset ) break;
6768 fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6770 guint8 tag_no, tag_info;
6772 guint lastoffset = 0, depth = 0;
6774 guint32 save_object_type;
6776 if (propertyIdentifier >= 0) {
6777 g_snprintf(ar, sizeof(ar), "%s: ",
6778 val_to_split_str(propertyIdentifier, 512,
6779 BACnetPropertyIdentifier,
6780 ASHRAE_Reserved_Fmt,
6781 Vendor_Proprietary_Fmt));
6783 g_snprintf(ar, sizeof(ar), "Abstract Type: ");
6785 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6786 lastoffset = offset;
6787 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6788 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
6789 if (depth <= 0) return offset;
6792 /* Application Tags */
6793 switch (propertyIdentifier) {
6794 case 2: /* action */
6795 /* loop object is application tagged,
6796 command object is context tagged */
6797 if (tag_is_context_specific(tag_info)) {
6798 /* BACnetActionList */
6799 offset = fActionList(tvb, pinfo, tree, offset);
6802 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6806 case 30: /* BACnetAddressBinding */
6807 offset = fAddressBinding(tvb, pinfo, tree, offset);
6809 case 54: /* list of object property reference */
6810 offset = fLOPR(tvb, pinfo, tree, offset);
6812 case 55: /* list-of-session-keys */
6813 fSessionKey(tvb, pinfo, tree, offset);
6815 case 79: /* object-type */
6816 case 96: /* protocol-object-types-supported */
6817 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar,
6818 BACnetObjectType, 128);
6820 case 97: /* Protocol-Services-Supported */
6821 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6822 BACnetServicesSupported);
6824 case 102: /* recipient-list */
6825 offset = fDestination(tvb, pinfo, tree, offset);
6827 case 107: /* segmentation-supported */
6828 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6829 BACnetSegmentation);
6831 case 111: /* Status-Flags */
6832 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6835 case 112: /* System-Status */
6836 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6837 BACnetDeviceStatus);
6839 case 117: /* units */
6840 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6841 BACnetEngineeringUnits);
6843 case 87: /* priority-array -- accessed as a BACnetARRAY */
6844 if (propertyArrayIndex == 0) {
6845 /* BACnetARRAY index 0 refers to the length
6846 of the array, not the elements of the array */
6847 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6849 offset = fPriorityArray(tvb, pinfo, tree, offset);
6852 case 38: /* exception-schedule */
6853 if (object_type < 128) {
6854 if (propertyArrayIndex == 0) {
6855 /* BACnetARRAY index 0 refers to the length
6856 of the array, not the elements of the array */
6857 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6859 offset = fSpecialEvent(tvb, pinfo, tree, offset);
6863 case 19: /* controlled-variable-reference */
6864 case 60: /* manipulated-variable-reference */
6865 case 132: /* log-device-object-property */
6866 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
6868 case 109: /* Setpoint-Reference */
6869 /* setpoint-Reference is actually BACnetSetpointReference which is a SEQ of [0] */
6870 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6871 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
6872 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6874 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
6875 if (object_type < 128) {
6876 if (propertyArrayIndex == 0) {
6877 /* BACnetARRAY index 0 refers to the length
6878 of the array, not the elements of the array */
6879 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6881 offset = fWeeklySchedule(tvb, pinfo, tree, offset);
6885 case 127: /* client COV increment */
6886 offset = fClientCOV(tvb, pinfo, tree, offset);
6888 case 131: /* log-buffer */
6889 if ( object_type == 25 )
6890 offset = fEventLogRecord(tvb, pinfo, tree, offset);
6891 else if ( object_type == 27 )
6892 offset = fLogMultipleRecord(tvb, pinfo, tree, offset);
6894 offset = fLogRecord(tvb, pinfo, tree, offset);
6896 case 159: /* member-of */
6897 case 165: /* zone-members */
6898 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6900 case 196: /* last-restart-reason */
6901 offset = fRestartReason(tvb, pinfo, tree, offset);
6903 case 212: /* actual-shed-level */
6904 case 214: /* expected-shed-level */
6905 case 218: /* requested-shed-level */
6906 offset = fShedLevel(tvb, pinfo, tree, offset);
6908 case 152: /* active-cov-subscriptions */
6909 offset = fCOVSubscription(tvb, pinfo, tree, offset);
6911 case 23: /* date-list */
6912 offset = fCalendarEntry(tvb, pinfo, tree, offset);
6914 case 116: /* time-sychronization-recipients */
6915 offset = fRecipient(tvb, pinfo, tree, offset);
6917 case 83: /* event-parameters */
6918 offset = fEventParameter(tvb, pinfo, tree, offset);
6920 case 211: /* subordinate-list */
6921 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6923 case 130: /* event-time-stamp */
6924 offset = fEventTimeStamps(tvb, pinfo, tree, offset);
6926 case 197: /* logging-type */
6927 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType);
6929 case 36: /* event-state */
6930 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64);
6932 case 103: /* reliability */
6933 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability);
6935 case 72: /* notify-type */
6936 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNotifyType);
6938 case 208: /* node-type */
6939 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType);
6941 case 231: /* door-status */
6942 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus);
6944 case 233: /* lock-status */
6945 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus);
6947 case 235: /* secured-status */
6948 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus);
6950 case 158: /* maintenance-required */
6951 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance);
6953 case 92: /* program-state */
6954 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState);
6956 case 90: /* program-change */
6957 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest);
6959 case 100: /* reason-for-halt */
6960 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError);
6962 case 160: /* mode */
6963 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode);
6965 case 163: /* silenced */
6966 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState);
6968 case 161: /* operation-expected */
6969 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation);
6971 case 164: /* tracking-value */
6972 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState);
6974 case 41: /* file-access-method */
6975 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod);
6977 case 185: /* prescale */
6978 offset = fPrescale(tvb, pinfo, tree, offset);
6980 case 187: /* scale */
6981 offset = fScale(tvb, pinfo, tree, offset);
6983 case 184: /* logging-record */
6984 offset = fLoggingRecord(tvb, pinfo, tree, offset);
6986 case 228: /* door-members */
6987 offset = fDoorMembers(tvb, pinfo, tree, offset);
6989 case 181: /* input-reference */
6990 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6992 case 78: /* object-property-reference */
6993 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6995 case 234: /* masked-alarm-values */
6996 offset = fSequenceOfEnums(tvb, pinfo, tree, offset, "masked-alarm-value: ", BACnetDoorAlarmState);
6998 case 53: /* list-of-group-members */
6999 save_object_type = object_type;
7000 offset = fListOfGroupMembers(tvb, pinfo, tree, offset);
7001 object_type = save_object_type;
7003 case 85: /* present-value */
7004 if ( object_type == 11 ) /* group object handling of present-value */
7006 offset = fReadAccessResult(tvb, pinfo, tree, offset);
7009 /* intentially fall through here so don't reorder this case statement */
7012 if (tag_is_opening(tag_info)) {
7014 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7015 } else if (tag_is_closing(tag_info)) {
7017 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7019 offset = fContextTaggedValue(tvb, pinfo, tree, offset, ar);
7022 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
7026 if (offset == lastoffset) break; /* nothing happened, exit loop */
7033 fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
7038 if (tag_is_opening(tag_info)) {
7039 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
7040 &tag_no, &tag_info, &lvt);
7041 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
7042 if (tvb_reported_length_remaining(tvb, offset) > 0) {
7043 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
7044 &tag_no, &tag_info, &lvt);
7047 proto_tree_add_text(tree, tvb, offset, tvb_reported_length(tvb) - offset,
7048 "expected Opening Tag!");
7049 offset = tvb_reported_length(tvb);
7057 fPropertyIdentifierValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
7059 guint lastoffset = offset;
7060 guint8 tag_no, tag_info;
7063 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
7064 if (offset > lastoffset) {
7065 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7066 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
7067 offset = fPropertyValue(tvb, pinfo, tree, offset, tag_info);
7074 fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7076 guint lastoffset = 0;
7077 guint8 tag_no, tag_info;
7080 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7081 lastoffset = offset;
7082 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
7083 if (offset > lastoffset) {
7084 /* detect optional priority
7085 by looking to see if the next tag is context tag number 3 */
7086 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7087 if (tag_is_context_specific(tag_info) && (tag_no == 3))
7088 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: ");
7090 if (offset == lastoffset) break; /* nothing happened, exit loop */
7096 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7098 guint lastoffset = 0, len;
7099 guint8 tag_no, tag_info;
7101 proto_tree *subtree = tree;
7103 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7104 lastoffset = offset;
7105 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7106 if (tag_is_closing(tag_info)) {
7113 case 0: /* ProcessId */
7114 offset = fUnsignedTag(tvb, pinfo, tree, offset, "subscriber Process Id: ");
7116 case 1: /* monitored ObjectId */
7117 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7119 case 2: /* issueConfirmedNotifications */
7120 offset = fBooleanTag(tvb, pinfo, tree, offset, "issue Confirmed Notifications: ");
7122 case 3: /* life time */
7123 offset = fTimeSpan(tvb, pinfo, tree, offset, "life time");
7125 case 4: /* monitoredPropertyIdentifier */
7126 if (tag_is_opening(tag_info)) {
7127 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "monitoredPropertyIdentifier");
7128 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7129 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
7134 case 5: /* covIncrement */
7135 offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
7140 if (offset == lastoffset) break; /* nothing happened, exit loop */
7146 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7148 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
7152 fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7154 guint lastoffset = 0;
7156 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7157 lastoffset = offset;
7159 switch (fTagNo(tvb, offset)) {
7160 case 0: /* deviceInstanceLowLimit */
7161 offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance Low Limit: ");
7163 case 1: /* deviceInstanceHighLimit */
7164 offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance High Limit: ");
7166 case 2: /* BACnetObjectId */
7167 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7169 case 3: /* messageText */
7170 offset = fCharacterString(tvb, pinfo, tree, offset, "Object Name: ");
7175 if (offset == lastoffset) break; /* nothing happened, exit loop */
7182 fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7184 guint lastoffset = 0;
7185 guint8 tag_no, tag_info;
7188 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7189 if (tag_is_opening(tag_info) && tag_no == 0) {
7190 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
7191 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7192 lastoffset = offset;
7193 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7194 if (tag_is_closing(tag_info)) {
7195 /* should be closing context tag 0 */
7196 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7200 offset = fTimeValue(tvb, pinfo, subtree, offset);
7201 if (offset == lastoffset) break; /* nothing happened, exit loop */
7203 } else if ((tag_no == 0) && (lvt == 0)) {
7204 /* not sure null (empty array element) is legal */
7205 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7211 fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7213 guint lastoffset = 0;
7214 guint8 tag_no, tag_info;
7216 guint i = 1; /* day of week array index */
7217 proto_tree *subtree = tree;
7219 if (propertyArrayIndex > 0) {
7220 /* BACnetARRAY index 0 refers to the length
7221 of the array, not the elements of the array.
7222 BACnetARRAY index -1 is our internal flag that
7223 the optional index was not used.
7224 BACnetARRAY refers to this as all elements of the array.
7225 If the optional index is specified for a BACnetARRAY,
7226 then that specific array element is referenced. */
7227 i = propertyArrayIndex;
7229 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7230 lastoffset = offset;
7231 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7232 if (tag_is_closing(tag_info)) {
7233 return offset; /* outer encoding will print out closing tag */
7235 subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_bacapp_value, NULL,
7236 val_to_str(i++, day_of_week, "day of week (%d) not found"));
7237 offset = fDailySchedule(tvb, pinfo, subtree, offset);
7238 if (offset == lastoffset) break; /* nothing happened, exit loop */
7245 fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7247 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7250 return fDateTime(tvb, pinfo, tree, offset, "UTC-Time: ");
7254 fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7256 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7259 return fDateTime(tvb, pinfo, tree, offset, NULL);
7263 fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7265 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7267 offset = fDate(tvb, pinfo, tree, offset, "Start Date: ");
7268 return fDate(tvb, pinfo, tree, offset, "End Date: ");
7272 fVendorIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7275 guint8 tag_no, tag_info;
7279 proto_tree *subtree;
7280 const gchar *label = "Vendor ID";
7282 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7283 if (fUnsigned32(tvb, offset + tag_len, lvt, &val))
7284 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7287 val_to_str_ext_const(val, &BACnetVendorIdentifiers_ext, "Unknown Vendor"),
7290 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7291 "%s - %u octets (Unsigned)", label, lvt);
7292 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7293 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7295 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
7296 proto_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
7297 "Wrong length indicated. Expected 1 or 2, got %u", lvt);
7298 return offset+tag_len+lvt;
7301 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
7302 offset+tag_len, lvt, ENC_BIG_ENDIAN);
7304 return offset+tag_len+lvt;
7308 fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7311 guint8 tag_no, tag_info;
7315 proto_tree *subtree;
7316 const gchar *label = "Restart Reason";
7318 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7319 if (fUnsigned32(tvb, offset + tag_len, lvt, &val))
7320 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7321 "%s: %s (%u)", label,
7322 val_to_str_const(val, BACnetRestartReason, "Unknown reason"), val);
7324 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7325 "%s - %u octets (Unsigned)", label, lvt);
7326 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7327 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7330 proto_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
7331 "Wrong length indicated. Expected 1, got %u", lvt);
7332 return offset+tag_len+lvt;
7335 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
7336 offset+tag_len, lvt, ENC_BIG_ENDIAN);
7338 return offset+tag_len+lvt;
7342 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7344 guint lastoffset = 0;
7346 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7347 lastoffset = offset;
7348 switch (fTagNo(tvb, offset)) {
7350 case 0: /* textMessageSourceDevice */
7351 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7353 case 1: /* messageClass */
7354 switch (fTagNo(tvb, offset)) {
7355 case 0: /* numeric */
7356 offset = fUnsignedTag(tvb, pinfo, tree, offset, "message Class: ");
7358 case 1: /* character */
7359 offset = fCharacterString(tvb, pinfo, tree, offset, "message Class: ");
7363 case 2: /* messagePriority */
7364 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "message Priority: ",
7365 BACnetMessagePriority);
7367 case 3: /* message */
7368 offset = fCharacterString(tvb, pinfo, tree, offset, "message: ");
7373 if (offset == lastoffset) break; /* nothing happened, exit loop */
7379 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7381 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
7385 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7387 guint lastoffset, len;
7388 guint8 tag_no, tag_info;
7390 proto_tree *subtree = tree;
7392 guint vendor_identifier = 0;
7393 guint service_number = 0;
7395 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7396 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
7397 if (col_get_writable(pinfo->cinfo))
7398 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
7399 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
7401 next_tvb = tvb_new_subset_remaining(tvb, offset);
7402 if (dissector_try_uint(bacapp_dissector_table,
7403 vendor_identifier, next_tvb, pinfo, tree)) {
7404 /* we parsed it so skip over length and we are done */
7405 offset += tvb_reported_length(next_tvb);
7409 /* Not handled by vendor dissector */
7411 /* exit loop if nothing happens inside */
7412 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7413 lastoffset = offset;
7414 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7415 if (tag_is_closing(tag_info)) {
7416 if (tag_no == 2) { /* Make sure it's the expected tag */
7421 break; /* End loop if incorrect closing tag */
7426 /* vendorID is now parsed above */
7427 case 1: /* serviceNumber */
7428 fUnsigned32(tvb, offset+len, lvt, &service_number);
7429 if (col_get_writable(pinfo->cinfo))
7430 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
7431 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: ");
7433 case 2: /*serviceParameters */
7434 if (tag_is_opening(tag_info)) {
7435 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1,
7436 ett_bacapp_value, NULL, "service Parameters");
7437 propertyIdentifier = -1;
7438 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7446 if (offset == lastoffset) break; /* nothing happened, exit loop */
7453 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7455 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7459 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7461 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7465 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
7467 guint lastoffset = 0;
7468 guint8 tag_no, tag_info;
7470 proto_tree *subtree = tree;
7472 if (label != NULL) {
7473 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, label);
7476 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7477 lastoffset = offset;
7478 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7481 case 0: /* subscriberProcessId */
7482 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "requesting Process Id: ");
7484 case 1: /* requestingSource */
7485 offset = fCharacterString(tvb, pinfo, tree, offset, "requesting Source: ");
7487 case 2: /* request */
7488 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
7489 "request: ", BACnetLifeSafetyOperation, 64);
7491 case 3: /* objectId */
7492 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
7497 if (offset == lastoffset) break; /* nothing happened, exit loop */
7502 typedef struct _value_string_enum {
7503 const value_string *valstr;
7504 } value_string_enum;
7506 static const value_string_enum
7507 BACnetPropertyStatesEnums[] = {
7512 {BACnetProgramRequest },
7513 {BACnetProgramState },
7514 {BACnetProgramError },
7515 {BACnetReliability },
7516 {BACnetEventState },
7517 {BACnetDeviceStatus },
7518 {BACnetEngineeringUnits },
7520 {BACnetLifeSafetyMode },
7521 {BACnetLifeSafetyState },
7522 {BACnetRestartReason },
7523 {BACnetDoorAlarmState },
7525 {BACnetDoorSecuredStatus },
7526 {BACnetDoorStatus },
7527 { NULL }, /* {BACnetDoorValue }, */
7528 {BACnetFileAccessMethod },
7529 {BACnetLockStatus },
7530 {BACnetLifeSafetyOperation },
7531 {BACnetMaintenance },
7533 {BACnetNotifyType },
7534 { NULL }, /* {BACnetSecurityLevel }, */
7536 {BACnetSilencedState },
7538 { NULL }, /* {BACnetAccessEvent }, */
7539 { NULL }, /* {BACnetZoneOccupancyState }, */
7540 { NULL }, /* {BACnetAccessCredentialDisableReason }, */
7541 { NULL }, /* {BACnetAccessCredentialDisable }, */
7542 { NULL }, /* {BACnetAuthenticationStatus }, */
7544 { NULL }, /* {BACnetBackupState }, */
7546 #define BACnetPropertyStatesEnums_Size 36
7549 fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
7551 guint8 tag_no, tag_info;
7555 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7556 label = wmem_strdup_printf(wmem_packet_scope(), "%s: ",
7557 val_to_str_const( tag_no, VALS(BACnetPropertyStates), "Unknown State" ));
7561 offset = fBooleanTag(tvb, pinfo, tree, offset, label);
7564 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
7567 if ( (tag_no > BACnetPropertyStatesEnums_Size) ||
7568 VALS(BACnetPropertyStatesEnums[tag_no].valstr) == NULL)
7570 offset = fEnumeratedTag(tvb, pinfo, tree, offset, label, NULL);
7571 /* don't use Abstract type here because it is context tagged and therefore we don't know app type */
7575 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label,
7576 VALS(BACnetPropertyStatesEnums[tag_no].valstr), 64);
7585 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
7586 deviceIdentifier [0] BACnetObjectIdentifier,
7587 objectIdentifier [1] BACnetObjectIdentifier,
7588 propertyIdentifier [2] BACnetPropertyIdentifier,
7589 arrayIndex [3] Unsigned OPTIONAL,
7590 value [4] ABSTRACT-SYNTAX.&Type
7594 fDeviceObjectPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7596 guint lastoffset = 0;
7597 guint8 tag_no, tag_info;
7600 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7601 lastoffset = offset;
7602 /* check the tag. A closing tag means we are done */
7603 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7604 if (tag_is_closing(tag_info)) {
7608 case 0: /* deviceIdentifier */
7609 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7611 case 1: /* objectIdentifier */
7612 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7614 case 2: /* propertyIdentifier */
7615 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
7617 case 3: /* arrayIndex - OPTIONAL */
7618 offset = fUnsignedTag(tvb, pinfo, tree, offset,
7622 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7623 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
7624 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7629 if (offset == lastoffset) break; /* nothing happened, exit loop */
7635 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7636 objectIdentifier [0] BACnetObjectIdentifier,
7637 propertyIdentifier [1] BACnetPropertyIdentifier,
7638 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7639 -- if omitted with an array then
7640 -- the entire array is referenced
7641 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7645 fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7647 return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7651 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7652 objectIdentifier [0] BACnetObjectIdentifier,
7653 propertyIdentifier [1] BACnetPropertyIdentifier,
7654 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7655 -- if omitted with an array then
7656 -- the entire array is referenced
7657 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7661 fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7663 guint lastoffset = 0;
7664 guint8 tag_no, tag_info;
7667 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7668 lastoffset = offset;
7669 /* check the tag. A closing tag means we are done */
7670 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7671 if (tag_is_closing(tag_info)) {
7675 case 0: /* objectIdentifier */
7676 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7678 case 1: /* propertyIdentifier */
7679 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
7681 case 2: /* arrayIndex - OPTIONAL */
7682 offset = fUnsignedTag(tvb, pinfo, tree, offset,
7685 case 3: /* deviceIdentifier - OPTIONAL */
7686 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7691 if (offset == lastoffset) break; /* nothing happened, exit loop */
7697 fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7699 guint lastoffset = offset;
7700 guint8 tag_no, tag_info;
7702 proto_tree *subtree = tree;
7704 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7705 subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0,
7706 ett_bacapp_value, NULL, "notification parameters (%d) %s",
7707 tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
7708 /* Opening tag for parameter choice */
7709 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7712 case 0: /* change-of-bitstring */
7713 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7714 lastoffset = offset;
7715 switch (fTagNo(tvb, offset)) {
7717 offset = fBitStringTag(tvb, pinfo, subtree, offset,
7718 "referenced-bitstring: ");
7721 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7722 "status-flags: ", BACnetStatusFlags);
7723 lastoffset = offset;
7728 if (offset == lastoffset) break; /* nothing happened, exit loop */
7731 case 1: /* change-of-state */
7732 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7733 lastoffset = offset;
7734 switch (fTagNo(tvb, offset)) {
7736 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7737 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7738 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7741 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7742 "status-flags: ", BACnetStatusFlags);
7743 lastoffset = offset;
7748 if (offset == lastoffset) break; /* nothing happened, exit loop */
7751 case 2: /* change-of-value */
7752 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7753 lastoffset = offset;
7754 switch (fTagNo(tvb, offset)) {
7756 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7757 switch (fTagNo(tvb, offset)) {
7759 offset = fBitStringTag(tvb, pinfo, subtree, offset,
7763 offset = fRealTag(tvb, pinfo, subtree, offset,
7769 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7772 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7773 "status-flags: ", BACnetStatusFlags);
7774 lastoffset = offset;
7779 if (offset == lastoffset) break; /* nothing happened, exit loop */
7782 case 3: /* command-failure */
7783 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7784 lastoffset = offset;
7785 switch (fTagNo(tvb, offset)) {
7786 case 0: /* "command-value: " */
7787 /* from BACnet Table 13-3,
7788 Standard Object Property Values Returned in Notifications */
7789 propertyIdentifier = 85; /* PRESENT_VALUE */
7790 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7791 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7792 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7795 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7796 "status-flags: ", BACnetStatusFlags);
7798 case 2: /* "feedback-value: " */
7799 propertyIdentifier = 40; /* FEEDBACK_VALUE */
7800 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7801 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7802 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7803 lastoffset = offset;
7808 if (offset == lastoffset) break; /* nothing happened, exit loop */
7811 case 4: /* floating-limit */
7812 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7813 lastoffset = offset;
7814 switch (fTagNo(tvb, offset)) {
7816 offset = fRealTag(tvb, pinfo, subtree, offset, "reference-value: ");
7819 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7820 "status-flags: ", BACnetStatusFlags);
7823 offset = fRealTag(tvb, pinfo, subtree, offset, "setpoint-value: ");
7826 offset = fRealTag(tvb, pinfo, subtree, offset, "error-limit: ");
7827 lastoffset = offset;
7832 if (offset == lastoffset) break; /* nothing happened, exit loop */
7835 case 5: /* out-of-range */
7836 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7837 lastoffset = offset;
7838 switch (fTagNo(tvb, offset)) {
7840 offset = fRealTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7843 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7844 "status-flags: ", BACnetStatusFlags);
7847 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
7850 offset = fRealTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
7851 lastoffset = offset;
7856 if (offset == lastoffset) break; /* nothing happened, exit loop */
7860 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7861 lastoffset = offset;
7862 offset =fBACnetPropertyValue(tvb, pinfo, subtree, offset);
7863 if (offset == lastoffset) break; /* nothing happened, exit loop */
7866 case 7: /* deprecated (was 'buffer-ready', changed and moved to [10]) */
7867 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7868 lastoffset = offset;
7869 switch (fTagNo(tvb, offset)) {
7871 offset = fObjectIdentifier(tvb, pinfo, subtree, offset); /* buffer-device */
7874 offset = fObjectIdentifier(tvb, pinfo, subtree, offset); /* buffer-object */
7877 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7878 offset = fDateTime(tvb, pinfo, subtree, offset, "previous-notification: ");
7879 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7882 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7883 offset = fDateTime(tvb, pinfo, subtree, offset, "current-notification: ");
7884 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7885 lastoffset = offset;
7890 if (offset == lastoffset) break; /* nothing happened, exit loop */
7893 case 8: /* change-of-life-safety */
7894 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7895 lastoffset = offset;
7896 switch (fTagNo(tvb, offset)) {
7898 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7899 "new-state: ", BACnetLifeSafetyState, 256);
7902 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7903 "new-mode: ", BACnetLifeSafetyMode, 256);
7906 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7907 "status-flags: ", BACnetStatusFlags);
7910 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7911 "operation-expected: ", BACnetLifeSafetyOperation, 64);
7912 lastoffset = offset;
7917 if (offset == lastoffset) break; /* nothing happened, exit loop */
7920 case 9: /* extended */
7921 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7922 lastoffset = offset;
7923 switch (fTagNo(tvb, offset)) {
7925 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
7928 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7929 "extended-event-type: ");
7931 case 2: /* parameters */
7932 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7933 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
7934 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
7935 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7936 lastoffset = offset;
7941 if (offset == lastoffset) break; /* nothing happened, exit loop */
7944 case 10: /* buffer ready */
7945 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7946 lastoffset = offset;
7947 switch (fTagNo(tvb, offset)) {
7948 case 0: /* buffer-property */
7949 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7950 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
7951 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7954 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7955 "previous-notification: ");
7958 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7959 "current-notification: ");
7960 lastoffset = offset;
7965 if (offset == lastoffset) break; /* nothing happened, exit loop */
7968 case 11: /* unsigned range */
7969 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7970 lastoffset = offset;
7971 switch (fTagNo(tvb, offset)) {
7973 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7974 "exceeding-value: ");
7977 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7978 "status-flags: ", BACnetStatusFlags);
7981 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7982 "exceeded-limit: ");
7983 lastoffset = offset;
7988 if (offset == lastoffset) break; /* nothing happened, exit loop */
7992 case 13: /* access-event */
7994 case 14: /* double-out-of-range */
7995 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7996 lastoffset = offset;
7997 switch (fTagNo(tvb, offset)) {
7999 offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
8002 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
8003 "status-flags: ", BACnetStatusFlags);
8006 offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: ");
8009 offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
8010 lastoffset = offset;
8015 if (offset == lastoffset) break; /* nothing happened, exit loop */
8018 case 15: /* signed-out-of-range */
8019 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8020 lastoffset = offset;
8021 switch (fTagNo(tvb, offset)) {
8023 offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
8026 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
8027 "status-flags: ", BACnetStatusFlags);
8030 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8033 offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
8034 lastoffset = offset;
8039 if (offset == lastoffset) break; /* nothing happened, exit loop */
8042 case 16: /* unsigned-out-of-range */
8043 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8044 lastoffset = offset;
8045 switch (fTagNo(tvb, offset)) {
8047 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
8050 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
8051 "status-flags: ", BACnetStatusFlags);
8054 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8057 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
8058 lastoffset = offset;
8063 if (offset == lastoffset) break; /* nothing happened, exit loop */
8066 case 17: /* change-of-characterstring */
8067 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8068 lastoffset = offset;
8069 switch (fTagNo(tvb, offset)) {
8071 /* changed-value (CharacterString) */
8072 offset = fCharacterString(tvb, pinfo, subtree, offset, "changed-value: ");
8075 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
8076 "status-flags: ", BACnetStatusFlags);
8079 /* alarm-value (CharacterString) */
8080 offset = fCharacterString(tvb, pinfo, subtree, offset, "alarm-value: ");
8081 lastoffset = offset;
8086 if (offset == lastoffset) break; /* nothing happened, exit loop */
8089 case 18: /* change-of-status-flags */
8090 while (tvb_reported_length_remaining(tvb, offset) > 0) {
8091 /* exit loop if nothing happens inside */
8092 lastoffset = offset;
8093 switch (fTagNo(tvb, offset)) {
8095 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8096 offset = fApplicationTypesEnumerated(tvb, pinfo, subtree, offset,
8097 "present-value: ", BACnetStatusFlags);
8098 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8101 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
8102 "referenced-flags: ", BACnetStatusFlags);
8103 lastoffset = offset;
8108 if (offset == lastoffset) break; /* nothing happened, exit loop */
8111 /* todo: add new parameters here ... */
8113 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
8117 /* Closing tag for parameter choice */
8118 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8124 fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8126 guint lastoffset = offset;
8127 guint8 tag_no, tag_info;
8129 proto_tree *subtree = tree;
8131 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8132 subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0,
8133 ett_bacapp_value, NULL, "event parameters (%d) %s",
8134 tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
8136 /* Opening tag for parameter choice */
8137 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8140 case 0: /* change-of-bitstring */
8141 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8142 lastoffset = offset;
8143 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8144 if (tag_is_closing(tag_info)) {
8149 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8152 offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: ");
8154 case 2: /* SEQUENCE OF BIT STRING */
8155 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8156 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8157 lastoffset = offset;
8158 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8159 if (tag_is_closing(tag_info)) {
8162 offset = fBitStringTag(tvb, pinfo, subtree, offset,
8163 "bitstring value: ");
8165 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8172 case 1: /* change-of-state */
8173 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8174 lastoffset = offset;
8175 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8176 if (tag_is_closing(tag_info)) {
8181 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8183 case 1: /* SEQUENCE OF BACnetPropertyStates */
8184 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8185 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8186 lastoffset = offset;
8187 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8188 if (tag_is_closing(tag_info)) {
8191 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
8193 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8200 case 2: /* change-of-value */
8201 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8202 lastoffset = offset;
8203 switch (fTagNo(tvb, offset)) {
8205 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8207 case 1: /* don't loop it, it's a CHOICE */
8208 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8209 switch (fTagNo(tvb, offset)) {
8211 offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: ");
8214 offset = fRealTag(tvb, pinfo, subtree, offset,
8215 "referenced Property Increment: ");
8220 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8227 case 3: /* command-failure */
8228 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8229 lastoffset = offset;
8230 tag_no = fTagNo(tvb, offset);
8233 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
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 4: /* floating-limit */
8246 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8247 lastoffset = offset;
8248 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8249 if (tag_is_closing(tag_info)) {
8254 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8257 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8258 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8259 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8262 offset = fRealTag(tvb, pinfo, subtree, offset, "low diff limit: ");
8265 offset = fRealTag(tvb, pinfo, subtree, offset, "high diff limit: ");
8268 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
8275 case 5: /* out-of-range */
8276 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8277 lastoffset = offset;
8278 switch (fTagNo(tvb, offset)) {
8280 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8283 offset = fRealTag(tvb, pinfo, subtree, offset, "low limit: ");
8286 offset = fRealTag(tvb, pinfo, subtree, offset, "high limit: ");
8289 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
8298 offset = fBACnetPropertyValue (tvb, pinfo, tree, offset);
8302 case 7: /* buffer-ready */
8305 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
8306 lastoffset = offset;
8307 switch (fTagNo(tvb, offset)) {
8309 offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification threshold");
8312 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8313 "previous notification count: ");
8321 case 8: /* change-of-life-safety */
8322 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8323 lastoffset = offset;
8324 switch (fTagNo(tvb, offset)) {
8326 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8329 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8330 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8331 lastoffset = offset;
8332 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8333 if (tag_is_closing(tag_info)) {
8336 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8337 "life safety alarm value: ", BACnetLifeSafetyState, 256);
8339 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8342 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8343 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8344 lastoffset = offset;
8345 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8346 if (tag_is_closing(tag_info)) {
8349 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8350 "alarm value: ", BACnetLifeSafetyState, 256);
8352 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8355 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8356 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8357 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8364 case 9: /* extended */
8365 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8366 lastoffset = offset;
8367 switch (fTagNo(tvb, offset)) {
8369 offset = fVendorIdentifier(tvb, pinfo, tree, offset);
8372 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8373 "extended-event-type: ");
8375 case 2: /* parameters */
8376 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8377 offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
8378 offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
8379 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8380 lastoffset = offset;
8385 if (offset == lastoffset) break; /* nothing happened, exit loop */
8388 case 10: /* buffer-ready */
8389 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8390 lastoffset = offset;
8391 switch (fTagNo(tvb, offset)) {
8393 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
8394 "notification-threshold: ");
8397 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
8398 "previous-notification-count: ");
8405 case 11: /* unsigned-range */
8406 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8407 lastoffset = offset;
8408 switch (fTagNo(tvb, offset)) {
8410 offset = fTimeSpan(tvb, pinfo, tree, offset, "Time Delay");
8413 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8417 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8425 case 13: /* access-event */
8426 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8427 lastoffset = offset;
8428 switch (fTagNo(tvb, offset)) {
8430 /* TODO: [0] SEQUENCE OF BACnetAccessEvent */
8431 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8432 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8433 lastoffset = offset;
8434 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8435 if (tag_is_closing(tag_info)) {
8438 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8439 "access event: ", BACnetAccessEvent, 512);
8441 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8444 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8445 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8446 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8453 case 14: /* double-out-of-range */
8454 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8455 lastoffset = offset;
8456 switch (fTagNo(tvb, offset)) {
8458 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8461 offset = fDoubleTag(tvb, pinfo, subtree, offset, "low limit: ");
8464 offset = fDoubleTag(tvb, pinfo, subtree, offset, "high limit: ");
8467 offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: ");
8474 case 15: /* signed-out-of-range */
8475 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8476 lastoffset = offset;
8477 switch (fTagNo(tvb, offset)) {
8479 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8482 offset = fSignedTag(tvb, pinfo, subtree, offset, "low limit: ");
8485 offset = fSignedTag(tvb, pinfo, subtree, offset, "high limit: ");
8488 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8495 case 16: /* unsigned-out-of-range */
8496 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8497 lastoffset = offset;
8498 switch (fTagNo(tvb, offset)) {
8500 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8503 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "low limit: ");
8506 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "high limit: ");
8509 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8516 case 17: /* change-of-characterstring */
8517 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8518 lastoffset = offset;
8519 switch (fTagNo(tvb, offset)) {
8521 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8523 case 1: /* SEQUENCE OF CharacterString */
8524 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8525 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8526 lastoffset = offset;
8527 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8528 if (tag_is_closing(tag_info)) {
8531 offset = fCharacterString(tvb, pinfo, tree, offset, "alarm value: ");
8533 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8540 case 18: /* change-of-status-flags */
8541 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8542 lastoffset = offset;
8543 switch (fTagNo(tvb, offset)) {
8545 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8548 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
8549 "selected flags: ", BACnetStatusFlags);
8556 /* todo: add new event-parameter cases here */
8561 /* Closing tag for parameter choice */
8562 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8567 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8569 guint lastoffset = 0;
8570 guint8 tag_no, tag_info;
8572 proto_tree *subtree = tree;
8574 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8575 lastoffset = offset;
8576 switch (fTagNo(tvb, offset)) {
8577 case 0: /* timestamp */
8578 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8579 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8580 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8581 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8583 case 1: /* logDatum: don't loop, it's a CHOICE */
8584 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8585 switch (fTagNo(tvb, offset)) {
8586 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8587 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8589 case 1: /* todo: move this to new method fConfirmedEventNotificationRequestTag... */
8590 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "notification: ");
8591 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8592 offset = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset);
8593 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8596 offset = fRealTag(tvb, pinfo, tree, offset, "time-change: ");
8601 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8606 if (offset == lastoffset) break; /* nothing happened, exit loop */
8612 fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8614 guint lastoffset = 0;
8615 guint8 tag_no, tag_info;
8618 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8619 lastoffset = offset;
8620 switch (fTagNo(tvb, offset)) {
8621 case 0: /* timestamp */
8622 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8623 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8624 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8625 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8627 case 1: /* logDatum: don't loop, it's a CHOICE */
8628 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8629 switch (fTagNo(tvb, offset)) {
8630 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8631 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8634 offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: ");
8637 offset = fRealTag(tvb, pinfo, tree, offset, "real value: ");
8640 offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: ");
8643 offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: ");
8646 offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: ");
8649 offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: ");
8652 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8655 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8656 offset = fError(tvb, pinfo, tree, offset);
8657 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8660 offset = fRealTag(tvb, pinfo, tree, offset, "time change: ");
8662 case 10: /* any Value */
8663 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8664 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
8665 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8670 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8673 /* Changed this to BitString per BACnet Spec. */
8674 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "Status Flags:", BACnetStatusFlags);
8679 if (offset == lastoffset) break; /* nothing happened, exit loop */
8685 fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8687 guint lastoffset = 0;
8688 guint8 tag_no, tag_info;
8691 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8692 lastoffset = offset;
8693 switch (fTagNo(tvb, offset)) {
8694 case 0: /* timestamp */
8695 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8696 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8697 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8698 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8700 case 1: /* logData: don't loop, it's a CHOICE */
8701 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8702 switch (fTagNo(tvb, offset)) {
8703 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8704 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8706 case 1: /* log-data: SEQUENCE OF CHOICE */
8707 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8708 while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset != lastoffset)) { /* exit loop if nothing happens inside */
8709 lastoffset = offset;
8710 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8711 if (tag_is_closing(tag_info)) {
8712 lastoffset = offset;
8717 offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: ");
8720 offset = fRealTag(tvb, pinfo, tree, offset, "real value: ");
8723 offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: ");
8726 offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: ");
8729 offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: ");
8732 offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: ");
8735 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8738 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8739 offset = fError(tvb, pinfo, tree, offset);
8740 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8742 case 8: /* any Value */
8743 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8744 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
8745 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8751 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8754 offset = fRealTag(tvb, pinfo, tree, offset, "time-change: ");
8759 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8764 if (offset == lastoffset) break; /* nothing happened, exit loop */
8771 fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8773 guint lastoffset = 0;
8774 guint8 tag_no, tag_info;
8777 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8778 lastoffset = offset;
8779 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8780 if (tag_is_closing(tag_info)) {
8785 case 0: /* ProcessId */
8786 offset = fProcessId(tvb, pinfo, tree, offset);
8788 case 1: /* initiating ObjectId */
8789 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8791 case 2: /* event ObjectId */
8792 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8794 case 3: /* time stamp */
8795 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8796 offset = fTimeStamp(tvb, pinfo, tree, offset, NULL);
8797 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8799 case 4: /* notificationClass */
8800 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: ");
8802 case 5: /* Priority */
8803 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: ");
8805 case 6: /* EventType */
8806 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8807 "Event Type: ", BACnetEventType, 64);
8809 case 7: /* messageText */
8810 offset = fCharacterString(tvb, pinfo, tree, offset, "message Text: ");
8812 case 8: /* NotifyType */
8813 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8814 "Notify Type: ", BACnetNotifyType);
8816 case 9: /* ackRequired */
8817 offset = fBooleanTag(tvb, pinfo, tree, offset, "ack Required: ");
8819 case 10: /* fromState */
8820 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8821 "from State: ", BACnetEventState, 64);
8823 case 11: /* toState */
8824 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8825 "to State: ", BACnetEventState, 64);
8827 case 12: /* NotificationParameters */
8828 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8829 offset = fNotificationParameters(tvb, pinfo, tree, offset);
8830 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8835 if (offset == lastoffset) break; /* nothing happened, exit loop */
8841 fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8843 return fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
8847 fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8849 guint lastoffset = 0, len;
8850 guint8 tag_no, tag_info;
8852 proto_tree *subtree = tree;
8854 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8855 lastoffset = offset;
8856 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8857 if (tag_is_closing(tag_info)) {
8864 case 0: /* ProcessId */
8865 offset = fProcessId(tvb, pinfo, tree, offset);
8867 case 1: /* initiating DeviceId */
8868 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
8870 case 2: /* monitored ObjectId */
8871 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
8873 case 3: /* time remaining */
8874 offset = fTimeSpan(tvb, pinfo, tree, offset, "Time remaining");
8876 case 4: /* List of Values */
8877 if (tag_is_opening(tag_info)) {
8878 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "list of Values");
8879 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8880 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
8888 if (offset == lastoffset) break; /* nothing happened, exit loop */
8894 fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8896 return fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
8900 fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8902 guint lastoffset = 0;
8903 guint8 tag_no = 0, tag_info = 0;
8906 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8907 lastoffset = offset;
8908 switch (fTagNo(tvb, offset)) {
8909 case 0: /* acknowledgingProcessId */
8910 offset = fUnsignedTag(tvb, pinfo, tree, offset, "acknowledging Process Id: ");
8912 case 1: /* eventObjectId */
8913 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8915 case 2: /* eventStateAcknowledged */
8916 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8917 "event State Acknowledged: ", BACnetEventState, 64);
8919 case 3: /* timeStamp */
8920 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8921 offset = fTimeStamp(tvb, pinfo, tree, offset, NULL);
8922 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8924 case 4: /* acknowledgementSource */
8925 offset = fCharacterString(tvb, pinfo, tree, offset, "acknowledgement Source: ");
8927 case 5: /* timeOfAcknowledgement */
8928 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8929 offset = fTimeStamp(tvb, pinfo, tree, offset, "acknowledgement timestamp: ");
8930 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8935 if (offset == lastoffset) break; /* nothing happened, exit loop */
8941 fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8943 guint lastoffset = 0;
8945 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8946 lastoffset = offset;
8947 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
8948 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
8949 "alarm State: ", BACnetEventState, 64);
8950 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
8951 "acknowledged Transitions: ", BACnetEventTransitionBits);
8952 if (offset == lastoffset) break; /* nothing happened, exit loop */
8958 fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8960 guint lastoffset = 0;
8961 guint8 tag_no, tag_info;
8964 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8965 lastoffset = offset;
8966 switch (fTagNo(tvb, offset)) {
8967 case 0: /* acknowledgmentFilter */
8968 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8969 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
8971 case 1: /* eventObjectId - OPTIONAL */
8972 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8973 offset = fRecipientProcess(tvb, pinfo, tree, offset);
8974 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8976 case 2: /* eventStateFilter */
8977 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8978 "event State Filter: ", BACnetEventStateFilter);
8980 case 3: /* eventTypeFilter - OPTIONAL */
8981 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8982 "event Type Filter: ", BACnetEventType);
8984 case 4: /* priorityFilter */
8985 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8986 offset = fUnsignedTag(tvb, pinfo, tree, offset, "min Priority: ");
8987 offset = fUnsignedTag(tvb, pinfo, tree, offset, "max Priority: ");
8988 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8990 case 5: /* notificationClassFilter - OPTIONAL */
8991 offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification Class Filter: ");
8996 if (offset == lastoffset) break; /* nothing happened, exit loop */
9002 fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9004 guint lastoffset = 0;
9006 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9007 lastoffset = offset;
9008 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
9009 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
9010 "event Type: ", BACnetEventType, 64);
9011 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
9012 "event State: ", BACnetEventState);
9013 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Priority: ");
9014 if (tvb_reported_length_remaining(tvb, offset) > 0 && fTagNo(tvb, offset) == 2) /* Notification Class - OPTIONAL */
9015 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: ");
9016 if (offset == lastoffset) break; /* nothing happened, exit loop */
9023 fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9025 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9026 if (fTagNo(tvb, offset) == 0) {
9027 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9034 flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9036 guint lastoffset = 0;
9037 guint8 tag_no, tag_info;
9039 proto_tree* subtree = tree;
9041 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9042 lastoffset = offset;
9043 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9044 /* we are finished here if we spot a closing tag */
9045 if (tag_is_closing(tag_info)) {
9049 case 0: /* ObjectId */
9050 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9052 case 1: /* eventState */
9053 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
9054 "event State: ", BACnetEventState);
9056 case 2: /* acknowledgedTransitions */
9057 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
9058 "acknowledged Transitions: ", BACnetEventTransitionBits);
9060 case 3: /* eventTimeStamps */
9061 subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventTimeStamps");
9062 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9063 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: ");
9064 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: ");
9065 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: ");
9066 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9068 case 4: /* notifyType */
9069 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
9070 "Notify Type: ", BACnetNotifyType);
9072 case 5: /* eventEnable */
9073 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
9074 "event Enable: ", BACnetEventTransitionBits);
9076 case 6: /* eventPriorities */
9077 subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventPriorities");
9078 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9079 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-OFFNORMAL Priority: ");
9080 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-FAULT Priority: ");
9081 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-NORMAL Priority: ");
9082 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9087 if (offset == lastoffset) break; /* nothing happened, exit loop */
9093 fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9095 guint lastoffset = 0;
9096 guint8 tag_no, tag_info;
9099 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9100 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9101 lastoffset = offset;
9102 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9103 /* we are finished here if we spot a closing tag */
9104 if (tag_is_closing(tag_info)) {
9107 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
9108 if (offset == lastoffset) break; /* nothing happened, exit loop */
9114 fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9116 guint lastoffset = 0;
9117 guint8 tag_no, tag_info;
9120 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9121 lastoffset = offset;
9122 switch (fTagNo(tvb, offset)) {
9123 case 0: /* listOfEventSummaries */
9124 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9125 offset = flistOfEventSummaries(tvb, pinfo, tree, offset);
9126 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9128 case 1: /* moreEvents */
9129 offset = fBooleanTag(tvb, pinfo, tree, offset, "more Events: ");
9134 if (offset == lastoffset) break; /* nothing happened, exit loop */
9140 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9142 guint lastoffset = 0, len;
9143 guint8 tag_no, tag_info;
9145 proto_tree *subtree = tree;
9147 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9149 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9150 lastoffset = offset;
9151 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9152 if (tag_is_closing(tag_info)) {
9159 case 0: /* ObjectId */
9160 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9162 case 3: /* listOfElements */
9163 if (tag_is_opening(tag_info)) {
9164 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfElements");
9165 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9166 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
9174 if (offset == lastoffset) break; /* nothing happened, exit loop */
9180 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9182 return fObjectIdentifier(tvb, pinfo, tree, offset);
9186 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9188 guint lastoffset = 0;
9190 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9191 lastoffset = offset;
9193 switch (fTagNo(tvb, offset)) {
9194 case 0: /* timeDuration */
9195 offset = fUnsignedTag(tvb, pinfo, tree, offset, "time Duration: ");
9197 case 1: /* enable-disable */
9198 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "enable-disable: ",
9199 BACnetEnableDisable);
9201 case 2: /* password - OPTIONAL */
9202 offset = fCharacterString(tvb, pinfo, tree, offset, "Password: ");
9207 if (offset == lastoffset) break; /* nothing happened, exit loop */
9213 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9215 guint lastoffset = 0;
9217 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9218 lastoffset = offset;
9220 switch (fTagNo(tvb, offset)) {
9221 case 0: /* reinitializedStateOfDevice */
9222 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
9223 "reinitialized State Of Device: ",
9224 BACnetReinitializedStateOfDevice);
9226 case 1: /* password - OPTIONAL */
9227 offset = fCharacterString(tvb, pinfo, tree, offset, "Password: ");
9232 if (offset == lastoffset) break; /* nothing happened, exit loop */
9238 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9240 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
9241 "vtClass: ", BACnetVTClass);
9242 return fApplicationTypes(tvb, pinfo, tree, offset, "local VT Session ID: ");
9246 fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9248 return fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: ");
9252 fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9254 guint lastoffset = 0;
9256 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9257 lastoffset = offset;
9258 offset= fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: ");
9259 if (offset == lastoffset) break; /* nothing happened, exit loop */
9265 fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9267 offset= fApplicationTypes(tvb, pinfo, tree, offset, "VT Session ID: ");
9268 offset = fApplicationTypes(tvb, pinfo, tree, offset, "VT New Data: ");
9269 return fApplicationTypes(tvb, pinfo, tree, offset, "VT Data Flag: ");
9273 fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9275 guint lastoffset = 0;
9277 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9278 lastoffset = offset;
9280 switch (fTagNo(tvb, offset)) {
9281 case 0: /* BOOLEAN */
9282 offset = fBooleanTag(tvb, pinfo, tree, offset, "all New Data Accepted: ");
9284 case 1: /* Unsigned OPTIONAL */
9285 offset = fUnsignedTag(tvb, pinfo, tree, offset, "accepted Octet Count: ");
9290 if (offset == lastoffset) break; /* nothing happened, exit loop */
9296 fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9298 guint lastoffset = 0;
9300 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9301 lastoffset = offset;
9303 switch (fTagNo(tvb, offset)) {
9304 case 0: /* Unsigned32 */
9305 offset = fUnsignedTag(tvb, pinfo, tree, offset, "pseudo Random Number: ");
9307 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
9308 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
9310 case 2: /* Chararacter String OPTIONAL */
9311 offset = fCharacterString(tvb, pinfo, tree, offset, "operator Name: ");
9313 case 3: /* Chararacter String OPTIONAL */
9314 offset = fCharacterString(tvb, pinfo, tree, offset, "operator Password: ");
9316 case 4: /* Boolean OPTIONAL */
9317 offset = fBooleanTag(tvb, pinfo, tree, offset, "start Encyphered Session: ");
9322 if (offset == lastoffset) break; /* nothing happened, exit loop */
9328 fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9330 return fApplicationTypes(tvb, pinfo, tree, offset, "modified Random Number: ");
9334 fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9336 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* Requesting Device Identifier */
9337 offset = fAddress(tvb, pinfo, tree, offset);
9338 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* Remote Device Identifier */
9339 return fAddress(tvb, pinfo, tree, offset);
9343 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9345 /* Same as AddListElement request after service choice */
9346 return fAddListElementRequest(tvb, pinfo, tree, offset);
9350 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9352 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
9356 fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9358 guint lastoffset = 0, len;
9359 guint8 tag_no, tag_info;
9361 proto_tree *subtree = tree;
9363 /* set the optional global properties to indicate not-used */
9364 propertyArrayIndex = -1;
9365 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9366 lastoffset = offset;
9367 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9368 if (tag_is_closing(tag_info)) {
9374 case 0: /* objectIdentifier */
9375 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9377 case 1: /* propertyIdentifier */
9378 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9380 case 2: /* propertyArrayIndex */
9381 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
9383 case 3: /* propertyValue */
9384 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9389 if (offset == lastoffset) break; /* nothing happened, exit loop */
9395 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9397 guint lastoffset = 0;
9398 guint8 tag_no, tag_info;
9400 proto_tree *subtree = tree;
9402 /* set the optional global properties to indicate not-used */
9403 propertyArrayIndex = -1;
9404 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9405 lastoffset = offset;
9406 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9407 /* quit loop if we spot a closing tag */
9408 if (tag_is_closing(tag_info)) {
9413 case 0: /* objectIdentifier */
9414 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9416 case 1: /* propertyIdentifier */
9417 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9419 case 2: /* propertyArrayIndex */
9420 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
9422 case 3: /* propertyValue */
9423 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9425 case 4: /* Priority (only used for write) */
9426 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
9431 if (offset == lastoffset) break; /* nothing happened, exit loop */
9437 fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9439 guint lastoffset = 0, len;
9440 guint8 tag_no, tag_info;
9443 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9444 lastoffset = offset;
9445 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9446 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
9447 if (tag_is_closing(tag_info)) {
9453 case 0: /* objectIdentifier */
9454 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9456 case 1: /* listOfPropertyValues */
9457 if (tag_is_opening(tag_info)) {
9458 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9459 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
9467 if (offset == lastoffset) break; /* nothing happened, exit loop */
9473 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9475 if (offset >= tvb_reported_length(tvb))
9478 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9479 return fWriteAccessSpecification(tvb, pinfo, tree, offset);
9483 fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
9485 guint lastoffset = 0;
9486 guint8 tag_no, tag_info;
9489 /* set the optional global properties to indicate not-used */
9490 propertyArrayIndex = -1;
9491 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9492 lastoffset = offset;
9493 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9494 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
9496 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
9499 switch (tag_no-tagoffset) {
9500 case 0: /* PropertyIdentifier */
9501 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
9503 case 1: /* propertyArrayIndex */
9504 offset = fPropertyArrayIndex(tvb, pinfo, tree, offset);
9505 if (list != 0) break; /* Continue decoding if this may be a list */
9507 lastoffset = offset; /* Set loop end condition */
9510 if (offset == lastoffset) break; /* nothing happened, exit loop */
9516 fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
9518 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9519 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
9523 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9525 guint lastoffset = 0;
9527 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9528 lastoffset = offset;
9530 switch (fTagNo(tvb, offset)) {
9531 case 0: /* ObjectIdentifier */
9532 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9534 case 1: /* PropertyIdentifier and propertyArrayIndex */
9535 offset = fPropertyReference(tvb, pinfo, tree, offset, 1, 0);
9536 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9538 lastoffset = offset; /* Set loop end condition */
9541 if (offset == lastoffset) break; /* nothing happened, exit loop */
9548 fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, guint offset)
9550 guint lastoffset = 0;
9551 guint8 tag_no, tag_info;
9553 proto_tree* subtree = tree;
9556 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
9557 lastoffset = offset;
9558 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9559 if (tag_is_closing(tag_info)) {
9560 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
9561 &tag_no, &tag_info, &lvt);
9565 case 0: /* ObjectIdentifier */
9566 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9568 case 1: /* PropertyIdentifier */
9569 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9571 case 2: /* propertyArrayIndex */
9572 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "property Array Index: ");
9575 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9577 case 4: /* Priority */
9578 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
9589 fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9591 char i = 1, ar[256];
9592 guint lastoffset = 0;
9594 if (propertyArrayIndex > 0) {
9595 /* BACnetARRAY index 0 refers to the length
9596 of the array, not the elements of the array.
9597 BACnetARRAY index -1 is our internal flag that
9598 the optional index was not used.
9599 BACnetARRAY refers to this as all elements of the array.
9600 If the optional index is specified for a BACnetARRAY,
9601 then that specific array element is referenced. */
9602 i = propertyArrayIndex;
9604 while (tvb_reported_length_remaining(tvb, offset) > 0) {
9605 /* exit loop if nothing happens inside */
9606 lastoffset = offset;
9607 g_snprintf(ar, sizeof(ar), "%s[%d]: ",
9608 val_to_split_str(87 , 512,
9609 BACnetPropertyIdentifier,
9610 ASHRAE_Reserved_Fmt,
9611 Vendor_Proprietary_Fmt),
9613 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
9614 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
9615 /* there are only 16 priority array elements */
9619 if (offset == lastoffset) break; /* nothing happened, exit loop */
9626 fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9628 guint lastoffset = 0;
9630 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9631 lastoffset = offset;
9633 switch (fTagNo(tvb, offset)) {
9634 case 0: /* deviceIdentifier - OPTIONAL */
9635 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9637 case 1: /* ObjectIdentifier */
9638 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9643 if (offset == lastoffset) break; /* nothing happened, exit loop */
9649 fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9651 guint8 tag_no, tag_info;
9653 guint lastoffset = 0;
9655 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9656 lastoffset = offset;
9657 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9658 /* quit loop if we spot an un-matched closing tag */
9659 if (tag_is_closing(tag_info)) {
9663 case 0: /* calendarEntry */
9664 if (tag_is_opening(tag_info)) {
9665 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9666 offset = fCalendarEntry(tvb, pinfo, subtree, offset);
9667 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9670 case 1: /* calendarReference */
9671 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9673 case 2: /* list of BACnetTimeValue */
9674 if (tag_is_opening(tag_info)) {
9675 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9676 offset = fTimeValue(tvb, pinfo, subtree, offset);
9677 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9682 case 3: /* eventPriority */
9683 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "event priority: ");
9688 if (offset == lastoffset) break; /* nothing happened, exit loop */
9694 fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9696 guint lastoffset = 0, len;
9697 guint8 tag_no, tag_info;
9700 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9701 lastoffset = offset;
9702 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9703 /* maybe a listOfSelectionCriteria if we spot a closing tag */
9704 if (tag_is_closing(tag_info)) {
9709 switch (fTagNo(tvb, offset)) {
9710 case 0: /* propertyIdentifier */
9711 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
9713 case 1: /* propertyArrayIndex */
9714 offset = fPropertyArrayIndex(tvb, pinfo, tree, offset);
9716 case 2: /* relationSpecifier */
9717 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
9718 "relation Specifier: ", BACnetRelationSpecifier);
9720 case 3: /* comparisonValue */
9721 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9722 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
9723 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9728 if (offset == lastoffset) break; /* nothing happened, exit loop */
9734 fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9736 guint lastoffset = 0;
9737 guint8 tag_no, tag_info;
9740 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9741 lastoffset = offset;
9742 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9743 /* quit loop if we spot a closing tag */
9744 if (tag_is_closing(tag_info)) {
9749 case 0: /* selectionLogic */
9750 offset = fEnumeratedTag(tvb, pinfo, subtree, offset,
9751 "selection Logic: ", BACnetSelectionLogic);
9753 case 1: /* listOfSelectionCriteria */
9754 if (tag_is_opening(tag_info)) {
9755 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9756 offset = fSelectionCriteria(tvb, pinfo, subtree, offset);
9757 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9765 if (offset == lastoffset) break; /* nothing happened, exit loop */
9772 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
9774 guint lastoffset = 0;
9775 guint8 tag_no, tag_info;
9778 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9779 lastoffset = offset;
9780 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9782 if (tag_is_opening(tag_info) && tag_no < 2) {
9783 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9785 case 0: /* objectSelectionCriteria */
9786 offset = fObjectSelectionCriteria(tvb, pinfo, subtree, offset);
9788 case 1: /* listOfPropertyReferences */
9789 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
9794 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9796 if (offset == lastoffset) break; /* nothing happened, exit loop */
9802 fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9804 guint lastoffset = 0;
9805 guint8 tag_no, tag_info;
9807 proto_tree *subtree = tree;
9809 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9810 lastoffset = offset;
9811 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9813 case 0: /* objectIdentifier */
9814 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9816 case 1: /* listOfPropertyReferences */
9817 if (tag_is_opening(tag_info)) {
9818 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfPropertyReferences");
9819 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9820 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
9821 } else if (tag_is_closing(tag_info)) {
9822 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
9823 &tag_no, &tag_info, &lvt);
9826 /* error condition: let caller handle */
9833 if (offset == lastoffset) break; /* nothing happened, exit loop */
9839 fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9841 guint lastoffset = 0, len;
9845 proto_tree *subtree = tree;
9847 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9848 lastoffset = offset;
9849 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9850 /* maybe a listOfReadAccessResults if we spot a closing tag here */
9851 if (tag_is_closing(tag_info)) {
9853 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
9858 case 0: /* objectSpecifier */
9859 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9861 case 1: /* list of Results */
9862 if (tag_is_opening(tag_info)) {
9863 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfResults");
9864 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9869 case 2: /* propertyIdentifier */
9870 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
9872 case 5: /* propertyAccessError */
9873 if (tag_is_opening(tag_info)) {
9874 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "propertyAccessError");
9875 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9876 /* Error Code follows */
9877 offset = fError(tvb, pinfo, subtree, offset);
9885 if (offset == lastoffset) break; /* nothing happened, exit loop */
9892 fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9894 /* listOfReadAccessResults */
9895 return fReadAccessResult(tvb, pinfo, tree, offset);
9900 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9902 guint lastoffset = 0;
9903 guint8 tag_no, tag_info;
9906 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9907 lastoffset = offset;
9908 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9911 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9913 case 0: /* objectSpecifier */
9914 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
9915 case 0: /* objectType */
9916 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, "Object Type: ", BACnetObjectType, 128);
9918 case 1: /* objectIdentifier */
9919 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9925 case 1: /* propertyValue */
9926 if (tag_is_opening(tag_info)) {
9927 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
9935 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9937 if (offset == lastoffset) break; /* nothing happened, exit loop */
9943 fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9945 return fObjectIdentifier(tvb, pinfo, tree, offset);
9949 fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9951 guint8 tag_no, tag_info;
9953 proto_tree *subtree = tree;
9955 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9957 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9958 /* optional range choice */
9959 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, BACnetReadRangeOptions, "unknown range option"));
9963 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9965 case 3: /* range byPosition */
9966 case 6: /* range bySequenceNumber, 2004 spec */
9967 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Index: ");
9968 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: ");
9970 case 4: /* range byTime - deprecated in 2004 */
9971 case 7: /* 2004 spec */
9972 offset = fDateTime(tvb, pinfo, subtree, offset, "reference Date/Time: ");
9973 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: ");
9975 case 5: /* range timeRange - deprecated in 2004 */
9976 offset = fDateTime(tvb, pinfo, subtree, offset, "beginning Time: ");
9977 offset = fDateTime(tvb, pinfo, subtree, offset, "ending Time: ");
9982 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9989 fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9991 guint8 tag_no, tag_info;
9993 proto_tree *subtree = tree;
9995 /* set the optional global properties to indicate not-used */
9996 propertyArrayIndex = -1;
9997 /* objectIdentifier, propertyIdentifier, and
9998 OPTIONAL propertyArrayIndex */
9999 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
10000 /* resultFlags => BACnetResultFlags ::= BIT STRING */
10001 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
10003 BACnetResultFlags);
10005 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "item Count: ");
10007 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10008 if (tag_is_opening(tag_info)) {
10009 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10010 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "itemData");
10011 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10012 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
10013 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10015 /* firstSequenceNumber - OPTIONAL */
10016 if (tvb_reported_length_remaining(tvb, offset) > 0) {
10017 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "first Sequence Number: ");
10024 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10026 guint lastoffset = 0;
10028 guint8 tag_no, tag_info;
10029 proto_tree* subtree = NULL;
10031 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10033 if (tag_is_opening(tag_info)) {
10034 subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL,
10035 val_to_str_const(tag_no, BACnetFileAccessOption, "invalid access method"));
10036 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10037 offset = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "invalid option"));
10038 offset = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileWriteInfo, "unknown option"));
10041 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
10042 /* exit loop if nothing happens inside */
10043 lastoffset = offset;
10044 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "Record Data: ");
10048 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
10049 /* More Flag is not set, so we can look for closing tag in this segment */
10050 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10051 if (tag_is_closing(tag_info)) {
10052 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10060 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10062 guint8 tag_no, tag_info;
10064 proto_tree *subtree = tree;
10066 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
10068 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10070 if (tag_is_opening(tag_info)) {
10071 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL,
10072 val_to_str_const(tag_no, BACnetFileAccessOption, "unknown access method"));
10073 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10074 offset = fSignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
10075 offset = fUnsignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileRequestCount, "unknown option"));
10076 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10082 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10085 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* file Identifier */
10086 offset = fAccessMethod(tvb, pinfo, tree, offset);
10092 fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10094 guint tag_no = fTagNo(tvb, offset);
10095 return fSignedTag(tvb, pinfo, tree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
10099 fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10101 offset = fApplicationTypes(tvb, pinfo, tree, offset, "End Of File: ");
10102 offset = fAccessMethod(tvb, pinfo, tree, offset);
10108 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
10110 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10111 return fReadAccessSpecification(tvb, pinfo, subtree, offset);
10115 fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10117 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10118 return fReadAccessResult(tvb, pinfo, tree, offset);
10122 fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10124 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10127 switch (service_choice) {
10128 case 0: /* acknowledgeAlarm */
10129 offset = fAcknowledgeAlarmRequest(tvb, pinfo, tree, offset);
10131 case 1: /* confirmedCOVNotification */
10132 offset = fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
10134 case 2: /* confirmedEventNotification */
10135 offset = fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
10137 case 3: /* confirmedGetAlarmSummary conveys no parameters */
10139 case 4: /* getEnrollmentSummaryRequest */
10140 offset = fGetEnrollmentSummaryRequest(tvb, pinfo, tree, offset);
10142 case 5: /* subscribeCOVRequest */
10143 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
10145 case 6: /* atomicReadFile-Request */
10146 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
10148 case 7: /* atomicWriteFile-Request */
10149 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
10151 case 8: /* AddListElement-Request */
10152 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
10154 case 9: /* removeListElement-Request */
10155 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
10157 case 10: /* createObjectRequest */
10158 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
10160 case 11: /* deleteObject */
10161 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
10164 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
10167 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
10170 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
10173 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
10176 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
10179 offset = fDeviceCommunicationControlRequest(tvb, pinfo, tree, offset);
10182 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
10185 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
10188 offset = fReinitializeDeviceRequest(tvb, pinfo, tree, offset);
10191 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
10194 offset = fVtCloseRequest(tvb, pinfo, tree, offset);
10197 offset = fVtDataRequest(tvb, pinfo, tree, offset);
10200 offset = fAuthenticateRequest(tvb, pinfo, tree, offset);
10203 offset = fRequestKeyRequest(tvb, pinfo, tree, offset);
10206 offset = fReadRangeRequest(tvb, pinfo, tree, offset);
10209 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
10212 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
10215 offset = fGetEventInformationRequest(tvb, pinfo, tree, offset);
10224 fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10226 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10229 switch (service_choice) {
10230 case 3: /* confirmedEventNotificationAck */
10231 offset = fGetAlarmSummaryAck(tvb, pinfo, tree, offset);
10233 case 4: /* getEnrollmentSummaryAck */
10234 offset = fGetEnrollmentSummaryAck(tvb, pinfo, tree, offset);
10236 case 6: /* atomicReadFile */
10237 offset = fAtomicReadFileAck(tvb, pinfo, tree, offset);
10239 case 7: /* atomicReadFileAck */
10240 offset = fAtomicWriteFileAck(tvb, pinfo, tree, offset);
10242 case 10: /* createObject */
10243 offset = fCreateObjectAck(tvb, pinfo, tree, offset);
10246 offset = fReadPropertyAck(tvb, pinfo, tree, offset);
10249 offset = fReadPropertyConditionalAck(tvb, pinfo, tree, offset);
10252 offset = fReadPropertyMultipleAck(tvb, pinfo, tree, offset);
10255 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
10258 offset = fVtOpenAck(tvb, pinfo, tree, offset);
10261 offset = fVtDataAck(tvb, pinfo, tree, offset);
10264 offset = fAuthenticateAck(tvb, pinfo, tree, offset);
10267 offset = fReadRangeAck(tvb, pinfo, tree, offset);
10270 offset = fGetEventInformationACK(tvb, pinfo, tree, offset);
10279 fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10281 /* BACnetObjectIdentifier */
10282 offset = fApplicationTypes(tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
10284 /* MaxAPDULengthAccepted */
10285 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
10287 /* segmentationSupported */
10288 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
10289 "Segmentation Supported: ", BACnetSegmentation);
10292 return fVendorIdentifier(tvb, pinfo, tree, offset);
10296 fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10298 /* BACnetDeviceIdentifier */
10299 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Device Identifier: ");
10301 /* BACnetObjectIdentifier */
10302 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
10305 return fApplicationTypes(tvb, pinfo, tree, offset, "Object Name: ");
10310 fWhoIsRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
10312 guint lastoffset = 0;
10316 guint8 tag_no, tag_info;
10319 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10320 lastoffset = offset;
10322 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10326 /* DeviceInstanceRangeLowLimit Optional */
10327 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
10328 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
10329 offset = fDevice_Instance(tvb, pinfo, tree, offset,
10330 hf_Device_Instance_Range_Low_Limit);
10333 /* DeviceInstanceRangeHighLimit Optional but
10334 required if DeviceInstanceRangeLowLimit is there */
10335 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
10336 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
10337 offset = fDevice_Instance(tvb, pinfo, tree, offset,
10338 hf_Device_Instance_Range_High_Limit);
10343 if (offset == lastoffset) break; /* nothing happened, exit loop */
10349 fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10351 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10354 switch (service_choice) {
10355 case 0: /* I-Am-Request */
10356 offset = fIAmRequest(tvb, pinfo, tree, offset);
10358 case 1: /* i-Have Request */
10359 offset = fIHaveRequest(tvb, pinfo, tree, offset);
10361 case 2: /* unconfirmedCOVNotification */
10362 offset = fUnconfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
10364 case 3: /* unconfirmedEventNotification */
10365 offset = fUnconfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
10367 case 4: /* unconfirmedPrivateTransfer */
10368 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
10370 case 5: /* unconfirmedTextMessage */
10371 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
10373 case 206: /* utc-time-synchronization-recipients */
10374 case 6: /* timeSynchronization */
10375 offset = fTimeSynchronizationRequest(tvb, pinfo, tree, offset);
10377 case 7: /* who-Has */
10378 offset = fWhoHas(tvb, pinfo, tree, offset);
10380 case 8: /* who-Is */
10381 offset = fWhoIsRequest(tvb, pinfo, tree, offset);
10383 case 9: /* utcTimeSynchronization */
10384 offset = fUTCTimeSynchronizationRequest(tvb, pinfo, tree, offset);
10393 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
10394 gint *svc, proto_item **tt)
10397 proto_tree *bacapp_tree_control;
10402 tmp = (gint) tvb_get_guint8(tvb, offset);
10403 bacapp_flags = tmp & 0x0f;
10408 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
10409 if (bacapp_flags & 0x08)
10410 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
10412 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10413 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
10414 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
10416 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
10417 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
10418 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
10419 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
10420 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
10421 offset, 1, ENC_BIG_ENDIAN);
10422 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
10423 offset, 1, ENC_BIG_ENDIAN);
10426 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
10427 if (bacapp_flags & 0x08) {
10428 bacapp_seq = tvb_get_guint8(tvb, offset);
10429 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
10430 offset++, 1, ENC_BIG_ENDIAN);
10431 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
10432 offset++, 1, ENC_BIG_ENDIAN);
10434 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
10435 offset++, 1, ENC_BIG_ENDIAN);
10440 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
10441 { /* BACnet-Confirmed-Request */
10442 /* ASHRAE 135-2001 20.1.2 */
10444 return fConfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, svc);
10448 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10449 { /* BACnet-Confirmed-Request */
10450 /* ASHRAE 135-2001 20.1.2 */
10452 proto_item *tt = 0;
10454 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
10455 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
10459 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10460 { /* BACnet-Unconfirmed-Request-PDU */
10461 /* ASHRAE 135-2001 20.1.3 */
10465 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10467 tmp = tvb_get_guint8(tvb, offset);
10468 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
10469 offset++, 1, ENC_BIG_ENDIAN);
10470 /* Service Request follows... Variable Encoding 20.2ff */
10471 return fUnconfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, tmp);
10475 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10476 { /* BACnet-Simple-Ack-PDU */
10477 /* ASHRAE 135-2001 20.1.4 */
10479 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10481 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
10482 offset++, 1, ENC_BIG_ENDIAN);
10483 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
10484 offset++, 1, ENC_BIG_ENDIAN);
10490 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
10491 { /* BACnet-Complex-Ack-PDU */
10492 /* ASHRAE 135-2001 20.1.5 */
10494 /* Service ACK follows... */
10495 return fConfirmedServiceAck(tvb, pinfo, bacapp_tree, offset, svc);
10499 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10500 { /* BACnet-Complex-Ack-PDU */
10501 /* ASHRAE 135-2001 20.1.5 */
10503 proto_item *tt = 0;
10505 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
10506 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
10510 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10511 { /* BACnet-SegmentAck-PDU */
10512 /* ASHRAE 135-2001 20.1.6 */
10515 proto_tree *bacapp_tree_control;
10517 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10518 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10520 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
10521 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10522 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10523 offset++, 1, ENC_BIG_ENDIAN);
10524 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
10525 offset++, 1, ENC_BIG_ENDIAN);
10526 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
10527 offset++, 1, ENC_BIG_ENDIAN);
10532 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10534 guint8 tag_info = 0;
10535 guint8 parsed_tag = 0;
10538 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
10539 offset = fError(tvb, pinfo, tree, offset);
10540 return offset + fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
10544 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10546 guint lastoffset = 0;
10547 guint8 tag_no = 0, tag_info = 0;
10549 proto_tree *subtree = tree;
10551 guint vendor_identifier = 0;
10552 guint service_number = 0;
10553 guint8 tag_len = 0;
10555 while (tvb_reported_length_remaining(tvb, offset) > 0) {
10556 /* exit loop if nothing happens inside */
10557 lastoffset = offset;
10558 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10560 case 0: /* errorType */
10561 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
10563 case 1: /* vendorID */
10564 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
10565 if (col_get_writable(pinfo->cinfo))
10566 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
10567 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
10569 case 2: /* serviceNumber */
10570 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
10571 if (col_get_writable(pinfo->cinfo))
10572 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
10573 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: ");
10575 case 3: /* errorParameters */
10576 if (tag_is_opening(tag_info)) {
10577 subtree = proto_tree_add_subtree(subtree, tvb, offset, 1,
10578 ett_bacapp_value, NULL, "error Parameters");
10579 propertyIdentifier = -1;
10580 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10581 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
10582 } else if (tag_is_closing(tag_info)) {
10583 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
10584 &tag_no, &tag_info, &lvt);
10587 /* error condition: let caller handle */
10594 if (offset == lastoffset) break; /* nothing happened, exit loop */
10600 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10602 guint lastoffset = 0;
10604 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10605 lastoffset = offset;
10606 switch (fTagNo(tvb, offset)) {
10607 case 0: /* errorType */
10608 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10610 case 1: /* firstFailedElementNumber */
10611 offset = fUnsignedTag(tvb, pinfo, tree, offset, "first failed element number: ");
10616 if (offset == lastoffset) break; /* nothing happened, exit loop */
10622 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10624 /* Identical to CreateObjectError */
10625 return fCreateObjectError(tvb, pinfo, tree, offset);
10629 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10631 guint8 tag_no = 0, tag_info = 0;
10634 if (fTagNo(tvb, offset) == 0) {
10636 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10637 if (fTagNo(tvb, offset) == 1) {
10638 /* listOfVTSessionIdentifiers [OPTIONAL] */
10639 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10640 offset = fVtCloseRequest(tvb, pinfo, tree, offset);
10641 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10644 /* should report bad packet if initial tag wasn't 0 */
10649 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10651 guint lastoffset = 0;
10652 guint8 tag_no = 0, tag_info = 0;
10655 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10656 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10657 lastoffset = offset;
10658 switch (fTagNo(tvb, offset)) {
10659 case 0: /* errorType */
10660 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10662 case 1: /* firstFailedWriteAttempt */
10663 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10664 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
10665 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10670 if (offset == lastoffset) break; /* nothing happened, exit loop */
10676 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10678 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
10679 "error Class: ", BACnetErrorClass, 64);
10680 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
10681 "error Code: ", BACnetErrorCode, 256);
10685 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
10688 case 8: /* no break here !!!! */
10690 offset = fChangeListError(tvb, pinfo, tree, offset);
10693 offset = fCreateObjectError(tvb, pinfo, tree, offset);
10696 offset = fWritePropertyMultipleError(tvb, pinfo, tree, offset);
10699 offset = fConfirmedPrivateTransferError(tvb, pinfo, tree, offset);
10702 offset = fVTCloseError(tvb, pinfo, tree, offset);
10705 return fError(tvb, pinfo, tree, offset);
10711 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10712 { /* BACnet-Error-PDU */
10713 /* ASHRAE 135-2001 20.1.7 */
10716 proto_tree *bacapp_tree_control;
10719 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10720 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10722 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10723 offset++, 1, ENC_BIG_ENDIAN);
10724 tmp = tvb_get_guint8(tvb, offset);
10725 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
10726 offset++, 1, ENC_BIG_ENDIAN);
10727 /* Error Handling follows... */
10728 return fBACnetError(tvb, pinfo, bacapp_tree, offset, tmp);
10732 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10733 { /* BACnet-Reject-PDU */
10734 /* ASHRAE 135-2001 20.1.8 */
10737 proto_tree *bacapp_tree_control;
10739 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10740 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10742 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10743 offset++, 1, ENC_BIG_ENDIAN);
10744 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
10745 offset++, 1, ENC_BIG_ENDIAN);
10750 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10751 { /* BACnet-Abort-PDU */
10752 /* ASHRAE 135-2001 20.1.9 */
10755 proto_tree *bacapp_tree_control;
10757 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10758 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10760 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10761 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10762 offset++, 1, ENC_BIG_ENDIAN);
10763 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
10764 offset++, 1, ENC_BIG_ENDIAN);
10769 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10771 guint8 flag, bacapp_type;
10774 flag = (gint) tvb_get_guint8(tvb, 0);
10775 bacapp_type = (flag >> 4) & 0x0f;
10781 /* ASHRAE 135-2001 20.1.1 */
10782 switch (bacapp_type) {
10783 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
10784 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
10786 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
10787 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
10789 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
10790 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
10792 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
10793 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
10795 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
10796 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
10798 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
10799 offset = fErrorPDU(tvb, pinfo, tree, offset);
10801 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
10802 offset = fRejectPDU(tvb, pinfo, tree, offset);
10804 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
10805 offset = fAbortPDU(tvb, pinfo, tree, offset);
10812 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10814 guint8 flag, bacapp_type;
10815 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
10816 tvbuff_t *new_tvb = NULL;
10818 guint8 bacapp_seqno = 0;
10819 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
10820 guint8 bacapp_invoke_id = 0;
10822 proto_tree *bacapp_tree = NULL;
10825 proto_item *tt = 0;
10828 /* Strings for BACnet Statistics */
10829 const gchar errstr[] = "ERROR: ";
10830 const gchar rejstr[] = "REJECTED: ";
10831 const gchar abortstr[] = "ABORTED: ";
10832 const gchar sackstr[] = " (SimpleAck)";
10833 const gchar cackstr[] = " (ComplexAck)";
10834 const gchar uconfsreqstr[] = " (Unconfirmed Service Request)";
10835 const gchar confsreqstr[] = " (Confirmed Service Request)";
10837 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
10838 col_clear(pinfo->cinfo, COL_INFO);
10840 flag = tvb_get_guint8(tvb, 0);
10841 bacapp_type = (flag >> 4) & 0x0f;
10843 /* show some descriptive text in the INFO column */
10844 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
10845 val_to_str_const(bacapp_type, BACnetTypeName, "# unknown APDU #"));
10847 bacinfo.service_type = NULL;
10848 bacinfo.invoke_id = NULL;
10849 bacinfo.instance_ident = NULL;
10850 bacinfo.object_ident = NULL;
10852 switch (bacapp_type) {
10853 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10854 /* segmented messages have 2 additional bytes */
10855 if (flag & BACAPP_SEGMENTED_REQUEST) {
10858 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
10859 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10860 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
10861 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
10862 bacapp_service = tvb_get_guint8(tvb, offset + 5);
10865 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10866 bacapp_service = tvb_get_guint8(tvb, offset + 3);
10868 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
10869 val_to_str_const(bacapp_service,
10870 BACnetConfirmedServiceChoice,
10871 bacapp_unknown_service_str),
10874 updateBacnetInfoValue(BACINFO_INVOKEID,
10875 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10877 updateBacnetInfoValue(BACINFO_SERVICE,
10878 wmem_strconcat(wmem_packet_scope(),
10879 val_to_str_const(bacapp_service,
10880 BACnetConfirmedServiceChoice,
10881 bacapp_unknown_service_str),
10882 confsreqstr, NULL));
10884 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
10885 bacapp_service = tvb_get_guint8(tvb, offset + 1);
10886 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
10887 val_to_str_const(bacapp_service,
10888 BACnetUnconfirmedServiceChoice,
10889 bacapp_unknown_service_str));
10891 updateBacnetInfoValue(BACINFO_SERVICE,
10892 wmem_strconcat(wmem_packet_scope(),
10893 val_to_str_const(bacapp_service,
10894 BACnetUnconfirmedServiceChoice,
10895 bacapp_unknown_service_str),
10896 uconfsreqstr, NULL));
10898 case BACAPP_TYPE_SIMPLE_ACK:
10899 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10900 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10901 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10902 val_to_str_const(bacapp_service,
10903 BACnetConfirmedServiceChoice,
10904 bacapp_unknown_service_str),
10907 updateBacnetInfoValue(BACINFO_INVOKEID,
10908 wmem_strdup_printf(wmem_packet_scope(),
10909 "Invoke ID: %d", bacapp_invoke_id));
10911 updateBacnetInfoValue(BACINFO_SERVICE,
10912 wmem_strconcat(wmem_packet_scope(),
10913 val_to_str_const(bacapp_service,
10914 BACnetConfirmedServiceChoice,
10915 bacapp_unknown_service_str),
10918 case BACAPP_TYPE_COMPLEX_ACK:
10919 /* segmented messages have 2 additional bytes */
10920 if (flag & BACAPP_SEGMENTED_REQUEST) {
10923 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
10924 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10925 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
10926 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
10927 bacapp_service = tvb_get_guint8(tvb, offset + 4);
10930 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10931 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10933 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10934 val_to_str_const(bacapp_service,
10935 BACnetConfirmedServiceChoice,
10936 bacapp_unknown_service_str),
10939 updateBacnetInfoValue(BACINFO_INVOKEID,
10940 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10942 updateBacnetInfoValue(BACINFO_SERVICE,
10943 wmem_strconcat(wmem_packet_scope(),
10944 val_to_str_const(bacapp_service,
10945 BACnetConfirmedServiceChoice,
10946 bacapp_unknown_service_str),
10949 case BACAPP_TYPE_SEGMENT_ACK:
10950 /* nothing more to add */
10952 case BACAPP_TYPE_ERROR:
10953 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10954 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10955 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10956 val_to_str_const(bacapp_service,
10957 BACnetConfirmedServiceChoice,
10958 bacapp_unknown_service_str),
10961 updateBacnetInfoValue(BACINFO_INVOKEID,
10962 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10964 updateBacnetInfoValue(BACINFO_SERVICE,
10965 wmem_strconcat(wmem_packet_scope(),
10967 val_to_str_const(bacapp_service,
10968 BACnetConfirmedServiceChoice,
10969 bacapp_unknown_service_str),
10972 case BACAPP_TYPE_REJECT:
10973 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10974 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10975 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10976 val_to_split_str(bacapp_reason,
10978 BACnetRejectReason,
10979 ASHRAE_Reserved_Fmt,
10980 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10982 updateBacnetInfoValue(BACINFO_INVOKEID,
10983 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10985 updateBacnetInfoValue(BACINFO_SERVICE,
10986 wmem_strconcat(wmem_packet_scope(), rejstr,
10987 val_to_split_str(bacapp_reason, 64,
10988 BACnetRejectReason,
10989 ASHRAE_Reserved_Fmt,
10990 Vendor_Proprietary_Fmt),
10993 case BACAPP_TYPE_ABORT:
10994 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10995 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10996 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10997 val_to_split_str(bacapp_reason,
11000 ASHRAE_Reserved_Fmt,
11001 Vendor_Proprietary_Fmt), bacapp_invoke_id);
11003 updateBacnetInfoValue(BACINFO_INVOKEID,
11004 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
11006 updateBacnetInfoValue(BACINFO_SERVICE,
11007 wmem_strconcat(wmem_packet_scope(), abortstr,
11008 val_to_split_str(bacapp_reason,
11011 ASHRAE_Reserved_Fmt,
11012 Vendor_Proprietary_Fmt),
11017 /* nothing more to add */
11021 save_fragmented = pinfo->fragmented;
11023 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA);
11024 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
11027 do_the_dissection(tvb, pinfo, bacapp_tree);
11029 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
11030 /* not resetting the offset so the remaining can be done */
11032 if (fragment) { /* fragmented */
11033 fragment_head *frag_msg;
11035 pinfo->fragmented = TRUE;
11037 frag_msg = fragment_add_seq_check(&msg_reassembly_table,
11040 bacapp_invoke_id, /* ID for fragments belonging together */
11042 bacapp_seqno, /* fragment sequence number */
11043 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
11044 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
11045 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
11046 "Reassembled BACapp", frag_msg, &msg_frag_items,
11049 if (new_tvb) { /* Reassembled */
11050 col_append_str(pinfo->cinfo, COL_INFO,
11051 " (Message Reassembled)");
11052 } else { /* Not last packet of reassembled Short Message */
11053 col_append_fstr(pinfo->cinfo, COL_INFO,
11054 " (Message fragment %u)", bacapp_seqno);
11056 if (new_tvb) { /* take it all */
11057 switch (bacapp_type) {
11058 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
11059 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
11061 case BACAPP_TYPE_COMPLEX_ACK:
11062 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
11071 pinfo->fragmented = save_fragmented;
11074 tap_queue_packet(bacapp_tap, pinfo, &bacinfo);
11078 bacapp_init_routine(void)
11080 reassembly_table_init(&msg_reassembly_table,
11081 &addresses_reassembly_table_functions);
11085 proto_register_bacapp(void)
11087 static hf_register_info hf[] = {
11089 { "APDU Type", "bacapp.type",
11090 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
11092 { &hf_bacapp_pduflags,
11093 { "PDU Flags", "bacapp.pduflags",
11094 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
11097 { "Segmented Request", "bacapp.segmented_request",
11098 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
11101 { "More Segments", "bacapp.more_segments",
11102 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
11105 { "SA", "bacapp.SA",
11106 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
11108 { &hf_bacapp_max_adpu_size,
11109 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
11110 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
11112 { &hf_bacapp_response_segments,
11113 { "Max Response Segments accepted", "bacapp.response_segments",
11114 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
11116 { &hf_bacapp_objectType,
11117 { "Object Type", "bacapp.objectType",
11118 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
11120 { &hf_bacapp_instanceNumber,
11121 { "Instance Number", "bacapp.instance_number",
11122 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
11124 { &hf_BACnetPropertyIdentifier,
11125 { "Property Identifier", "bacapp.property_identifier",
11126 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
11128 { &hf_BACnetVendorIdentifier,
11129 { "Vendor Identifier", "bacapp.vendor_identifier",
11130 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &BACnetVendorIdentifiers_ext, 0, NULL, HFILL }
11132 { &hf_BACnetRestartReason,
11133 { "Restart Reason", "bacapp.restart_reason",
11134 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
11136 { &hf_bacapp_invoke_id,
11137 { "Invoke ID", "bacapp.invoke_id",
11138 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11140 { &hf_bacapp_sequence_number,
11141 { "Sequence Number", "bacapp.sequence_number",
11142 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11144 { &hf_bacapp_window_size,
11145 { "Proposed Window Size", "bacapp.window_size",
11146 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11148 { &hf_bacapp_service,
11149 { "Service Choice", "bacapp.confirmed_service",
11150 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
11152 { &hf_bacapp_uservice,
11153 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
11154 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
11157 { "NAK", "bacapp.NAK",
11158 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
11161 { "SRV", "bacapp.SRV",
11162 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
11164 { &hf_Device_Instance_Range_Low_Limit,
11165 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
11166 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
11168 { &hf_Device_Instance_Range_High_Limit,
11169 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
11170 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
11172 { &hf_BACnetRejectReason,
11173 { "Reject Reason", "bacapp.reject_reason",
11174 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
11176 { &hf_BACnetAbortReason,
11177 { "Abort Reason", "bacapp.abort_reason",
11178 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
11180 { &hf_BACnetApplicationTagNumber,
11181 { "Application Tag Number",
11182 "bacapp.application_tag_number",
11183 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
11186 { &hf_BACnetContextTagNumber,
11187 { "Context Tag Number",
11188 "bacapp.context_tag_number",
11189 FT_UINT8, BASE_DEC, NULL, 0xF0,
11192 { &hf_BACnetExtendedTagNumber,
11193 { "Extended Tag Number",
11194 "bacapp.extended_tag_number",
11195 FT_UINT8, BASE_DEC, NULL, 0,
11198 { &hf_BACnetNamedTag,
11200 "bacapp.named_tag",
11201 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
11204 { &hf_BACnetCharacterSet,
11205 { "String Character Set",
11206 "bacapp.string_character_set",
11207 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet), 0,
11210 { &hf_BACnetTagClass,
11211 { "Tag Class", "bacapp.tag_class",
11212 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
11214 { &hf_bacapp_tag_lvt,
11215 { "Length Value Type",
11217 FT_UINT8, BASE_DEC, NULL, 0,
11220 { &hf_bacapp_tag_ProcessId,
11221 { "ProcessIdentifier", "bacapp.processId",
11222 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
11224 { &hf_bacapp_tag_IPV4,
11225 { "IPV4", "bacapp.IPV4",
11226 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
11228 { &hf_bacapp_tag_IPV6,
11229 { "IPV6", "bacapp.IPV6",
11230 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
11232 { &hf_bacapp_tag_PORT,
11233 { "Port", "bacapp.Port",
11234 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
11236 {&hf_msg_fragments,
11237 {"Message fragments", "bacapp.fragments",
11238 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11240 {"Message fragment", "bacapp.fragment",
11241 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11242 {&hf_msg_fragment_overlap,
11243 {"Message fragment overlap", "bacapp.fragment.overlap",
11244 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11245 {&hf_msg_fragment_overlap_conflicts,
11246 {"Message fragment overlapping with conflicting data",
11247 "bacapp.fragment.overlap.conflicts",
11248 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11249 {&hf_msg_fragment_multiple_tails,
11250 {"Message has multiple tail fragments",
11251 "bacapp.fragment.multiple_tails",
11252 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11253 {&hf_msg_fragment_too_long_fragment,
11254 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
11255 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11256 {&hf_msg_fragment_error,
11257 {"Message defragmentation error", "bacapp.fragment.error",
11258 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11259 {&hf_msg_fragment_count,
11260 {"Message fragment count", "bacapp.fragment.count",
11261 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
11262 {&hf_msg_reassembled_in,
11263 {"Reassembled in", "bacapp.reassembled.in",
11264 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11265 {&hf_msg_reassembled_length,
11266 {"Reassembled BACapp length", "bacapp.reassembled.length",
11267 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
11269 static gint *ett[] = {
11271 &ett_bacapp_control,
11280 static ei_register_info ei[] = {
11281 { &ei_bacapp_bad_length, { "bacapp.bad_length", PI_MALFORMED, PI_ERROR, "Wrong length indicated", EXPFILL }},
11284 expert_module_t* expert_bacapp;
11286 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
11287 "BACapp", "bacapp");
11289 proto_register_field_array(proto_bacapp, hf, array_length(hf));
11290 proto_register_subtree_array(ett, array_length(ett));
11291 expert_bacapp = expert_register_protocol(proto_bacapp);
11292 expert_register_field_array(expert_bacapp, ei, array_length(ei));
11293 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
11294 register_init_routine(&bacapp_init_routine);
11296 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
11297 "BACapp Vendor Identifier",
11298 FT_UINT8, BASE_HEX);
11300 /* Register BACnet Statistic trees */
11301 register_bacapp_stat_trees();
11302 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
11306 * Editor modelines - http://www.wireshark.org/tools/modelines.html
11309 * c-basic-offset: 4
11311 * indent-tabs-mode: nil
11314 * vi: set shiftwidth=4 tabstop=8 expandtab:
11315 * :indentSize=4:tabSize=8:noTabs=true: