2 * Routines for BACnet (APDU) dissection
3 * Copyright 2001, Hartmut Mueller <hartmut[AT]abmlinux.org>, FH Dortmund
4 * Enhanced by Steve Karg, 2005, <skarg[AT]users.sourceforge.net>, Atlanta
5 * Enhanced by Herbert Lischka, 2005, <lischka[AT]kieback-peter.de>, Berlin
6 * Enhanced by Felix Kraemer, 2010, <sauter-cumulus[AT]de.sauter-bc.com>,
7 * Sauter-Cumulus GmbH, Freiburg
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald[AT]wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include <epan/packet.h>
35 #include <epan/to_str.h>
36 #include <epan/wmem/wmem.h>
37 #include <epan/reassemble.h>
38 #include <epan/expert.h>
39 #include <epan/stats_tree.h>
40 #include "packet-bacapp.h"
42 static int bacapp_tap = -1;
44 /* formerly bacapp.h contains definitions and forward declarations */
47 #define FAULT proto_tree_add_text(subtree, tvb, offset, tvb_length(tvb) - offset, "something is going wrong here !!"); \
48 offset = tvb_length(tvb);
51 /* BACnet PDU Types */
52 #define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0
53 #define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1
54 #define BACAPP_TYPE_SIMPLE_ACK 2
55 #define BACAPP_TYPE_COMPLEX_ACK 3
56 #define BACAPP_TYPE_SEGMENT_ACK 4
57 #define BACAPP_TYPE_ERROR 5
58 #define BACAPP_TYPE_REJECT 6
59 #define BACAPP_TYPE_ABORT 7
60 #define MAX_BACAPP_TYPE 8
62 #define BACAPP_SEGMENTED_REQUEST 0x08
63 #define BACAPP_MORE_SEGMENTS 0x04
64 #define BACAPP_SEGMENTED_RESPONSE 0x02
65 #define BACAPP_SEGMENT_NAK 0x02
66 #define BACAPP_SENT_BY 0x01
70 * dissect_bacapp ::= CHOICE {
71 * confirmed-request-PDU [0] BACnet-Confirmed-Request-PDU,
72 * unconfirmed-request-PDU [1] BACnet-Unconfirmed-Request-PDU,
73 * simpleACK-PDU [2] BACnet-SimpleACK-PDU,
74 * complexACK-PDU [3] BACnet-ComplexACK-PDU,
75 * segmentACK-PDU [4] BACnet-SegmentACK-PDU,
76 * error-PDU [5] BACnet-Error-PDU,
77 * reject-PDU [6] BACnet-Reject-PDU,
78 * abort-PDU [7] BACnet-Abort-PDU
80 * @param tvb the tv buffer of the current data
81 * @param pinfo the packet info of the current data
82 * @param tree the tree to append this item to
85 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
88 * ConfirmedRequest-PDU ::= SEQUENCE {
89 * pdu-type [0] Unsigned (0..15), -- 0 for this PDU Type
90 * segmentedMessage [1] BOOLEAN,
91 * moreFollows [2] BOOLEAN,
92 * segmented-response-accepted [3] BOOLEAN,
93 * reserved [4] Unsigned (0..3), -- must be set zero
94 * max-segments-accepted [5] Unsigned (0..7), -- as per 20.1.2.4
95 * max-APDU-length-accepted [5] Unsigned (0..15), -- as per 20.1.2.5
96 * invokeID [6] Unsigned (0..255),
97 * sequence-number [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
98 * proposed-window-size [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
99 * service-choice [9] BACnetConfirmedServiceChoice,
100 * service-request [10] BACnet-Confirmed-Service-Request OPTIONAL
102 * @param tvb the tv buffer of the current data
103 * @param pinfo the packet info of the current data
104 * @param tree the tree to append this item to
105 * @param offset the offset in the tvb
106 * @return modified offset
109 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
112 * @param tvb the tv buffer of the current data
113 * @param pinfo the packet info of the current data
114 * @param tree the tree to append this item to
115 * @param offset the offset in the tvb
116 * @param ack - indocates whether working on request or ack
117 * @param svc - output variable to return service choice
118 * @param tt - output varable to return service choice item
119 * @return modified offset
122 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 ack,
123 gint *svc, proto_item **tt);
126 * Unconfirmed-Request-PDU ::= SEQUENCE {
127 * pdu-type [0] Unsigned (0..15), -- 1 for this PDU type
128 * reserved [1] Unsigned (0..15), -- must be set zero
129 * service-choice [2] BACnetUnconfirmedServiceChoice,
130 * service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
132 * @param tvb the tv buffer of the current data
133 * @param pinfo the packet info of the current data
134 * @param tree the tree to append this item to
135 * @param offset the offset in the tvb
136 * @return modified offset
139 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
142 * SimpleACK-PDU ::= SEQUENCE {
143 * pdu-type [0] Unsigned (0..15), -- 2 for this PDU type
144 * reserved [1] Unsigned (0..15), -- must be set zero
145 * invokeID [2] Unsigned (0..255),
146 * service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
148 * @param tvb the tv buffer of the current data
149 * @param pinfo the packet info of the current data
150 * @param tree the tree to append this item to
151 * @param offset the offset in the tvb
152 * @return modified offset
155 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
158 * ComplexACK-PDU ::= SEQUENCE {
159 * pdu-type [0] Unsigned (0..15), -- 3 for this PDU Type
160 * segmentedMessage [1] BOOLEAN,
161 * moreFollows [2] BOOLEAN,
162 * reserved [3] Unsigned (0..3), -- must be set zero
163 * invokeID [4] Unsigned (0..255),
164 * sequence-number [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
165 * proposed-window-size [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
166 * service-ACK-choice [7] BACnetConfirmedServiceChoice,
167 * service-ACK [8] BACnet-Confirmed-Service-Request -- Context-specific tags 0..8 are NOT used in header encoding
169 * @param tvb the tv buffer of the current data
170 * @param pinfo the packet info of the current data
171 * @param tree the tree to append this item to
172 * @param offset the offset in the tvb
173 * @return modified offset
176 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
179 * SegmentACK-PDU ::= SEQUENCE {
180 * pdu-type [0] Unsigned (0..15), -- 4 for this PDU Type
181 * reserved [1] Unsigned (0..3), -- must be set zero
182 * negative-ACK [2] BOOLEAN,
183 * server [3] BOOLEAN,
184 * original-invokeID [4] Unsigned (0..255),
185 * sequence-number [5] Unsigned (0..255),
186 * actual-window-size [6] Unsigned (0..127)
188 * @param tvb the tv buffer of the current data
189 * @param pinfo the packet info of the current data
190 * @param tree the tree to append this item to
191 * @param offset the offset in the tvb
192 * @return modified offset
195 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
198 * Error-PDU ::= SEQUENCE {
199 * pdu-type [0] Unsigned (0..15), -- 5 for this PDU Type
200 * reserved [1] Unsigned (0..3), -- must be set zero
201 * original-invokeID [2] Unsigned (0..255),
202 * error-choice [3] BACnetConfirmedServiceChoice,
203 * error [4] BACnet-Error
205 * @param tvb the tv buffer of the current data
206 * @param pinfo the packet info of the current data
207 * @param tree the tree to append this item to
208 * @param offset the offset in the tvb
209 * @return modified offset
212 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
215 * Reject-PDU ::= SEQUENCE {
216 * pdu-type [0] Unsigned (0..15), -- 6 for this PDU Type
217 * reserved [1] Unsigned (0..3), -- must be set zero
218 * original-invokeID [2] Unsigned (0..255),
219 * reject-reason [3] BACnetRejectReason
221 * @param tvb the tv buffer of the current data
222 * @param pinfo the packet info of the current data
223 * @param tree the tree to append this item to
224 * @param offset the offset in the tvb
225 * @return modified offset
228 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
231 * Abort-PDU ::= SEQUENCE {
232 * pdu-type [0] Unsigned (0..15), -- 7 for this PDU Type
233 * reserved [1] Unsigned (0..3), -- must be set zero
234 * server [2] BOOLEAN,
235 * original-invokeID [3] Unsigned (0..255),
236 * abort-reason [4] BACnetAbortReason
238 * @param tvb the tv buffer of the current data
239 * @param pinfo the packet info of the current data
240 * @param tree the tree to append this item to
241 * @param offset the offset in the tvb
242 * @return modified offset
245 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
248 * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree
249 * @param tvb the tv buffer of the current data
250 * @param pinfo the packet info of the current data
251 * @param tree the tree to append this item to
252 * @param offset the offset in the tvb
253 * @param label the label of this item
254 * @return modified offset
257 fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
260 * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
261 * @param tvb the tv buffer of the current data
262 * @param pinfo the packet info of the current data
263 * @param tree the tree to append this item to
264 * @param offset the offset in the tvb
265 * @param label the label of this item
266 * @return modified offset
269 fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
272 * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
273 * @param tvb the tv buffer of the current data
274 * @param pinfo the packet info of the current data
275 * @param tree the tree to append this item to
276 * @param offset the offset in the tvb
277 * @param label the label of this item
278 * @param lvt length of String
279 * @return modified offset
282 fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
285 * 20.2.12, adds the label with Date Value to tree
286 * @param tvb the tv buffer of the current data
287 * @param pinfo the packet info of the current data
288 * @param tree the tree to append this item to
289 * @param offset the offset in the tvb
290 * @param label the label of this item
291 * @return modified offset
294 fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
297 * 20.2.13, adds the label with Time Value to tree
298 * @param tvb the tv buffer of the current data
299 * @param pinfo the packet info of the current data
300 * @param tree the tree to append this item to
301 * @param offset the offset in the tvb
302 * @param label the label of this item
303 * @return modified offset
306 fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
309 * 20.2.14, adds Object Identifier to tree
310 * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
311 * @param tvb the tv buffer of the current data
312 * @param pinfo the packet info of the current data
313 * @param tree the tree to append this item to
314 * @param offset the offset in the tvb
315 * @return modified offset
318 fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
321 * BACnet-Confirmed-Service-Request ::= CHOICE {
323 * @param tvb the tv buffer of the current data
324 * @param pinfo the packet info of the current data
325 * @param tree the tree to append this item to
326 * @param offset the offset in the tvb
327 * @param service_choice the service choice
331 fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
334 * BACnet-Confirmed-Service-ACK ::= CHOICE {
336 * @param tvb the tv buffer of the current data
337 * @param pinfo the packet info of the current data
338 * @param tree the tree to append this item to
339 * @param offset the offset in the tvb
340 * @param service_choice the service choice
344 fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
347 * AcknowledgeAlarm-Request ::= SEQUENCE {
348 * acknowledgingProcessIdentifier [0] Unsigned32,
349 * eventObjectIdentifier [1] BACnetObjectIdentifer,
350 * eventStateAcknowledge [2] BACnetEventState,
351 * timeStamp [3] BACnetTimeStamp,
352 * acknowledgementSource [4] Character String,
353 * timeOfAcknowledgement [5] BACnetTimeStamp
355 * @param tvb the tv buffer of the current data
356 * @param pinfo the packet info of the current data
357 * @param tree the tree to append this item to
358 * @param offset the offset in the tvb
359 * @return modified offset
362 fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
365 * ConfirmedCOVNotification-Request ::= SEQUENCE {
366 * subscriberProcessIdentifier [0] Unsigned32,
367 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
368 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
369 * timeRemaining [3] unsigned,
370 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
372 * @param tvb the tv buffer of the current data
373 * @param pinfo the packet info of the current data
374 * @param tree the tree to append this item to
375 * @param offset the offset in the tvb
376 * @return modified offset
379 fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
382 * ConfirmedEventNotification-Request ::= SEQUENCE {
383 * ProcessIdentifier [0] Unsigned32,
384 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
385 * eventObjectIdentifier [2] BACnetObjectIdentifer,
386 * timeStamp [3] BACnetTimeStamp,
387 * notificationClass [4] unsigned,
388 * priority [5] unsigned8,
389 * eventType [6] BACnetEventType,
390 * messageText [7] CharacterString OPTIONAL,
391 * notifyType [8] BACnetNotifyType,
392 * ackRequired [9] BOOLEAN OPTIONAL,
393 * fromState [10] BACnetEventState OPTIONAL,
394 * toState [11] BACnetEventState,
395 * eventValues [12] BACnetNotificationParameters OPTIONAL
397 * @param tvb the tv buffer of the current data
398 * @param pinfo the packet info of the current data
399 * @param tree the tree to append this item to
400 * @param offset the offset in the tvb
401 * @return modified offset
404 fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
407 * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
408 * objectIdentifier BACnetObjectIdentifer,
409 * alarmState BACnetEventState,
410 * acknowledgedTransitions BACnetEventTransitionBits
412 * @param tvb the tv buffer of the current data
413 * @param pinfo the packet info of the current data
414 * @param tree the tree to append this item to
415 * @param offset the offset in the tvb
416 * @return modified offset
419 fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
422 * GetEnrollmentSummary-Request ::= SEQUENCE {
423 * acknowledgmentFilter [0] ENUMERATED {
428 * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL,
429 * eventStateFilter [2] ENUMERATED {
436 * eventTypeFilter [3] BACnetEventType OPTIONAL,
437 * priorityFilter [4] SEQUENCE {
438 * minPriority [0] Unsigned8,
439 * maxPriority [1] Unsigned8
441 * notificationClassFilter [5] Unsigned OPTIONAL
443 * @param tvb the tv buffer of the current data
444 * @param pinfo the packet info of the current data
445 * @param tree the tree to append this item to
446 * @param offset the offset in the tvb
447 * @return modified offset
450 fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
453 * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
454 * objectIdentifier BACnetObjectIdentifer,
455 * eventType BACnetEventType,
456 * eventState BACnetEventState,
457 * priority Unsigned8,
458 * notificationClass Unsigned OPTIONAL
460 * @param tvb the tv buffer of the current data
461 * @param pinfo the packet info of the current data
462 * @param tree the tree to append this item to
463 * @param offset the offset in the tvb
464 * @return modified offset
467 fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
470 * GetEventInformation-Request ::= SEQUENCE {
471 * lastReceivedObjectIdentifier [0] BACnetObjectIdentifer
473 * @param tvb the tv buffer of the current data
474 * @param pinfo the packet info of the current data
475 * @param tree the tree to append this item to
476 * @param offset the offset in the tvb
477 * @return modified offset
480 fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
483 * GetEventInformation-ACK ::= SEQUENCE {
484 * listOfEventSummaries [0] listOfEventSummaries,
485 * moreEvents [1] BOOLEAN
487 * @param tvb the tv buffer of the current data
488 * @param pinfo the packet info of the current data
489 * @param tree the tree to append this item to
490 * @param offset the offset in the tvb
491 * @return modified offset
494 fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
497 * LifeSafetyOperation-Request ::= SEQUENCE {
498 * requestingProcessIdentifier [0] Unsigned32
499 * requestingSource [1] CharacterString
500 * request [2] BACnetLifeSafetyOperation
501 * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL
503 * @param tvb the tv buffer of the current data
504 * @param pinfo the packet info of the current data
505 * @param tree the tree to append this item to
506 * @param offset the offset in the tvb
507 * @return modified offset
510 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
513 * SubscribeCOV-Request ::= SEQUENCE {
514 * subscriberProcessIdentifier [0] Unsigned32
515 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
516 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
517 * lifetime [3] Unsigned OPTIONAL
519 * @param tvb the tv buffer of the current data
520 * @param pinfo the packet info of the current data
521 * @param tree the tree to append this item to
522 * @param offset the offset in the tvb
523 * @return modified offset
526 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
529 * SubscribeCOVProperty-Request ::= SEQUENCE {
530 * subscriberProcessIdentifier [0] Unsigned32
531 * monitoredObjectIdentifier [1] BACnetObjectIdentifier
532 * issueConfirmedNotifications [2] BOOLEAN OPTIONAL
533 * lifetime [3] Unsigned OPTIONAL
534 * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
535 * covIncrement [5] Unsigned OPTIONAL
537 * @param tvb the tv buffer of the current data
538 * @param pinfo the packet info of the current data
539 * @param tree the tree to append this item to
540 * @param offset the offset in the tvb
541 * @return modified offset
544 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
547 * AtomicReadFile-Request ::= SEQUENCE {
548 * fileIdentifier BACnetObjectIdentifier,
549 * accessMethod CHOICE {
550 * streamAccess [0] SEQUENCE {
551 * fileStartPosition INTEGER,
552 * requestedOctetCount Unsigned
554 * recordAccess [1] SEQUENCE {
555 * fileStartRecord INTEGER,
556 * requestedRecordCount Unsigned
560 * @param tvb the tv buffer of the current data
561 * @param pinfo the packet info of the current data
562 * @param tree the tree to append this item to
563 * @param offset the offset in the tvb
564 * @return modified offset
567 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
570 * AtomicWriteFile-ACK ::= SEQUENCE {
572 * accessMethod CHOICE {
573 * streamAccess [0] SEQUENCE {
574 * fileStartPosition INTEGER,
575 * fileData OCTET STRING
577 * recordAccess [1] SEQUENCE {
578 * fileStartRecord INTEGER,
579 * returnedRecordCount Unsigned,
580 * fileRecordData SEQUENCE OF OCTET STRING
584 * @param tvb the tv buffer of the current data
585 * @param pinfo the packet info of the current data
586 * @param tree the tree to append this item to
587 * @param offset the offset in the tvb
588 * @return modified offset
591 fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
594 * AtomicWriteFile-Request ::= SEQUENCE {
595 * fileIdentifier BACnetObjectIdentifier,
596 * accessMethod CHOICE {
597 * streamAccess [0] SEQUENCE {
598 * fileStartPosition INTEGER,
599 * fileData OCTET STRING
601 * recordAccess [1] SEQUENCE {
602 * fileStartRecord INTEGER,
603 * recordCount Unsigned,
604 * fileRecordData SEQUENCE OF OCTET STRING
608 * @param tvb the tv buffer of the current data
609 * @param pinfo the packet info of the current data
610 * @param tree the tree to append this item to
611 * @param offset the offset in the tvb
612 * @return modified offset
615 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
618 * AtomicWriteFile-ACK ::= SEQUENCE {
619 * fileStartPosition [0] INTEGER,
620 * fileStartRecord [1] INTEGER,
622 * @param tvb the tv buffer of the current data
623 * @param pinfo the packet info of the current data
624 * @param tree the tree to append this item to
625 * @param offset the offset in the tvb
626 * @return modified offset
629 fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
632 * AddListElement-Request ::= SEQUENCE {
633 * objectIdentifier [0] BACnetObjectIdentifier,
634 * propertyIdentifier [1] BACnetPropertyIdentifier,
635 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
636 * listOfElements [3] ABSTRACT-SYNTAX.&Type
638 * @param tvb the tv buffer of the current data
639 * @param pinfo the packet info of the current data
640 * @param tree the tree to append this item to
641 * @param offset the offset in the tvb
642 * @return modified offset
645 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
648 * CreateObject-Request ::= SEQUENCE {
649 * objectSpecifier [0] ObjectSpecifier,
650 * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
652 * @param tvb the tv buffer of the current data
653 * @param pinfo the packet info of the current data
654 * @param subtree the sub tree to append this item to
655 * @param offset the offset in the tvb
656 * @return modified offset
659 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
662 * CreateObject-Request ::= BACnetObjectIdentifier
663 * @param tvb the tv buffer of the current data
664 * @param pinfo the packet info of the current data
665 * @param tree the tree to append this item to
666 * @param offset the offset in the tvb
667 * @return modified offset
670 fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
673 * DeleteObject-Request ::= SEQUENCE {
674 * ObjectIdentifier BACnetObjectIdentifer
676 * @param tvb the tv buffer of the current data
677 * @param pinfo the packet info of the current data
678 * @param tree the tree to append this item to
679 * @param offset the offset in the tvb
680 * @return modified offset
683 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
686 * ReadProperty-Request ::= SEQUENCE {
687 * objectIdentifier [0] BACnetObjectIdentifier,
688 * propertyIdentifier [1] BACnetPropertyIdentifier,
689 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
691 * @param tvb the tv buffer of the current data
692 * @param pinfo the packet info of the current data
693 * @param tree the tree to append this item to
694 * @param offset the offset in the tvb
695 * @return modified offset
698 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
701 * ReadProperty-ACK ::= SEQUENCE {
702 * objectIdentifier [0] BACnetObjectIdentifier,
703 * propertyIdentifier [1] BACnetPropertyIdentifier,
704 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
705 * propertyValue [3] ABSTRACT-SYNTAX.&Type
707 * @param tvb the tv buffer of the current data
708 * @param pinfo the packet info of the current data
709 * @param tree the tree to append this item to
710 * @param offset the offset in the tvb
711 * @return modified offset
714 fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
717 * ReadPropertyConditional-Request ::= SEQUENCE {
718 * objectSelectionCriteria [0] objectSelectionCriteria,
719 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
721 * @param tvb the tv buffer of the current data
722 * @param pinfo the packet info of the current data
723 * @param subtree the sub tree to append this item to
724 * @param offset the offset in the tvb
725 * @return modified offset
728 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
731 * ReadPropertyConditional-ACK ::= SEQUENCE {
732 * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL
734 * @param tvb the tv buffer of the current data
735 * @param pinfo the packet info of the current data
736 * @param tree the tree to append this item to
737 * @param offset the offset in the tvb
738 * @return modified offset
741 fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
744 * ReadPropertyMultiple-Request ::= SEQUENCE {
745 * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification
747 * @param tvb the tv buffer of the current data
748 * @param pinfo the packet info of the current data
749 * @param subtree the sub tree to append this item to
750 * @param offset the offset in the tvb
751 * @return offset modified
754 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
757 * ReadPropertyMultiple-Ack ::= SEQUENCE {
758 * listOfReadAccessResults SEQUENCE OF ReadAccessResult
760 * @param tvb the tv buffer of the current data
762 * @param tree the tree to append this item to
763 * @param offset the offset in the tvb
764 * @return offset modified
767 fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
770 * ReadRange-Request ::= SEQUENCE {
771 * objectIdentifier [0] BACnetObjectIdentifier,
772 * propertyIdentifier [1] BACnetPropertyIdentifier,
773 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
775 * byPosition [3] SEQUENCE {
776 * referencedIndex Unsigned,
779 * byTime [4] SEQUENCE {
780 * referenceTime BACnetDateTime,
783 * timeRange [5] SEQUENCE {
784 * beginningTime BACnetDateTime,
785 * endingTime BACnetDateTime
789 * @param tvb the tv buffer of the current data
790 * @param pinfo the packet info of the current data
791 * @param tree the tree to append this item to
792 * @param offset the offset in the tvb
793 * @return modified offset
796 fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
799 * ReadRange-ACK ::= SEQUENCE {
800 * objectIdentifier [0] BACnetObjectIdentifier,
801 * propertyIdentifier [1] BACnetPropertyIdentifier,
802 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
803 * resultFlags [3] BACnetResultFlags,
804 * itemCount [4] Unsigned,
805 * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
807 * @param tvb the tv buffer of the current data
808 * @param pinfo the packet info of the current data
809 * @param tree the tree to append this item to
810 * @param offset the offset in the tvb
811 * @return modified offset
814 fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
817 * RemoveListElement-Request ::= SEQUENCE {
818 * objectIdentifier [0] BACnetObjectIdentifier,
819 * propertyIdentifier [1] BACnetPropertyIdentifier,
820 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
821 * listOfElements [3] ABSTRACT-SYNTAX.&Type
823 * @param tvb the tv buffer of the current data
824 * @param pinfo the packet info of the current data
825 * @param tree the tree to append this item to
826 * @param offset the offset in the tvb
827 * @return modified offset
830 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
833 * WriteProperty-Request ::= SEQUENCE {
834 * objectIdentifier [0] BACnetObjectIdentifier,
835 * propertyIdentifier [1] BACnetPropertyIdentifier,
836 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
837 * propertyValue [3] ABSTRACT-SYNTAX.&Type
838 * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
840 * @param tvb the tv buffer of the current data
841 * @param pinfo the packet info of the current data
842 * @param tree the tree to append this item to
843 * @param offset the offset in the tvb
844 * @return modified offset
847 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
850 * WritePropertyMultiple-Request ::= SEQUENCE {
851 * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
853 * @param tvb the tv buffer of the current data
854 * @param pinfo the packet info of the current data
855 * @param tree the tree to append this item to
856 * @param offset the offset in the tvb
857 * @return modified offset
860 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
863 * DeviceCommunicationControl-Request ::= SEQUENCE {
864 * timeDuration [0] Unsigned16 OPTIONAL,
865 * enable-disable [1] ENUMERATED {
869 * password [2] CharacterString (SIZE(1..20)) OPTIONAL
871 * @param tvb the tv buffer of the current data
872 * @param pinfo the packet info of the current data
873 * @param tree the tree to append this item to
874 * @param offset the offset in the tvb
875 * @return modified offset
878 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
881 * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
882 * vendorID [0] Unsigned,
883 * serviceNumber [1] Unsigned,
884 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
886 * @param tvb the tv buffer of the current data
887 * @param pinfo the packet info of the current data
888 * @param tree the tree to append this item to
889 * @param offset the offset in the tvb
890 * @return modified offset
893 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
896 * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
897 * vendorID [0] Unsigned,
898 * serviceNumber [1] Unsigned,
899 * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL
901 * @param tvb the tv buffer of the current data
902 * @param pinfo the packet info of the current data
903 * @param tree the tree to append this item to
904 * @param offset the offset in the tvb
905 * @return modified offset
908 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
911 * ConfirmedTextMessage-Request ::= SEQUENCE {
912 * textMessageSourceDevice [0] BACnetObjectIdentifier,
913 * messageClass [1] CHOICE {
914 * numeric [0] Unsigned,
915 * character [1] CharacterString
917 * messagePriority [2] ENUMERATED {
921 * message [3] CharacterString
923 * @param tvb the tv buffer of the current data
924 * @param pinfo the packet info of the current data
925 * @param tree the tree to append this item to
926 * @param offset the offset in the tvb
927 * @return modified offset
930 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
933 * ReinitializeDevice-Request ::= SEQUENCE {
934 * reinitializedStateOfDevice [0] ENUMERATED {
943 * password [1] CharacterString (SIZE(1..20)) OPTIONAL
945 * @param tvb the tv buffer of the current data
946 * @param pinfo the packet info of the current data
947 * @param tree the tree to append this item to
948 * @param offset the offset in the tvb
949 * @return modified offset
952 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
955 * VTOpen-Request ::= SEQUENCE {
956 * vtClass BACnetVTClass,
957 * localVTSessionIdentifier Unsigned8
959 * @param tvb the tv buffer of the current data
960 * @param pinfo the packet info of the current data
961 * @param tree the tree to append this item to
962 * @param offset the offset in the tvb
963 * @return modified offset
966 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
969 * VTOpen-ACK ::= SEQUENCE {
970 * remoteVTSessionIdentifier Unsigned8
972 * @param tvb the tv buffer of the current data
973 * @param pinfo the packet info of the current data
974 * @param tree the tree to append this item to
975 * @param offset the offset in the tvb
976 * @return modified offset
979 fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
982 * VTClose-Request ::= SEQUENCE {
983 * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8
985 * @param tvb the tv buffer of the current data
986 * @param pinfo the packet info of the current data
987 * @param tree the tree to append this item to
988 * @param offset the offset in the tvb
989 * @return modified offset
992 fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
995 * VTData-Request ::= SEQUENCE {
996 * vtSessionIdentifier Unsigned8,
997 * vtNewData OCTET STRING,
998 * vtDataFlag Unsigned (0..1)
1000 * @param tvb the tv buffer of the current data
1001 * @param pinfo the packet info of the current data
1002 * @param tree the tree to append this item to
1003 * @param offset the offset in the tvb
1004 * @return modified offset
1007 fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1010 * VTData-ACK ::= SEQUENCE {
1011 * allNewDataAccepted [0] BOOLEAN,
1012 * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
1014 * @param tvb the tv buffer of the current data
1015 * @param pinfo the packet info of the current data
1016 * @param tree the tree to append this item to
1017 * @param offset the offset in the tvb
1018 * @return modified offset
1021 fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1024 * Authenticate-Request ::= SEQUENCE {
1025 * pseudoRandomNumber [0] Unsigned32,
1026 * excpectedInvokeID [1] Unsigned8 OPTIONAL,
1027 * operatorName [2] CharacterString OPTIONAL,
1028 * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL,
1029 * startEncypheredSession [4] BOOLEAN OPTIONAL
1031 * @param tvb the tv buffer of the current data
1032 * @param pinfo the packet info of the current data
1033 * @param tree the tree to append this item to
1034 * @param offset the offset in the tvb
1035 * @return modified offset
1038 fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1041 * Authenticate-ACK ::= SEQUENCE {
1042 * modifiedRandomNumber Unsigned32,
1044 * @param tvb the tv buffer of the current data
1045 * @param pinfo the packet info of the current data
1046 * @param tree the tree to append this item to
1047 * @param offset the offset in the tvb
1048 * @return modified offset
1051 fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1054 * RequestKey-Request ::= SEQUENCE {
1055 * requestingDeviceIdentifier BACnetObjectIdentifier,
1056 * requestingDeviceAddress BACnetAddress,
1057 * remoteDeviceIdentifier BACnetObjectIdentifier,
1058 * remoteDeviceAddress BACnetAddress
1060 * @param tvb the tv buffer of the current data
1061 * @param pinfo the packet info of the current data
1062 * @param tree the tree to append this item to
1063 * @param offset the offset in the tvb
1064 * @return modified offset
1067 fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1070 * Unconfirmed-Service-Request ::= CHOICE {
1072 * @param tvb the tv buffer of the current data
1073 * @param pinfo the packet info of the current data
1074 * @param tree the tree to append this item to
1075 * @param offset the offset in the tvb
1076 * @param service_choice the service choice
1077 * @return modified offset
1080 fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
1083 * UnconfirmedCOVNotification-Request ::= SEQUENCE {
1084 * subscriberProcessIdentifier [0] Unsigned32,
1085 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1086 * monitoredObjectIdentifier [2] BACnetObjectIdentifer,
1087 * timeRemaining [3] unsigned,
1088 * listOfValues [4] SEQUENCE OF BACnetPropertyValues
1090 * @param tvb the tv buffer of the current data
1091 * @param pinfo the packet info of the current data
1092 * @param tree the tree to append this item to
1093 * @param offset the offset in the tvb
1094 * @return modified offset
1097 fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1100 * UnconfirmedEventNotification-Request ::= SEQUENCE {
1101 * ProcessIdentifier [0] Unsigned32,
1102 * initiatingDeviceIdentifier [1] BACnetObjectIdentifer,
1103 * eventObjectIdentifier [2] BACnetObjectIdentifer,
1104 * timeStamp [3] BACnetTimeStamp,
1105 * notificationClass [4] unsigned,
1106 * priority [5] unsigned8,
1107 * eventType [6] BACnetEventType,
1108 * messageText [7] CharacterString OPTIONAL,
1109 * notifyType [8] BACnetNotifyType,
1110 * ackRequired [9] BOOLEAN OPTIONAL,
1111 * fromState [10] BACnetEventState OPTIONAL,
1112 * toState [11] BACnetEventState,
1113 * eventValues [12] BACnetNotificationParameters OPTIONAL
1115 * @param tvb the tv buffer of the current data
1116 * @param pinfo the packet info of the current data
1117 * @param tree the tree to append this item to
1118 * @param offset the offset in the tvb
1119 * @return modified offset
1122 fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1125 * I-Am-Request ::= SEQUENCE {
1126 * aAmDeviceIdentifier BACnetObjectIdentifier,
1127 * maxAPDULengthAccepted Unsigned,
1128 * segmentationSupported BACnetSegmentation,
1131 * @param tvb the tv buffer of the current data
1132 * @param pinfo the packet info of the current data
1133 * @param tree the tree to append this item to
1134 * @param offset the offset in the tvb
1135 * @return modified offset
1138 fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1142 * I-Have-Request ::= SEQUENCE {
1143 * deviceIdentifier BACnetObjectIdentifier,
1144 * objectIdentifier BACnetObjectIdentifier,
1145 * objectName CharacterString
1147 * @param tvb the tv buffer of the current data
1148 * @param pinfo the packet info of the current data
1149 * @param tree the tree to append this item to
1150 * @param offset the offset in the tvb
1151 * @return modified offset
1154 fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1157 * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
1158 * vendorID [0] Unsigned,
1159 * serviceNumber [1] Unsigned,
1160 * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
1162 * @param tvb the tv buffer of the current data
1163 * @param pinfo the packet info of the current data
1164 * @param tree the tree to append this item to
1165 * @param offset the offset in the tvb
1166 * @return modified offset
1169 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1172 * UnconfirmedTextMessage-Request ::= SEQUENCE {
1173 * textMessageSourceDevice [0] BACnetObjectIdentifier,
1174 * messageClass [1] CHOICE {
1175 * numeric [0] Unsigned,
1176 * character [1] CharacterString
1178 * messagePriority [2] ENUMERATED {
1182 * message [3] CharacterString
1184 * @param tvb the tv buffer of the current data
1185 * @param pinfo the packet info of the current data
1186 * @param tree the tree to append this item to
1187 * @param offset the offset in the tvb
1188 * @return modified offset
1191 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1194 * TimeSynchronization-Request ::= SEQUENCE {
1197 * @param tvb the tv buffer of the current data
1198 * @param pinfo the packet info of the current data
1199 * @param tree the tree to append this item to
1200 * @param offset the offset in the tvb
1201 * @return modified offset
1204 fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1207 * UTCTimeSynchronization-Request ::= SEQUENCE {
1210 * @param tvb the tv buffer of the current data
1211 * @param pinfo the packet info of the current data
1212 * @param tree the tree to append this item to
1213 * @param offset the offset in the tvb
1214 * @return modified offset
1217 fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1220 * Who-Has-Request ::= SEQUENCE {
1222 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
1223 * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
1226 * objectIdentifier [2] BACnetObjectIdentifier,
1227 * objectName [3] CharacterString
1230 * @param tvb the tv buffer of the current data
1231 * @param pinfo the packet info of the current data
1232 * @param tree the tree to append this item to
1233 * @param offset the offset in the tvb
1234 * @return modified offset
1237 fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1240 * Who-Is-Request ::= SEQUENCE {
1241 * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1242 * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
1244 * @param tvb the tv buffer of the current data
1245 * @param tree the tree to append this item to
1246 * @param offset the offset in the tvb
1247 * @return modified offset
1250 fWhoIsRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1253 * BACnet-Error ::= CHOICE {
1254 * addListElement [8] ChangeList-Error,
1255 * removeListElement [9] ChangeList-Error,
1256 * writePropertyMultiple [16] WritePropertyMultiple-Error,
1257 * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
1258 * vtClose [22] VTClose-Error,
1259 * readRange [26] ObjectAccessService-Error
1262 * @param tvb the tv buffer of the current data
1263 * @param pinfo the packet info of the current data
1264 * @param tree the tree to append this item to
1265 * @param offset the offset in the tvb
1266 * @param service the service
1267 * @return modified offset
1270 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service);
1273 * Dissect a BACnetError in a context tag
1275 * @param tvb the tv buffer of the current data
1276 * @param pinfo the packet info of the current data
1277 * @param tree the tree to append this item to
1278 * @param offset the offset in the tvb
1279 * @return modified offset
1281 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1284 * ChangeList-Error ::= SEQUENCE {
1285 * errorType [0] Error,
1286 * firstFailedElementNumber [1] Unsigned
1289 * @param tvb the tv buffer of the current data
1290 * @param pinfo the packet info of the current data
1291 * @param tree the tree to append this item to
1292 * @param offset the offset in the tvb
1293 * @return modified offset
1296 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1299 * CreateObject-Error ::= SEQUENCE {
1300 * errorType [0] Error,
1301 * firstFailedElementNumber [1] Unsigned
1304 * @param tvb the tv buffer of the current data
1305 * @param pinfo the packet info of the current data
1306 * @param tree the tree to append this item to
1307 * @param offset the offset in the tvb
1308 * @return modified offset
1311 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1314 * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
1315 * errorType [0] Error,
1316 * vendorID [1] Unsigned,
1317 * serviceNumber [2] Unsigned,
1318 * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
1321 * @param tvb the tv buffer of the current data
1322 * @param pinfo the packet info of the current data
1323 * @param tree the tree to append this item to
1324 * @param offset the offset in the tvb
1325 * @return modified offset
1328 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1331 * WritePropertyMultiple-Error ::= SEQUENCE {
1332 * errorType [0] Error,
1333 * firstFailedWriteAttempt [1] Unsigned
1336 * @param tvb the tv buffer of the current data
1337 * @param pinfo the packet info of the current data
1338 * @param tree the tree to append this item to
1339 * @param offset the offset in the tvb
1340 * @return modified offset
1343 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1346 * VTClose-Error ::= SEQUENCE {
1347 * errorType [0] Error,
1348 * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
1351 * @param tvb the tv buffer of the current data
1352 * @param pinfo the packet info of the current data
1353 * @param tree the tree to append this item to
1354 * @param offset the offset in the tvb
1355 * @return modified offset
1358 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1361 * BACnet Application Types chapter 20.2.1
1362 * @param tvb the tv buffer of the current data
1363 * @param pinfo the packet info of the current data
1364 * @param tree the tree to append this item to
1365 * @param offset the offset in the tvb
1366 * @param label the label of this item
1367 * @return modified offset
1370 fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1373 * BACnetActionCommand ::= SEQUENCE {
1374 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1375 * objectIdentifier [1] BACnetObjectIdentifier,
1376 * propertyIdentifier [2] BACnetPropertyIdentifier,
1377 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype
1378 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
1379 * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable
1380 * postDelay [6] Unsigned OPTIONAL,
1381 * quitOnFailure [7] BOOLEAN,
1382 * writeSuccessful [8] BOOLEAN
1384 * @param tvb the tv buffer of the current data
1385 * @param pinfo the packet info of the current data
1386 * @param tree the tree to append this item to
1387 * @param offset the offset in the tvb
1388 * @param tag_match the tag number
1389 * @return modified offset
1392 fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
1395 * BACnetActionList ::= SEQUENCE {
1396 * action [0] SEQUENCE of BACnetActionCommand
1398 * @param tvb the tv buffer of the current data
1399 * @param pinfo the packet info of the current data
1400 * @param tree the tree to append this item to
1401 * @param offset the offset in the tvb
1402 * @return modified offset
1405 fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1407 /** BACnetAddress ::= SEQUENCE {
1408 * network-number Unsigned16, -- A value 0 indicates the local network
1409 * mac-address OCTET STRING -- A string of length 0 indicates a broadcast
1411 * @param tvb the tv buffer of the current data
1412 * @param pinfo the packet info of the current data
1413 * @param tree the tree to append this item to
1414 * @param offset the offset in the tvb
1415 * @return modified offset
1418 fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1421 * BACnetAddressBinding ::= SEQUENCE {
1422 * deviceObjectID BACnetObjectIdentifier
1423 * deviceAddress BacnetAddress
1425 * @param tvb the tv buffer of the current data
1426 * @param pinfo the packet info of the current data
1427 * @param tree the tree to append this item to
1428 * @param offset the offset in the tvb
1429 * @return modified offset
1432 fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1435 * BACnetCalendarEntry ::= CHOICE {
1437 * dateRange [1] BACnetDateRange,
1438 * weekNDay [2] BacnetWeekNday
1440 * @param tvb the tv buffer of the current data
1441 * @param pinfo the packet info of the current data
1442 * @param tree the tree to append this item to
1443 * @param offset the offset in the tvb
1444 * @return modified offset
1447 fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1450 * BACnetClientCOV ::= CHOICE {
1451 * real-increment REAL,
1452 * default-increment NULL
1454 * @param tvb the tv buffer of the current data
1455 * @param tree the tree to append this item to
1456 * @param offset the offset in the tvb
1457 * @return modified offset
1460 fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1464 * BACnetDailySchedule ::= SEQUENCE {
1465 * day-schedule [0] SENQUENCE OF BACnetTimeValue
1467 * @param tvb the tv buffer of the current data
1468 * @param pinfo the packet info of the current data
1469 * @param tree the tree to append this item to
1470 * @param offset the offset in the tvb
1471 * @return modified offset
1474 fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1477 * BACnetWeeklySchedule ::= SEQUENCE {
1478 * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule
1480 * @param tvb the tv buffer of the current data
1481 * @param pinfo the packet info of the current data
1482 * @param tree the tree to append this item to
1483 * @param offset the offset in the tvb
1484 * @return modified offset
1487 fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1490 * BACnetDateRange ::= SEQUENCE {
1494 * @param tvb the tv buffer of the current data
1495 * @param pinfo the packet info of the current data
1496 * @param tree the tree to append this item to
1497 * @param offset the offset in the tvb
1498 * @return modified offset
1501 fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1504 * BACnetDateTime ::= SEQUENCE {
1508 * @param tvb the tv buffer of the current data
1509 * @param pinfo the packet info of the current data
1510 * @param tree the tree to append this item to
1511 * @param offset the offset in the tvb
1512 * @param label the label of this item
1513 * @return modified offset
1516 fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
1519 * BACnetDestination ::= SEQUENCE {
1520 * validDays BACnetDaysOfWeek,
1523 * recipient BACnetRecipient,
1524 * processIdentifier Unsigned32,
1525 * issueConfirmedNotifications BOOLEAN,
1526 * transitions BACnetEventTransitionBits
1528 * @param tvb the tv buffer of the current data
1529 * @param pinfo the packet info of the current data
1530 * @param tree the tree to append this item to
1531 * @param offset the offset in the tvb
1532 * @return modified offset
1535 fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1538 * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
1539 * objectIdentifier [0] BACnetObjectIdentifier,
1540 * propertyIdentifier [1] BACnetPropertyIdentifier,
1541 * propertyArrayIndex [2] Unsigend OPTIONAL,
1542 * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
1544 * @param tvb the tv buffer of the current data
1545 * @param pinfo the packet info of the current data
1546 * @param tree the tree to append this item to
1547 * @param offset the offset in the tvb
1548 * @return modified offset
1551 fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1554 * BACnetObjectPropertyReference ::= SEQUENCE {
1555 * objectIdentifier [0] BACnetObjectIdentifier,
1556 * propertyIdentifier [1] BACnetPropertyIdentifier,
1557 * propertyArrayIndex [2] Unsigend OPTIONAL,
1559 * @param tvb the tv buffer of the current data
1560 * @param pinfo the packet info of the current data
1561 * @param tree the tree to append this item to
1562 * @param offset the offset in the tvb
1563 * @return modified offset
1566 fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1569 * BACnetDeviceObjectReference ::= SEQUENCE {
1570 * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
1571 * objectIdentifier [1] BACnetObjectIdentifier
1573 * @param tvb the tv buffer of the current data
1574 * @param pinfo the packet info of the current data
1575 * @param tree the tree to append this item to
1576 * @param offset the offset in the tvb
1577 * @return modified offset
1580 fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1583 * BACnetEventParameter ::= CHOICE {
1584 * change-of-bitstring [0] SEQUENCE {
1585 * time-delay [0] Unsigned,
1586 * bitmask [1] BIT STRING,
1587 * list-of-bitstring-values [2] SEQUENCE OF BIT STRING
1589 * change-of-state [1] SEQUENCE {
1590 * time-delay [0] Unsigned,
1591 * list-of-values [1] SEQUENCE OF BACnetPropertyStates
1593 * change-of-value [2] SEQUENCE {
1594 * time-delay [0] Unsigned,
1595 * cov-criteria [1] CHOICE {
1596 * bitmask [0] BIT STRING,
1597 * referenced-property-increment [1] REAL
1600 * command-failure [3] SEQUENCE {
1601 * time-delay [0] Unsigned,
1602 * feedback-property-reference [1] BACnetDeviceObjectPropertyReference
1604 * floating-limit [4] SEQUENCE {
1605 * time-delay [0] Unsigned,
1606 * setpoint-reference [1] BACnetDeviceObjectPropertyReference,
1607 * low-diff-limit [2] REAL,
1608 * high-diff-limit [3] REAL,
1611 * out-of-range [5] SEQUENCE {
1612 * time-delay [0] Unsigned,
1613 * low-limit [1] REAL,
1614 * high-limit [2] REAL,
1617 * -- context tag 7 is deprecated
1618 * change-of-life-safety [8] SEQUENCE {
1619 * time-delay [0] Unsigned,
1620 * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
1621 * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
1622 * mode-property-reference [3] BACnetDeviceObjectPropertyReference
1624 * extended [9] SEQUENCE {
1625 * vendor-id [0] Unsigned16,
1626 * extended-event-type [1] Unsigned,
1627 * parameters [2] SEQUENCE OF CHOICE {
1633 * octet OCTET STRING,
1634 * bitstring BIT STRING,
1636 * reference [0] BACnetDeviceObjectPropertyReference
1639 * buffer-ready [10] SEQUENCE {
1640 * notification-threshold [0] Unsigned,
1641 * previous-notification-count [1] Unsigned32
1643 * unsigned-range [11] SEQUENCE {
1644 * time-delay [0] Unsigned,
1645 * low-limit [1] Unsigned,
1646 * high-limit [2] Unsigned,
1648 * -- context tag 12 is reserved for future addenda
1649 * access-event [13] SEQUENCE {
1650 * list-of-access-events [0] SEQUENCE OF BACnetAccessEvent,
1651 * access-event-time-reference [1] BACnetDeviceObjectPropertyReference
1653 * double-out-of-range [14] SEQUENCE {
1654 * time-delay [0] Unsigned,
1655 * low-limit [1] Double,
1656 * high-limit [2] Double,
1657 * deadband [3] Double
1659 * signed-out-of-range [15] SEQUENCE {
1660 * time-delay [0] Unsigned,
1661 * low-limit [1] INTEGER,
1662 * high-limit [2] INTEGER,
1663 * deadband [3] Unsigned
1665 * unsigned-out-of-range [16] SEQUENCE {
1666 * time-delay [0] Unsigned,
1667 * low-limit [1] Unsigned,
1668 * high-limit [2] Unsigned,
1669 * deadband [3] Unsigned
1671 * change-of-characterstring [17] SEQUENCE {
1672 * time-delay [0] Unsigned,
1673 * list-of-alarm-values [1] SEQUENCE OF CharacterString,
1675 * change-of-status-flags [18] SEQUENCE {
1676 * time-delay [0] Unsigned,
1677 * selected-flags [1] BACnetStatusFlags
1680 * @param tvb the tv buffer of the current data
1681 * @param tree the tree to append this item to
1682 * @param offset the offset in the tvb
1683 * @return modified offset
1686 fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1691 * BACnetLogRecord ::= SEQUENCE {
1692 * timestamp [0] BACnetDateTime,
1693 * logDatum [1] CHOICE {
1694 * log-status [0] BACnetLogStatus,
1695 * boolean-value [1] BOOLEAN,
1696 * real-value [2] REAL,
1697 * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
1698 * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
1699 * signed-value [5] INTEGER, -- Optionally limited to 32 bits
1700 * bitstring-value [6] BIT STRING, -- Optionally limited to 32 bits
1701 * null-value [7] NULL,
1702 * failure [8] Error,
1703 * time-change [9] REAL,
1704 * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
1706 * statusFlags [2] BACnetStatusFlags OPTIONAL
1708 * @param tvb the tv buffer of the current data
1709 * @param pinfo the packet info of the current data
1710 * @param tree the tree to append this item to
1711 * @param offset the offset in the tvb
1712 * @return modified offset
1715 fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1718 * BACnetEventLogRecord ::= SEQUENCE {
1719 * timestamp [0] BACnetDateTime,
1720 * logDatum [1] CHOICE {
1721 * log-status [0] BACnetLogStatus,
1722 * notification [1] ConfirmedEventNotification-Request,
1723 * time-change [2] REAL,
1726 * @param tvb the tv buffer of the current data
1727 * @param pinfo the packet info of the current data
1728 * @param tree the tree to append this item to
1729 * @param offset the offset in the tvb
1730 * @return modified offset
1733 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1736 fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1739 * BACnetNotificationParameters ::= CHOICE {
1740 * change-of-bitstring [0] SEQUENCE {
1741 * referenced-bitstring [0] BIT STRING,
1742 * status-flags [1] BACnetStatusFlags
1744 * change-of-state [1] SEQUENCE {
1745 * new-state [0] BACnetPropertyStatus,
1746 * status-flags [1] BACnetStatusFlags
1748 * change-of-value [2] SEQUENCE {
1749 * new-value [0] CHOICE {
1750 * changed-bits [0] BIT STRING,
1751 * changed-value [1] REAL
1753 * status-flags [1] BACnetStatusFlags
1755 * command-failure [3] SEQUENCE {
1756 * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
1757 * status-flags [1] BACnetStatusFlags
1758 * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
1760 * floating-limit [4] SEQUENCE {
1761 * reference-value [0] REAL,
1762 * status-flags [1] BACnetStatusFlags
1763 * setpoint-value [2] REAL,
1764 * error-limit [3] REAL
1766 * out-of-range [5] SEQUENCE {
1767 * exceeding-value [0] REAL,
1768 * status-flags [1] BACnetStatusFlags
1769 * deadband [2] REAL,
1770 * exceeded-limit [3] REAL
1772 * complex-event-type [6] SEQUENCE OF BACnetPropertyValue,
1773 * -- complex tag 7 is deprecated
1774 * change-of-life-safety [8] SEQUENCE {
1775 * new-state [0] BACnetLifeSafetyState,
1776 * new-mode [1] BACnetLifeSafetyState
1777 * status-flags [2] BACnetStatusFlags,
1778 * operation-expected [3] BACnetLifeSafetyOperation
1780 * extended [9] SEQUENCE {
1781 * vendor-id [0] Unsigned16,
1782 * extended-event-type [1] Unsigned,
1783 * parameters [2] SEQUENCE OF CHOICE {
1789 * octet OCTET STRING,
1790 * bitstring BIT STRING,
1792 * propertyValue [0] BACnetDeviceObjectPropertyValue
1795 * buffer-ready [10] SEQUENCE {
1796 * buffer-property [0] BACnetDeviceObjectPropertyReference,
1797 * previous-notification[1] Unsigned32,
1798 * current-notification [2] BACneUnsigned32tDateTime
1800 * unsigned-range [11] SEQUENCE {
1801 * exceeding-value [0] Unsigned,
1802 * status-flags [1] BACnetStatusFlags,
1803 * exceeded-limit [2] Unsigned
1805 * -- context tag 12 is reserved for future addenda
1806 * access-event [13] SEQUENCE {
1807 * access-event [0] BACnetAccessEvent,
1808 * status-flags [1] BACnetStatusFlags,
1809 * access-event-tag [2] Unsigned,
1810 * access-event-time [3] BACnetTimeStamp,
1811 * access-credential [4] BACnetDeviceObjectReference,
1812 * authentication-factor [5] BACnetAuthenticationFactor OPTIONAL
1814 * double-out-of-range [14] SEQUENCE {
1815 * exceeding-value [0] Double,
1816 * status-flags [1] BACnetStatusFlags
1817 * deadband [2] Double,
1818 * exceeded-limit [3] Double
1820 * signed-out-of-range [15] SEQUENCE {
1821 * exceeding-value [0] INTEGER,
1822 * status-flags [1] BACnetStatusFlags
1823 * deadband [2] Unsigned,
1824 * exceeded-limit [3] INTEGER
1826 * unsigned-out-of-range [16] SEQUENCE {
1827 * exceeding-value [0] Unsigned,
1828 * status-flags [1] BACnetStatusFlags
1829 * deadband [2] Unsigned,
1830 * exceeded-limit [3] Unsigned
1832 * change-of-characterstring [17] SEQUENCE {
1833 * changed-value [0] CharacterString,
1834 * status-flags [1] BACnetStatusFlags
1835 * alarm-value [2] CharacterString
1837 * change-of-status-flags [18] SEQUENCE {
1838 * present-value [0] ABSTRACT-SYNTAX.&Type OPTIONAL,
1839 * -- depends on referenced property
1840 * referenced-flags [1] BACnetStatusFlags
1843 * @param tvb the tv buffer of the current data
1844 * @param pinfo the packet info of the current data
1845 * @param tree the tree to append this item to
1846 * @param offset the offset in the tvb
1847 * @return modified offset
1850 fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1853 * BACnetObjectPropertyReference ::= SEQUENCE {
1854 * objectIdentifier [0] BACnetObjectIdentifier,
1855 * propertyIdentifier [1] BACnetPropertyIdentifier,
1856 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1858 * @param tvb the tv buffer of the current data
1859 * @param pinfo the packet info of the current data
1860 * @param tree the tree to append this item to
1861 * @param offset the offset in the tvb
1862 * @return modified offset
1865 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1869 * BACnetObjectPropertyValue ::= SEQUENCE {
1870 * objectIdentifier [0] BACnetObjectIdentifier,
1871 * propertyIdentifier [1] BACnetPropertyIdentifier,
1872 * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
1873 * -- if omitted with an array the entire array is referenced
1874 * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
1875 * priority [4] Unsigned (1..16) OPTIONAL
1877 * @param tvb the tv buffer of the current data
1878 * @param tree the tree to append this item to
1879 * @param offset the offset in the tvb
1880 * @return modified offset
1883 fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, guint offset);
1887 * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
1888 * @param tvb the tv buffer of the current data
1889 * @param pinfo the packet info of the current data
1890 * @param tree the tree to append this item to
1891 * @param offset the offset in the tvb
1892 * @return modified offset
1895 fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1898 fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
1901 * BACnetPropertyReference ::= SEQUENCE {
1902 * propertyIdentifier [0] BACnetPropertyIdentifier,
1903 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
1905 * @param tvb the tv buffer of the current data
1906 * @param pinfo the packet info of the current data
1907 * @param tree the tree to append this item to
1908 * @param offset the offset in the tvb
1909 * @return modified offset
1912 fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
1915 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
1918 fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1921 fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1924 * BACnetPropertyValue ::= SEQUENCE {
1925 * PropertyIdentifier [0] BACnetPropertyIdentifier,
1926 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
1927 * -- if omitted with an array the entire array is referenced
1928 * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
1929 * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
1931 * @param tvb the tv buffer of the current data
1932 * @param pinfo the packet info of the current data
1933 * @param tree the tree to append this item to
1934 * @param offset the offset in the tvb
1935 * @return modified offset
1938 fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1941 fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
1944 * BACnet Application PDUs chapter 21
1945 * BACnetRecipient::= CHOICE {
1946 * device [0] BACnetObjectIdentifier
1947 * address [1] BACnetAddress
1949 * @param tvb the tv buffer of the current data
1950 * @param pinfo the packet info of the current data
1951 * @param tree the tree to append this item to
1952 * @param offset the offset in the tvb
1953 * @return modified offset
1956 fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1959 * BACnet Application PDUs chapter 21
1960 * BACnetRecipientProcess::= SEQUENCE {
1961 * recipient [0] BACnetRecipient
1962 * processID [1] Unsigned32
1964 * @param tvb the tv buffer of the current data
1965 * @param pinfo the packet info of the current data
1966 * @param tree the tree to append this item to
1967 * @param offset the offset in the tvb
1968 * @return modified offset
1971 fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1974 fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
1978 * BACnetSessionKey ::= SEQUENCE {
1979 * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
1980 * peerAddress BACnetAddress
1982 * @param tvb the tv buffer of the current data
1983 * @param tree the tree to append this item to
1984 * @param offset the offset in the tvb
1985 * @return modified offset
1986 * @todo check if checksum is displayed correctly
1989 fSessionKey(tvbuff_t *tvb, proto_tree *tree, guint offset);
1993 * BACnetSpecialEvent ::= SEQUENCE {
1995 * calendarEntry [0] BACnetCalendarEntry,
1996 * calendarRefernce [1] BACnetObjectIdentifier
1998 * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue,
1999 * eventPriority [3] Unsigned (1..16)
2001 * @param tvb the tv buffer of the current data
2002 * @param pinfo the packet info of the current data
2003 * @param tree the tree to append this item to
2004 * @param offset the offset in the tvb
2005 * @return modified offset
2008 fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2011 * BACnetTimeStamp ::= CHOICE {
2013 * sequenceNumber [1] Unsigned (0..65535),
2014 * dateTime [2] BACnetDateTime
2016 * @param tvb the tv buffer of the current data
2017 * @param pinfo the packet info of the current data
2018 * @param tree the tree to append this item to
2019 * @param offset the offset in the tvb
2020 * @param label the label of this item
2021 * @return modified offset
2024 fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2027 fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2030 * BACnetTimeValue ::= SEQUENCE {
2032 * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
2034 * @param tvb the tv buffer of the current data
2035 * @param pinfo the packet info of the current data
2036 * @param tree the tree to append this item to
2037 * @param offset the offset in the tvb
2038 * @return modified offset
2041 fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2045 * BACnetVTSession ::= SEQUENCE {
2046 * local-vtSessionID Unsigned8,
2047 * remote-vtSessionID Unsigned8,
2048 * remote-vtAddress BACnetAddress
2050 * @param tvb the tv buffer of the current data
2051 * @param tree the tree to append this item to
2052 * @param offset the offset in the tvb
2053 * @return modified offset
2056 fVTSession(tvbuff_t *tvb, proto_tree *tree, guint offset);
2060 * BACnetWeekNDay ::= OCTET STRING (SIZE (3))
2061 * -- first octet month (1..12) January = 1, X'FF' = any month
2062 * -- second octet weekOfMonth where: 1 = days numbered 1-7
2063 * -- 2 = days numbered 8-14
2064 * -- 3 = days numbered 15-21
2065 * -- 4 = days numbered 22-28
2066 * -- 5 = days numbered 29-31
2067 * -- 6 = last 7 days of this month
2068 * -- X'FF' = any week of this month
2069 * -- third octet dayOfWeek (1..7) where 1 = Monday
2071 * -- X'FF' = any day of week
2072 * @param tvb the tv buffer of the current data
2073 * @param pinfo the packet info of the current data
2074 * @param tree the tree to append this item to
2075 * @param offset the offset in the tvb
2076 * @return modified offset
2079 fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2082 * ReadAccessResult ::= SEQUENCE {
2083 * objectIdentifier [0] BACnetObjectIdentifier,
2084 * listOfResults [1] SEQUENCE OF SEQUENCE {
2085 * propertyIdentifier [2] BACnetPropertyIdentifier,
2086 * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
2087 * readResult CHOICE {
2088 * propertyValue [4] ABSTRACT-SYNTAX.&Type,
2089 * propertyAccessError [5] Error
2093 * @param tvb the tv buffer of the current data
2094 * @param pinfo the packet info of the current data
2095 * @param tree the tree to append this item to
2096 * @param offset the offset in the tvb
2097 * @return modified offset
2100 fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2103 * ReadAccessSpecification ::= SEQUENCE {
2104 * objectIdentifier [0] BACnetObjectIdentifier,
2105 * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
2107 * @param tvb the tv buffer of the current data
2108 * @param pinfo the packet info of the current data
2109 * @param subtree the subtree to append this item to
2110 * @param offset the offset in the tvb
2111 * @return modified offset
2114 fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2117 * WriteAccessSpecification ::= SEQUENCE {
2118 * objectIdentifier [0] BACnetObjectIdentifier,
2119 * listOfProperty [1] SEQUENCE OF BACnetPropertyValue
2121 * @param tvb the tv buffer of the current data
2122 * @param pinfo the packet info of the current data
2123 * @param subtree the sub tree to append this item to
2124 * @param offset the offset in the tvb
2125 * @return modified offset
2128 fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2131 /********************************************************* Helper functions *******************************************/
2134 * extracts the tag number from the tag header.
2135 * @param tvb the tv buffer of the current data "TestyVirtualBuffer"
2136 * @param offset the offset in the tvb in actual tvb
2137 * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
2140 fTagNo(tvbuff_t *tvb, guint offset);
2143 * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
2144 * @param tvb the tv buffer of the current data = "TestyVirtualBuffer"
2145 * @param pinfo the packet info of the current data = packet info
2146 * @param offset the offset in the tvb = offset in actual tvb
2147 * @return tag_no BACnet 20.2.1.2 Tag Number
2148 * @return class_tag BACnet 20.2.1.1 Class
2149 * @return lvt BACnet 20.2.1.3 Length/Value/Type
2150 * @return offs = length of this header
2154 fTagHeader(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
2158 * adds processID with max 32Bit unsigned Integer Value to tree
2159 * @param tvb the tv buffer of the current data
2160 * @param pinfo the packet info of the current data
2161 * @param tree the tree to append this item to
2162 * @param offset the offset in the tvb
2163 * @return modified offset
2166 fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2169 * adds timeSpan with max 32Bit unsigned Integer Value to tree
2170 * @param tvb the tv buffer of the current data
2171 * @param pinfo the packet info of the current data
2172 * @param tree the tree to append this item to
2173 * @param offset the offset in the tvb
2174 * @return modified offset
2177 fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2180 * BACnet Application PDUs chapter 21
2181 * BACnetPropertyIdentifier::= ENUMERATED {
2182 * @see bacapp_property_identifier
2184 * @param tvb the tv buffer of the current data
2185 * @param pinfo the packet info of the current data
2186 * @param tree the tree to append this item to
2187 * @param offset the offset in the tvb
2188 * @return modified offset
2191 fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2194 * BACnet Application PDUs chapter 21
2195 * BACnetPropertyArrayIndex::= ENUMERATED {
2196 * @see bacapp_property_array_index
2198 * @param tvb the tv buffer of the current data
2199 * @param pinfo the packet info of the current data
2200 * @param tree the tree to append this item to
2201 * @param offset the offset in the tvb
2202 * @return modified offset
2205 fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2208 * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
2209 * objectIdentifier [0] BACnetObjectIdentifier,
2210 * eventState [1] BACnetEventState,
2211 * acknowledgedTransitions [2] BACnetEventTransitionBits,
2212 * eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
2213 * notifyType [4] BACnetNotifyType,
2214 * eventEnable [5] BACnetEventTransitionBits,
2215 * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
2217 * @param tvb the tv buffer of the current data
2218 * @param pinfo the packet info of the current data
2219 * @param tree the tree to append this item to
2220 * @param offset the offset in the tvb
2221 * @return modified offset
2224 flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2227 * SelectionCriteria ::= SEQUENCE {
2228 * propertyIdentifier [0] BACnetPropertyIdentifier,
2229 * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
2230 * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier },
2231 * comparisonValue [3] ABSTRACT-SYNTAX.&Type
2233 * @param tvb the tv buffer of the current data
2234 * @param pinfo the packet info of the current data
2235 * @param tree the tree to append this item to
2236 * @param offset the offset in the tvb
2237 * @return modified offset
2240 fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2243 * objectSelectionCriteria ::= SEQUENCE {
2244 * selectionLogic [0] ENUMERATED { bacapp_selectionLogic },
2245 * listOfSelectionCriteria [1] SelectionCriteria
2247 * @param tvb the tv buffer of the current data
2248 * @param pinfo the packet info of the current data
2249 * @param subtree the sub tree to append this item to
2250 * @param offset the offset in the tvb
2251 * @return modified offset
2254 fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
2257 * BACnet-Error ::= SEQUENCE {
2258 * error-class ENUMERATED {},
2259 * error-code ENUMERATED {}
2262 * @param tvb the tv buffer of the current data
2263 * @param pinfo the packet info of the current data
2264 * @param tree the tree to append this item to
2265 * @param offset the offset in the tvb
2266 * @return modified offset
2269 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2272 * Generic handler for context tagged values. Mostly for handling
2273 * vendor-defined properties and services.
2274 * @param tvb the tv buffer of the current data
2275 * @param pinfo the packet info of the current data
2276 * @param tree the tree to append this item to
2277 * @param offset the offset in the tvb
2278 * @return modified offset
2279 * @todo beautify this ugly construct
2282 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
2285 * realizes some ABSTRACT-SYNTAX.&Type
2286 * @param tvb the tv buffer of the current data
2287 * @param pinfo the packet info of the current data
2288 * @param tree the tree to append this item to
2289 * @param offset the offset in the tvb
2290 * @return modified offset
2291 * @todo beautify this ugly construct
2294 fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
2298 fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
2299 const value_string *src);
2305 proto_register_bacapp(void);
2308 * proto_reg_handoff_bacapp
2311 proto_reg_handoff_bacapp(void);
2313 /* <<<< formerly bacapp.h */
2315 /* reassembly table for segmented messages */
2316 static reassembly_table msg_reassembly_table;
2318 /* some necessary forward function prototypes */
2320 fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
2321 const gchar *label, const value_string *vs);
2323 static const char *bacapp_unknown_service_str = "unknown service"; /* Usage: no format specifiers */
2324 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
2325 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
2327 static const value_string
2328 BACnetTypeName[] = {
2329 { 0, "Confirmed-REQ"},
2330 { 1, "Unconfirmed-REQ"},
2332 { 3, "Complex-ACK"},
2333 { 4, "Segment-ACK"},
2340 static const true_false_string segments_follow = {
2341 "Segmented Request",
2342 "Unsegmented Request"
2345 static const true_false_string more_follow = {
2346 "More Segments Follow",
2347 "No More Segments Follow"
2350 static const true_false_string segmented_accept = {
2351 "Segmented Response accepted",
2352 "Segmented Response not accepted"
2355 static const true_false_string
2357 "Context Specific Tag",
2361 static const value_string
2362 BACnetMaxSegmentsAccepted [] = {
2363 { 0, "Unspecified"},
2367 { 4, "16 segments"},
2368 { 5, "32 segments"},
2369 { 6, "64 segments"},
2370 { 7, "Greater than 64 segments"},
2374 static const value_string
2375 BACnetMaxAPDULengthAccepted [] = {
2376 { 0, "Up to MinimumMessageSize (50 octets)"},
2377 { 1, "Up to 128 octets"},
2378 { 2, "Up to 206 octets (fits in a LonTalk frame)"},
2379 { 3, "Up to 480 octets (fits in an ARCNET frame)"},
2380 { 4, "Up to 1024 octets"},
2381 { 5, "Up to 1476 octets (fits in an ISO 8802-3 frame)"},
2382 { 6, "reserved by ASHRAE"},
2383 { 7, "reserved by ASHRAE"},
2384 { 8, "reserved by ASHRAE"},
2385 { 9, "reserved by ASHRAE"},
2386 { 10, "reserved by ASHRAE"},
2387 { 11, "reserved by ASHRAE"},
2388 { 12, "reserved by ASHRAE"},
2389 { 13, "reserved by ASHRAE"},
2390 { 14, "reserved by ASHRAE"},
2391 { 15, "reserved by ASHRAE"},
2395 static const value_string
2396 BACnetRejectReason [] = {
2398 {1, "buffer-overflow"},
2399 {2, "inconsistent-parameters"},
2400 {3, "invalid-parameter-data-type"},
2402 {5, "missing-required-parameter"},
2403 {6, "parameter-out-of-range"},
2404 {7, "too-many-arguments"},
2405 {8, "undefined-enumeration"},
2406 {9, "unrecognized-service"},
2410 static const value_string
2411 BACnetRestartReason [] = {
2415 { 3, "detected-power-lost"},
2416 { 4, "detected-powered-off"},
2417 { 5, "hardware-watchdog"},
2418 { 6, "software-watchdog"},
2423 static const value_string
2424 BACnetApplicationTagNumber [] = {
2427 { 2, "Unsigned Integer"},
2428 { 3, "Signed Integer (2's complement notation)"},
2429 { 4, "Real (ANSI/IEE-754 floating point)"},
2430 { 5, "Double (ANSI/IEE-754 double precision floating point)"},
2431 { 6, "Octet String"},
2432 { 7, "Character String"},
2437 { 12, "BACnetObjectIdentifier"},
2438 { 13, "reserved by ASHRAE"},
2439 { 14, "reserved by ASHRAE"},
2440 { 15, "reserved by ASHRAE"},
2444 static const value_string
2451 static const value_string
2452 BACnetAccessEvent [] = {
2456 { 3, "passback-detected"},
2459 { 6, "lockout-max-attempts"},
2460 { 7, "lockout-other"},
2461 { 8, "lockout-relinquished"},
2462 { 9, "lockout-by-higher-priority"},
2463 { 10, "out-of-service"},
2464 { 11, "out-of-service-relinquished"},
2465 { 12, "accompaniment-by"},
2466 { 13, "authentication-factor-read"},
2467 { 14, "authorization-delayed"},
2468 { 15, "verification-required"},
2469 /* Enumerated values 128-511 are used for events
2470 * which indicate that access has been denied. */
2471 { 128, "denied-deny-all"},
2472 { 129, "denied-unknown-credential"},
2473 { 130, "denied-authentication-unavailable"},
2474 { 131, "denied-authentication-factor-timeout"},
2475 { 132, "denied-incorrect-authentication-factor"},
2476 { 133, "denied-zone-no-access-rights"},
2477 { 134, "denied-point-no-access-rights"},
2478 { 135, "denied-no-access-rights"},
2479 { 136, "denied-out-of-time-range"},
2480 { 137, "denied-threat-level"},
2481 { 138, "denied-passback"},
2482 { 139, "denied-unexpected-location-usage"},
2483 { 140, "denied-max-attempts"},
2484 { 141, "denied-lower-occupancy-limit"},
2485 { 142, "denied-upper-occupancy-limit"},
2486 { 143, "denied-authentication-factor-lost"},
2487 { 144, "denied-authentication-factor-stolen"},
2488 { 145, "denied-authentication-factor-damaged"},
2489 { 146, "denied-authentication-factor-destroyed"},
2490 { 147, "denied-authentication-factor-disabled"},
2491 { 148, "denied-authentication-factor-error"},
2492 { 149, "denied-credential-unassigned"},
2493 { 150, "denied-credential-not-provisioned"},
2494 { 151, "denied-credential-not-yet-active"},
2495 { 152, "denied-credential-expired"},
2496 { 153, "denied-credential-manual-disable"},
2497 { 154, "denied-credential-lockout"},
2498 { 155, "denied-credential-max-days"},
2499 { 156, "denied-credential-max-uses"},
2500 { 157, "denied-credential-inactivity"},
2501 { 158, "denied-credential-disabled"},
2502 { 159, "denied-no-accompaniment"},
2503 { 160, "denied-incorrect-accompaniment"},
2504 { 161, "denied-lockout"},
2505 { 162, "denied-verification-failed"},
2506 { 163, "denied-verification-timeout"},
2507 { 164, "denied-other"},
2509 /* Enumerated values 0-512 are reserved for definition by ASHRAE.
2510 Enumerated values 512-65535 may be used by others subject to
2511 procedures and constraints described in Clause 23. */
2514 static const value_string
2515 BACnetFileAccessMethod [] = {
2516 { 0, "record-access"},
2517 { 1, "stream-access"},
2521 /* For some reason, BACnet defines the choice parameter
2522 in the file read and write services backwards from the
2523 BACnetFileAccessMethod enumeration.
2525 static const value_string
2526 BACnetFileAccessOption [] = {
2527 { 0, "stream access"},
2528 { 1, "record access"},
2532 static const value_string
2533 BACnetFileStartOption [] = {
2534 { 0, "File Start Position: "},
2535 { 1, "File Start Record: "},
2539 static const value_string
2540 BACnetFileRequestCount [] = {
2541 { 0, "Requested Octet Count: "},
2542 { 1, "Requested Record Count: "},
2546 static const value_string
2547 BACnetFileWriteInfo [] = {
2548 { 0, "File Data: "},
2549 { 1, "Record Count: "},
2553 static const value_string
2554 BACnetAbortReason [] = {
2556 { 1, "buffer-overflow"},
2557 { 2, "invalid-apdu-in-this-state"},
2558 { 3, "preempted-by-higher-priority-task"},
2559 { 4, "segmentation-not-supported"},
2563 static const value_string
2564 BACnetLifeSafetyMode [] = {
2575 { 10, "disconnected"},
2578 { 13, "atomic-release-disabled"},
2581 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2582 Enumerated values 256-65535 may be used by others subject to
2583 procedures and constraints described in Clause 23. */
2586 static const value_string
2587 BACnetLifeSafetyOperation [] = {
2590 { 2, "silence-audible"},
2591 { 3, "silence-visual"},
2593 { 5, "reset-alarm"},
2594 { 6, "reset-fault"},
2596 { 8, "unsilence-audible"},
2597 { 9, "unsilence-visual"},
2599 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
2600 Enumerated values 64-65535 may be used by others subject to
2601 procedures and constraints described in Clause 23. */
2605 static const value_string
2606 BACnetLimitEnable [] = {
2607 { 0, "lowLimitEnable"},
2608 { 1, "highLimitEnable"},
2613 static const value_string
2614 BACnetLifeSafetyState [] = {
2619 { 4, "fault-pre-alarm"},
2620 { 5, "fault-alarm"},
2625 { 10, "test-active"},
2626 { 11, "test-fault"},
2627 { 12, "test-fault-alarm"},
2630 { 15, "tamper-alarm"},
2632 { 17, "emergency-power"},
2635 { 20, "local-alarm"},
2636 { 21, "general-alarm"},
2637 { 22, "supervisory"},
2638 { 23, "test-supervisory"},
2640 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
2641 Enumerated values 256-65535 may be used by others subject to
2642 procedures and constraints described in Clause 23. */
2645 static const value_string
2646 BACnetConfirmedServiceChoice [] = {
2647 { 0, "acknowledgeAlarm"},
2648 { 1, "confirmedCOVNotification"},
2649 { 2, "confirmedEventNotification"},
2650 { 3, "getAlarmSummary"},
2651 { 4, "getEnrollmentSummary"},
2652 { 5, "subscribeCOV"},
2653 { 6, "atomicReadFile"},
2654 { 7, "atomicWriteFile"},
2655 { 8, "addListElement"},
2656 { 9, "removeListElement"},
2657 { 10, "createObject"},
2658 { 11, "deleteObject"},
2659 { 12, "readProperty"},
2660 { 13, "readPropertyConditional"},
2661 { 14, "readPropertyMultiple"},
2662 { 15, "writeProperty"},
2663 { 16, "writePropertyMultiple"},
2664 { 17, "deviceCommunicationControl"},
2665 { 18, "confirmedPrivateTransfer"},
2666 { 19, "confirmedTextMessage"},
2667 { 20, "reinitializeDevice"},
2671 { 24, "authenticate"},
2672 { 25, "requestKey"},
2674 { 27, "lifeSafetyOperation"},
2675 { 28, "subscribeCOVProperty"},
2676 { 29, "getEventInformation"},
2677 { 30, "reserved by ASHRAE"},
2681 static const value_string
2682 BACnetReliability [] = {
2683 { 0, "no-fault-detected"},
2686 { 3, "under-range"},
2688 { 5, "shorted-loop"},
2690 { 7, "unreliable-other"},
2691 { 8, "process-error"},
2692 { 9, "multi-state-fault"},
2693 { 10, "configuration-error"},
2694 /* enumeration value 11 is reserved for a future addendum */
2695 { 12, "communication-failure"},
2696 { 13, "member-fault"},
2700 static const value_string
2701 BACnetUnconfirmedServiceChoice [] = {
2704 { 2, "unconfirmedCOVNotification"},
2705 { 3, "unconfirmedEventNotification"},
2706 { 4, "unconfirmedPrivateTransfer"},
2707 { 5, "unconfirmedTextMessage"},
2708 { 6, "timeSynchronization"},
2711 { 9, "utcTimeSynchronization"},
2716 static const value_string
2717 BACnetUnconfirmedServiceRequest [] = {
2718 { 0, "i-Am-Request"},
2719 { 1, "i-Have-Request"},
2720 { 2, "unconfirmedCOVNotification-Request"},
2721 { 3, "unconfirmedEventNotification-Request"},
2722 { 4, "unconfirmedPrivateTransfer-Request"},
2723 { 5, "unconfirmedTextMessage-Request"},
2724 { 6, "timeSynchronization-Request"},
2725 { 7, "who-Has-Request"},
2726 { 8, "who-Is-Request"},
2727 { 9, "utcTimeSynchonization-Request"},
2732 static const value_string
2733 BACnetObjectType [] = {
2734 { 0, "analog-input"},
2735 { 1, "analog-output"},
2736 { 2, "analog-value"},
2737 { 3, "binary-input"},
2738 { 4, "binary-output"},
2739 { 5, "binary-value"},
2743 { 9, "event-enrollment"},
2747 { 13, "multi-state-input"},
2748 { 14, "multi-state-output"},
2749 { 15, "notification-class"},
2753 { 19, "multi-state-value"},
2755 { 21, "life-safety-point"},
2756 { 22, "life-safety-zone"},
2757 { 23, "accumulator"},
2758 { 24, "pulse-converter"},
2760 { 26, "global-group"},
2761 { 27, "trend-log-multiple"},
2762 { 28, "load-control"},
2763 { 29, "structured-view"},
2764 { 30, "access-door"}, /* 30-37 added with addanda 135-2008j */
2765 /* value 31 is unassigned */
2766 { 32, "access-credential"},
2767 { 33, "access-point"},
2768 { 34, "access-rights"},
2769 { 35, "access-user"},
2770 { 36, "access-zone"},
2771 { 37, "credential-data-input"},
2772 { 38, "network-security"},
2773 { 39, "bitstring-value"}, /* 39-50 added with addenda 135-2008w */
2774 { 40, "characterstring-value"},
2775 { 41, "date-pattern-value"},
2776 { 42, "date-value"},
2777 { 43, "datetime-pattern-value"},
2778 { 44, "datetime-value"},
2779 { 45, "integer-value"},
2780 { 46, "large-analog-value"},
2781 { 47, "octetstring-value"},
2782 { 48, "positive-integer-value"},
2783 { 49, "time-pattern-value"},
2784 { 50, "time-value"},
2786 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
2787 Enumerated values 128-1023 may be used by others subject to
2788 the procedures and constraints described in Clause 23. */
2791 static const value_string
2792 BACnetEngineeringUnits [] = {
2795 { 2, "Milliamperes"},
2801 { 8, "Volt Amperes"},
2802 { 9, "Kilovolt Amperes"},
2803 { 10, "Megavolt Amperes"},
2804 { 11, "Volt Amperes Reactive"},
2805 { 12, "Kilovolt Amperes Reactive"},
2806 { 13, "Megavolt Amperes Reactive"},
2807 { 14, "Degrees Phase"},
2808 { 15, "Power Factor"},
2810 { 17, "Kilojoules"},
2811 { 18, "Watt Hours"},
2812 { 19, "Kilowatt Hours"},
2816 { 23, "Joules Per Kg Dry Air"},
2817 { 24, "BTUs Per Pound Dry Air"},
2818 { 25, "Cycles Per Hour"},
2819 { 26, "Cycles Per Minute"},
2821 { 28, "Grams Of Water Per Kilogram Dry Air"},
2822 { 29, "Relative Humidity"},
2823 { 30, "Millimeters"},
2827 { 34, "Watts Per Sq Foot"},
2828 { 35, "Watts Per Sq meter"},
2831 { 38, "Foot Candles"},
2833 { 40, "Pounds Mass"},
2835 { 42, "Kgs per Second"},
2836 { 43, "Kgs Per Minute"},
2837 { 44, "Kgs Per Hour"},
2838 { 45, "Pounds Mass Per Minute"},
2839 { 46, "Pounds Mass Per Hour"},
2843 { 50, "BTUs Per Hour"},
2844 { 51, "Horsepower"},
2845 { 52, "Tons Refrigeration"},
2847 { 54, "Kilopascals"},
2849 { 56, "Pounds Force Per Square Inch"},
2850 { 57, "Centimeters Of Water"},
2851 { 58, "Inches Of Water"},
2852 { 59, "Millimeters Of Mercury"},
2853 { 60, "Centimeters Of Mercury"},
2854 { 61, "Inches Of Mercury"},
2855 { 62, "Degrees Celsius"},
2856 { 63, "Degrees Kelvin"},
2857 { 64, "Degrees Fahrenheit"},
2858 { 65, "Degree Days Celsius"},
2859 { 66, "Degree Days Fahrenheit"},
2867 { 74, "Meters Per Second"},
2868 { 75, "Kilometers Per Hour"},
2869 { 76, "Feed Per Second"},
2870 { 77, "Feet Per Minute"},
2871 { 78, "Miles Per Hour"},
2872 { 79, "Cubic Feet"},
2873 { 80, "Cubic Meters"},
2874 { 81, "Imperial Gallons"},
2876 { 83, "US Gallons"},
2877 { 84, "Cubic Feet Per Minute"},
2878 { 85, "Cubic Meters Per Second"},
2879 { 86, "Imperial Gallons Per Minute"},
2880 { 87, "Liters Per Second"},
2881 { 88, "Liters Per Minute"},
2882 { 89, "US Gallons Per Minute"},
2883 { 90, "Degrees Angular"},
2884 { 91, "Degrees Celsius Per Hour"},
2885 { 92, "Degrees Celsius Per Minute"},
2886 { 93, "Degrees Fahrenheit Per Hour"},
2887 { 94, "Degrees Fahrenheit Per Minute"},
2889 { 96, "Parts Per Million"},
2890 { 97, "Parts Per Billion"},
2892 { 99, "Pecent Per Second"},
2893 { 100, "Per Minute"},
2894 { 101, "Per Second"},
2895 { 102, "Psi Per Degree Fahrenheit"},
2897 { 104, "Revolutions Per Min"},
2898 { 105, "Currency1"},
2899 { 106, "Currency2"},
2900 { 107, "Currency3"},
2901 { 108, "Currency4"},
2902 { 109, "Currency5"},
2903 { 110, "Currency6"},
2904 { 111, "Currency7"},
2905 { 112, "Currency8"},
2906 { 113, "Currency9"},
2907 { 114, "Currency10"},
2908 { 115, "Sq Inches"},
2909 { 116, "Sq Centimeters"},
2910 { 117, "BTUs Per Pound"},
2911 { 118, "Centimeters"},
2912 { 119, "Pounds Mass Per Second"},
2913 { 120, "Delta Degrees Fahrenheit"},
2914 { 121, "Delta Degrees Kelvin"},
2917 { 124, "Millivolts"},
2918 { 125, "Kilojoules Per Kg"},
2919 { 126, "Megajoules"},
2920 { 127, "Joules Per Degree Kelvin"},
2921 { 128, "Joules Per Kg Degree Kelvin"},
2922 { 129, "Kilohertz"},
2923 { 130, "Megahertz"},
2925 { 132, "Milliwatts"},
2926 { 133, "Hectopascals"},
2927 { 134, "Millibars"},
2928 { 135, "Cubic Meters Per Hour"},
2929 { 136, "Liters Per Hour"},
2930 { 137, "KWatt Hours Per Square Meter"},
2931 { 138, "KWatt Hours Per Square Foot"},
2932 { 139, "Megajoules Per Square Meter"},
2933 { 140, "Megajoules Per Square Foot"},
2934 { 141, "Watts Per Sq Meter Degree Kelvin"},
2935 { 142, "Cubic Feet Per Second"},
2936 { 143, "Percent Obstruction Per Foot"},
2937 { 144, "Percent Obstruction Per Meter"},
2938 { 145, "milliohms"},
2939 { 146, "megawatt-hours"},
2940 { 147, "kilo-btus"},
2941 { 148, "mega-btus"},
2942 { 149, "kilojoules-per-kilogram-dry-air"},
2943 { 150, "megajoules-per-kilogram-dry-air"},
2944 { 151, "kilojoules-per-degree-Kelvin"},
2945 { 152, "megajoules-per-degree-Kelvin"},
2947 { 154, "grams-per-second"},
2948 { 155, "grams-per-minute"},
2949 { 156, "tons-per-hour"},
2950 { 157, "kilo-btus-per-hour"},
2951 { 158, "hundredths-seconds"},
2952 { 159, "milliseconds"},
2953 { 160, "newton-meters"},
2954 { 161, "millimeters-per-second"},
2955 { 162, "millimeters-per-minute"},
2956 { 163, "meters-per-minute"},
2957 { 164, "meters-per-hour"},
2958 { 165, "cubic-meters-per-minute"},
2959 { 166, "meters-per-second-per-second"},
2960 { 167, "amperes-per-meter"},
2961 { 168, "amperes-per-square-meter"},
2962 { 169, "ampere-square-meters"},
2965 { 172, "ohm-meters"},
2967 { 174, "siemens-per-meter"},
2969 { 176, "volts-per-degree-Kelvin"},
2970 { 177, "volts-per-meter"},
2973 { 180, "candelas-per-square-meter"},
2974 { 181, "degrees-Kelvin-per-hour"},
2975 { 182, "degrees-Kelvin-per-minute"},
2976 { 183, "joule-seconds"},
2977 { 184, "radians-per-second"},
2978 { 185, "square-meters-per-Newton"},
2979 { 186, "kilograms-per-cubic-meter"},
2980 { 187, "newton-seconds"},
2981 { 188, "newtons-per-meter"},
2982 { 189, "watts-per-meter-per-degree-Kelvin"},
2983 { 190, "micro-siemens"},
2984 { 191, "cubic-feet-per-hour"},
2985 { 192, "us-gallons-per-hour"},
2986 { 193, "kilometers"},
2987 { 194, "micrometers"},
2989 { 196, "milligrams"},
2990 { 197, "milliliters"},
2991 { 198, "milliliters-per-second"},
2993 { 200, "decibels-millivolt"},
2994 { 201, "decibels-volt"},
2995 { 202, "millisiemens"},
2996 { 203, "watt-hours-reactive"},
2997 { 204, "kilowatt-hours-reactive"},
2998 { 205, "megawatt-hours-reactive"},
2999 { 206, "millimeters-of-water"},
3000 { 207, "per-mille"},
3001 { 208, "grams-per-gram"},
3002 { 209, "kilograms-per-kilogram"},
3003 { 210, "grams-per-kilogram"},
3004 { 211, "milligrams-per-gram"},
3005 { 212, "milligrams-per-kilogram"},
3006 { 213, "grams-per-milliliter"},
3007 { 214, "grams-per-liter"},
3008 { 215, "milligrams-per-liter"},
3009 { 216, "micrograms-per-liter"},
3010 { 217, "grams-per-cubic-meter"},
3011 { 218, "milligrams-per-cubic-meter"},
3012 { 219, "micrograms-per-cubic-meter"},
3013 { 220, "nanograms-per-cubic-meter"},
3014 { 221, "grams-per-cubic-centimeter"},
3015 { 222, "becquerels"},
3016 { 223, "kilobecquerels"},
3017 { 224, "megabecquerels"},
3019 { 226, "milligray"},
3020 { 227, "microgray"},
3022 { 229, "millisieverts"},
3023 { 230, "microsieverts"},
3024 { 231, "microsieverts-per-hour"},
3025 { 232, "decibels-a"},
3026 { 233, "nephelometric-turbidity-unit"},
3028 { 235, "grams-per-square-meter"},
3029 { 236, "minutes-per-degree-kelvin"},
3031 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
3032 Enumerated values 256-65535 may be used by others subject to
3033 the procedures and constraints described in Clause 23. */
3036 static const value_string
3037 BACnetErrorCode [] = {
3039 { 1, "authentication-failed"},
3040 { 2, "configuration-in-progress"},
3041 { 3, "device-busy"},
3042 { 4, "dynamic-creation-not-supported"},
3043 { 5, "file-access-denied"},
3044 { 6, "incompatible-security-levels"},
3045 { 7, "inconsistent-parameters"},
3046 { 8, "inconsistent-selection-criterion"},
3047 { 9, "invalid-data-type"},
3048 { 10, "invalid-file-access-method"},
3049 { 11, "invalid-file-start-position"},
3050 { 12, "invalid-operator-name"},
3051 { 13, "invalid-parameter-data-type"},
3052 { 14, "invalid-time-stamp"},
3053 { 15, "key-generation-error"},
3054 { 16, "missing-required-parameter"},
3055 { 17, "no-objects-of-specified-type"},
3056 { 18, "no-space-for-object"},
3057 { 19, "no-space-to-add-list-element"},
3058 { 20, "no-space-to-write-property"},
3059 { 21, "no-vt-sessions-available"},
3060 { 22, "property-is-not-a-list"},
3061 { 23, "object-deletion-not-permitted"},
3062 { 24, "object-identifier-already-exists"},
3063 { 25, "operational-problem"},
3064 { 26, "password-failure"},
3065 { 27, "read-access-denied"},
3066 { 28, "security-not-supported"},
3067 { 29, "service-request-denied"},
3069 { 31, "unknown-object"},
3070 { 32, "unknown-property"},
3071 { 33, "removed enumeration"},
3072 { 34, "unknown-vt-class"},
3073 { 35, "unknown-vt-session"},
3074 { 36, "unsupported-object-type"},
3075 { 37, "value-out-of-range"},
3076 { 38, "vt-session-already-closed"},
3077 { 39, "vt-session-termination-failure"},
3078 { 40, "write-access-denied"},
3079 { 41, "character-set-not-supported"},
3080 { 42, "invalid-array-index"},
3081 { 43, "cov-subscription-failed"},
3082 { 44, "not-cov-property"},
3083 { 45, "optional-functionality-not-supported"},
3084 { 46, "invalid-configuration-data"},
3085 { 47, "datatype-not-supported"},
3086 { 48, "duplicate-name"},
3087 { 49, "duplicate-object-id"},
3088 { 50, "property-is-not-an-array"},
3089 { 73, "invalid-event-state"},
3090 { 74, "no-alarm-configured"},
3091 { 75, "log-buffer-full"},
3092 { 76, "logged-value-purged"},
3093 { 77, "no-property-specified"},
3094 { 78, "not-configured-for-triggered-logging"},
3095 { 79, "unknown-subscription"},
3096 { 80, "parameter-out-of-range"},
3097 { 81, "list-element-not-found"},
3099 { 83, "communication-disabled"},
3101 { 85, "access-denied"},
3102 { 86, "bad-destination-address"},
3103 { 87, "bad-destination-device-id"},
3104 { 88, "bad-signature"},
3105 { 89, "bad-source-address"},
3106 { 90, "bad-timestamp"},
3107 { 91, "cannot-use-key"},
3108 { 92, "cannot-verify-message-id"},
3109 { 93, "correct-key-revision"},
3110 { 94, "destination-device-id-required"},
3111 { 95, "duplicate-message"},
3112 { 96, "encryption-not-configured"},
3113 { 97, "encryption-required"},
3114 { 98, "incorrect-key"},
3115 { 99, "invalid-key-data"},
3116 { 100, "key-update-in-progress"},
3117 { 101, "malformed-message"},
3118 { 102, "not-key-server"},
3119 { 103, "security-not-configured"},
3120 { 104, "source-security-required"},
3121 { 105, "too-many-keys"},
3122 { 106, "unknown-authentication-type"},
3123 { 107, "unknown-key"},
3124 { 108, "unknown-key-revision"},
3125 { 109, "unknown-source-message"},
3126 { 110, "not-router-to-dnet"},
3127 { 111, "router-busy"},
3128 { 112, "unknown-network-message"},
3129 { 113, "message-too-long"},
3130 { 114, "security-error"},
3131 { 115, "addressing-error"},
3132 { 116, "write-bdt-failed"},
3133 { 117, "read-bdt-failed"},
3134 { 118, "register-foreign-device-failed"},
3135 { 119, "read-fdt-failed"},
3136 { 120, "delete-fdt-entry-failed"},
3137 { 121, "distribute-broadcast-failed"},
3138 { 122, "unknown-file-size"},
3139 { 123, "abort-apdu-too-long"},
3140 { 124, "abort-application-exceeded-reply-time"},
3141 { 125, "abort-out-of-resources"},
3142 { 126, "abort-tsm-timeout"},
3143 { 127, "abort-window-size-out-of-range"},
3144 { 128, "file-full"},
3145 { 129, "inconsistent-configuration"},
3146 { 130, "inconsistent-object-type"},
3147 { 131, "internal-error"},
3148 { 132, "not-configured"},
3149 { 133, "out-of-memory"},
3150 { 134, "value-too-long"},
3151 { 135, "abort-insufficient-security"},
3152 { 136, "abort-security-error"},
3154 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
3155 Enumerated values 256-65535 may be used by others subject to the
3156 procedures and constraints described in Clause 23. */
3159 static const value_string
3160 BACnetPropertyIdentifier [] = {
3161 { 0, "acked-transition"},
3162 { 1, "ack-required"},
3164 { 3, "action-text"},
3165 { 4, "active-text"},
3166 { 5, "active-vt-session"},
3167 { 6, "alarm-value"},
3168 { 7, "alarm-values"},
3170 { 9, "all-write-successful"},
3171 { 10, "apdu-segment-timeout"},
3172 { 11, "apdu-timeout"},
3173 { 12, "application-software-version"},
3176 { 15, "change-of-state-count"},
3177 { 16, "change-of-state-time"},
3178 { 17, "notification-class"},
3179 { 18, "the property in this place was deleted"},
3180 { 19, "controlled-variable-reference"},
3181 { 20, "controlled-variable-units"},
3182 { 21, "controlled-variable-value"},
3183 { 22, "cov-increment"},
3185 { 24, "daylights-savings-status"},
3187 { 26, "derivative-constant"},
3188 { 27, "derivative-constant-units"},
3189 { 28, "description"},
3190 { 29, "description-of-halt"},
3191 { 30, "device-address-binding"},
3192 { 31, "device-type"},
3193 { 32, "effective-period"},
3194 { 33, "elapsed-active-time"},
3195 { 34, "error-limit"},
3196 { 35, "event-enable"},
3197 { 36, "event-state"},
3198 { 37, "event-type"},
3199 { 38, "exception-schedule"},
3200 { 39, "fault-values"},
3201 { 40, "feedback-value"},
3202 { 41, "file-access-method"},
3205 { 44, "firmware-revision"},
3206 { 45, "high-limit"},
3207 { 46, "inactive-text"},
3208 { 47, "in-progress"},
3209 { 48, "instance-of"},
3210 { 49, "integral-constant"},
3211 { 50, "integral-constant-units"},
3212 { 51, "issue-confirmed-notifications"},
3213 { 52, "limit-enable"},
3214 { 53, "list-of-group-members"},
3215 { 54, "list-of-object-property-references"},
3216 { 55, "list-of-session-keys"},
3217 { 56, "local-date"},
3218 { 57, "local-time"},
3221 { 60, "manipulated-variable-reference"},
3222 { 61, "maximum-output"},
3223 { 62, "max-apdu-length-accepted"},
3224 { 63, "max-info-frames"},
3225 { 64, "max-master"},
3226 { 65, "max-pres-value"},
3227 { 66, "minimum-off-time"},
3228 { 67, "minimum-on-time"},
3229 { 68, "minimum-output"},
3230 { 69, "min-pres-value"},
3231 { 70, "model-name"},
3232 { 71, "modification-date"},
3233 { 72, "notify-type"},
3234 { 73, "number-of-APDU-retries"},
3235 { 74, "number-of-states"},
3236 { 75, "object-identifier"},
3237 { 76, "object-list"},
3238 { 77, "object-name"},
3239 { 78, "object-property-reference"},
3240 { 79, "object-type"},
3242 { 81, "out-of-service"},
3243 { 82, "output-units"},
3244 { 83, "event-parameters"},
3246 { 85, "present-value"},
3248 { 87, "priority-array"},
3249 { 88, "priority-for-writing"},
3250 { 89, "process-identifier"},
3251 { 90, "program-change"},
3252 { 91, "program-location"},
3253 { 92, "program-state"},
3254 { 93, "proportional-constant"},
3255 { 94, "proportional-constant-units"},
3256 { 95, "protocol-conformance-class"},
3257 { 96, "protocol-object-types-supported"},
3258 { 97, "protocol-services-supported"},
3259 { 98, "protocol-version"},
3261 { 100, "reason-for-halt"},
3262 { 101, "recipient"},
3263 { 102, "recipient-list"},
3264 { 103, "reliability"},
3265 { 104, "relinquish-default"},
3267 { 106, "resolution"},
3268 { 107, "segmentation-supported"},
3270 { 109, "setpoint-reference"},
3271 { 110, "state-text"},
3272 { 111, "status-flags"},
3273 { 112, "system-status"},
3274 { 113, "time-delay"},
3275 { 114, "time-of-active-time-reset"},
3276 { 115, "time-of-state-count-reset"},
3277 { 116, "time-synchronization-recipients"},
3279 { 118, "update-interval"},
3280 { 119, "utc-offset"},
3281 { 120, "vendor-identifier"},
3282 { 121, "vendor-name"},
3283 { 122, "vt-class-supported"},
3284 { 123, "weekly-schedule"},
3285 { 124, "attempted-samples"},
3286 { 125, "average-value"},
3287 { 126, "buffer-size"},
3288 { 127, "client-cov-increment"},
3289 { 128, "cov-resubscription-interval"},
3290 { 129, "current-notify-time"},
3291 { 130, "event-time-stamp"},
3292 { 131, "log-buffer"},
3293 { 132, "log-device-object-property"},
3294 { 133, "enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
3295 { 134, "log-interval"},
3296 { 135, "maximum-value"},
3297 { 136, "minimum-value"},
3298 { 137, "notification-threshold"},
3299 { 138, "previous-notify-time"},
3300 { 139, "protocol-revision"},
3301 { 140, "records-since-notification"},
3302 { 141, "record-count"},
3303 { 142, "start-time"},
3304 { 143, "stop-time"},
3305 { 144, "stop-when-full"},
3306 { 145, "total-record-count"},
3307 { 146, "valid-samples"},
3308 { 147, "window-interval"},
3309 { 148, "window-samples"},
3310 { 149, "maximum-value-time-stamp"},
3311 { 150, "minimum-value-time-stamp"},
3312 { 151, "variance-value"},
3313 { 152, "active-cov-subscriptions"},
3314 { 153, "backup-failure-timeout"},
3315 { 154, "configuration-files"},
3316 { 155, "database-revision"},
3317 { 156, "direct-reading"},
3318 { 157, "last-restore-time"},
3319 { 158, "maintenance-required"},
3320 { 159, "member-of"},
3322 { 161, "operation-expected"},
3325 { 164, "tracking-value"},
3326 { 165, "zone-members"},
3327 { 166, "life-safety-alarm-values"},
3328 { 167, "max-segments-accepted"},
3329 { 168, "profile-name"},
3330 { 169, "auto-slave-discovery"},
3331 { 170, "manual-slave-address-binding"},
3332 { 171, "slave-address-binding"},
3333 { 172, "slave-proxy-enable"},
3334 { 173, "last-notify-record"}, /* bug 4117 */
3335 { 174, "schedule-default"},
3336 { 175, "accepted-modes"},
3337 { 176, "adjust-value"},
3339 { 178, "count-before-change"},
3340 { 179, "count-change-time"},
3341 { 180, "cov-period"},
3342 { 181, "input-reference"},
3343 { 182, "limit-monitoring-interval"},
3344 { 183, "logging-device"},
3345 { 184, "logging-record"},
3347 { 186, "pulse-rate"},
3349 { 188, "scale-factor"},
3350 { 189, "update-time"},
3351 { 190, "value-before-change"},
3352 { 191, "value-set"},
3353 { 192, "value-change-time"},
3354 { 193, "align-intervals"},
3355 { 194, "group-member-names"},
3356 { 195, "interval-offset"},
3357 { 196, "last-restart-reason"},
3358 { 197, "logging-type"},
3359 { 198, "member-status-flags"},
3360 { 199, "notification-period"},
3361 { 200, "previous-notify-record"},
3362 { 201, "requested-update-interval"},
3363 { 202, "restart-notification-recipients"},
3364 { 203, "time-of-device-restart"},
3365 { 204, "time-synchronization-interval"},
3367 { 206, "UTC-time-synchronization-recipients"},
3368 { 207, "node-subtype"},
3369 { 208, "node-type"},
3370 { 209, "structured-object-list"},
3371 { 210, "subordinate-annotations"},
3372 { 211, "subordinate-list"},
3373 { 212, "actual-shed-level"},
3374 { 213, "duty-window"},
3375 { 214, "expected-shed-level"},
3376 { 215, "full-duty-baseline"},
3377 { 216, "node-subtype"},
3378 { 217, "node-type"},
3379 { 218, "requested-shed-level"},
3380 { 219, "shed-duration"},
3381 { 220, "shed-level-descriptions"},
3382 { 221, "shed-levels"},
3383 { 222, "state-description"},
3384 /* enumeration values 223-225 are unassigned */
3385 { 226, "door-alarm-state"},
3386 { 227, "door-extended-pulse-time"},
3387 { 228, "door-members"},
3388 { 229, "door-open-too-long-time"},
3389 { 230, "door-pulse-time"},
3390 { 231, "door-status"},
3391 { 232, "door-unlock-delay-time"},
3392 { 233, "lock-status"},
3393 { 234, "masked-alarm-values"},
3394 { 235, "secured-status"},
3395 /* enumeration values 236-243 are unassigned */
3396 { 244, "absentee-limit"}, /* added with addenda 135-2008j */
3397 { 245, "access-alarm-events"},
3398 { 246, "access-doors"},
3399 { 247, "access-event"},
3400 { 248, "access-event-authentication-factor"},
3401 { 249, "access-event-credential"},
3402 { 250, "access-event-time"},
3403 { 251, "access-transaction-events"},
3404 { 252, "accompaniment"},
3405 { 253, "accompaniment-time"},
3406 { 254, "activation-time"},
3407 { 255, "active-authentication-policy"},
3408 { 256, "assigned-access-rights"},
3409 { 257, "authentication-factors"},
3410 { 258, "authentication-policy-list"},
3411 { 259, "authentication-policy-names"},
3412 { 260, "authentication-status"},
3413 { 261, "authorization-mode"},
3414 { 262, "belongs-to"},
3415 { 263, "credential-disable"},
3416 { 264, "credential-status"},
3417 { 265, "credentials"},
3418 { 266, "credentials-in-zone"},
3419 { 267, "days-remaining"},
3420 { 268, "entry-points"},
3421 { 269, "exit-points"},
3422 { 270, "expiry-time"},
3423 { 271, "extended-time-enable"},
3424 { 272, "failed-attempt-events"},
3425 { 273, "failed-attempts"},
3426 { 274, "failed-attempts-time"},
3427 { 275, "last-access-event"},
3428 { 276, "last-access-point"},
3429 { 277, "last-credential-added"},
3430 { 278, "last-credential-added-time"},
3431 { 279, "last-credential-removed"},
3432 { 280, "last-credential-removed-time"},
3433 { 281, "last-use-time"},
3435 { 283, "lockout-relinquish-time"},
3436 { 284, "master-exemption"},
3437 { 285, "max-failed-attempts"},
3439 { 287, "muster-point"},
3440 { 288, "negative-access-rules"},
3441 { 289, "number-of-authentication-policies"},
3442 { 290, "occupancy-count"},
3443 { 291, "occupancy-count-adjust"},
3444 { 292, "occupancy-count-enable"},
3445 { 293, "occupancy-exemption"},
3446 { 294, "occupancy-lower-limit"},
3447 { 295, "occupancy-lower-limit-enforced"},
3448 { 296, "occupancy-state"},
3449 { 297, "occupancy-upper-limit"},
3450 { 298, "occupancy-upper-limit-enforced"},
3451 { 299, "passback-exemption"},
3452 { 300, "passback-mode"},
3453 { 301, "passback-timeout"},
3454 { 302, "positive-access-rules"},
3455 { 303, "reason-for-disable"},
3456 { 304, "supported-formats"},
3457 { 305, "supported-format-classes"},
3458 { 306, "threat-authority"},
3459 { 307, "threat-level"},
3460 { 308, "trace-flag"},
3461 { 309, "transaction-notification-class"},
3462 { 310, "user-external-identifier"},
3463 { 311, "user-information-reference"},
3464 /* enumeration values 312-316 are unassigned */
3465 { 317, "user-name"},
3466 { 318, "user-type"},
3467 { 319, "uses-remaining"},
3468 { 320, "zone-from"},
3470 { 322, "access-event-tag"},
3471 { 323, "global-identifier"},
3472 /* enumeration values 324-325 reserved for future addenda */
3473 { 326, "verification-time"},
3474 { 327, "base-device-security-policy"},
3475 { 328, "distribution-key-revision"},
3476 { 329, "do-not-hide"},
3478 { 331, "last-key-server"},
3479 { 332, "network-access-security-policies"},
3480 { 333, "packet-reorder-time"},
3481 { 334, "security-pdu-timeout"},
3482 { 335, "security-time-window"},
3483 { 336, "supported-security-algorithms"},
3484 { 337, "update-key-set-timeout"},
3485 { 338, "backup-and-restore-state"},
3486 { 339, "backup-preparation-time"},
3487 { 340, "restore-completion-time"},
3488 { 341, "restore-preparation-time"},
3489 { 342, "bit-mask"}, /* addenda 135-2008w */
3492 { 345, "group-members"},
3493 { 346, "group-member-names"},
3494 { 347, "member-status-flags"},
3495 { 348, "requested-update-interval"},
3496 { 349, "covu-period"},
3497 { 350, "covu-recipients"},
3498 { 351, "event-message-texts"},
3500 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
3501 Enumerated values 512-4194303 may be used by others subject to
3502 the procedures and constraints described in Clause 23. */
3505 static const value_string
3506 BACnetBinaryPV [] = {
3513 #define ANSI_X3_4 0 /* ANSI X3.4, a/k/a "ASCII"; full UTF-8 since 2010 */
3514 /* See, for example, ANSI/ASHRAE Addendum k to ANSI/ASHRAE Standard 135-2008 */
3515 /* XXX - I've seen captures using this for ISO 8859-1 */
3516 #define IBM_MS_DBCS 1 /* "IBM/Microsoft DBCS"; was there only one such DBCS? */
3517 #define JIS_C_6226 2 /* JIS C 6226 */
3518 #define ISO_10646_UCS4 3 /* ISO 10646 (UCS-4) - 4-byte Unicode */
3519 #define ISO_10646_UCS2 4 /* ISO 10646 (UCS-2) - 2-byte Unicode Basic Multilingual Plane (not UTF-16, presumably) */
3520 #define ISO_8859_1 5 /* ISO 8859-1 */
3521 static const value_string
3522 BACnetCharacterSet [] = {
3523 { ANSI_X3_4, "ANSI X3.4 / UTF-8 (since 2010)"},
3524 { IBM_MS_DBCS, "IBM/Microsoft DBCS"},
3525 { JIS_C_6226, "JIS C 6226"},
3526 { ISO_10646_UCS4, "ISO 10646 (UCS-4)"},
3527 { ISO_10646_UCS2, "ISO 10646 (UCS-2)"},
3528 { ISO_8859_1, "ISO 8859-1"},
3532 static const value_string
3533 BACnetStatusFlags [] = {
3537 { 3, "out-of-service"},
3541 static const value_string
3542 BACnetMessagePriority [] = {
3548 static const value_string
3549 BACnetAcknowledgementFilter [] = {
3556 static const value_string
3557 BACnetResultFlags [] = {
3564 static const value_string
3565 BACnetRelationSpecifier [] = {
3569 { 3, "greater-than"},
3570 { 4, "less-than-or-equal"},
3571 { 5, "greater-than-or-equal"},
3575 static const value_string
3576 BACnetSelectionLogic [] = {
3583 static const value_string
3584 BACnetEventStateFilter [] = {
3593 static const value_string
3594 BACnetEventTransitionBits [] = {
3595 { 0, "to-offnormal"},
3601 static const value_string
3602 BACnetSegmentation [] = {
3603 { 0, "segmented-both"},
3604 { 1, "segmented-transmit"},
3605 { 2, "segmented-receive"},
3606 { 3, "no-segmentation"},
3610 static const value_string
3611 BACnetSilencedState [] = {
3613 { 1, "audible-silenced"},
3614 { 2, "visible-silenced"},
3615 { 3, "all-silenced"},
3619 static const value_string
3620 BACnetDeviceStatus [] = {
3621 { 0, "operational"},
3622 { 1, "operational-read-only"},
3623 { 2, "download-required"},
3624 { 3, "download-in-progress"},
3625 { 4, "non-operational"},
3626 { 5, "backup-in-progress"},
3630 static const value_string
3631 BACnetEnableDisable [] = {
3634 { 2, "disable-initiation"},
3638 static const value_string
3652 { 255, "any month" },
3656 static const value_string
3658 { 1, "days numbered 1-7" },
3659 { 2, "days numbered 8-14" },
3660 { 3, "days numbered 15-21" },
3661 { 4, "days numbered 22-28" },
3662 { 5, "days numbered 29-31" },
3663 { 6, "last 7 days of this month" },
3664 { 255, "any week of this month" },
3668 /* note: notification class object recipient-list uses
3669 different day-of-week enum */
3670 static const value_string
3679 { 255, "any day of week" },
3683 static const value_string
3684 BACnetErrorClass [] = {
3692 { 7, "communication" },
3694 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3695 Enumerated values64-65535 may be used by others subject to
3696 the procedures and constraints described in Clause 23. */
3699 static const value_string
3700 BACnetVTClass [] = {
3701 { 0, "default-terminal" },
3702 { 1, "ansi-x3-64" },
3711 static const value_string
3712 BACnetEventType [] = {
3713 { 0, "change-of-bitstring" },
3714 { 1, "change-of-state" },
3715 { 2, "change-of-value" },
3716 { 3, "command-failure" },
3717 { 4, "floating-limit" },
3718 { 5, "out-of-range" },
3719 { 6, "complex-event-type" },
3720 { 7, "(deprecated)buffer-ready" },
3721 { 8, "change-of-life-safety" },
3723 { 10, "buffer-ready" },
3724 { 11, "unsigned-range" },
3725 { 14, "double-out-of-range"}, /* added with addenda 135-2008w */
3726 { 15, "signed-out-of-range"},
3727 { 16, "unsigned-out-of-range"},
3728 { 17, "change-of-characterstring"},
3729 { 18, "change-of-status-flags"},
3731 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3732 Enumerated values 64-65535 may be used by others subject to
3733 the procedures and constraints described in Clause 23.
3734 It is expected that these enumerated values will correspond
3735 to the use of the complex-event-type CHOICE [6] of the
3736 BACnetNotificationParameters production. */
3739 static const value_string
3740 BACnetEventState [] = {
3744 { 3, "high-limit" },
3746 { 5, "life-safety-alarm" },
3748 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3749 Enumerated values 64-65535 may be used by others subject to
3750 the procedures and constraints described in Clause 23. */
3753 static const value_string
3754 BACnetLogStatus [] = {
3755 { 0, "log-disabled" },
3756 { 1, "buffer-purged" },
3757 { 2, "log-interrupted"},
3761 static const value_string
3762 BACnetMaintenance [] = {
3764 { 1, "periodic-test" },
3765 { 2, "need-service-operational" },
3766 { 3, "need-service-inoperative" },
3770 static const value_string
3771 BACnetNotifyType [] = {
3774 { 2, "ack-notification" },
3778 static const value_string
3779 BACnetServicesSupported [] = {
3780 { 0, "acknowledgeAlarm"},
3781 { 1, "confirmedCOVNotification"},
3782 { 2, "confirmedEventNotification"},
3783 { 3, "getAlarmSummary"},
3784 { 4, "getEnrollmentSummary"},
3785 { 5, "subscribeCOV"},
3786 { 6, "atomicReadFile"},
3787 { 7, "atomicWriteFile"},
3788 { 8, "addListElement"},
3789 { 9, "removeListElement"},
3790 { 10, "createObject"},
3791 { 11, "deleteObject"},
3792 { 12, "readProperty"},
3793 { 13, "readPropertyConditional"},
3794 { 14, "readPropertyMultiple"},
3795 { 15, "writeProperty"},
3796 { 16, "writePropertyMultiple"},
3797 { 17, "deviceCommunicationControl"},
3798 { 18, "confirmedPrivateTransfer"},
3799 { 19, "confirmedTextMessage"},
3800 { 20, "reinitializeDevice"},
3804 { 24, "authenticate"},
3805 { 25, "requestKey"},
3808 { 28, "unconfirmedCOVNotification"},
3809 { 29, "unconfirmedEventNotification"},
3810 { 30, "unconfirmedPrivateTransfer"},
3811 { 31, "unconfirmedTextMessage"},
3812 { 32, "timeSynchronization"},
3816 { 36, "utcTimeSynchronization"},
3817 { 37, "lifeSafetyOperation"},
3818 { 38, "subscribeCOVProperty"},
3819 { 39, "getEventInformation"},
3823 static const value_string
3824 BACnetPropertyStates [] = {
3825 { 0, "boolean-value"},
3826 { 1, "binary-value"},
3829 { 4, "program-change"},
3830 { 5, "program-state"},
3831 { 6, "reason-for-halt"},
3832 { 7, "reliability"},
3834 { 9, "system-status"},
3836 { 11, "unsigned-value"},
3837 { 12, "life-safety-mode"},
3838 { 13, "life-safety-state"},
3839 { 14, "restart-reason"},
3840 { 15, "door-alarm-state"},
3842 { 17, "door-secured-status"},
3843 { 18, "door-status"},
3844 { 19, "door-value"},
3845 { 20, "file-access-method"},
3846 { 21, "lock-status"},
3847 { 22, "life-safety-operation"},
3848 { 23, "maintenance"},
3850 { 25, "notify-type"},
3851 { 26, "security-level"},
3852 { 27, "shed-state"},
3853 { 28, "silenced-state"},
3854 /* context tag 29 reserved for future addenda */
3855 { 29, "unknown-29"},
3856 { 30, "access-event"},
3857 { 31, "zone-occupancy-state"},
3858 { 32, "access-credential-disable-reason"},
3859 { 33, "access-credential-disable"},
3860 { 34, "authentication-status"},
3861 { 35, "unknown-35"},
3862 { 36, "backup-state"},
3864 /* Tag values 0-63 are reserved for definition by ASHRAE.
3865 Tag values of 64-254 may be used by others to accommodate
3866 vendor specific properties that have discrete or enumerated values,
3867 subject to the constraints described in Clause 23. */
3870 static const value_string
3871 BACnetProgramError [] = {
3873 { 1, "load-failed"},
3878 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
3879 Enumerated values 64-65535 may be used by others subject to
3880 the procedures and constraints described in Clause 23. */
3883 static const value_string
3884 BACnetProgramRequest [] = {
3894 static const value_string
3895 BACnetProgramState [] = {
3905 static const value_string
3906 BACnetReinitializedStateOfDevice [] = {
3909 { 2, "startbackup"},
3911 { 4, "startrestore"},
3913 { 6, "abortrestore"},
3917 static const value_string
3918 BACnetPolarity [] = {
3924 static const value_string
3925 BACnetTagNames[] = {
3926 { 5, "Extended Value" },
3927 { 6, "Opening Tag" },
3928 { 7, "Closing Tag" },
3932 static const value_string
3933 BACnetReadRangeOptions[] = {
3934 { 3, "range byPosition" },
3935 { 4, "range byTime" },
3936 { 5, "range timeRange" },
3937 { 6, "range bySequenceNumber" },
3938 { 7, "range byTime" },
3942 /* Present_Value for Load Control Object */
3943 static const value_string
3944 BACnetShedState[] = {
3945 { 0, "shed-inactive" },
3946 { 1, "shed-request-pending" },
3947 { 2, "shed-compliant" },
3948 { 3, "shed-non-compliant" },
3952 static const value_string
3953 BACnetNodeType [] = {
3958 { 4, "organizational" },
3962 { 8, "collection" },
3964 { 10, "functional" },
3969 static const value_string
3970 BACnetLoggingType [] = {
3977 static const value_string
3978 BACnetDoorStatus [] = {
3985 static const value_string
3986 BACnetLockStatus [] = {
3994 static const value_string
3995 BACnetDoorSecuredStatus [] = {
4002 static const value_string
4003 BACnetDoorAlarmState [] = {
4006 { 2, "door-open-too-long" },
4007 { 3, "forced-open" },
4009 { 5, "door-fault" },
4011 { 7, "free-access" },
4012 { 8, "egress-open" },
4016 static const value_string
4017 BACnetAccumulatorStatus [] = {
4026 /* These values are (manually) transferred from
4027 * http://www.bacnet.org/VendorID/BACnet Vendor IDs.htm
4028 * Version: "As of September 16, 2013"
4031 static const value_string
4032 BACnetVendorIdentifiers [] = {
4035 { 2, "The Trane Company" },
4036 { 3, "McQuay International" },
4038 { 5, "Johnson Controls, Inc." },
4039 { 6, "American Auto-Matrix" },
4040 { 7, "Siemens Schweiz AG (Formerly: Landis & Staefa Division Europe)" },
4041 { 8, "Delta Controls" },
4042 { 9, "Siemens Schweiz AG" },
4043 { 10, "Schneider Electric" },
4045 { 12, "Orion Analysis Corporation" },
4046 { 13, "Teletrol Systems Inc." },
4047 { 14, "Cimetrics Technology" },
4048 { 15, "Cornell University" },
4049 { 16, "United Technologies Carrier" },
4050 { 17, "Honeywell Inc." },
4051 { 18, "Alerton / Honeywell" },
4053 { 20, "Hewlett-Packard Company" },
4054 { 21, "Dorsette's Inc." },
4055 { 22, "Siemens Schweiz AG (Formerly: Cerberus AG)" },
4056 { 23, "York Controls Group" },
4057 { 24, "Automated Logic Corporation" },
4058 { 25, "CSI Control Systems International" },
4059 { 26, "Phoenix Controls Corporation" },
4060 { 27, "Innovex Technologies, Inc." },
4061 { 28, "KMC Controls, Inc." },
4062 { 29, "Xn Technologies, Inc." },
4063 { 30, "Hyundai Information Technology Co., Ltd." },
4064 { 31, "Tokimec Inc." },
4066 { 33, "North Building Technologies Limited" },
4068 { 35, "Reliable Controls Corporation" },
4069 { 36, "Tridium Inc." },
4070 { 37, "Sierra Monitor Corporation/FieldServer Technologies" },
4071 { 38, "Silicon Energy" },
4072 { 39, "Kieback & Peter GmbH & Co KG" },
4073 { 40, "Anacon Systems, Inc." },
4074 { 41, "Systems Controls & Instruments, LLC" },
4075 { 42, "Lithonia Lighting" },
4076 { 43, "Micropower Manufacturing" },
4077 { 44, "Matrix Controls" },
4078 { 45, "METALAIRE" },
4079 { 46, "ESS Engineering" },
4080 { 47, "Sphere Systems Pty Ltd." },
4081 { 48, "Walker Technologies Corporation" },
4082 { 49, "H I Solutions, Inc." },
4084 { 51, "SAMSON AG" },
4085 { 52, "Badger Meter Inc." },
4086 { 53, "DAIKIN Industries Ltd." },
4087 { 54, "NARA Controls Inc." },
4088 { 55, "Mammoth Inc." },
4089 { 56, "Liebert Corporation" },
4090 { 57, "SEMCO Incorporated" },
4091 { 58, "Air Monitor Corporation" },
4092 { 59, "TRIATEK, LLC" },
4094 { 61, "Multistack" },
4095 { 62, "TSI Incorporated" },
4096 { 63, "Weather-Rite, Inc." },
4097 { 64, "Dunham-Bush" },
4098 { 65, "Reliance Electric" },
4100 { 67, "Regulator Australia PTY Ltd." },
4101 { 68, "Touch-Plate Lighting Controls" },
4102 { 69, "Amann GmbH" },
4103 { 70, "RLE Technologies" },
4104 { 71, "Cardkey Systems" },
4105 { 72, "SECOM Co., Ltd." },
4106 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
4107 { 74, "KNX Association cvba" },
4108 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
4109 { 76, "Nohmi Bosai, Ltd." },
4110 { 77, "Carel S.p.A." },
4111 { 78, "AirSense Technology, Inc." },
4112 { 79, "Hochiki Corporation" },
4113 { 80, "Fr. Sauter AG" },
4114 { 81, "Matsushita Electric Works, Ltd." },
4115 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
4116 { 83, "Mitsubishi Heavy Industries, Ltd." },
4117 { 84, "ITT Bell & Gossett" },
4118 { 85, "Yamatake Building Systems Co., Ltd." },
4119 { 86, "The Watt Stopper, Inc." },
4120 { 87, "Aichi Tokei Denki Co., Ltd." },
4121 { 88, "Activation Technologies, LLC" },
4122 { 89, "Saia-Burgess Controls, Ltd." },
4123 { 90, "Hitachi, Ltd." },
4124 { 91, "Novar Corp./Trend Control Systems Ltd." },
4125 { 92, "Mitsubishi Electric Lighting Corporation" },
4126 { 93, "Argus Control Systems, Ltd." },
4127 { 94, "Kyuki Corporation" },
4128 { 95, "Richards-Zeta Building Intelligence, Inc." },
4129 { 96, "Scientech R&D, Inc." },
4130 { 97, "VCI Controls, Inc." },
4131 { 98, "Toshiba Corporation" },
4132 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
4133 { 100, "Custom Mechanical Equipment, LLC" },
4134 { 101, "ClimateMaster" },
4135 { 102, "ICP Panel-Tec, Inc." },
4136 { 103, "D-Tek Controls" },
4137 { 104, "NEC Engineering, Ltd." },
4138 { 105, "PRIVA BV" },
4139 { 106, "Meidensha Corporation" },
4140 { 107, "JCI Systems Integration Services" },
4141 { 108, "Freedom Corporation" },
4142 { 109, "Neuberger Gebaudeautomation GmbH" },
4143 { 110, "Sitronix" },
4144 { 111, "Leviton Manufacturing" },
4145 { 112, "Fujitsu Limited" },
4146 { 113, "Emerson Network Power" },
4147 { 114, "S. A. Armstrong, Ltd." },
4148 { 115, "Visonet AG" },
4149 { 116, "M&M Systems, Inc." },
4150 { 117, "Custom Software Engineering" },
4151 { 118, "Nittan Company, Limited" },
4152 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
4153 { 120, "Pacom Systems Pty., Ltd." },
4154 { 121, "Unico, Inc." },
4155 { 122, "Ebtron, Inc." },
4156 { 123, "Scada Engine" },
4157 { 124, "AC Technology Corporation" },
4158 { 125, "Eagle Technology" },
4159 { 126, "Data Aire, Inc." },
4160 { 127, "ABB, Inc." },
4161 { 128, "Transbit Sp. z o. o." },
4162 { 129, "Toshiba Carrier Corporation" },
4163 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
4164 { 131, "Tokai Soft" },
4165 { 132, "Blue Ridge Technologies" },
4166 { 133, "Veris Industries" },
4167 { 134, "Centaurus Prime" },
4168 { 135, "Sand Network Systems" },
4169 { 136, "Regulvar, Inc." },
4170 { 137, "AFDtek Division of Fastek International Inc." },
4171 { 138, "PowerCold Comfort Air Solutions, Inc." },
4172 { 139, "I Controls" },
4173 { 140, "Viconics Electronics, Inc." },
4174 { 141, "Yaskawa America, Inc." },
4175 { 142, "DEOS control systems GmbH" },
4176 { 143, "Digitale Mess- und Steuersysteme AG" },
4177 { 144, "Fujitsu General Limited" },
4178 { 145, "Project Engineering S.r.l." },
4179 { 146, "Sanyo Electric Co., Ltd." },
4180 { 147, "Integrated Information Systems, Inc." },
4181 { 148, "Temco Controls, Ltd." },
4182 { 149, "Airtek International Inc." },
4183 { 150, "Advantech Corporation" },
4184 { 151, "Titan Products, Ltd." },
4185 { 152, "Regel Partners" },
4186 { 153, "National Environmental Product" },
4187 { 154, "Unitec Corporation" },
4188 { 155, "Kanden Engineering Company" },
4189 { 156, "Messner Gebaudetechnik GmbH" },
4190 { 157, "Integrated.CH" },
4191 { 158, "Price Industries" },
4192 { 159, "SE-Elektronic GmbH" },
4193 { 160, "Rockwell Automation" },
4194 { 161, "Enflex Corp." },
4195 { 162, "ASI Controls" },
4196 { 163, "SysMik GmbH Dresden" },
4197 { 164, "HSC Regelungstechnik GmbH" },
4198 { 165, "Smart Temp Australia Pty. Ltd." },
4199 { 166, "Cooper Controls" },
4200 { 167, "Duksan Mecasys Co., Ltd." },
4201 { 168, "Fuji IT Co., Ltd." },
4202 { 169, "Vacon Plc" },
4203 { 170, "Leader Controls" },
4204 { 171, "Cylon Controls, Ltd." },
4206 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
4207 { 174, "Building Control Integrators" },
4208 { 175, "ITG Worldwide (M) Sdn Bhd" },
4209 { 176, "Lutron Electronics Co., Inc." },
4210 { 178, "LOYTEC Electronics GmbH" },
4212 { 180, "Mega Controls Limited" },
4213 { 181, "Micro Control Systems, Inc." },
4214 { 182, "Kiyon, Inc." },
4215 { 183, "Dust Networks" },
4216 { 184, "Advanced Building Automation Systems" },
4217 { 185, "Hermos AG" },
4220 { 188, "Lynxspring" },
4221 { 189, "Schneider Toshiba Inverter Europe" },
4222 { 190, "Danfoss Drives A/S" },
4223 { 191, "Eaton Corporation" },
4224 { 192, "Matyca S.A." },
4225 { 193, "Botech AB" },
4226 { 194, "Noveo, Inc." },
4228 { 196, "Yokogawa Electric Corporation" },
4229 { 197, "GFR Gesellschaft fur Regelungstechnik" },
4230 { 198, "Exact Logic" },
4231 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
4232 { 200, "Kandenko Co., Ltd." },
4233 { 201, "DTF, Daten-Technik Fries" },
4234 { 202, "Klimasoft, Ltd." },
4235 { 203, "Toshiba Schneider Inverter Corporation" },
4236 { 204, "Control Applications, Ltd." },
4237 { 205, "KDT Systems Co., Ltd." },
4238 { 206, "Onicon Incorporated" },
4239 { 207, "Automation Displays, Inc." },
4240 { 208, "Control Solutions, Inc." },
4241 { 209, "Remsdaq Limited" },
4242 { 210, "NTT Facilities, Inc." },
4243 { 211, "VIPA GmbH" },
4244 { 212, "TSC21 Association of Japan" },
4245 { 213, "Strato Automation" },
4246 { 214, "HRW Limited" },
4247 { 215, "Lighting Control & Design, Inc." },
4248 { 216, "Mercy Electronic and Electrical Industries" },
4249 { 217, "Samsung SDS Co., Ltd" },
4250 { 218, "Impact Facility Solutions, Inc." },
4251 { 219, "Aircuity" },
4252 { 220, "Control Techniques, Ltd." },
4253 { 221, "OpenGeneral Pty., Ltd." },
4254 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
4255 { 223, "Cerus Industrial" },
4256 { 224, "Chloride Power Protection Company" },
4257 { 225, "Computrols, Inc." },
4258 { 226, "Phoenix Contact GmbH & Co. KG" },
4259 { 227, "Grundfos Management A/S" },
4260 { 228, "Ridder Drive Systems" },
4261 { 229, "Soft Device SDN BHD" },
4262 { 230, "Integrated Control Technology Limited" },
4263 { 231, "AIRxpert Systems, Inc." },
4264 { 232, "Microtrol Limited" },
4265 { 233, "Red Lion Controls" },
4266 { 234, "Digital Electronics Corporation" },
4267 { 235, "Ennovatis GmbH" },
4268 { 236, "Serotonin Software Technologies, Inc." },
4269 { 237, "LS Industrial Systems Co., Ltd." },
4270 { 238, "Square D Company" },
4271 { 239, "S Squared Innovations, Inc." },
4272 { 240, "Aricent Ltd." },
4273 { 241, "EtherMetrics, LLC" },
4274 { 242, "Industrial Control Communications, Inc." },
4275 { 243, "Paragon Controls, Inc." },
4276 { 244, "A. O. Smith Corporation" },
4277 { 245, "Contemporary Control Systems, Inc." },
4278 { 246, "Intesis Software SL" },
4279 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
4280 { 248, "Heat-Timer Corporation" },
4281 { 249, "Ingrasys Technology, Inc." },
4282 { 250, "Costerm Building Automation" },
4284 { 252, "Embedia Technologies Corp." },
4285 { 253, "Technilog" },
4286 { 254, "HR Controls Ltd. & Co. KG" },
4287 { 255, "Lennox International, Inc." },
4288 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
4289 { 257, "Thermomax, Ltd." },
4290 { 258, "ELCON Electronic Control, Ltd." },
4291 { 259, "Larmia Control AB" },
4292 { 260, "BACnet Stack at SourceForge" },
4293 { 261, "G4S Security Services A/S" },
4294 { 262, "Exor International S.p.A." },
4295 { 263, "Cristal Controles" },
4296 { 264, "Regin AB" },
4297 { 265, "Dimension Software, Inc." },
4298 { 266, "SynapSense Corporation" },
4299 { 267, "Beijing Nantree Electronic Co., Ltd." },
4300 { 268, "Camus Hydronics Ltd." },
4301 { 269, "Kawasaki Heavy Industries, Ltd." },
4302 { 270, "Critical Environment Technologies" },
4303 { 271, "ILSHIN IBS Co., Ltd." },
4304 { 272, "ELESTA Energy Control AG" },
4305 { 273, "KROPMAN Installatietechniek" },
4306 { 274, "Baldor Electric Company" },
4307 { 275, "INGA mbH" },
4308 { 276, "GE Consumer & Industrial" },
4309 { 277, "Functional Devices, Inc." },
4311 { 279, "M-System Co., Ltd." },
4312 { 280, "Yokota Co., Ltd." },
4313 { 281, "Hitranse Technology Co., LTD" },
4314 { 282, "Federspiel Controls" },
4315 { 283, "Kele, Inc." },
4316 { 284, "Opera Electronics, Inc." },
4318 { 286, "Embedded Science Labs, LLC" },
4319 { 287, "Parker Hannifin Corporation" },
4320 { 288, "MaCaPS International Limited" },
4321 { 289, "Link4 Corporation" },
4322 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
4323 { 291, "Pribusin, Inc." },
4324 { 292, "Advantage Controls" },
4325 { 293, "Critical Room Control" },
4327 { 295, "Tongdy Control Technology Co., Ltd." },
4328 { 296, "ISSARO Integrierte Systemtechnik" },
4329 { 297, "Pro-Dev Industries" },
4330 { 298, "DRI-STEEM" },
4331 { 299, "Creative Electronic GmbH" },
4332 { 300, "Swegon AB" },
4333 { 301, "Jan Brachacek" },
4334 { 302, "Hitachi Appliances, Inc." },
4335 { 303, "Real Time Automation, Inc." },
4336 { 304, "ITEC Hankyu-Hanshin Co." },
4337 { 305, "Cyrus E&M Engineering Co., Ltd." },
4338 { 306, "Racine Federated, Inc." },
4339 { 307, "Cirrascale Corporation" },
4340 { 308, "Elesta GmbH Building Automation" },
4341 { 309, "Securiton" },
4342 { 310, "OSlsoft, Inc." },
4343 { 311, "Hanazeder Electronic GmbH" },
4344 { 312, "Honeywell Security Deutschland, Novar GmbH" },
4345 { 313, "Siemens Energy & Automation, Inc." },
4346 { 314, "ETM Professional Control GmbH" },
4347 { 315, "Meitav-tec, Ltd." },
4348 { 316, "Janitza Electronics GmbH" },
4349 { 317, "MKS Nordhausen" },
4350 { 318, "De Gier Drive Systems B.V." },
4351 { 319, "Cypress Envirosystems" },
4352 { 320, "SMARTron s.r.o." },
4353 { 321, "Verari Systems, Inc." },
4354 { 322, "K-W Electronic Service, Inc." },
4355 { 323, "ALFA-SMART Energy Management" },
4356 { 324, "Telkonet, Inc." },
4357 { 325, "Securiton GmbH" },
4358 { 326, "Cemtrex, Inc." },
4359 { 327, "Performance Technologies, Inc." },
4360 { 328, "Xtralis (Aust) Pty Ltd" },
4361 { 329, "TROX GmbH" },
4362 { 330, "Beijing Hysine Technology Co., Ltd" },
4363 { 331, "RCK Controls, Inc." },
4364 { 332, "Distech Controls SAS" },
4365 { 333, "Novar/Honeywell" },
4366 { 334, "The S4 Group, Inc." },
4367 { 335, "Schneider Electric" },
4368 { 336, "LHA Systems" },
4369 { 337, "GHM engineering Group, Inc." },
4370 { 338, "Cllimalux S.A." },
4371 { 339, "VAISALA Oyj" },
4372 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
4373 { 341, "SCADAmetrics" },
4374 { 342, "POWERPEG NSI Limited" },
4375 { 343, "BACnet Interoperability Testing Services, Inc." },
4376 { 344, "Teco a.s." },
4377 { 345, "Plexus Technology, Inc." },
4378 { 346, "Energy Focus, Inc." },
4379 { 347, "Powersmiths International Corp." },
4380 { 348, "Nichibei Co., Ltd." },
4381 { 349, "HKC Technology Ltd." },
4382 { 350, "Ovation Networks, Inc." },
4383 { 351, "Setra Systems" },
4384 { 352, "AVG Automation" },
4385 { 353, "ZXC Ltd." },
4386 { 354, "Byte Sphere" },
4387 { 355, "Generiton Co., Ltd." },
4388 { 356, "Holter Regelarmaturen GmbH & Co. KG" },
4389 { 357, "Bedford Instruments, LLC" },
4390 { 358, "Standair Inc." },
4391 { 359, "WEG Automation - R&D" },
4392 { 360, "Prolon Control Systems ApS" },
4393 { 361, "Inneasoft" },
4394 { 362, "ConneXSoft GmbH" },
4395 { 363, "CEAG Notlichtsysteme GmbH" },
4396 { 364, "Distech Controls Inc." },
4397 { 365, "Industrial Technology Research Institute" },
4398 { 366, "ICONICS, Inc." },
4399 { 367, "IQ Controls s.c." },
4400 { 368, "OJ Electronics A/S" },
4401 { 369, "Rolbit Ltd." },
4402 { 370, "Synapsys Solutions Ltd." },
4403 { 371, "ACME Engineering Prod. Ltd." },
4404 { 372, "Zener Electric Pty, Ltd." },
4405 { 373, "Selectronix, Inc." },
4406 { 374, "Gorbet & Banerjee, LLC." },
4408 { 376, "Stephen H. Dawson Computer Service" },
4409 { 377, "Accutrol, LLC" },
4410 { 378, "Schneider Elektronik GmbH" },
4411 { 379, "Alpha-Inno Tec GmbH" },
4412 { 380, "ADMMicro, Inc." },
4413 { 381, "Greystone Energy Systems, Inc." },
4414 { 382, "CAP Technologie" },
4415 { 383, "KeRo Systems" },
4416 { 384, "Domat Control System s.r.o." },
4417 { 385, "Efektronics Pty. Ltd." },
4418 { 386, "Hekatron Vertriebs GmbH" },
4419 { 387, "Securiton AG" },
4420 { 388, "Carlo Gavazzi Controls SpA" },
4421 { 389, "Chipkin Automation Systems" },
4422 { 390, "Savant Systems, LLC" },
4423 { 391, "Simmtronic Lighting Controls" },
4424 { 392, "Abelko Innovation AB" },
4425 { 393, "Seresco Technologies Inc." },
4426 { 394, "IT Watchdogs" },
4427 { 395, "Automation Assist Japan Corp." },
4428 { 396, "Thermokon Sensortechnik GmbH" },
4429 { 397, "EGauge Systems, LLC" },
4430 { 398, "Quantum Automation (ASIA) PTE, Ltd." },
4431 { 399, "Toshiba Lighting & Technology Corp." },
4432 { 400, "SPIN Engenharia de Automaca Ltda." },
4433 { 401, "Logistics Systems & Software Services India PVT. Ltd." },
4434 { 402, "Delta Controls Integration Products" },
4435 { 403, "Focus Media" },
4436 { 404, "LUMEnergi Inc." },
4437 { 405, "Kara Systems" },
4438 { 406, "RF Code, Inc." },
4439 { 407, "Fatek Automation Corp." },
4440 { 408, "JANDA Software Company, LLC" },
4441 { 409, "Open System Solutions Limited" },
4442 { 410, "Intelec Systems PTY Ltd." },
4443 { 411, "Ecolodgix, LLC" },
4444 { 412, "Douglas Lighting Controls" },
4445 { 413, "iSAtech GmbH" },
4447 { 415, "Beckhoff Automation GmbH" },
4448 { 416, "IPAS GmbH" },
4449 { 417, "KE2 Therm Solutions" },
4450 { 418, "Base2Products" },
4451 { 419, "DTL Controls, LLC" },
4452 { 420, "INNCOM International, Inc." },
4453 { 421, "BTR Netcom GmbH" },
4454 { 422, "Greentrol Automation, Inc" },
4455 { 423, "BELIMO Automation AG" },
4456 { 424, "Samsung Heavy Industries Co, Ltd" },
4457 { 425, "Triacta Power Technologies, Inc." },
4458 { 426, "Globestar Systems" },
4459 { 427, "MLB Advanced Media, LP" },
4460 { 428, "SWG Stuckmann Wirtschaftliche Gebaudesysteme GmbH" },
4461 { 429, "SensorSwitch" },
4462 { 430, "Multitek Power Limited" },
4463 { 431, "Aquametro AG" },
4464 { 432, "LG Electronics Inc." },
4465 { 433, "Electronic Theatre Controls, Inc." },
4466 { 434, "Mitsubishi Electric Corporation Nagoya Works" },
4467 { 435, "Delta Electronics, Inc." },
4468 { 436, "Elma Kurtalj, Ltd." },
4469 { 437, "ADT Fire and Security Sp. A.o.o." },
4470 { 438, "Nedap Security Management" },
4471 { 439, "ESC Automation Inc." },
4472 { 440, "DSP4YOU Ltd." },
4473 { 441, "GE Sensing and Inspection Technologies" },
4474 { 442, "Embedded Systems SIA" },
4475 { 443, "BEFEGA GmbH" },
4476 { 444, "Baseline Inc." },
4477 { 445, "M2M Systems Integrators" },
4479 { 447, "Clarkson Controls Limited" },
4480 { 448, "Rogerwell Control System Limited" },
4481 { 449, "SCL Elements" },
4482 { 450, "Hitachi Ltd." },
4483 { 451, "Newron System SA" },
4484 { 452, "BEVECO Gebouwautomatisering BV" },
4485 { 453, "Streamside Solutions" },
4486 { 454, "Yellowstone Soft" },
4487 { 455, "Oztech Intelligent Systems Pty Ltd." },
4488 { 456, "Novelan GmbH" },
4489 { 457, "Flexim Americas Corporation" },
4490 { 458, "ICP DAS Co., Ltd." },
4491 { 459, "CARMA Industries Inc." },
4492 { 460, "Log-One Ltd." },
4493 { 461, "TECO Electric & Machinery Co., Ltd." },
4494 { 462, "ConnectEx, Inc." },
4495 { 463, "Turbo DDC Sudwest" },
4496 { 464, "Quatrosense Environmental Ltd." },
4497 { 465, "Fifth Light Technology Ltd." },
4498 { 466, "Scientific Solutions, Ltd." },
4499 { 467, "Controller Area Network Solutions (M) Sdn Bhd" },
4500 { 468, "RESOL - Elektronische Regelungen GmbH" },
4501 { 469, "RPBUS LLC" },
4502 { 470, "BRS Sistemas Eletronicos" },
4503 { 471, "WindowMaster A/S" },
4504 { 472, "Sunlux Technologies Ltd." },
4505 { 473, "Measurlogic" },
4506 { 474, "Frimat GmbH" },
4507 { 475, "Spirax Sarco" },
4509 { 477, "Raypak Inc" },
4510 { 478, "Air Monitor Corporation" },
4511 { 479, "Regler Och Webbteknik Sverige (ROWS)" },
4512 { 480, "Intelligent Lighting Controls Inc." },
4513 { 481, "Sanyo Electric Industry Co., Ltd" },
4514 { 482, "E-Mon Energy Monitoring Products" },
4515 { 483, "Digital Control Systems" },
4516 { 484, "ATI Airtest Technologies, Inc." },
4518 { 486, "HMS Industrial Networks AB" },
4519 { 487, "Shenzhen Universal Intellisys Co Ltd" },
4520 { 488, "EK Intellisys Sdn Bhd" },
4522 { 490, "Firecom, Inc." },
4523 { 491, "ESA Elektroschaltanlagen Grimma GmbH" },
4524 { 492, "Kumahira Co Ltd" },
4526 { 494, "SABO Elektronik GmbH" },
4527 { 495, "Equip'Trans" },
4528 { 496, "TCS Basys Controls" },
4529 { 497, "FlowCon International A/S" },
4530 { 498, "ThyssenKrupp Elevator Americas" },
4531 { 499, "Abatement Technologies" },
4532 { 500, "Continental Control Systems, LLC" },
4533 { 501, "WISAG Automatisierungstechnik GmbH & Co KG" },
4535 { 503, "EAP-Electric GmbH" },
4536 { 504, "Hardmeier" },
4537 { 505, "Mircom Group of Companies" },
4538 { 506, "Quest Controls" },
4539 { 507, "Mestek, Inc" },
4540 { 508, "Pulse Energy" },
4541 { 509, "Tachikawa Corporation" },
4542 { 510, "University of Nebraska-Lincoln" },
4543 { 511, "Redwood Systems" },
4544 { 512, "PASStec Industrie-Elektronik GmbH" },
4545 { 513, "NgEK, Inc." },
4546 { 514, "FAW Electronics Ltd" },
4547 { 515, "Jireh Energy Tech Co., Ltd." },
4548 { 516, "Enlighted Inc." },
4549 { 517, "El-Piast Sp. Z o.o" },
4550 { 518, "NetxAutomation Software GmbH" },
4551 { 519, "Invertek Drives" },
4552 { 520, "Deutschmann Automation GmbH & Co. KG" },
4553 { 521, "EMU Electronic AG" },
4554 { 522, "Phaedrus Limited" },
4555 { 523, "Sigmatek GmbH & Co KG" },
4556 { 524, "Marlin Controls" },
4557 { 525, "Circutor, SA" },
4558 { 526, "UTC Fire & Security" },
4559 { 527, "DENT Instruments, Inc." },
4560 { 528, "FHP Manufacturing Company - Bosch Group" },
4561 { 529, "GE Intelligent Platforms" },
4562 { 530, "Inner Range Pty Ltd" },
4563 { 531, "GLAS Energy Technology" },
4564 { 532, "MSR-Electronic-GmbH" },
4565 { 533, "Energy Control Systems, Inc." },
4566 { 534, "EMT Controls" },
4567 { 535, "Daintree Networks Inc." },
4568 { 536, "EURO ICC d.o.o" },
4569 { 537, "TE Connectivity Energy" },
4570 { 538, "GEZE GmbH" },
4571 { 539, "NEC Corporation" },
4572 { 540, "Ho Cheung International Company Limited" },
4573 { 541, "Sharp Manufacturing Systems Corporation" },
4574 { 542, "DOT CONTROLS a.s." },
4575 { 543, "BeaconMedaes" },
4576 { 544, "Midea Commercial Aircon" },
4577 { 545, "WattMaster Controls" },
4578 { 546, "Kamstrup A/S" },
4579 { 547, "CA Computer Automation GmbH" },
4580 { 548, "Laars Heating Systems Company" },
4581 { 549, "Hitachi Systems, Ltd." },
4582 { 550, "Fushan AKE Electronic Engineering Co., Ltd." },
4583 { 551, "Toshiba International Corporation" },
4584 { 552, "Starman Systems, LLC" },
4585 { 553, "Samsung Techwin Co., Ltd." },
4586 { 554, "ISAS-Integrated Switchgear and Systems P/L" },
4588 { 557, "Marek Guzik" },
4589 { 558, "Vortek Instruments, LLC" },
4590 { 559, "Universal Lighting Technologies" },
4591 { 560, "Myers Power Products, Inc." },
4592 { 561, "Vector Controls GmbH" },
4593 { 562, "Crestron Electronics, Inc." },
4594 { 563, "A&E Controls Limited" },
4595 { 564, "Projektomontaza A.D." },
4596 { 565, "Freeaire Refrigeration" },
4597 { 566, "Aqua Cooler Pty Limited" },
4598 { 567, "Basic Controls" },
4599 { 568, "GE Measurement and Control Solutions Advanced Sensors" },
4600 { 569, "EQUAL Networks" },
4601 { 570, "Millennial Net" },
4602 { 571, "APLI Ltd" },
4603 { 572, "Electro Industries/GaugeTech" },
4604 { 573, "SangMyung University" },
4605 { 574, "Coppertree Analytics, Inc." },
4606 { 575, "CoreNetiX GmbH" },
4607 { 576, "Acutherm" },
4608 { 577, "Dr. Riedel Automatisierungstechnik GmbH" },
4609 { 578, "Shina System Co., Ltd" },
4610 { 579, "Iqapertus" },
4611 { 580, "PSE Technology" },
4612 { 581, "BA Systems" },
4614 { 583, "Monico, Inc." },
4616 { 585, "tekmar Control Systems Ltd." },
4617 { 586, "Control Technology Corporation" },
4618 { 587, "GFAE GmbH" },
4619 { 588, "BeKa Software GmbH" },
4620 { 589, "Isoil Industria SpA" },
4621 { 590, "Home Systems Consulting SpA" },
4623 { 592, "Everex Communications, Inc." },
4624 { 593, "Ceiec Electric Technology" },
4625 { 594, "Atrila GmbH" },
4626 { 595, "WingTechs" },
4627 { 596, "Shenzhen Mek Intellisys Pte Ltd." },
4628 { 597, "Nestfield Co., Ltd." },
4629 { 598, "Swissphone Telecom AG" },
4630 { 599, "PNTECH JSC" },
4631 { 600, "Horner APG, LLC" },
4632 { 601, "PVI Industries, LLC" },
4633 { 602, "Ela-compil" },
4634 { 603, "Pegasus Automation International LLC" },
4635 { 604, "Wight Electronic Services Ltd." },
4637 { 606, "Exhausto A/S" },
4638 { 607, "Dwyer Instruments, Inc." },
4639 { 608, "Link GmbH" },
4640 { 609, "Oppermann Regelgerate GmbH" },
4641 { 610, "NuAire, Inc." },
4642 { 611, "Nortec Humidity, Inc." },
4643 { 612, "Bigwood Systems, Inc." },
4644 { 613, "Enbala Power Networks" },
4645 { 614, "Inter Energy Co., Ltd." },
4647 { 616, "COMELEC S.A.R.L" },
4648 { 617, "Pythia Technologies" },
4649 { 618, "TrendPoint Systems, Inc." },
4652 { 621, "Kongsberg E-lon AS" },
4653 { 622, "FlaktWoods" },
4654 { 623, "E + E Elektronik GES M.B.H." },
4655 { 624, "ARC Informatique" },
4656 { 625, "SKIDATA AG" },
4657 { 626, "WSW Solutions" },
4658 { 627, "Trefon Electronic GmbH" },
4659 { 628, "Dongseo System" },
4660 { 629, "Kanontec Intelligence Technology Co., Ltd." },
4661 { 630, "EVCO S.p.A." },
4662 { 631, "Accuenergy (CANADA) Inc." },
4664 { 633, "Orion Energy Systems, Inc." },
4665 { 634, "Roboticsware" },
4666 { 635, "DOMIQ Sp. z o.o." },
4667 { 636, "Solidyne" },
4668 { 637, "Elecsys Corporation" },
4669 { 638, "Conditionaire International Pty. Limited" },
4670 { 639, "Quebec, Inc." },
4671 { 640, "Homerun Holdings" },
4672 { 641, "RFM, Inc." },
4674 { 643, "Westco Systems, Inc." },
4675 { 644, "Advancis Software & Services GmbH" },
4676 { 645, "Intergrid, LLC" },
4677 { 646, "Markerr Controls, Inc." },
4678 { 647, "Toshiba Elevator and Building Systems Corporation" },
4679 { 648, "Spectrum Controls, Inc." },
4680 { 649, "Mkservice" },
4681 { 650, "Fox Thermal Instruments" },
4682 { 651, "SyxthSense Ltd" },
4683 { 652, "DUHA System S R.O." },
4685 { 654, "Melink Corporation" },
4686 { 655, "Fritz-Haber-Institut" },
4687 { 656, "MTU Onsite Energy GmbH, Gas Power Systems" },
4688 { 657, "Omega Engineering, Inc." },
4690 { 659, "Ywire Technologies, Inc." },
4691 { 660, "M.R. Engineering Co., Ltd." },
4692 { 661, "Lochinvar, LLC" },
4693 { 662, "Sontay Limited" },
4694 { 663, "GRUPA Slawomir Chelminski" },
4695 { 664, "Arch Meter Corporation" },
4696 { 665, "Senva, Inc." },
4698 { 668, "Systems Specialists, Inc." },
4699 { 669, "SenseAir" },
4700 { 670, "AB IndustrieTechnik Srl" },
4701 { 671, "Cortland Research, LLC" },
4702 { 672, "MediaView" },
4703 { 673, "VDA Elettronica" },
4704 { 674, "CSS, Inc." },
4705 { 675, "Tek-Air Systems, Inc." },
4707 { 677, "The Armstrong Monitoring Corporation" },
4708 { 678, "DIXELL S.r.l" },
4709 { 679, "Lead System, Inc." },
4710 { 680, "ISM EuroCenter S.A." },
4712 { 682, "Trade FIDES" },
4713 { 683, "Knurr GmbH (Emerson Network Power)" },
4714 { 684, "Resource Data Management" },
4715 { 685, "Abies Technology, Inc." },
4717 { 687, "MIRAE Electrical Mfg. Co., Ltd." },
4718 { 688, "HunterDouglas Architectural Projects Scandinavia ApS" },
4719 { 689, "RUNPAQ Group Co., Ltd" },
4720 { 690, "Unicard SA" },
4721 { 691, "IE Technologies" },
4722 { 692, "Ruskin Manufacturing" },
4723 { 693, "Calon Associates Limited" },
4724 { 694, "Contec Co., Ltd." },
4726 { 696, "Autani Corporation"},
4727 { 697, "Christian Fortin"},
4729 { 699, "IPID Sp. Z.O.O Limited"},
4730 { 700, "Fuji Electric Co., Ltd"},
4731 { 701, "View, Inc."},
4732 { 702, "Samsung S1 Corporation"},
4734 { 704, "VRT Systems"},
4737 static value_string_ext BACnetVendorIdentifiers_ext = VALUE_STRING_EXT_INIT(BACnetVendorIdentifiers);
4739 static int proto_bacapp = -1;
4740 static int hf_bacapp_type = -1;
4741 static int hf_bacapp_pduflags = -1;
4742 static int hf_bacapp_SEG = -1;
4743 static int hf_bacapp_MOR = -1;
4744 static int hf_bacapp_SA = -1;
4745 static int hf_bacapp_response_segments = -1;
4746 static int hf_bacapp_max_adpu_size = -1;
4747 static int hf_bacapp_invoke_id = -1;
4748 static int hf_bacapp_objectType = -1;
4749 static int hf_bacapp_instanceNumber = -1;
4750 static int hf_bacapp_sequence_number = -1;
4751 static int hf_bacapp_window_size = -1;
4752 static int hf_bacapp_service = -1;
4753 static int hf_bacapp_NAK = -1;
4754 static int hf_bacapp_SRV = -1;
4755 static int hf_Device_Instance_Range_Low_Limit = -1;
4756 static int hf_Device_Instance_Range_High_Limit = -1;
4757 static int hf_BACnetRejectReason = -1;
4758 static int hf_BACnetAbortReason = -1;
4759 static int hf_BACnetApplicationTagNumber = -1;
4760 static int hf_BACnetContextTagNumber = -1;
4761 static int hf_BACnetExtendedTagNumber = -1;
4762 static int hf_BACnetNamedTag = -1;
4763 static int hf_BACnetTagClass = -1;
4764 static int hf_BACnetCharacterSet = -1;
4765 static int hf_bacapp_tag_lvt = -1;
4766 static int hf_bacapp_tag_ProcessId = -1;
4767 static int hf_bacapp_uservice = -1;
4768 static int hf_BACnetPropertyIdentifier = -1;
4769 static int hf_BACnetVendorIdentifier = -1;
4770 static int hf_BACnetRestartReason = -1;
4771 static int hf_bacapp_tag_IPV4 = -1;
4772 static int hf_bacapp_tag_IPV6 = -1;
4773 static int hf_bacapp_tag_PORT = -1;
4774 /* some more variables for segmented messages */
4775 static int hf_msg_fragments = -1;
4776 static int hf_msg_fragment = -1;
4777 static int hf_msg_fragment_overlap = -1;
4778 static int hf_msg_fragment_overlap_conflicts = -1;
4779 static int hf_msg_fragment_multiple_tails = -1;
4780 static int hf_msg_fragment_too_long_fragment = -1;
4781 static int hf_msg_fragment_error = -1;
4782 static int hf_msg_fragment_count = -1;
4783 static int hf_msg_reassembled_in = -1;
4784 static int hf_msg_reassembled_length = -1;
4786 static gint ett_msg_fragment = -1;
4787 static gint ett_msg_fragments = -1;
4789 static gint ett_bacapp = -1;
4790 static gint ett_bacapp_control = -1;
4791 static gint ett_bacapp_tag = -1;
4792 static gint ett_bacapp_list = -1;
4793 static gint ett_bacapp_value = -1;
4795 static expert_field ei_bacapp_bad_length = EI_INIT;
4797 static gint32 propertyIdentifier = -1;
4798 static gint32 propertyArrayIndex = -1;
4799 static guint32 object_type = 4096;
4801 static guint8 bacapp_flags = 0;
4802 static guint8 bacapp_seq = 0;
4804 /* Defined to allow vendor identifier registration of private transfer dissectors */
4805 static dissector_table_t bacapp_dissector_table;
4808 /* Stat: BACnet Packets sorted by IP */
4809 bacapp_info_value_t bacinfo;
4811 static const gchar* st_str_packets_by_ip = "BACnet Packets by IP";
4812 static const gchar* st_str_packets_by_ip_dst = "By Destination";
4813 static const gchar* st_str_packets_by_ip_src = "By Source";
4814 static int st_node_packets_by_ip = -1;
4815 static int st_node_packets_by_ip_dst = -1;
4816 static int st_node_packets_by_ip_src = -1;
4819 bacapp_packet_stats_tree_init(stats_tree* st)
4821 st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
4822 st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4823 st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4827 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4829 int packets_for_this_dst;
4830 int packets_for_this_src;
4831 int service_for_this_dst;
4832 int service_for_this_src;
4833 int src_for_this_dst;
4834 int dst_for_this_src;
4835 int objectid_for_this_dst;
4836 int objectid_for_this_src;
4837 int instanceid_for_this_dst;
4838 int instanceid_for_this_src;
4841 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4843 srcstr = wmem_strconcat(wmem_packet_scope(), "Src: ", ep_address_to_str(&pinfo->src), NULL);
4844 dststr = wmem_strconcat(wmem_packet_scope(), "Dst: ", ep_address_to_str(&pinfo->dst), NULL);
4846 tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
4847 packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
4848 packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
4849 src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
4850 dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
4851 service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
4852 service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
4853 if (binfo->service_type) {
4854 objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
4855 objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
4856 if (binfo->object_ident) {
4857 instanceid_for_this_dst = tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
4858 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
4859 instanceid_for_this_src = tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
4860 tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
4867 /* Stat: BACnet Packets sorted by Service */
4868 static const gchar* st_str_packets_by_service = "BACnet Packets by Service";
4869 static int st_node_packets_by_service = -1;
4872 bacapp_service_stats_tree_init(stats_tree* st)
4874 st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
4878 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4887 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4889 srcstr = wmem_strconcat(wmem_packet_scope(), "Src: ", ep_address_to_str(&pinfo->src), NULL);
4890 dststr = wmem_strconcat(wmem_packet_scope(), "Dst: ", ep_address_to_str(&pinfo->dst), NULL);
4892 tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
4893 if (binfo->service_type) {
4894 servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
4895 src = tick_stat_node(st, srcstr, servicetype, TRUE);
4896 dst = tick_stat_node(st, dststr, src, TRUE);
4897 if (binfo->object_ident) {
4898 objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
4899 tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
4906 /* Stat: BACnet Packets sorted by Object Type */
4907 static const gchar* st_str_packets_by_objectid = "BACnet Packets by Object Type";
4908 static int st_node_packets_by_objectid = -1;
4911 bacapp_objectid_stats_tree_init(stats_tree* st)
4913 st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
4917 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4925 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4927 srcstr = wmem_strconcat(wmem_packet_scope(), "Src: ", ep_address_to_str(&pinfo->src), NULL);
4928 dststr = wmem_strconcat(wmem_packet_scope(), "Dst: ", ep_address_to_str(&pinfo->dst), NULL);
4930 tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
4931 if (binfo->object_ident) {
4932 objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
4933 src = tick_stat_node(st, srcstr, objectid, TRUE);
4934 dst = tick_stat_node(st, dststr, src, TRUE);
4935 if (binfo->service_type) {
4936 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4937 tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
4944 /* Stat: BACnet Packets sorted by Instance No */
4945 static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
4946 static int st_node_packets_by_instanceid = -1;
4949 bacapp_instanceid_stats_tree_init(stats_tree* st)
4951 st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
4955 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
4963 const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
4965 srcstr = wmem_strconcat(wmem_packet_scope(), "Src: ", ep_address_to_str(&pinfo->src), NULL);
4966 dststr = wmem_strconcat(wmem_packet_scope(), "Dst: ", ep_address_to_str(&pinfo->dst), NULL);
4968 tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
4969 if (binfo->object_ident) {
4970 instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
4971 src = tick_stat_node(st, srcstr, instanceid, TRUE);
4972 dst = tick_stat_node(st, dststr, src, TRUE);
4973 if (binfo->service_type) {
4974 servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
4975 tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
4982 /* register all BACnet Ststistic trees */
4984 register_bacapp_stat_trees(void)
4986 stats_tree_register("bacapp", "bacapp_ip", "BACnet/Packets sorted by IP", 0,
4987 bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
4988 stats_tree_register("bacapp", "bacapp_service", "BACnet/Packets sorted by Service", 0,
4989 bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
4990 stats_tree_register("bacapp", "bacapp_objectid", "BACnet/Packets sorted by Object Type", 0,
4991 bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
4992 stats_tree_register("bacapp", "bacapp_instanceid", "BACnet/Packets sorted by Instance ID", 0,
4993 bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
4996 /* 'data' must be ep_ allocated */
4998 updateBacnetInfoValue(gint whichval, const gchar *data)
5000 if (whichval == BACINFO_SERVICE) {
5001 bacinfo.service_type = data;
5004 if (whichval == BACINFO_INVOKEID) {
5005 bacinfo.invoke_id = data;
5008 if (whichval == BACINFO_OBJECTID) {
5009 bacinfo.object_ident = data;
5012 if (whichval == BACINFO_INSTANCEID) {
5013 bacinfo.instance_ident = data;
5019 static const fragment_items msg_frag_items = {
5020 /* Fragment subtrees */
5023 /* Fragment fields */
5026 &hf_msg_fragment_overlap,
5027 &hf_msg_fragment_overlap_conflicts,
5028 &hf_msg_fragment_multiple_tails,
5029 &hf_msg_fragment_too_long_fragment,
5030 &hf_msg_fragment_error,
5031 &hf_msg_fragment_count,
5032 /* Reassembled in field */
5033 &hf_msg_reassembled_in,
5034 /* Reassembled length field */
5035 &hf_msg_reassembled_length,
5036 /* Reassembled data field */
5043 /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
5044 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
5045 static const guint MaxAPDUSize [] = { 50, 128, 206, 480, 1024, 1476 };
5048 fGetMaxAPDUSize(guint8 idx)
5050 /* only 16 values are defined, so use & 0x0f */
5051 /* check the size of the Array, deliver either the entry
5052 or the first entry if idx is outside of the array (bug 3736 comment#7) */
5054 if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
5055 return MaxAPDUSize[0];
5057 return MaxAPDUSize[idx & 0x0f];
5062 /* Used when there are ranges of reserved and proprietary enumerations */
5064 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
5065 const char *fmt, const char *split_fmt)
5067 if (val < split_val)
5068 return val_to_str(val, vs, fmt);
5070 return val_to_str(val, vs, split_fmt);
5073 /* from clause 20.2.1.3.2 Constructed Data */
5074 /* returns true if the extended value is used */
5076 tag_is_extended_value(guint8 tag)
5078 return (tag & 0x07) == 5;
5082 tag_is_opening(guint8 tag)
5084 return (tag & 0x07) == 6;
5088 tag_is_closing(guint8 tag)
5090 return (tag & 0x07) == 7;
5093 /* from clause 20.2.1.1 Class
5094 class bit shall be one for context specific tags */
5095 /* returns true if the tag is context specific */
5097 tag_is_context_specific(guint8 tag)
5099 return (tag & 0x08) != 0;
5103 tag_is_extended_tag_number(guint8 tag)
5105 return ((tag & 0xF0) == 0xF0);
5109 object_id_type(guint32 object_identifier)
5111 return ((object_identifier >> 22) & 0x3FF);
5115 object_id_instance(guint32 object_identifier)
5117 return (object_identifier & 0x3FFFFF);
5121 fTagNo(tvbuff_t *tvb, guint offset)
5123 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
5127 fUnsigned32(tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
5129 gboolean valid = TRUE;
5133 *val = tvb_get_guint8(tvb, offset);
5136 *val = tvb_get_ntohs(tvb, offset);
5139 *val = tvb_get_ntoh24(tvb, offset);
5142 *val = tvb_get_ntohl(tvb, offset);
5153 fUnsigned64(tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
5155 gboolean valid = FALSE;
5159 if (lvt && (lvt <= 8)) {
5161 for (i = 0; i < lvt; i++) {
5162 data = tvb_get_guint8(tvb, offset+i);
5163 value = (value << 8) + data;
5171 /* BACnet Signed Value uses 2's complement notation, but with a twist:
5172 All signed integers shall be encoded in the smallest number of octets
5173 possible. That is, the first octet of any multi-octet encoded value
5174 shall not be X'00' if the most significant bit (bit 7) of the second
5175 octet is 0, and the first octet shall not be X'FF' if the most
5176 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
5178 fSigned64(tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
5180 gboolean valid = FALSE;
5185 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
5186 if (lvt && (lvt <= 7)) {
5188 data = tvb_get_guint8(tvb, offset);
5189 if ((data & 0x80) != 0)
5190 value = (-1 << 8) | data;
5193 for (i = 1; i < lvt; i++) {
5194 data = tvb_get_guint8(tvb, offset+i);
5195 value = (value << 8) + data;
5204 fTagHeaderTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5205 guint offset, guint8 *tag_no, guint8* tag_info, guint32 *lvt)
5207 proto_item *ti = NULL;
5211 guint lvt_len = 1; /* used for tree display of lvt */
5212 guint lvt_offset; /* used for tree display of lvt */
5214 lvt_offset = offset;
5215 tag = tvb_get_guint8(tvb, offset);
5219 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
5220 /* can mean open/close tag or length of 6/7 after the length is */
5221 /* computed below - store whole tag info, not just context bit. */
5222 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
5224 if (tag_is_extended_tag_number(tag)) {
5225 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
5227 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
5228 lvt_offset += tag_len;
5229 value = tvb_get_guint8(tvb, lvt_offset);
5231 if (value == 254) { /* length is encoded with 16 Bits */
5232 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
5235 } else if (value == 255) { /* length is encoded with 32 Bits */
5236 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
5244 proto_tree *subtree;
5245 if (tag_is_opening(tag))
5246 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
5247 else if (tag_is_closing(tag))
5248 ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
5249 else if (tag_is_context_specific(tag)) {
5250 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
5251 "Context Tag: %u, Length/Value/Type: %u",
5254 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
5255 "Application Tag: %s, Length/Value/Type: %u",
5257 BACnetApplicationTagNumber,
5258 ASHRAE_Reserved_Fmt),
5261 /* details if needed */
5262 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5263 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
5264 if (tag_is_extended_tag_number(tag)) {
5265 proto_tree_add_uint_format(subtree,
5266 hf_BACnetContextTagNumber,
5267 tvb, offset, 1, tag,
5268 "Extended Tag Number");
5269 proto_tree_add_item(subtree,
5270 hf_BACnetExtendedTagNumber,
5271 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
5273 if (tag_is_context_specific(tag))
5274 proto_tree_add_item(subtree,
5275 hf_BACnetContextTagNumber,
5276 tvb, offset, 1, ENC_BIG_ENDIAN);
5278 proto_tree_add_item(subtree,
5279 hf_BACnetApplicationTagNumber,
5280 tvb, offset, 1, ENC_BIG_ENDIAN);
5282 if (tag_is_closing(tag) || tag_is_opening(tag))
5283 proto_tree_add_item(subtree,
5285 tvb, offset, 1, ENC_BIG_ENDIAN);
5286 else if (tag_is_extended_value(tag)) {
5287 proto_tree_add_item(subtree,
5289 tvb, offset, 1, ENC_BIG_ENDIAN);
5290 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
5291 tvb, lvt_offset, lvt_len, *lvt);
5293 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
5294 tvb, lvt_offset, lvt_len, *lvt);
5297 if (*lvt > tvb_length(tvb)) {
5298 expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
5299 "LVT length too long: %d > %d", *lvt,
5308 fTagHeader(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* tag_info,
5311 return fTagHeaderTree(tvb, pinfo, NULL, offset, tag_no, tag_info, lvt);
5315 fNullTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5317 guint8 tag_no, tag_info;
5320 proto_tree *subtree;
5322 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
5323 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5324 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5330 fBooleanTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5332 guint8 tag_no, tag_info;
5335 proto_tree *subtree;
5338 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5339 if (tag_info && lvt == 1) {
5340 lvt = tvb_get_guint8(tvb, offset+1);
5344 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
5345 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
5346 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5347 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5349 return offset + bool_len;
5353 fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5356 guint8 tag_no, tag_info;
5360 proto_tree *subtree;
5362 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5363 /* only support up to an 8 byte (64-bit) integer */
5364 if (fUnsigned64(tvb, offset + tag_len, lvt, &val))
5365 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5366 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
5368 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5369 "%s - %u octets (Unsigned)", label, lvt);
5370 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5371 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5373 return offset+tag_len+lvt;
5377 fDevice_Instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, int hf)
5379 guint8 tag_no, tag_info;
5380 guint32 lvt, safe_lvt;
5383 proto_tree *subtree;
5385 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5392 ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, safe_lvt, ENC_BIG_ENDIAN);
5394 if (lvt != safe_lvt)
5395 expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
5396 "This field claims to be an impossible %u bytes, while the max is %u", lvt, safe_lvt);
5398 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5399 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5401 return offset+tag_len+lvt;
5404 /* set split_val to zero when not needed */
5406 fEnumeratedTagSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5407 guint offset, const gchar *label, const value_string *vs, guint32 split_val)
5410 guint8 tag_no, tag_info;
5414 proto_tree *subtree;
5416 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5417 /* only support up to a 4 byte (32-bit) enumeration */
5418 if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) {
5420 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5421 "%s %s", label, val_to_split_str(val, split_val, vs,
5422 ASHRAE_Reserved_Fmt, Vendor_Proprietary_Fmt));
5424 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5425 "%s %u", label, val);
5427 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5428 "%s - %u octets (enumeration)", label, lvt);
5430 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5431 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5433 return offset+tag_len+lvt;
5437 fEnumeratedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5438 guint offset, const gchar *label, const value_string *vs)
5440 return fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, vs, 0);
5444 fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5447 guint8 tag_no, tag_info;
5451 proto_tree *subtree;
5453 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5454 if (fSigned64(tvb, offset + tag_len, lvt, &val))
5455 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5456 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
5458 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5459 "%s - %u octets (Signed)", label, lvt);
5460 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5461 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5463 return offset+tag_len+lvt;
5467 fRealTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5469 guint8 tag_no, tag_info;
5474 proto_tree *subtree;
5476 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5477 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
5478 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
5479 "%s%f (Real)", label, f_val);
5480 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5481 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5483 return offset+tag_len+4;
5487 fDoubleTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5489 guint8 tag_no, tag_info;
5494 proto_tree *subtree;
5496 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5497 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
5498 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
5499 "%s%f (Double)", label, d_val);
5500 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5501 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5503 return offset+tag_len+8;
5507 fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5509 guint32 val = 0, lvt;
5510 guint8 tag_no, tag_info;
5512 proto_tree *subtree;
5515 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5516 if (fUnsigned32(tvb, offset+tag_len, lvt, &val))
5517 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
5518 tvb, offset, lvt+tag_len, val);
5520 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5521 "Process Identifier - %u octets (Signed)", lvt);
5522 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5523 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5524 offset += tag_len + lvt;
5530 fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5532 guint32 val = 0, lvt;
5533 guint8 tag_no, tag_info;
5535 proto_tree *subtree;
5538 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5539 if (fUnsigned32(tvb, offset+tag_len, lvt, &val))
5540 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5541 "%s (hh.mm.ss): %d.%02d.%02d%s",
5543 (val / 3600), ((val % 3600) / 60), (val % 60),
5544 val == 0 ? " (indefinite)" : "");
5546 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5547 "%s - %u octets (Signed)", label, lvt);
5548 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5549 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5551 return offset+tag_len+lvt;
5555 fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5557 guint32 month, weekOfMonth, dayOfWeek;
5558 guint8 tag_no, tag_info;
5562 proto_tree *subtree;
5564 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5565 month = tvb_get_guint8(tvb, offset+tag_len);
5566 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
5567 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
5568 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
5569 val_to_str(month, months, "month (%d) not found"),
5570 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
5571 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
5572 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5573 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5575 return offset+tag_len+lvt;
5579 fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5581 guint32 year, month, day, weekday;
5582 guint8 tag_no, tag_info;
5586 proto_tree *subtree;
5588 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5589 year = tvb_get_guint8(tvb, offset+tag_len);
5590 month = tvb_get_guint8(tvb, offset+tag_len+1);
5591 day = tvb_get_guint8(tvb, offset+tag_len+2);
5592 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
5593 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
5594 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5597 else if (year != 255) {
5599 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5600 "%s%s %d, %d, (Day of Week = %s)",
5601 label, val_to_str(month,
5603 "month (%d) not found"),
5604 day, year, val_to_str(weekday,
5608 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5609 "%s%s %d, any year, (Day of Week = %s)",
5610 label, val_to_str(month, months, "month (%d) not found"),
5611 day, val_to_str(weekday, day_of_week, "(%d) not found"));
5613 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5614 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5616 return offset+tag_len+lvt;
5620 fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5622 guint32 hour, minute, second, msec, lvt;
5623 guint8 tag_no, tag_info;
5626 proto_tree *subtree;
5628 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5629 hour = tvb_get_guint8(tvb, offset+tag_len);
5630 minute = tvb_get_guint8(tvb, offset+tag_len+1);
5631 second = tvb_get_guint8(tvb, offset+tag_len+2);
5632 msec = tvb_get_guint8(tvb, offset+tag_len+3);
5633 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
5634 ti = proto_tree_add_text(tree, tvb, offset,
5635 lvt+tag_len, "%sany", label);
5637 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
5638 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
5640 hour > 12 ? hour - 12 : hour,
5641 minute, second, msec,
5642 hour >= 12 ? "P.M." : "A.M.",
5643 hour, minute, second, msec);
5644 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5645 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5647 return offset+tag_len+lvt;
5651 fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5653 proto_tree *subtree = tree;
5656 if (label != NULL) {
5657 tt = proto_tree_add_text(subtree, tvb, offset, 10, "%s", label);
5658 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5660 offset = fDate(tvb, pinfo, subtree, offset, "Date: ");
5661 return fTime(tvb, pinfo, subtree, offset, "Time: ");
5665 fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5667 guint lastoffset = 0;
5668 guint8 tag_no, tag_info;
5671 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5672 lastoffset = offset;
5673 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5674 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
5677 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
5678 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
5680 if (offset == lastoffset) break; /* exit loop if nothing happens inside */
5686 fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5688 guint8 tag_no, tag_info;
5691 switch (fTagNo(tvb, offset)) {
5693 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
5695 case 1: /* dateRange */
5696 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5697 offset = fDateRange(tvb, pinfo, tree, offset);
5698 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5700 case 2: /* BACnetWeekNDay */
5701 offset = fWeekNDay(tvb, pinfo, tree, offset);
5711 fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
5714 proto_tree* subtree = tree;
5717 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5718 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
5720 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5722 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: ");
5723 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: ");
5724 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: ");
5730 fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
5732 guint8 tag_no = 0, tag_info = 0;
5735 if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
5736 switch (fTagNo(tvb, offset)) {
5738 offset = fTime(tvb, pinfo, tree, offset, label?label:"time: ");
5740 case 1: /* sequenceNumber */
5741 offset = fUnsignedTag(tvb, pinfo, tree, offset,
5742 label?label:"sequence number: ");
5744 case 2: /* dateTime */
5745 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5746 offset = fDateTime(tvb, pinfo, tree, offset, label?label:"date time: ");
5747 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5759 fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5761 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5762 offset = fApplicationTypes(tvb, pinfo, tree, offset, "increment: ");
5767 static const value_string
5768 BACnetDaysOfWeek [] = {
5780 fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5782 if (tvb_reported_length_remaining(tvb, offset) > 0) {
5783 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
5784 "valid Days: ", BACnetDaysOfWeek);
5785 offset = fTime(tvb, pinfo, tree, offset, "from time: ");
5786 offset = fTime(tvb, pinfo, tree, offset, "to time: ");
5787 offset = fRecipient(tvb, pinfo, tree, offset);
5788 offset = fProcessId(tvb, pinfo, tree, offset);
5789 offset = fApplicationTypes(tvb, pinfo, tree, offset,
5790 "issue confirmed notifications: ");
5791 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
5792 "transitions: ", BACnetEventTransitionBits);
5799 fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5802 guint start = offset;
5803 guint8 tag_no, tag_info;
5804 proto_tree *subtree = tree;
5807 offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5810 tmp = tvb_bytes_to_ep_str(tvb, offset, lvt);
5811 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
5816 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5818 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5824 fMacAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
5827 guint start = offset;
5828 guint8 tag_no, tag_info;
5829 proto_tree* subtree = tree;
5832 offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5834 ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
5837 if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
5839 guint32 ip = tvb_get_ipv4(tvb, offset);
5840 guint16 port = tvb_get_ntohs(tvb, offset+4);
5842 proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
5843 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
5846 if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
5847 struct e_in6_addr addr;
5848 guint16 port = tvb_get_ntohs(tvb, offset+16);
5849 tvb_get_ipv6(tvb, offset, &addr);
5851 proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
5852 proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
5854 } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
5855 tmp = tvb_bytes_to_ep_str(tvb, offset, lvt);
5856 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
5863 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5865 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
5871 fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5873 guint8 tag_no, tag_info;
5877 offset = fUnsignedTag(tvb, pinfo, tree, offset, "network-number");
5878 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5880 proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
5883 offset = fMacAddress(tvb, pinfo, tree, offset, "MAC-address: ", lvt);
5889 fSessionKey(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5891 offset = fOctetString(tvb, pinfo, tree, offset, "session key: ", 8);
5892 return fAddress(tvb, pinfo, tree, offset);
5896 fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5898 guint8 tag_no, tag_info;
5902 proto_tree *subtree;
5905 tag_length = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5906 object_id = tvb_get_ntohl(tvb, offset+tag_length);
5907 object_type = object_id_type(object_id);
5908 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
5909 "ObjectIdentifier: %s, %u",
5910 val_to_split_str(object_type,
5913 ASHRAE_Reserved_Fmt,
5914 Vendor_Proprietary_Fmt),
5915 object_id_instance(object_id));
5916 if (col_get_writable(pinfo->cinfo))
5917 col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
5918 val_to_split_str(object_type,
5921 ASHRAE_Reserved_Fmt,
5922 Vendor_Proprietary_Fmt),
5923 object_id_instance(object_id));
5925 /* update BACnet Statistics */
5926 updateBacnetInfoValue(BACINFO_OBJECTID,
5927 wmem_strdup(wmem_packet_scope(),
5928 val_to_split_str(object_type, 128,
5929 BACnetObjectType, ASHRAE_Reserved_Fmt,
5930 Vendor_Proprietary_Fmt)));
5931 updateBacnetInfoValue(BACINFO_INSTANCEID,
5932 wmem_strdup_printf(wmem_packet_scope(),
5934 object_id_instance(object_id)));
5936 /* here are the details of how we arrived at the above text */
5937 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
5938 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
5939 offset += tag_length;
5940 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
5941 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
5948 fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5950 guint8 tag_no, tag_info;
5953 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
5955 if (tag_no == 0) { /* device */
5956 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
5958 else { /* address */
5959 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5960 offset = fAddress(tvb, pinfo, tree, offset);
5961 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
5968 fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
5970 guint lastoffset = 0;
5971 guint8 tag_no, tag_info;
5973 proto_tree *orgtree = tree;
5975 proto_tree *subtree;
5977 /* beginning of new item - indent and label */
5978 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
5979 tree = proto_item_add_subtree(tt, ett_bacapp_value);
5981 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
5982 lastoffset = offset;
5984 switch (fTagNo(tvb, offset)) {
5985 case 0: /* recipient */
5986 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
5987 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
5988 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5989 offset = fRecipient(tvb, pinfo, subtree, offset);
5990 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
5992 case 1: /* processId */
5993 offset = fProcessId(tvb, pinfo, tree, offset);
5994 lastoffset = offset;
5999 if (offset == lastoffset) break; /* nothing happened, exit loop */
6005 fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6007 guint lastoffset = 0;
6008 guint8 tag_no, tag_info;
6010 proto_tree *subtree;
6012 proto_tree *orgtree = tree;
6015 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6016 lastoffset = offset;
6017 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6018 if (tag_is_closing(tag_info) ) {
6023 case 0: /* recipient */
6024 /* beginning of new item in list */
6025 tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno); /* add tree label and indent */
6026 itemno = itemno + 1;
6027 tree = proto_item_add_subtree(tt, ett_bacapp_value);
6029 tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient"); /* add tree label and indent */
6030 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6031 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
6032 offset = fRecipientProcess(tvb, pinfo, subtree, offset);
6033 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */
6035 case 1: /* MonitoredPropertyReference */
6036 tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
6037 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
6038 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6039 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
6040 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6042 case 2: /* IssueConfirmedNotifications - boolean */
6043 offset = fBooleanTag(tvb, pinfo, tree, offset, "Issue Confirmed Notifications: ");
6045 case 3: /* TimeRemaining */
6046 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Time Remaining: ");
6048 case 4: /* COVIncrement */
6049 offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
6054 if (offset == lastoffset) break; /* nothing happened, exit loop */
6060 fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6062 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
6063 return fAddress(tvb, pinfo, tree, offset);
6067 fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
6069 guint lastoffset = 0, len;
6070 guint8 tag_no, tag_info;
6072 proto_tree *subtree = tree;
6074 /* set the optional global properties to indicate not-used */
6075 propertyArrayIndex = -1;
6076 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6077 lastoffset = offset;
6078 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6079 if (tag_is_closing(tag_info) ) {
6080 if (tag_no == tag_match) {
6089 case 0: /* deviceIdentifier */
6090 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
6092 case 1: /* objectIdentifier */
6093 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
6095 case 2: /* propertyIdentifier */
6096 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
6098 case 3: /* propertyArrayIndex */
6099 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
6101 case 4: /* propertyValue */
6102 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
6104 case 5: /* priority */
6105 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
6107 case 6: /* postDelay */
6108 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Post Delay: ");
6110 case 7: /* quitOnFailure */
6111 offset = fBooleanTag(tvb, pinfo, subtree, offset,
6112 "Quit On Failure: ");
6114 case 8: /* writeSuccessful */
6115 offset = fBooleanTag(tvb, pinfo, subtree, offset,
6116 "Write Successful: ");
6121 if (offset == lastoffset) break; /* nothing happened, exit loop */
6126 /* BACnetActionList ::= SEQUENCE{
6127 action [0] SEQUENCE OF BACnetActionCommand
6131 fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6133 guint lastoffset = 0, len;
6134 guint8 tag_no, tag_info;
6136 proto_tree *subtree = tree;
6139 while (tvb_reported_length_remaining(tvb, offset) > 0) {
6140 lastoffset = offset;
6141 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6142 if (tag_is_closing(tag_info)) {
6144 if ( tag_no != 0 ) /* don't eat the closing property tag, just return */
6149 if (tag_is_opening(tag_info)) {
6150 ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
6151 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6152 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
6153 &tag_no, &tag_info, &lvt);
6156 case 0: /* BACnetActionCommand */
6157 offset = fActionCommand(tvb, pinfo, subtree, offset, tag_no);
6162 if (offset == lastoffset) break; /* nothing happened, exit loop */
6168 fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6170 guint8 tag_no, tag_info;
6174 proto_tree *subtree;
6175 const gchar *label = "Property Identifier";
6177 propertyIdentifier = 0; /* global Variable */
6178 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6179 /* can we decode this value? */
6180 if (fUnsigned32(tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
6181 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6182 "%s: %s (%u)", label,
6183 val_to_split_str(propertyIdentifier, 512,
6184 BACnetPropertyIdentifier,
6185 ASHRAE_Reserved_Fmt,
6186 Vendor_Proprietary_Fmt), propertyIdentifier);
6187 if (col_get_writable(pinfo->cinfo))
6188 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
6189 val_to_split_str(propertyIdentifier, 512,
6190 BACnetPropertyIdentifier,
6191 ASHRAE_Reserved_Fmt,
6192 Vendor_Proprietary_Fmt));
6194 /* property identifiers cannot be larger than 22-bits */
6197 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6198 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6199 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
6200 offset+tag_len, lvt, ENC_BIG_ENDIAN);
6202 return offset+tag_len+lvt;
6206 fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6208 guint8 tag_no, tag_info;
6212 proto_tree *subtree;
6214 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6215 if (fUnsigned32(tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
6216 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6217 "property Array Index (Unsigned) %u", propertyArrayIndex);
6219 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
6220 "property Array Index - %u octets (Unsigned)", lvt);
6221 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6222 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6224 return offset+tag_len+lvt;
6228 fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6230 guint8 tag_no, tag_info, character_set;
6232 guint offs, extra = 1;
6234 guint8 bf_arr[512], *out = &bf_arr[0];
6236 proto_tree *subtree;
6237 guint start = offset;
6239 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6241 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6243 character_set = tvb_get_guint8(tvb, offset+offs);
6244 /* Account for code page if DBCS */
6245 if (character_set == 1) {
6248 offset += (offs+extra);
6254 * XXX - are we guaranteed that these encoding
6255 * names correspond, on *all* platforms with
6256 * iconv(), to the encodings we want?
6257 * If not (and perhaps even if so), we should
6258 * perhaps have our own iconv() implementation,
6259 * with a different name, so that we control the
6260 * encodings it supports and the names of those
6263 * We should also handle that in the general
6264 * string handling code, rather than making it
6265 * specific to the BACAPP dissector, as many
6266 * other dissectors need to handle various
6267 * character encodings.
6269 /** this decoding may be not correct for multi-byte characters, Lka */
6270 switch (character_set) {
6272 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UTF_8);
6276 out = tvb_get_string(wmem_packet_scope(), tvb, offset, l);
6277 coding = "IBM MS DBCS";
6280 out = tvb_get_string(wmem_packet_scope(), tvb, offset, l);
6281 coding = "JIS C 6226";
6283 case ISO_10646_UCS4:
6284 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UCS_4|ENC_BIG_ENDIAN);
6285 coding = "ISO 10646 UCS-4";
6287 case ISO_10646_UCS2:
6288 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UCS_2|ENC_BIG_ENDIAN);
6289 coding = "ISO 10646 UCS-2";
6292 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ISO_8859_1);
6293 coding = "ISO 8859-1";
6296 /* Assume this is some form of extended ASCII, with one-byte code points for ASCII characters */
6297 out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
6301 ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s '%s'", label, coding, out);
6306 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6308 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6309 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
6311 if (character_set == 1) {
6312 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
6314 /* XXX - put the string value here */
6320 fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
6321 const value_string *src)
6323 guint8 tag_no, tag_info, tmp;
6324 gint j, unused, skip;
6325 guint start = offset;
6327 guint32 lvt, i, numberOfBytes;
6329 proto_tree* subtree = tree;
6332 offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6333 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
6335 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
6336 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
6337 "%s(Bit String)", label);
6339 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6341 fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
6342 proto_tree_add_text(subtree, tvb, offset, 1,
6343 "Unused bits: %u", unused);
6344 memset(bf_arr, 0, 256);
6346 for (i = 0; i < numberOfBytes; i++) {
6347 tmp = tvb_get_guint8(tvb, (offset)+i+1);
6348 if (i == numberOfBytes-1) { skip = unused; }
6349 for (j = 0; j < 8-skip; j++) {
6351 if (tmp & (1 << (7 - j)))
6352 proto_tree_add_text(subtree, tvb,
6355 val_to_str((guint) (i*8 +j),
6357 ASHRAE_Reserved_Fmt));
6359 proto_tree_add_text(subtree, tvb,
6362 val_to_str((guint) (i*8 +j),
6364 ASHRAE_Reserved_Fmt));
6366 bf_arr[MIN(255, (i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
6372 bf_arr[MIN(255, numberOfBytes*8-unused)] = 0;
6373 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
6382 fBitStringTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6384 return fBitStringTagVS(tvb, pinfo, tree, offset, label, NULL);
6387 /* handles generic application types, as well as enumerated and enumerations
6388 with reserved and proprietarty ranges (split) */
6390 fApplicationTypesEnumeratedSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6391 const gchar *label, const value_string *src, guint32 split_val)
6393 guint8 tag_no, tag_info;
6397 if (tvb_reported_length_remaining(tvb, offset) > 0) {
6399 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6400 if (!tag_is_context_specific(tag_info)) {
6402 case 0: /** NULL 20.2.2 */
6403 offset = fNullTag(tvb, pinfo, tree, offset, label);
6405 case 1: /** BOOLEAN 20.2.3 */
6406 offset = fBooleanTag(tvb, pinfo, tree, offset, label);
6408 case 2: /** Unsigned Integer 20.2.4 */
6409 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
6411 case 3: /** Signed Integer 20.2.5 */
6412 offset = fSignedTag(tvb, pinfo, tree, offset, label);
6414 case 4: /** Real 20.2.6 */
6415 offset = fRealTag(tvb, pinfo, tree, offset, label);
6417 case 5: /** Double 20.2.7 */
6418 offset = fDoubleTag(tvb, pinfo, tree, offset, label);
6420 case 6: /** Octet String 20.2.8 */
6421 offset = fOctetString(tvb, pinfo, tree, offset, label, lvt);
6423 case 7: /** Character String 20.2.9 */
6424 offset = fCharacterString(tvb, pinfo, tree, offset, label);
6426 case 8: /** Bit String 20.2.10 */
6427 offset = fBitStringTagVS(tvb, pinfo, tree, offset, label, src);
6429 case 9: /** Enumerated 20.2.11 */
6430 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, src, split_val);
6432 case 10: /** Date 20.2.12 */
6433 offset = fDate(tvb, pinfo, tree, offset, label);
6435 case 11: /** Time 20.2.13 */
6436 offset = fTime(tvb, pinfo, tree, offset, label);
6438 case 12: /** BACnetObjectIdentifier 20.2.14 */
6439 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
6441 case 13: /* reserved for ASHRAE */
6444 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
6445 offset += lvt + tag_len;
6457 fShedLevel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6459 guint lastoffset = 0;
6461 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6462 lastoffset = offset;
6464 switch (fTagNo(tvb, offset)) {
6465 case 0: /* percent */
6466 offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed percent: ");
6469 offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed level: ");
6471 case 2: /* amount */
6472 offset = fRealTag(tvb, pinfo, tree, offset, "shed amount: ");
6477 if (offset == lastoffset) break; /* nothing happened, exit loop */
6483 fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6484 const gchar *label, const value_string *vs)
6486 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
6490 fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
6493 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
6497 fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
6499 guint8 tag_no, tag_info;
6503 proto_tree *subtree;
6507 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6508 /* cap the the suggested length in case of bad data */
6509 tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
6510 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
6513 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
6514 "Context Value (as %u DATA octets)", lvt);
6516 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
6517 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
6519 return offset + tag_len + lvt;
6522 BACnetPrescale ::= SEQUENCE {
6523 multiplier [0] Unsigned,
6524 moduloDivide [1] Unsigned
6528 fPrescale(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6530 guint8 tag_no, tag_info;
6532 guint lastoffset = 0;
6534 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6535 lastoffset = offset;
6536 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6537 if (tag_is_closing(tag_info) ) {
6541 case 0: /* multiplier */
6542 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Multiplier: ");
6544 case 1: /* moduloDivide */
6545 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Modulo Divide: ");
6550 if (offset == lastoffset) break; /* nothing happened, exit loop */
6556 BACnetScale ::= CHOICE {
6557 floatScale [0] REAL,
6558 integerScale [1] INTEGER
6562 fScale(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6564 guint8 tag_no, tag_info;
6566 guint lastoffset = 0;
6568 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6569 lastoffset = offset;
6570 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6571 if (tag_is_closing(tag_info) ) {
6575 case 0: /* floatScale */
6576 offset = fRealTag(tvb, pinfo, tree, offset, "Float Scale: ");
6578 case 1: /* integerScale */
6579 offset = fSignedTag(tvb, pinfo, tree, offset, "Integer Scale: ");
6584 if (offset == lastoffset) break; /* nothing happened, exit loop */
6589 BACnetAccumulatorRecord ::= SEQUENCE {
6590 timestamp [0] BACnetDateTime,
6591 presentValue [1] Unsigned,
6592 accumulatedValue [2] Unsigned,
6593 accumulatortStatus [3] ENUMERATED {
6603 fLoggingRecord(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
6605 guint8 tag_no, tag_info;
6607 guint lastoffset = 0;
6609 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6610 lastoffset = offset;
6611 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6612 if (tag_is_closing(tag_info) ) {
6616 case 0: /* timestamp */
6617 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6618 offset = fDateTime(tvb, pinfo, tree, offset, "Timestamp: ");
6619 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6621 case 1: /* presentValue */
6622 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Present Value: ");
6624 case 2: /* accumulatedValue */
6625 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Accumulated Value: ");
6627 case 3: /* accumulatorStatus */
6628 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus);
6633 if (offset == lastoffset) break; /* nothing happened, exit loop */
6639 SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState
6642 fSequenceOfEnums(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, const value_string *vs)
6644 guint8 tag_no, tag_info;
6646 guint lastoffset = 0;
6648 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6649 lastoffset = offset;
6650 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6651 if (tag_is_closing(tag_info) ) {
6654 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs);
6655 if ( offset == lastoffset ) break;
6661 SEQ OF BACnetDeviceObjectReference (accessed as an array)
6665 fDoorMembers(tvbuff_t *tvb, packet_info *pinfo, 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) ) {
6677 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6678 if (offset == lastoffset) break;
6684 SEQ OF ReadAccessSpecification
6687 fListOfGroupMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6689 guint8 tag_no, tag_info;
6691 guint lastoffset = 0;
6693 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6694 lastoffset = offset;
6695 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6696 if (tag_is_closing(tag_info) ) {
6699 offset = fReadAccessSpecification(tvb, pinfo, tree, offset);
6700 if ( offset == lastoffset ) break;
6706 fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
6708 guint8 tag_no, tag_info;
6710 guint lastoffset = 0, depth = 0;
6712 guint32 save_object_type;
6714 if (propertyIdentifier >= 0) {
6715 g_snprintf(ar, sizeof(ar), "%s: ",
6716 val_to_split_str(propertyIdentifier, 512,
6717 BACnetPropertyIdentifier,
6718 ASHRAE_Reserved_Fmt,
6719 Vendor_Proprietary_Fmt));
6721 g_snprintf(ar, sizeof(ar), "Abstract Type: ");
6723 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
6724 lastoffset = offset;
6725 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
6726 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
6727 if (depth <= 0) return offset;
6730 /* Application Tags */
6731 switch (propertyIdentifier) {
6732 case 2: /* action */
6733 /* loop object is application tagged,
6734 command object is context tagged */
6735 if (tag_is_context_specific(tag_info)) {
6736 /* BACnetActionList */
6737 offset = fActionList(tvb, pinfo, tree, offset);
6740 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6744 case 30: /* BACnetAddressBinding */
6745 offset = fAddressBinding(tvb, pinfo, tree, offset);
6747 case 54: /* list of object property reference */
6748 offset = fLOPR(tvb, pinfo, tree, offset);
6750 case 55: /* list-of-session-keys */
6751 fSessionKey(tvb, pinfo, tree, offset);
6753 case 79: /* object-type */
6754 case 96: /* protocol-object-types-supported */
6755 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar,
6756 BACnetObjectType, 128);
6758 case 97: /* Protocol-Services-Supported */
6759 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6760 BACnetServicesSupported);
6762 case 102: /* recipient-list */
6763 offset = fDestination(tvb, pinfo, tree, offset);
6765 case 107: /* segmentation-supported */
6766 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6767 BACnetSegmentation);
6769 case 111: /* Status-Flags */
6770 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6773 case 112: /* System-Status */
6774 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6775 BACnetDeviceStatus);
6777 case 117: /* units */
6778 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
6779 BACnetEngineeringUnits);
6781 case 87: /* priority-array -- accessed as a BACnetARRAY */
6782 if (propertyArrayIndex == 0) {
6783 /* BACnetARRAY index 0 refers to the length
6784 of the array, not the elements of the array */
6785 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6787 offset = fPriorityArray(tvb, pinfo, tree, offset);
6790 case 38: /* exception-schedule */
6791 if (object_type < 128) {
6792 if (propertyArrayIndex == 0) {
6793 /* BACnetARRAY index 0 refers to the length
6794 of the array, not the elements of the array */
6795 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6797 offset = fSpecialEvent(tvb, pinfo, tree, offset);
6801 case 19: /* controlled-variable-reference */
6802 case 60: /* manipulated-variable-reference */
6803 case 132: /* log-device-object-property */
6804 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
6806 case 109: /* Setpoint-Reference */
6807 /* setpoint-Reference is actually BACnetSetpointReference which is a SEQ of [0] */
6808 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6809 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
6810 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6812 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
6813 if (object_type < 128) {
6814 if (propertyArrayIndex == 0) {
6815 /* BACnetARRAY index 0 refers to the length
6816 of the array, not the elements of the array */
6817 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6819 offset = fWeeklySchedule(tvb, pinfo, tree, offset);
6823 case 127: /* client COV increment */
6824 offset = fClientCOV(tvb, pinfo, tree, offset);
6826 case 131: /* log-buffer */
6827 if ( object_type == 25 )
6828 offset = fEventLogRecord(tvb, pinfo, tree, offset);
6829 else if ( object_type == 27 )
6830 offset = fLogMultipleRecord(tvb, pinfo, tree, offset);
6832 offset = fLogRecord(tvb, pinfo, tree, offset);
6834 case 159: /* member-of */
6835 case 165: /* zone-members */
6836 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6838 case 196: /* last-restart-reason */
6839 offset = fRestartReason(tvb, pinfo, tree, offset);
6841 case 212: /* actual-shed-level */
6842 case 214: /* expected-shed-level */
6843 case 218: /* requested-shed-level */
6844 offset = fShedLevel(tvb, pinfo, tree, offset);
6846 case 152: /* active-cov-subscriptions */
6847 offset = fCOVSubscription(tvb, pinfo, tree, offset);
6849 case 23: /* date-list */
6850 offset = fCalendarEntry(tvb, pinfo, tree, offset);
6852 case 116: /* time-sychronization-recipients */
6853 offset = fRecipient(tvb, pinfo, tree, offset);
6855 case 83: /* event-parameters */
6856 offset = fEventParameter(tvb, pinfo, tree, offset);
6858 case 211: /* subordinate-list */
6859 offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
6861 case 130: /* event-time-stamp */
6862 offset = fEventTimeStamps(tvb, pinfo, tree, offset);
6864 case 197: /* logging-type */
6865 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType);
6867 case 36: /* event-state */
6868 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64);
6870 case 103: /* reliability */
6871 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability);
6873 case 72: /* notify-type */
6874 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNotifyType);
6876 case 208: /* node-type */
6877 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType);
6879 case 231: /* door-status */
6880 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus);
6882 case 233: /* lock-status */
6883 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus);
6885 case 235: /* secured-status */
6886 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus);
6888 case 158: /* maintenance-required */
6889 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance);
6891 case 92: /* program-state */
6892 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState);
6894 case 90: /* program-change */
6895 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest);
6897 case 100: /* reason-for-halt */
6898 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError);
6900 case 160: /* mode */
6901 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode);
6903 case 163: /* silenced */
6904 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState);
6906 case 161: /* operation-expected */
6907 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation);
6909 case 164: /* tracking-value */
6910 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState);
6912 case 41: /* file-access-method */
6913 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod);
6915 case 185: /* prescale */
6916 offset = fPrescale(tvb, pinfo, tree, offset);
6918 case 187: /* scale */
6919 offset = fScale(tvb, pinfo, tree, offset);
6921 case 184: /* logging-record */
6922 offset = fLoggingRecord(tvb, pinfo, tree, offset);
6924 case 228: /* door-members */
6925 offset = fDoorMembers(tvb, pinfo, tree, offset);
6927 case 181: /* input-reference */
6928 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6930 case 78: /* object-property-reference */
6931 offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
6933 case 234: /* masked-alarm-values */
6934 offset = fSequenceOfEnums(tvb, pinfo, tree, offset, "masked-alarm-value: ", BACnetDoorAlarmState);
6936 case 53: /* list-of-group-members */
6937 save_object_type = object_type;
6938 offset = fListOfGroupMembers(tvb, pinfo, tree, offset);
6939 object_type = save_object_type;
6941 case 85: /* present-value */
6942 if ( object_type == 11 ) /* group object handling of present-value */
6944 offset = fReadAccessResult(tvb, pinfo, tree, offset);
6947 /* intentially fall through here so don't reorder this case statement */
6950 if (tag_is_opening(tag_info)) {
6952 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6953 } else if (tag_is_closing(tag_info)) {
6955 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
6957 offset = fContextTaggedValue(tvb, pinfo, tree, offset, ar);
6960 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
6964 if (offset == lastoffset) break; /* nothing happened, exit loop */
6971 fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
6976 if (tag_is_opening(tag_info)) {
6977 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
6978 &tag_no, &tag_info, &lvt);
6979 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
6980 if (tvb_length_remaining(tvb, offset) > 0) {
6981 offset += fTagHeaderTree(tvb, pinfo, tree, offset,
6982 &tag_no, &tag_info, &lvt);
6985 proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
6986 "expected Opening Tag!");
6987 offset = tvb_length(tvb);
6995 fPropertyIdentifierValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
6997 guint lastoffset = offset;
6998 guint8 tag_no, tag_info;
7001 offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
7002 if (offset > lastoffset) {
7003 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7004 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
7005 offset = fPropertyValue(tvb, pinfo, tree, offset, tag_info);
7012 fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7014 guint lastoffset = 0;
7015 guint8 tag_no, tag_info;
7018 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7019 lastoffset = offset;
7020 offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
7021 if (offset > lastoffset) {
7022 /* detect optional priority
7023 by looking to see if the next tag is context tag number 3 */
7024 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7025 if (tag_is_context_specific(tag_info) && (tag_no == 3))
7026 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: ");
7028 if (offset == lastoffset) break; /* nothing happened, exit loop */
7034 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7036 guint lastoffset = 0, len;
7037 guint8 tag_no, tag_info;
7039 proto_tree *subtree = tree;
7042 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7043 lastoffset = offset;
7044 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7045 if (tag_is_closing(tag_info)) {
7052 case 0: /* ProcessId */
7053 offset = fUnsignedTag(tvb, pinfo, tree, offset, "subscriber Process Id: ");
7055 case 1: /* monitored ObjectId */
7056 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7058 case 2: /* issueConfirmedNotifications */
7059 offset = fBooleanTag(tvb, pinfo, tree, offset, "issue Confirmed Notifications: ");
7061 case 3: /* life time */
7062 offset = fTimeSpan(tvb, pinfo, tree, offset, "life time");
7064 case 4: /* monitoredPropertyIdentifier */
7065 if (tag_is_opening(tag_info)) {
7066 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
7068 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7070 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7071 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
7076 case 5: /* covIncrement */
7077 offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
7082 if (offset == lastoffset) break; /* nothing happened, exit loop */
7088 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7090 return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
7094 fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7096 guint lastoffset = 0;
7098 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7099 lastoffset = offset;
7101 switch (fTagNo(tvb, offset)) {
7102 case 0: /* deviceInstanceLowLimit */
7103 offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance Low Limit: ");
7105 case 1: /* deviceInstanceHighLimit */
7106 offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance High Limit: ");
7108 case 2: /* BACnetObjectId */
7109 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7111 case 3: /* messageText */
7112 offset = fCharacterString(tvb, pinfo, tree, offset, "Object Name: ");
7117 if (offset == lastoffset) break; /* nothing happened, exit loop */
7124 fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
7126 guint lastoffset = 0;
7127 guint8 tag_no, tag_info;
7130 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7131 if (tag_is_opening(tag_info) && tag_no == 0) {
7132 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
7133 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7134 lastoffset = offset;
7135 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7136 if (tag_is_closing(tag_info)) {
7137 /* should be closing context tag 0 */
7138 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7142 offset = fTimeValue(tvb, pinfo, subtree, offset);
7143 if (offset == lastoffset) break; /* nothing happened, exit loop */
7145 } else if ((tag_no == 0) && (lvt == 0)) {
7146 /* not sure null (empty array element) is legal */
7147 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7153 fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7155 guint lastoffset = 0;
7156 guint8 tag_no, tag_info;
7158 guint i = 1; /* day of week array index */
7159 proto_tree *subtree = tree;
7162 if (propertyArrayIndex > 0) {
7163 /* BACnetARRAY index 0 refers to the length
7164 of the array, not the elements of the array.
7165 BACnetARRAY index -1 is our internal flag that
7166 the optional index was not used.
7167 BACnetARRAY refers to this as all elements of the array.
7168 If the optional index is specified for a BACnetARRAY,
7169 then that specific array element is referenced. */
7170 i = propertyArrayIndex;
7172 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7173 lastoffset = offset;
7174 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7175 if (tag_is_closing(tag_info)) {
7176 return offset; /* outer encoding will print out closing tag */
7178 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
7179 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7180 offset = fDailySchedule(tvb, pinfo, subtree, offset);
7181 if (offset == lastoffset) break; /* nothing happened, exit loop */
7188 fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7190 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7193 return fDateTime(tvb, pinfo, tree, offset, "UTC-Time: ");
7197 fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7199 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7202 return fDateTime(tvb, pinfo, tree, offset, NULL);
7206 fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7208 if (tvb_reported_length_remaining(tvb, offset) <= 0)
7210 offset = fDate(tvb, pinfo, tree, offset, "Start Date: ");
7211 return fDate(tvb, pinfo, tree, offset, "End Date: ");
7215 fVendorIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7218 guint8 tag_no, tag_info;
7222 proto_tree *subtree;
7223 const gchar *label = "Vendor ID";
7225 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7226 if (fUnsigned32(tvb, offset + tag_len, lvt, &val))
7227 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7230 val_to_str_ext_const(val, &BACnetVendorIdentifiers_ext, "Unknown Vendor"),
7233 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7234 "%s - %u octets (Unsigned)", label, lvt);
7235 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7236 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7238 if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */
7239 proto_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
7240 "Wrong length indicated. Expected 1 or 2, got %u", lvt);
7241 return offset+tag_len+lvt;
7244 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
7245 offset+tag_len, lvt, ENC_BIG_ENDIAN);
7247 return offset+tag_len+lvt;
7251 fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7254 guint8 tag_no, tag_info;
7258 proto_tree *subtree;
7259 const gchar *label = "Restart Reason";
7261 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7262 if (fUnsigned32(tvb, offset + tag_len, lvt, &val))
7263 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7264 "%s: %s (%u)", label,
7265 val_to_str_const(val, BACnetRestartReason, "Unknown reason"), val);
7267 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
7268 "%s - %u octets (Unsigned)", label, lvt);
7269 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
7270 fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7273 proto_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
7274 "Wrong length indicated. Expected 1, got %u", lvt);
7275 return offset+tag_len+lvt;
7278 proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
7279 offset+tag_len, lvt, ENC_BIG_ENDIAN);
7281 return offset+tag_len+lvt;
7285 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7287 guint lastoffset = 0;
7289 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7290 lastoffset = offset;
7291 switch (fTagNo(tvb, offset)) {
7293 case 0: /* textMessageSourceDevice */
7294 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7296 case 1: /* messageClass */
7297 switch (fTagNo(tvb, offset)) {
7298 case 0: /* numeric */
7299 offset = fUnsignedTag(tvb, pinfo, tree, offset, "message Class: ");
7301 case 1: /* character */
7302 offset = fCharacterString(tvb, pinfo, tree, offset, "message Class: ");
7306 case 2: /* messagePriority */
7307 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "message Priority: ",
7308 BACnetMessagePriority);
7310 case 3: /* message */
7311 offset = fCharacterString(tvb, pinfo, tree, offset, "message: ");
7316 if (offset == lastoffset) break; /* nothing happened, exit loop */
7322 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7324 return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
7328 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7330 guint lastoffset, len;
7331 guint8 tag_no, tag_info;
7333 proto_tree *subtree = tree;
7336 guint vendor_identifier = 0;
7337 guint service_number = 0;
7339 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7340 fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
7341 if (col_get_writable(pinfo->cinfo))
7342 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
7343 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
7345 next_tvb = tvb_new_subset_remaining(tvb, offset);
7346 if (dissector_try_uint(bacapp_dissector_table,
7347 vendor_identifier, next_tvb, pinfo, tree)) {
7348 /* we parsed it so skip over length and we are done */
7349 offset += tvb_length(next_tvb);
7353 /* Not handled by vendor dissector */
7355 /* exit loop if nothing happens inside */
7356 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7357 lastoffset = offset;
7358 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7359 if (tag_is_closing(tag_info)) {
7360 if (tag_no == 2) { /* Make sure it's the expected tag */
7365 break; /* End loop if incorrect closing tag */
7370 /* vendorID is now parsed above */
7371 case 1: /* serviceNumber */
7372 fUnsigned32(tvb, offset+len, lvt, &service_number);
7373 if (col_get_writable(pinfo->cinfo))
7374 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
7375 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: ");
7377 case 2: /*serviceParameters */
7378 if (tag_is_opening(tag_info)) {
7379 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
7380 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7381 propertyIdentifier = -1;
7382 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7390 if (offset == lastoffset) break; /* nothing happened, exit loop */
7397 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7399 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7403 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7405 return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
7409 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
7411 guint lastoffset = 0;
7412 guint8 tag_no, tag_info;
7414 proto_tree *subtree = tree;
7417 if (label != NULL) {
7418 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", label);
7419 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7422 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7423 lastoffset = offset;
7424 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7427 case 0: /* subscriberProcessId */
7428 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "requesting Process Id: ");
7430 case 1: /* requestingSource */
7431 offset = fCharacterString(tvb, pinfo, tree, offset, "requesting Source: ");
7433 case 2: /* request */
7434 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
7435 "request: ", BACnetLifeSafetyOperation, 64);
7437 case 3: /* objectId */
7438 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
7443 if (offset == lastoffset) break; /* nothing happened, exit loop */
7448 typedef struct _value_string_enum {
7449 const value_string *valstr;
7450 } value_string_enum;
7452 static const value_string_enum
7453 BACnetPropertyStatesEnums[] = {
7458 {BACnetProgramRequest },
7459 {BACnetProgramState },
7460 {BACnetProgramError },
7461 {BACnetReliability },
7462 {BACnetEventState },
7463 {BACnetDeviceStatus },
7464 {BACnetEngineeringUnits },
7466 {BACnetLifeSafetyMode },
7467 {BACnetLifeSafetyState },
7468 {BACnetRestartReason },
7469 {BACnetDoorAlarmState },
7471 {BACnetDoorSecuredStatus },
7472 {BACnetDoorStatus },
7473 { NULL }, /* {BACnetDoorValue }, */
7474 {BACnetFileAccessMethod },
7475 {BACnetLockStatus },
7476 {BACnetLifeSafetyOperation },
7477 {BACnetMaintenance },
7479 {BACnetNotifyType },
7480 { NULL }, /* {BACnetSecurityLevel }, */
7482 {BACnetSilencedState },
7484 { NULL }, /* {BACnetAccessEvent }, */
7485 { NULL }, /* {BACnetZoneOccupancyState }, */
7486 { NULL }, /* {BACnetAccessCredentialDisableReason }, */
7487 { NULL }, /* {BACnetAccessCredentialDisable }, */
7488 { NULL }, /* {BACnetAuthenticationStatus }, */
7490 { NULL }, /* {BACnetBackupState }, */
7492 #define BACnetPropertyStatesEnums_Size 36
7495 fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
7497 guint8 tag_no, tag_info;
7501 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7502 label = wmem_strdup_printf(wmem_packet_scope(), "%s: ",
7503 val_to_str_const( tag_no, VALS(BACnetPropertyStates), "Unknown State" ));
7507 offset = fBooleanTag(tvb, pinfo, tree, offset, label);
7510 offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
7513 if ( (tag_no > BACnetPropertyStatesEnums_Size) ||
7514 VALS(BACnetPropertyStatesEnums[tag_no].valstr) == NULL)
7516 offset = fEnumeratedTag(tvb, pinfo, tree, offset, label, NULL);
7517 /* don't use Abstract type here because it is context tagged and therefore we don't know app type */
7521 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label,
7522 VALS(BACnetPropertyStatesEnums[tag_no].valstr), 64);
7531 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
7532 deviceIdentifier [0] BACnetObjectIdentifier,
7533 objectIdentifier [1] BACnetObjectIdentifier,
7534 propertyIdentifier [2] BACnetPropertyIdentifier,
7535 arrayIndex [3] Unsigned OPTIONAL,
7536 value [4] ABSTRACT-SYNTAX.&Type
7540 fDeviceObjectPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7542 guint lastoffset = 0;
7543 guint8 tag_no, tag_info;
7546 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7547 lastoffset = offset;
7548 /* check the tag. A closing tag means we are done */
7549 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7550 if (tag_is_closing(tag_info)) {
7554 case 0: /* deviceIdentifier */
7555 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7557 case 1: /* objectIdentifier */
7558 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7560 case 2: /* propertyIdentifier */
7561 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
7563 case 3: /* arrayIndex - OPTIONAL */
7564 offset = fUnsignedTag(tvb, pinfo, tree, offset,
7568 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7569 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
7570 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
7575 if (offset == lastoffset) break; /* nothing happened, exit loop */
7581 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7582 objectIdentifier [0] BACnetObjectIdentifier,
7583 propertyIdentifier [1] BACnetPropertyIdentifier,
7584 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7585 -- if omitted with an array then
7586 -- the entire array is referenced
7587 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7591 fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7593 return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
7597 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
7598 objectIdentifier [0] BACnetObjectIdentifier,
7599 propertyIdentifier [1] BACnetPropertyIdentifier,
7600 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
7601 -- if omitted with an array then
7602 -- the entire array is referenced
7603 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
7607 fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7609 guint lastoffset = 0;
7610 guint8 tag_no, tag_info;
7613 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7614 lastoffset = offset;
7615 /* check the tag. A closing tag means we are done */
7616 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7617 if (tag_is_closing(tag_info)) {
7621 case 0: /* objectIdentifier */
7622 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7624 case 1: /* propertyIdentifier */
7625 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
7627 case 2: /* arrayIndex - OPTIONAL */
7628 offset = fUnsignedTag(tvb, pinfo, tree, offset,
7631 case 3: /* deviceIdentifier - OPTIONAL */
7632 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
7637 if (offset == lastoffset) break; /* nothing happened, exit loop */
7643 fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
7645 guint lastoffset = offset;
7646 guint8 tag_no, tag_info;
7648 proto_tree *subtree = tree;
7651 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
7652 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
7653 tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
7654 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
7655 /* Opening tag for parameter choice */
7656 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7659 case 0: /* change-of-bitstring */
7660 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7661 lastoffset = offset;
7662 switch (fTagNo(tvb, offset)) {
7664 offset = fBitStringTag(tvb, pinfo, subtree, offset,
7665 "referenced-bitstring: ");
7668 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7669 "status-flags: ", BACnetStatusFlags);
7670 lastoffset = offset;
7675 if (offset == lastoffset) break; /* nothing happened, exit loop */
7678 case 1: /* change-of-state */
7679 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7680 lastoffset = offset;
7681 switch (fTagNo(tvb, offset)) {
7683 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7684 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
7685 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7688 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7689 "status-flags: ", BACnetStatusFlags);
7690 lastoffset = offset;
7695 if (offset == lastoffset) break; /* nothing happened, exit loop */
7698 case 2: /* change-of-value */
7699 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7700 lastoffset = offset;
7701 switch (fTagNo(tvb, offset)) {
7703 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7704 switch (fTagNo(tvb, offset)) {
7706 offset = fBitStringTag(tvb, pinfo, subtree, offset,
7710 offset = fRealTag(tvb, pinfo, subtree, offset,
7716 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7719 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7720 "status-flags: ", BACnetStatusFlags);
7721 lastoffset = offset;
7726 if (offset == lastoffset) break; /* nothing happened, exit loop */
7729 case 3: /* command-failure */
7730 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7731 lastoffset = offset;
7732 switch (fTagNo(tvb, offset)) {
7733 case 0: /* "command-value: " */
7734 /* from BACnet Table 13-3,
7735 Standard Object Property Values Returned in Notifications */
7736 propertyIdentifier = 85; /* PRESENT_VALUE */
7737 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7738 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7739 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7742 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7743 "status-flags: ", BACnetStatusFlags);
7745 case 2: /* "feedback-value: " */
7746 propertyIdentifier = 40; /* FEEDBACK_VALUE */
7747 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7748 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
7749 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7750 lastoffset = offset;
7755 if (offset == lastoffset) break; /* nothing happened, exit loop */
7758 case 4: /* floating-limit */
7759 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7760 lastoffset = offset;
7761 switch (fTagNo(tvb, offset)) {
7763 offset = fRealTag(tvb, pinfo, subtree, offset, "reference-value: ");
7766 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7767 "status-flags: ", BACnetStatusFlags);
7770 offset = fRealTag(tvb, pinfo, subtree, offset, "setpoint-value: ");
7773 offset = fRealTag(tvb, pinfo, subtree, offset, "error-limit: ");
7774 lastoffset = offset;
7779 if (offset == lastoffset) break; /* nothing happened, exit loop */
7782 case 5: /* out-of-range */
7783 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7784 lastoffset = offset;
7785 switch (fTagNo(tvb, offset)) {
7787 offset = fRealTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7790 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7791 "status-flags: ", BACnetStatusFlags);
7794 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
7797 offset = fRealTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
7798 lastoffset = offset;
7803 if (offset == lastoffset) break; /* nothing happened, exit loop */
7807 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7808 lastoffset = offset;
7809 offset =fBACnetPropertyValue(tvb, pinfo, subtree, offset);
7810 if (offset == lastoffset) break; /* nothing happened, exit loop */
7813 case 7: /* deprecated (was 'buffer-ready', changed and moved to [10]) */
7814 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7815 lastoffset = offset;
7816 switch (fTagNo(tvb, offset)) {
7818 offset = fObjectIdentifier(tvb, pinfo, subtree, offset); /* buffer-device */
7821 offset = fObjectIdentifier(tvb, pinfo, subtree, offset); /* buffer-object */
7824 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7825 offset = fDateTime(tvb, pinfo, subtree, offset, "previous-notification: ");
7826 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7829 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7830 offset = fDateTime(tvb, pinfo, subtree, offset, "current-notification: ");
7831 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7832 lastoffset = offset;
7837 if (offset == lastoffset) break; /* nothing happened, exit loop */
7840 case 8: /* change-of-life-safety */
7841 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7842 lastoffset = offset;
7843 switch (fTagNo(tvb, offset)) {
7845 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7846 "new-state: ", BACnetLifeSafetyState, 256);
7849 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7850 "new-mode: ", BACnetLifeSafetyMode, 256);
7853 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7854 "status-flags: ", BACnetStatusFlags);
7857 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
7858 "operation-expected: ", BACnetLifeSafetyOperation, 64);
7859 lastoffset = offset;
7864 if (offset == lastoffset) break; /* nothing happened, exit loop */
7867 case 9: /* extended */
7868 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7869 lastoffset = offset;
7870 switch (fTagNo(tvb, offset)) {
7872 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
7875 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7876 "extended-event-type: ");
7878 case 2: /* parameters */
7879 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7880 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
7881 offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
7882 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7883 lastoffset = offset;
7888 if (offset == lastoffset) break; /* nothing happened, exit loop */
7891 case 10: /* buffer ready */
7892 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7893 lastoffset = offset;
7894 switch (fTagNo(tvb, offset)) {
7895 case 0: /* buffer-property */
7896 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7897 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
7898 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
7901 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7902 "previous-notification: ");
7905 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7906 "current-notification: ");
7907 lastoffset = offset;
7912 if (offset == lastoffset) break; /* nothing happened, exit loop */
7915 case 11: /* unsigned range */
7916 while (tvb_reported_length_remaining(tvb, offset) > 0) {
7917 lastoffset = offset;
7918 switch (fTagNo(tvb, offset)) {
7920 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7921 "exceeding-value: ");
7924 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7925 "status-flags: ", BACnetStatusFlags);
7928 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
7929 "exceeded-limit: ");
7930 lastoffset = offset;
7935 if (offset == lastoffset) break; /* nothing happened, exit loop */
7939 case 13: /* access-event */
7941 case 14: /* double-out-of-range */
7942 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7943 lastoffset = offset;
7944 switch (fTagNo(tvb, offset)) {
7946 offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7949 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7950 "status-flags: ", BACnetStatusFlags);
7953 offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: ");
7956 offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
7957 lastoffset = offset;
7962 if (offset == lastoffset) break; /* nothing happened, exit loop */
7965 case 15: /* signed-out-of-range */
7966 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7967 lastoffset = offset;
7968 switch (fTagNo(tvb, offset)) {
7970 offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7973 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7974 "status-flags: ", BACnetStatusFlags);
7977 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
7980 offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
7981 lastoffset = offset;
7986 if (offset == lastoffset) break; /* nothing happened, exit loop */
7989 case 16: /* unsigned-out-of-range */
7990 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
7991 lastoffset = offset;
7992 switch (fTagNo(tvb, offset)) {
7994 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
7997 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
7998 "status-flags: ", BACnetStatusFlags);
8001 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8004 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
8005 lastoffset = offset;
8010 if (offset == lastoffset) break; /* nothing happened, exit loop */
8013 case 17: /* change-of-characterstring */
8015 case 18: /* change-of-status-flags */
8017 /* todo: add new parameters here ... */
8019 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
8023 /* Closing tag for parameter choice */
8024 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8030 fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8032 guint lastoffset = offset;
8033 guint8 tag_no, tag_info;
8035 proto_tree *subtree = tree;
8038 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8039 tt = proto_tree_add_text(subtree, tvb, offset, 0, "event parameters (%d) %s",
8040 tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
8041 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8042 /* Opening tag for parameter choice */
8043 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8046 case 0: /* change-of-bitstring */
8047 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8048 lastoffset = offset;
8049 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8050 if (tag_is_closing(tag_info)) {
8055 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8058 offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: ");
8060 case 2: /* SEQUENCE OF BIT STRING */
8061 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8062 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8063 lastoffset = offset;
8064 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8065 if (tag_is_closing(tag_info)) {
8068 offset = fBitStringTag(tvb, pinfo, subtree, offset,
8069 "bitstring value: ");
8071 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8078 case 1: /* change-of-state */
8079 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8080 lastoffset = offset;
8081 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8082 if (tag_is_closing(tag_info)) {
8087 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8089 case 1: /* SEQUENCE OF BACnetPropertyStates */
8090 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8091 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8092 lastoffset = offset;
8093 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8094 if (tag_is_closing(tag_info)) {
8097 offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
8099 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8106 case 2: /* change-of-value */
8107 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8108 lastoffset = offset;
8109 switch (fTagNo(tvb, offset)) {
8111 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8113 case 1: /* don't loop it, it's a CHOICE */
8114 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8115 switch (fTagNo(tvb, offset)) {
8117 offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: ");
8120 offset = fRealTag(tvb, pinfo, subtree, offset,
8121 "referenced Property Increment: ");
8126 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8133 case 3: /* command-failure */
8134 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8135 lastoffset = offset;
8136 tag_no = fTagNo(tvb, offset);
8139 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8142 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8143 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8144 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8151 case 4: /* floating-limit */
8152 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8153 lastoffset = offset;
8154 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8155 if (tag_is_closing(tag_info)) {
8160 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8163 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8164 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8165 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8168 offset = fRealTag(tvb, pinfo, subtree, offset, "low diff limit: ");
8171 offset = fRealTag(tvb, pinfo, subtree, offset, "high diff limit: ");
8174 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
8181 case 5: /* out-of-range */
8182 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8183 lastoffset = offset;
8184 switch (fTagNo(tvb, offset)) {
8186 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8189 offset = fRealTag(tvb, pinfo, subtree, offset, "low limit: ");
8192 offset = fRealTag(tvb, pinfo, subtree, offset, "high limit: ");
8195 offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
8204 offset = fBACnetPropertyValue (tvb, pinfo, tree, offset);
8208 case 7: /* buffer-ready */
8211 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
8212 lastoffset = offset;
8213 switch (fTagNo(tvb, offset)) {
8215 offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification threshold");
8218 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8219 "previous notification count: ");
8227 case 8: /* change-of-life-safety */
8228 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8229 lastoffset = offset;
8230 switch (fTagNo(tvb, offset)) {
8232 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8235 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8236 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8237 lastoffset = offset;
8238 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8239 if (tag_is_closing(tag_info)) {
8242 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8243 "life safety alarm value: ", BACnetLifeSafetyState, 256);
8245 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8248 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8249 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8250 lastoffset = offset;
8251 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8252 if (tag_is_closing(tag_info)) {
8255 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8256 "alarm value: ", BACnetLifeSafetyState, 256);
8258 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8261 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8262 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8263 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8270 case 9: /* extended */
8271 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8272 lastoffset = offset;
8273 switch (fTagNo(tvb, offset)) {
8275 offset = fVendorIdentifier(tvb, pinfo, tree, offset);
8278 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8279 "extended-event-type: ");
8281 case 2: /* parameters */
8282 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8283 offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
8284 offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
8285 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8286 lastoffset = offset;
8291 if (offset == lastoffset) break; /* nothing happened, exit loop */
8294 case 10: /* buffer-ready */
8295 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8296 lastoffset = offset;
8297 switch (fTagNo(tvb, offset)) {
8299 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
8300 "notification-threshold: ");
8303 offset = fUnsignedTag(tvb, pinfo, subtree, offset,
8304 "previous-notification-count: ");
8311 case 11: /* unsigned-range */
8312 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8313 lastoffset = offset;
8314 switch (fTagNo(tvb, offset)) {
8316 offset = fTimeSpan(tvb, pinfo, tree, offset, "Time Delay");
8319 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8323 offset = fUnsignedTag(tvb, pinfo, tree, offset,
8331 case 13: /* access-event */
8332 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8333 lastoffset = offset;
8334 switch (fTagNo(tvb, offset)) {
8336 /* TODO: [0] SEQUENCE OF BACnetAccessEvent */
8337 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8338 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8339 lastoffset = offset;
8340 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8341 if (tag_is_closing(tag_info)) {
8344 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
8345 "access event: ", BACnetAccessEvent, 512);
8347 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8350 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8351 offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
8352 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8359 case 14: /* double-out-of-range */
8360 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8361 lastoffset = offset;
8362 switch (fTagNo(tvb, offset)) {
8364 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8367 offset = fDoubleTag(tvb, pinfo, subtree, offset, "low limit: ");
8370 offset = fDoubleTag(tvb, pinfo, subtree, offset, "high limit: ");
8373 offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: ");
8380 case 15: /* signed-out-of-range */
8381 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8382 lastoffset = offset;
8383 switch (fTagNo(tvb, offset)) {
8385 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8388 offset = fSignedTag(tvb, pinfo, subtree, offset, "low limit: ");
8391 offset = fSignedTag(tvb, pinfo, subtree, offset, "high limit: ");
8394 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8401 case 16: /* unsigned-out-of-range */
8402 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8403 lastoffset = offset;
8404 switch (fTagNo(tvb, offset)) {
8406 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8409 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "low limit: ");
8412 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "high limit: ");
8415 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
8422 case 17: /* change-of-characterstring */
8423 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8424 lastoffset = offset;
8425 switch (fTagNo(tvb, offset)) {
8427 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8429 case 1: /* SEQUENCE OF CharacterString */
8430 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8431 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8432 lastoffset = offset;
8433 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8434 if (tag_is_closing(tag_info)) {
8437 offset = fCharacterString(tvb, pinfo, tree, offset, "alarm value: ");
8439 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8446 case 18: /* change-of-status-flags */
8447 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
8448 lastoffset = offset;
8449 switch (fTagNo(tvb, offset)) {
8451 offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
8454 offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
8455 "selected flags: ", BACnetStatusFlags);
8462 /* todo: add new event-parameter cases here */
8467 /* Closing tag for parameter choice */
8468 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8473 fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8475 guint lastoffset = 0;
8476 guint8 tag_no, tag_info;
8478 proto_tree *subtree = tree;
8481 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8482 lastoffset = offset;
8483 switch (fTagNo(tvb, offset)) {
8484 case 0: /* timestamp */
8485 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8486 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8487 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8488 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8490 case 1: /* logDatum: don't loop, it's a CHOICE */
8491 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8492 switch (fTagNo(tvb, offset)) {
8493 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8494 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8496 case 1: /* todo: move this to new method fConfirmedEventNotificationRequestTag... */
8497 tt = proto_tree_add_text(tree, tvb, offset, 1, "notification: ");
8498 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8499 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8500 offset = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset);
8501 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8504 offset = fRealTag(tvb, pinfo, tree, offset, "time-change: ");
8509 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8514 if (offset == lastoffset) break; /* nothing happened, exit loop */
8520 fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8522 guint lastoffset = 0;
8523 guint8 tag_no, tag_info;
8526 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8527 lastoffset = offset;
8528 switch (fTagNo(tvb, offset)) {
8529 case 0: /* timestamp */
8530 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8531 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8532 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8533 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8535 case 1: /* logDatum: don't loop, it's a CHOICE */
8536 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8537 switch (fTagNo(tvb, offset)) {
8538 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8539 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8542 offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: ");
8545 offset = fRealTag(tvb, pinfo, tree, offset, "real value: ");
8548 offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: ");
8551 offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: ");
8554 offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: ");
8557 offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: ");
8560 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8563 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8564 offset = fError(tvb, pinfo, tree, offset);
8565 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8568 offset = fRealTag(tvb, pinfo, tree, offset, "time change: ");
8570 case 10: /* any Value */
8571 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8572 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
8573 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8578 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8581 /* Changed this to BitString per BACnet Spec. */
8582 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "Status Flags:", BACnetStatusFlags);
8587 if (offset == lastoffset) break; /* nothing happened, exit loop */
8593 fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8595 guint lastoffset = 0;
8596 guint8 tag_no, tag_info;
8599 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8600 lastoffset = offset;
8601 switch (fTagNo(tvb, offset)) {
8602 case 0: /* timestamp */
8603 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8604 offset = fDate(tvb, pinfo, tree, offset, "Date: ");
8605 offset = fTime(tvb, pinfo, tree, offset, "Time: ");
8606 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8608 case 1: /* logData: don't loop, it's a CHOICE */
8609 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8610 switch (fTagNo(tvb, offset)) {
8611 case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */
8612 offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
8614 case 1: /* log-data: SEQUENCE OF CHOICE */
8615 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8616 while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset != lastoffset)) { /* exit loop if nothing happens inside */
8617 lastoffset = offset;
8618 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8619 if (tag_is_closing(tag_info)) {
8620 lastoffset = offset;
8625 offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: ");
8628 offset = fRealTag(tvb, pinfo, tree, offset, "real value: ");
8631 offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: ");
8634 offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: ");
8637 offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: ");
8640 offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: ");
8643 offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
8646 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8647 offset = fError(tvb, pinfo, tree, offset);
8648 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8650 case 8: /* any Value */
8651 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8652 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
8653 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8659 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8662 offset = fRealTag(tvb, pinfo, tree, offset, "time-change: ");
8667 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8672 if (offset == lastoffset) break; /* nothing happened, exit loop */
8679 fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8681 guint lastoffset = 0;
8682 guint8 tag_no, tag_info;
8685 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8686 lastoffset = offset;
8687 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8688 if (tag_is_closing(tag_info)) {
8693 case 0: /* ProcessId */
8694 offset = fProcessId(tvb, pinfo, tree, offset);
8696 case 1: /* initiating ObjectId */
8697 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8699 case 2: /* event ObjectId */
8700 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8702 case 3: /* time stamp */
8703 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8704 offset = fTimeStamp(tvb, pinfo, tree, offset, NULL);
8705 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8707 case 4: /* notificationClass */
8708 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: ");
8710 case 5: /* Priority */
8711 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: ");
8713 case 6: /* EventType */
8714 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8715 "Event Type: ", BACnetEventType, 64);
8717 case 7: /* messageText */
8718 offset = fCharacterString(tvb, pinfo, tree, offset, "message Text: ");
8720 case 8: /* NotifyType */
8721 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8722 "Notify Type: ", BACnetNotifyType);
8724 case 9: /* ackRequired */
8725 offset = fBooleanTag(tvb, pinfo, tree, offset, "ack Required: ");
8727 case 10: /* fromState */
8728 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8729 "from State: ", BACnetEventState, 64);
8731 case 11: /* toState */
8732 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8733 "to State: ", BACnetEventState, 64);
8735 case 12: /* NotificationParameters */
8736 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8737 offset = fNotificationParameters(tvb, pinfo, tree, offset);
8738 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8743 if (offset == lastoffset) break; /* nothing happened, exit loop */
8749 fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8751 return fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
8755 fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8757 guint lastoffset = 0, len;
8758 guint8 tag_no, tag_info;
8760 proto_tree *subtree = tree;
8763 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8764 lastoffset = offset;
8765 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8766 if (tag_is_closing(tag_info)) {
8773 case 0: /* ProcessId */
8774 offset = fProcessId(tvb, pinfo, tree, offset);
8776 case 1: /* initiating DeviceId */
8777 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
8779 case 2: /* monitored ObjectId */
8780 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
8782 case 3: /* time remaining */
8783 offset = fTimeSpan(tvb, pinfo, tree, offset, "Time remaining");
8785 case 4: /* List of Values */
8786 if (tag_is_opening(tag_info)) {
8787 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
8788 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
8789 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8790 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
8798 if (offset == lastoffset) break; /* nothing happened, exit loop */
8804 fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8806 return fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
8810 fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8812 guint lastoffset = 0;
8813 guint8 tag_no = 0, tag_info = 0;
8816 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8817 lastoffset = offset;
8818 switch (fTagNo(tvb, offset)) {
8819 case 0: /* acknowledgingProcessId */
8820 offset = fUnsignedTag(tvb, pinfo, tree, offset, "acknowledging Process Id: ");
8822 case 1: /* eventObjectId */
8823 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8825 case 2: /* eventStateAcknowledged */
8826 offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
8827 "event State Acknowledged: ", BACnetEventState, 64);
8829 case 3: /* timeStamp */
8830 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8831 offset = fTimeStamp(tvb, pinfo, tree, offset, NULL);
8832 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8834 case 4: /* acknowledgementSource */
8835 offset = fCharacterString(tvb, pinfo, tree, offset, "acknowledgement Source: ");
8837 case 5: /* timeOfAcknowledgement */
8838 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8839 offset = fTimeStamp(tvb, pinfo, tree, offset, "acknowledgement timestamp: ");
8840 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8845 if (offset == lastoffset) break; /* nothing happened, exit loop */
8851 fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8853 guint lastoffset = 0;
8855 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8856 lastoffset = offset;
8857 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
8858 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
8859 "alarm State: ", BACnetEventState, 64);
8860 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
8861 "acknowledged Transitions: ", BACnetEventTransitionBits);
8862 if (offset == lastoffset) break; /* nothing happened, exit loop */
8868 fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8870 guint lastoffset = 0;
8871 guint8 tag_no, tag_info;
8874 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8875 lastoffset = offset;
8876 switch (fTagNo(tvb, offset)) {
8877 case 0: /* acknowledgmentFilter */
8878 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8879 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
8881 case 1: /* eventObjectId - OPTIONAL */
8882 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8883 offset = fRecipientProcess(tvb, pinfo, tree, offset);
8884 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8886 case 2: /* eventStateFilter */
8887 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8888 "event State Filter: ", BACnetEventStateFilter);
8890 case 3: /* eventTypeFilter - OPTIONAL */
8891 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8892 "event Type Filter: ", BACnetEventType);
8894 case 4: /* priorityFilter */
8895 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8896 offset = fUnsignedTag(tvb, pinfo, tree, offset, "min Priority: ");
8897 offset = fUnsignedTag(tvb, pinfo, tree, offset, "max Priority: ");
8898 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
8900 case 5: /* notificationClassFilter - OPTIONAL */
8901 offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification Class Filter: ");
8906 if (offset == lastoffset) break; /* nothing happened, exit loop */
8912 fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8914 guint lastoffset = 0;
8916 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8917 lastoffset = offset;
8918 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
8919 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
8920 "event Type: ", BACnetEventType, 64);
8921 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
8922 "event State: ", BACnetEventState);
8923 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Priority: ");
8924 if (tvb_reported_length_remaining(tvb, offset) > 0 && fTagNo(tvb, offset) == 2) /* Notification Class - OPTIONAL */
8925 offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: ");
8926 if (offset == lastoffset) break; /* nothing happened, exit loop */
8933 fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8935 if (tvb_reported_length_remaining(tvb, offset) > 0) {
8936 if (fTagNo(tvb, offset) == 0) {
8937 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8944 flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
8946 guint lastoffset = 0;
8947 guint8 tag_no, tag_info;
8949 proto_tree* subtree = tree;
8952 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
8953 lastoffset = offset;
8954 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
8955 /* we are finished here if we spot a closing tag */
8956 if (tag_is_closing(tag_info)) {
8960 case 0: /* ObjectId */
8961 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
8963 case 1: /* eventState */
8964 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8965 "event State: ", BACnetEventState);
8967 case 2: /* acknowledgedTransitions */
8968 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
8969 "acknowledged Transitions: ", BACnetEventTransitionBits);
8971 case 3: /* eventTimeStamps */
8972 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
8974 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8976 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8977 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: ");
8978 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: ");
8979 offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: ");
8980 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8982 case 4: /* notifyType */
8983 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
8984 "Notify Type: ", BACnetNotifyType);
8986 case 5: /* eventEnable */
8987 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
8988 "event Enable: ", BACnetEventTransitionBits);
8990 case 6: /* eventPriorities */
8991 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
8993 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
8995 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
8996 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-OFFNORMAL Priority: ");
8997 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-FAULT Priority: ");
8998 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-NORMAL Priority: ");
8999 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9004 if (offset == lastoffset) break; /* nothing happened, exit loop */
9010 fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9012 guint lastoffset = 0;
9013 guint8 tag_no, tag_info;
9016 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9017 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9018 lastoffset = offset;
9019 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9020 /* we are finished here if we spot a closing tag */
9021 if (tag_is_closing(tag_info)) {
9024 offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
9025 if (offset == lastoffset) break; /* nothing happened, exit loop */
9031 fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9033 guint lastoffset = 0;
9034 guint8 tag_no, tag_info;
9037 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9038 lastoffset = offset;
9039 switch (fTagNo(tvb, offset)) {
9040 case 0: /* listOfEventSummaries */
9041 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9042 offset = flistOfEventSummaries(tvb, pinfo, tree, offset);
9043 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9045 case 1: /* moreEvents */
9046 offset = fBooleanTag(tvb, pinfo, tree, offset, "more Events: ");
9051 if (offset == lastoffset) break; /* nothing happened, exit loop */
9057 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9059 guint lastoffset = 0, len;
9060 guint8 tag_no, tag_info;
9062 proto_tree *subtree = tree;
9065 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9067 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9068 lastoffset = offset;
9069 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9070 if (tag_is_closing(tag_info)) {
9077 case 0: /* ObjectId */
9078 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9080 case 3: /* listOfElements */
9081 if (tag_is_opening(tag_info)) {
9082 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
9083 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9084 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9085 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
9093 if (offset == lastoffset) break; /* nothing happened, exit loop */
9099 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9101 return fObjectIdentifier(tvb, pinfo, tree, offset);
9105 fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9107 guint lastoffset = 0;
9109 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9110 lastoffset = offset;
9112 switch (fTagNo(tvb, offset)) {
9113 case 0: /* timeDuration */
9114 offset = fUnsignedTag(tvb, pinfo, tree, offset, "time Duration: ");
9116 case 1: /* enable-disable */
9117 offset = fEnumeratedTag(tvb, pinfo, tree, offset, "enable-disable: ",
9118 BACnetEnableDisable);
9120 case 2: /* password - OPTIONAL */
9121 offset = fCharacterString(tvb, pinfo, tree, offset, "Password: ");
9126 if (offset == lastoffset) break; /* nothing happened, exit loop */
9132 fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9134 guint lastoffset = 0;
9136 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9137 lastoffset = offset;
9139 switch (fTagNo(tvb, offset)) {
9140 case 0: /* reinitializedStateOfDevice */
9141 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
9142 "reinitialized State Of Device: ",
9143 BACnetReinitializedStateOfDevice);
9145 case 1: /* password - OPTIONAL */
9146 offset = fCharacterString(tvb, pinfo, tree, offset, "Password: ");
9151 if (offset == lastoffset) break; /* nothing happened, exit loop */
9157 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9159 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
9160 "vtClass: ", BACnetVTClass);
9161 return fApplicationTypes(tvb, pinfo, tree, offset, "local VT Session ID: ");
9165 fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9167 return fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: ");
9171 fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9173 guint lastoffset = 0;
9175 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9176 lastoffset = offset;
9177 offset= fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: ");
9178 if (offset == lastoffset) break; /* nothing happened, exit loop */
9184 fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9186 offset= fApplicationTypes(tvb, pinfo, tree, offset, "VT Session ID: ");
9187 offset = fApplicationTypes(tvb, pinfo, tree, offset, "VT New Data: ");
9188 return fApplicationTypes(tvb, pinfo, tree, offset, "VT Data Flag: ");
9192 fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9194 guint lastoffset = 0;
9196 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9197 lastoffset = offset;
9199 switch (fTagNo(tvb, offset)) {
9200 case 0: /* BOOLEAN */
9201 offset = fBooleanTag(tvb, pinfo, tree, offset, "all New Data Accepted: ");
9203 case 1: /* Unsigned OPTIONAL */
9204 offset = fUnsignedTag(tvb, pinfo, tree, offset, "accepted Octet Count: ");
9209 if (offset == lastoffset) break; /* nothing happened, exit loop */
9215 fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9217 guint lastoffset = 0;
9219 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9220 lastoffset = offset;
9222 switch (fTagNo(tvb, offset)) {
9223 case 0: /* Unsigned32 */
9224 offset = fUnsignedTag(tvb, pinfo, tree, offset, "pseudo Random Number: ");
9226 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
9227 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
9229 case 2: /* Chararacter String OPTIONAL */
9230 offset = fCharacterString(tvb, pinfo, tree, offset, "operator Name: ");
9232 case 3: /* Chararacter String OPTIONAL */
9233 offset = fCharacterString(tvb, pinfo, tree, offset, "operator Password: ");
9235 case 4: /* Boolean OPTIONAL */
9236 offset = fBooleanTag(tvb, pinfo, tree, offset, "start Encyphered Session: ");
9241 if (offset == lastoffset) break; /* nothing happened, exit loop */
9247 fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9249 return fApplicationTypes(tvb, pinfo, tree, offset, "modified Random Number: ");
9253 fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9255 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* Requesting Device Identifier */
9256 offset = fAddress(tvb, pinfo, tree, offset);
9257 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* Remote Device Identifier */
9258 return fAddress(tvb, pinfo, tree, offset);
9262 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9264 /* Same as AddListElement request after service choice */
9265 return fAddListElementRequest(tvb, pinfo, tree, offset);
9269 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9271 return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
9275 fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9277 guint lastoffset = 0, len;
9278 guint8 tag_no, tag_info;
9280 proto_tree *subtree = tree;
9282 /* set the optional global properties to indicate not-used */
9283 propertyArrayIndex = -1;
9284 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9285 lastoffset = offset;
9286 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9287 if (tag_is_closing(tag_info)) {
9293 case 0: /* objectIdentifier */
9294 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9296 case 1: /* propertyIdentifier */
9297 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9299 case 2: /* propertyArrayIndex */
9300 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
9302 case 3: /* propertyValue */
9303 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9308 if (offset == lastoffset) break; /* nothing happened, exit loop */
9314 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9316 guint lastoffset = 0;
9317 guint8 tag_no, tag_info;
9319 proto_tree *subtree = tree;
9321 /* set the optional global properties to indicate not-used */
9322 propertyArrayIndex = -1;
9323 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9324 lastoffset = offset;
9325 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9326 /* quit loop if we spot a closing tag */
9327 if (tag_is_closing(tag_info)) {
9332 case 0: /* objectIdentifier */
9333 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9335 case 1: /* propertyIdentifier */
9336 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9338 case 2: /* propertyArrayIndex */
9339 offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
9341 case 3: /* propertyValue */
9342 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9344 case 4: /* Priority (only used for write) */
9345 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
9350 if (offset == lastoffset) break; /* nothing happened, exit loop */
9356 fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9358 guint lastoffset = 0, len;
9359 guint8 tag_no, tag_info;
9362 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9363 lastoffset = offset;
9364 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9365 /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
9366 if (tag_is_closing(tag_info)) {
9372 case 0: /* objectIdentifier */
9373 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9375 case 1: /* listOfPropertyValues */
9376 if (tag_is_opening(tag_info)) {
9377 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9378 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
9386 if (offset == lastoffset) break; /* nothing happened, exit loop */
9392 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9394 if (offset >= tvb_reported_length(tvb))
9397 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9398 return fWriteAccessSpecification(tvb, pinfo, tree, offset);
9402 fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
9404 guint lastoffset = 0;
9405 guint8 tag_no, tag_info;
9408 /* set the optional global properties to indicate not-used */
9409 propertyArrayIndex = -1;
9410 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9411 lastoffset = offset;
9412 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9413 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
9415 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
9418 switch (tag_no-tagoffset) {
9419 case 0: /* PropertyIdentifier */
9420 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
9422 case 1: /* propertyArrayIndex */
9423 offset = fPropertyArrayIndex(tvb, pinfo, tree, offset);
9424 if (list != 0) break; /* Continue decoding if this may be a list */
9426 lastoffset = offset; /* Set loop end condition */
9429 if (offset == lastoffset) break; /* nothing happened, exit loop */
9435 fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
9437 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9438 return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
9442 fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9444 guint lastoffset = 0;
9446 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9447 lastoffset = offset;
9449 switch (fTagNo(tvb, offset)) {
9450 case 0: /* ObjectIdentifier */
9451 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9453 case 1: /* PropertyIdentifier and propertyArrayIndex */
9454 offset = fPropertyReference(tvb, pinfo, tree, offset, 1, 0);
9455 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9457 lastoffset = offset; /* Set loop end condition */
9460 if (offset == lastoffset) break; /* nothing happened, exit loop */
9467 fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, guint offset)
9469 guint lastoffset = 0;
9470 guint8 tag_no, tag_info;
9472 proto_tree* subtree = tree;
9475 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
9476 lastoffset = offset;
9477 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9478 if (tag_is_closing(tag_info)) {
9479 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
9480 &tag_no, &tag_info, &lvt);
9484 case 0: /* ObjectIdentifier */
9485 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9487 case 1: /* PropertyIdentifier */
9488 offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
9490 case 2: /* propertyArrayIndex */
9491 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "property Array Index: ");
9494 offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
9496 case 4: /* Priority */
9497 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
9508 fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9510 char i = 1, ar[256];
9511 guint lastoffset = 0;
9513 if (propertyArrayIndex > 0) {
9514 /* BACnetARRAY index 0 refers to the length
9515 of the array, not the elements of the array.
9516 BACnetARRAY index -1 is our internal flag that
9517 the optional index was not used.
9518 BACnetARRAY refers to this as all elements of the array.
9519 If the optional index is specified for a BACnetARRAY,
9520 then that specific array element is referenced. */
9521 i = propertyArrayIndex;
9523 while (tvb_reported_length_remaining(tvb, offset) > 0) {
9524 /* exit loop if nothing happens inside */
9525 lastoffset = offset;
9526 g_snprintf(ar, sizeof(ar), "%s[%d]: ",
9527 val_to_split_str(87 , 512,
9528 BACnetPropertyIdentifier,
9529 ASHRAE_Reserved_Fmt,
9530 Vendor_Proprietary_Fmt),
9532 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
9533 offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
9534 /* there are only 16 priority array elements */
9538 if (offset == lastoffset) break; /* nothing happened, exit loop */
9545 fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9547 guint lastoffset = 0;
9549 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9550 lastoffset = offset;
9552 switch (fTagNo(tvb, offset)) {
9553 case 0: /* deviceIdentifier - OPTIONAL */
9554 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9556 case 1: /* ObjectIdentifier */
9557 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9562 if (offset == lastoffset) break; /* nothing happened, exit loop */
9568 fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9570 guint8 tag_no, tag_info;
9572 guint lastoffset = 0, len;
9573 gboolean closing_found = FALSE; /* tracks when we are done decoding the fSpecialEvent entries */
9575 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9576 lastoffset = offset;
9577 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9578 /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
9579 if (tag_is_closing(tag_info)) {
9580 /* if we find 2 closing tags in succession we need to exit without incrementing the offset again */
9581 /* This handles the special case where we have a special event entry in an RPM-ACK msg */
9582 if ( closing_found == TRUE )
9585 closing_found = TRUE;
9590 case 0: /* calendarEntry */
9591 if (tag_is_opening(tag_info)) {
9592 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9593 offset = fCalendarEntry(tvb, pinfo, subtree, offset);
9594 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9597 case 1: /* calendarReference */
9598 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9600 case 2: /* list of BACnetTimeValue */
9601 if (tag_is_opening(tag_info)) {
9602 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9603 offset = fTimeValue(tvb, pinfo, subtree, offset);
9604 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9609 case 3: /* eventPriority */
9610 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "event priority: ");
9615 closing_found = FALSE; /* reset our closing tag status, we processed another open tag */
9616 if (offset == lastoffset) break; /* nothing happened, exit loop */
9622 fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9624 guint lastoffset = 0, len;
9625 guint8 tag_no, tag_info;
9628 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9629 lastoffset = offset;
9630 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9631 /* maybe a listOfSelectionCriteria if we spot a closing tag */
9632 if (tag_is_closing(tag_info)) {
9637 switch (fTagNo(tvb, offset)) {
9638 case 0: /* propertyIdentifier */
9639 offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
9641 case 1: /* propertyArrayIndex */
9642 offset = fPropertyArrayIndex(tvb, pinfo, tree, offset);
9644 case 2: /* relationSpecifier */
9645 offset = fEnumeratedTag(tvb, pinfo, tree, offset,
9646 "relation Specifier: ", BACnetRelationSpecifier);
9648 case 3: /* comparisonValue */
9649 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9650 offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
9651 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
9656 if (offset == lastoffset) break; /* nothing happened, exit loop */
9662 fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9664 guint lastoffset = 0;
9665 guint8 tag_no, tag_info;
9668 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9669 lastoffset = offset;
9670 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9671 /* quit loop if we spot a closing tag */
9672 if (tag_is_closing(tag_info)) {
9677 case 0: /* selectionLogic */
9678 offset = fEnumeratedTag(tvb, pinfo, subtree, offset,
9679 "selection Logic: ", BACnetSelectionLogic);
9681 case 1: /* listOfSelectionCriteria */
9682 if (tag_is_opening(tag_info)) {
9683 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9684 offset = fSelectionCriteria(tvb, pinfo, subtree, offset);
9685 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9693 if (offset == lastoffset) break; /* nothing happened, exit loop */
9700 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
9702 guint lastoffset = 0;
9703 guint8 tag_no, tag_info;
9706 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9707 lastoffset = offset;
9708 fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9710 if (tag_is_opening(tag_info) && tag_no < 2) {
9711 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9713 case 0: /* objectSelectionCriteria */
9714 offset = fObjectSelectionCriteria(tvb, pinfo, subtree, offset);
9716 case 1: /* listOfPropertyReferences */
9717 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
9722 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9724 if (offset == lastoffset) break; /* nothing happened, exit loop */
9730 fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9732 guint lastoffset = 0;
9733 guint8 tag_no, tag_info;
9736 proto_tree *subtree = tree;
9738 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9739 lastoffset = offset;
9740 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9742 case 0: /* objectIdentifier */
9743 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9745 case 1: /* listOfPropertyReferences */
9746 if (tag_is_opening(tag_info)) {
9747 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
9748 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9749 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9750 offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
9751 } else if (tag_is_closing(tag_info)) {
9752 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
9753 &tag_no, &tag_info, &lvt);
9756 /* error condition: let caller handle */
9763 if (offset == lastoffset) break; /* nothing happened, exit loop */
9769 fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9771 guint lastoffset = 0, len;
9775 proto_tree *subtree = tree;
9778 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9779 lastoffset = offset;
9780 len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9781 /* maybe a listOfReadAccessResults if we spot a closing tag here */
9782 if (tag_is_closing(tag_info)) {
9784 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
9789 case 0: /* objectSpecifier */
9790 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
9792 case 1: /* list of Results */
9793 if (tag_is_opening(tag_info)) {
9794 tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
9795 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9796 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9801 case 2: /* propertyIdentifier */
9802 offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
9804 case 5: /* propertyAccessError */
9805 if (tag_is_opening(tag_info)) {
9806 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
9807 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9808 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9809 /* Error Code follows */
9810 offset = fError(tvb, pinfo, subtree, offset);
9818 if (offset == lastoffset) break; /* nothing happened, exit loop */
9825 fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9827 /* listOfReadAccessResults */
9828 return fReadAccessResult(tvb, pinfo, tree, offset);
9833 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
9835 guint lastoffset = 0;
9836 guint8 tag_no, tag_info;
9839 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
9840 lastoffset = offset;
9841 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9844 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9846 case 0: /* objectSpecifier */
9847 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
9848 case 0: /* objectType */
9849 offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, "Object Type: ", BACnetObjectType, 128);
9851 case 1: /* objectIdentifier */
9852 offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
9858 case 1: /* propertyValue */
9859 if (tag_is_opening(tag_info)) {
9860 offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
9868 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9870 if (offset == lastoffset) break; /* nothing happened, exit loop */
9876 fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9878 return fObjectIdentifier(tvb, pinfo, tree, offset);
9882 fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9884 guint8 tag_no, tag_info;
9886 proto_tree *subtree = tree;
9889 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9891 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9892 /* optional range choice */
9893 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9894 if (tag_is_opening(tag_info)) {
9895 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str_const(tag_no, BACnetReadRangeOptions, "unknown range option"));
9896 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9897 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9899 case 3: /* range byPosition */
9900 case 6: /* range bySequenceNumber, 2004 spec */
9901 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Index: ");
9902 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: ");
9904 case 4: /* range byTime - deprecated in 2004 */
9905 case 7: /* 2004 spec */
9906 offset = fDateTime(tvb, pinfo, subtree, offset, "reference Date/Time: ");
9907 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: ");
9909 case 5: /* range timeRange - deprecated in 2004 */
9910 offset = fDateTime(tvb, pinfo, subtree, offset, "beginning Time: ");
9911 offset = fDateTime(tvb, pinfo, subtree, offset, "ending Time: ");
9916 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9923 fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9925 guint8 tag_no, tag_info;
9927 proto_tree *subtree = tree;
9930 /* set the optional global properties to indicate not-used */
9931 propertyArrayIndex = -1;
9932 /* objectIdentifier, propertyIdentifier, and
9933 OPTIONAL propertyArrayIndex */
9934 offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
9935 /* resultFlags => BACnetResultFlags ::= BIT STRING */
9936 offset = fBitStringTagVS(tvb, pinfo, tree, offset,
9940 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "item Count: ");
9942 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9943 if (tag_is_opening(tag_info)) {
9944 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
9945 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
9946 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9947 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9948 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
9949 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9951 /* firstSequenceNumber - OPTIONAL */
9952 if (tvb_reported_length_remaining(tvb, offset) > 0) {
9953 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "first Sequence Number: ");
9960 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9962 guint lastoffset = 0;
9964 guint8 tag_no, tag_info;
9966 proto_tree* subtree = NULL;
9968 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9970 if (tag_is_opening(tag_info)) {
9971 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str_const(tag_no, BACnetFileAccessOption, "invalid access method"));
9972 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
9973 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9974 offset = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "invalid option"));
9975 offset = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileWriteInfo, "unknown option"));
9978 while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
9979 /* exit loop if nothing happens inside */
9980 lastoffset = offset;
9981 offset = fApplicationTypes(tvb, pinfo, subtree, offset, "Record Data: ");
9985 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
9986 /* More Flag is not set, so we can look for closing tag in this segment */
9987 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
9988 if (tag_is_closing(tag_info)) {
9989 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
9997 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
9999 guint8 tag_no, tag_info;
10001 proto_tree *subtree = tree;
10004 offset = fObjectIdentifier(tvb, pinfo, tree, offset);
10006 fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10008 if (tag_is_opening(tag_info)) {
10009 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str_const(tag_no, BACnetFileAccessOption, "unknown access method"));
10010 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
10011 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10012 offset = fSignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
10013 offset = fUnsignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileRequestCount, "unknown option"));
10014 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10020 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10023 offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* file Identifier */
10024 offset = fAccessMethod(tvb, pinfo, tree, offset);
10030 fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10032 guint tag_no = fTagNo(tvb, offset);
10033 return fSignedTag(tvb, pinfo, tree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
10037 fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10039 offset = fApplicationTypes(tvb, pinfo, tree, offset, "End Of File: ");
10040 offset = fAccessMethod(tvb, pinfo, tree, offset);
10046 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
10048 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10049 return fReadAccessSpecification(tvb, pinfo, subtree, offset);
10053 fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10055 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10056 return fReadAccessResult(tvb, pinfo, tree, offset);
10060 fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10062 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10065 switch (service_choice) {
10066 case 0: /* acknowledgeAlarm */
10067 offset = fAcknowledgeAlarmRequest(tvb, pinfo, tree, offset);
10069 case 1: /* confirmedCOVNotification */
10070 offset = fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
10072 case 2: /* confirmedEventNotification */
10073 offset = fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
10075 case 3: /* confirmedGetAlarmSummary conveys no parameters */
10077 case 4: /* getEnrollmentSummaryRequest */
10078 offset = fGetEnrollmentSummaryRequest(tvb, pinfo, tree, offset);
10080 case 5: /* subscribeCOVRequest */
10081 offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
10083 case 6: /* atomicReadFile-Request */
10084 offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
10086 case 7: /* atomicWriteFile-Request */
10087 offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
10089 case 8: /* AddListElement-Request */
10090 offset = fAddListElementRequest(tvb, pinfo, tree, offset);
10092 case 9: /* removeListElement-Request */
10093 offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
10095 case 10: /* createObjectRequest */
10096 offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
10098 case 11: /* deleteObject */
10099 offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
10102 offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
10105 offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
10108 offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
10111 offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
10114 offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
10117 offset = fDeviceCommunicationControlRequest(tvb, pinfo, tree, offset);
10120 offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
10123 offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
10126 offset = fReinitializeDeviceRequest(tvb, pinfo, tree, offset);
10129 offset = fVtOpenRequest(tvb, pinfo, tree, offset);
10132 offset = fVtCloseRequest(tvb, pinfo, tree, offset);
10135 offset = fVtDataRequest(tvb, pinfo, tree, offset);
10138 offset = fAuthenticateRequest(tvb, pinfo, tree, offset);
10141 offset = fRequestKeyRequest(tvb, pinfo, tree, offset);
10144 offset = fReadRangeRequest(tvb, pinfo, tree, offset);
10147 offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
10150 offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
10153 offset = fGetEventInformationRequest(tvb, pinfo, tree, offset);
10162 fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10164 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10167 switch (service_choice) {
10168 case 3: /* confirmedEventNotificationAck */
10169 offset = fGetAlarmSummaryAck(tvb, pinfo, tree, offset);
10171 case 4: /* getEnrollmentSummaryAck */
10172 offset = fGetEnrollmentSummaryAck(tvb, pinfo, tree, offset);
10174 case 6: /* atomicReadFile */
10175 offset = fAtomicReadFileAck(tvb, pinfo, tree, offset);
10177 case 7: /* atomicReadFileAck */
10178 offset = fAtomicWriteFileAck(tvb, pinfo, tree, offset);
10180 case 10: /* createObject */
10181 offset = fCreateObjectAck(tvb, pinfo, tree, offset);
10184 offset = fReadPropertyAck(tvb, pinfo, tree, offset);
10187 offset = fReadPropertyConditionalAck(tvb, pinfo, tree, offset);
10190 offset = fReadPropertyMultipleAck(tvb, pinfo, tree, offset);
10193 offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
10196 offset = fVtOpenAck(tvb, pinfo, tree, offset);
10199 offset = fVtDataAck(tvb, pinfo, tree, offset);
10202 offset = fAuthenticateAck(tvb, pinfo, tree, offset);
10205 offset = fReadRangeAck(tvb, pinfo, tree, offset);
10208 offset = fGetEventInformationACK(tvb, pinfo, tree, offset);
10217 fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10219 /* BACnetObjectIdentifier */
10220 offset = fApplicationTypes(tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
10222 /* MaxAPDULengthAccepted */
10223 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
10225 /* segmentationSupported */
10226 offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
10227 "Segmentation Supported: ", BACnetSegmentation);
10230 return fVendorIdentifier(tvb, pinfo, tree, offset);
10234 fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10236 /* BACnetDeviceIdentifier */
10237 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Device Identifier: ");
10239 /* BACnetObjectIdentifier */
10240 offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
10243 return fApplicationTypes(tvb, pinfo, tree, offset, "Object Name: ");
10248 fWhoIsRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
10250 guint lastoffset = 0;
10254 guint8 tag_no, tag_info;
10257 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10258 lastoffset = offset;
10260 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10264 /* DeviceInstanceRangeLowLimit Optional */
10265 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
10266 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
10267 offset = fDevice_Instance(tvb, pinfo, tree, offset,
10268 hf_Device_Instance_Range_Low_Limit);
10271 /* DeviceInstanceRangeHighLimit Optional but
10272 required if DeviceInstanceRangeLowLimit is there */
10273 if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
10274 col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
10275 offset = fDevice_Instance(tvb, pinfo, tree, offset,
10276 hf_Device_Instance_Range_High_Limit);
10281 if (offset == lastoffset) break; /* nothing happened, exit loop */
10287 fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
10289 if (tvb_reported_length_remaining(tvb, offset) <= 0)
10292 switch (service_choice) {
10293 case 0: /* I-Am-Request */
10294 offset = fIAmRequest(tvb, pinfo, tree, offset);
10296 case 1: /* i-Have Request */
10297 offset = fIHaveRequest(tvb, pinfo, tree, offset);
10299 case 2: /* unconfirmedCOVNotification */
10300 offset = fUnconfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
10302 case 3: /* unconfirmedEventNotification */
10303 offset = fUnconfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
10305 case 4: /* unconfirmedPrivateTransfer */
10306 offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
10308 case 5: /* unconfirmedTextMessage */
10309 offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
10311 case 206: /* utc-time-synchronization-recipients */
10312 case 6: /* timeSynchronization */
10313 offset = fTimeSynchronizationRequest(tvb, pinfo, tree, offset);
10315 case 7: /* who-Has */
10316 offset = fWhoHas(tvb, pinfo, tree, offset);
10318 case 8: /* who-Is */
10319 offset = fWhoIsRequest(tvb, pinfo, tree, offset);
10321 case 9: /* utcTimeSynchronization */
10322 offset = fUTCTimeSynchronizationRequest(tvb, pinfo, tree, offset);
10331 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
10332 gint *svc, proto_item **tt)
10335 proto_tree *bacapp_tree_control;
10340 tmp = (gint) tvb_get_guint8(tvb, offset);
10341 bacapp_flags = tmp & 0x0f;
10346 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
10347 if (bacapp_flags & 0x08)
10348 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
10350 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10351 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
10352 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
10354 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
10355 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
10356 if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
10357 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
10358 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
10359 offset, 1, ENC_BIG_ENDIAN);
10360 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
10361 offset, 1, ENC_BIG_ENDIAN);
10364 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
10365 if (bacapp_flags & 0x08) {
10366 bacapp_seq = tvb_get_guint8(tvb, offset);
10367 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
10368 offset++, 1, ENC_BIG_ENDIAN);
10369 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
10370 offset++, 1, ENC_BIG_ENDIAN);
10372 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
10373 offset++, 1, ENC_BIG_ENDIAN);
10378 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
10379 { /* BACnet-Confirmed-Request */
10380 /* ASHRAE 135-2001 20.1.2 */
10382 return fConfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, svc);
10386 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10387 { /* BACnet-Confirmed-Request */
10388 /* ASHRAE 135-2001 20.1.2 */
10390 proto_item *tt = 0;
10392 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
10393 return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
10397 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10398 { /* BACnet-Unconfirmed-Request-PDU */
10399 /* ASHRAE 135-2001 20.1.3 */
10403 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10405 tmp = tvb_get_guint8(tvb, offset);
10406 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
10407 offset++, 1, ENC_BIG_ENDIAN);
10408 /* Service Request follows... Variable Encoding 20.2ff */
10409 return fUnconfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, tmp);
10413 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10414 { /* BACnet-Simple-Ack-PDU */
10415 /* ASHRAE 135-2001 20.1.4 */
10417 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10419 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
10420 offset++, 1, ENC_BIG_ENDIAN);
10421 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
10422 offset++, 1, ENC_BIG_ENDIAN);
10428 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
10429 { /* BACnet-Complex-Ack-PDU */
10430 /* ASHRAE 135-2001 20.1.5 */
10432 /* Service ACK follows... */
10433 return fConfirmedServiceAck(tvb, pinfo, bacapp_tree, offset, svc);
10437 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10438 { /* BACnet-Complex-Ack-PDU */
10439 /* ASHRAE 135-2001 20.1.5 */
10441 proto_item *tt = 0;
10443 offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
10444 return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
10448 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10449 { /* BACnet-SegmentAck-PDU */
10450 /* ASHRAE 135-2001 20.1.6 */
10453 proto_tree *bacapp_tree_control;
10455 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10456 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10458 proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
10459 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10460 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10461 offset++, 1, ENC_BIG_ENDIAN);
10462 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
10463 offset++, 1, ENC_BIG_ENDIAN);
10464 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
10465 offset++, 1, ENC_BIG_ENDIAN);
10470 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10472 guint8 tag_info = 0;
10473 guint8 parsed_tag = 0;
10476 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
10477 offset = fError(tvb, pinfo, tree, offset);
10478 return offset + fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
10482 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10484 guint lastoffset = 0;
10485 guint8 tag_no = 0, tag_info = 0;
10487 proto_tree *subtree = tree;
10490 guint vendor_identifier = 0;
10491 guint service_number = 0;
10492 guint8 tag_len = 0;
10494 while (tvb_reported_length_remaining(tvb, offset) > 0) {
10495 /* exit loop if nothing happens inside */
10496 lastoffset = offset;
10497 tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
10499 case 0: /* errorType */
10500 offset = fContextTaggedError(tvb, pinfo, subtree, offset);
10502 case 1: /* vendorID */
10503 fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
10504 if (col_get_writable(pinfo->cinfo))
10505 col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
10506 offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
10508 case 2: /* serviceNumber */
10509 fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
10510 if (col_get_writable(pinfo->cinfo))
10511 col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number);
10512 offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: ");
10514 case 3: /* errorParameters */
10515 if (tag_is_opening(tag_info)) {
10516 tt = proto_tree_add_text(subtree, tvb, offset, 1,
10517 "error Parameters");
10518 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
10519 propertyIdentifier = -1;
10520 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
10521 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
10522 } else if (tag_is_closing(tag_info)) {
10523 offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
10524 &tag_no, &tag_info, &lvt);
10527 /* error condition: let caller handle */
10534 if (offset == lastoffset) break; /* nothing happened, exit loop */
10540 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10542 guint lastoffset = 0;
10544 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10545 lastoffset = offset;
10546 switch (fTagNo(tvb, offset)) {
10547 case 0: /* errorType */
10548 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10550 case 1: /* firstFailedElementNumber */
10551 offset = fUnsignedTag(tvb, pinfo, tree, offset, "first failed element number: ");
10556 if (offset == lastoffset) break; /* nothing happened, exit loop */
10562 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10564 /* Identical to CreateObjectError */
10565 return fCreateObjectError(tvb, pinfo, tree, offset);
10569 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10571 guint8 tag_no = 0, tag_info = 0;
10574 if (fTagNo(tvb, offset) == 0) {
10576 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10577 if (fTagNo(tvb, offset) == 1) {
10578 /* listOfVTSessionIdentifiers [OPTIONAL] */
10579 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10580 offset = fVtCloseRequest(tvb, pinfo, tree, offset);
10581 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10584 /* should report bad packet if initial tag wasn't 0 */
10589 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10591 guint lastoffset = 0;
10592 guint8 tag_no = 0, tag_info = 0;
10595 col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
10596 while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */
10597 lastoffset = offset;
10598 switch (fTagNo(tvb, offset)) {
10599 case 0: /* errorType */
10600 offset = fContextTaggedError(tvb, pinfo, tree, offset);
10602 case 1: /* firstFailedWriteAttempt */
10603 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10604 offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
10605 offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
10610 if (offset == lastoffset) break; /* nothing happened, exit loop */
10616 fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
10618 offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
10619 "error Class: ", BACnetErrorClass, 64);
10620 return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
10621 "error Code: ", BACnetErrorCode, 256);
10625 fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
10628 case 8: /* no break here !!!! */
10630 offset = fChangeListError(tvb, pinfo, tree, offset);
10633 offset = fCreateObjectError(tvb, pinfo, tree, offset);
10636 offset = fWritePropertyMultipleError(tvb, pinfo, tree, offset);
10639 offset = fConfirmedPrivateTransferError(tvb, pinfo, tree, offset);
10642 offset = fVTCloseError(tvb, pinfo, tree, offset);
10645 return fError(tvb, pinfo, tree, offset);
10651 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
10652 { /* BACnet-Error-PDU */
10653 /* ASHRAE 135-2001 20.1.7 */
10656 proto_tree *bacapp_tree_control;
10659 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10660 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10662 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10663 offset++, 1, ENC_BIG_ENDIAN);
10664 tmp = tvb_get_guint8(tvb, offset);
10665 proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
10666 offset++, 1, ENC_BIG_ENDIAN);
10667 /* Error Handling follows... */
10668 return fBACnetError(tvb, pinfo, bacapp_tree, offset, tmp);
10672 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10673 { /* BACnet-Reject-PDU */
10674 /* ASHRAE 135-2001 20.1.8 */
10677 proto_tree *bacapp_tree_control;
10679 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
10680 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10682 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10683 offset++, 1, ENC_BIG_ENDIAN);
10684 proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
10685 offset++, 1, ENC_BIG_ENDIAN);
10690 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
10691 { /* BACnet-Abort-PDU */
10692 /* ASHRAE 135-2001 20.1.9 */
10695 proto_tree *bacapp_tree_control;
10697 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
10698 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
10700 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
10701 proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
10702 offset++, 1, ENC_BIG_ENDIAN);
10703 proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
10704 offset++, 1, ENC_BIG_ENDIAN);
10709 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10711 guint8 flag, bacapp_type;
10714 flag = (gint) tvb_get_guint8(tvb, 0);
10715 bacapp_type = (flag >> 4) & 0x0f;
10721 /* ASHRAE 135-2001 20.1.1 */
10722 switch (bacapp_type) {
10723 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
10724 offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
10726 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
10727 offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
10729 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
10730 offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
10732 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
10733 offset = fComplexAckPDU(tvb, pinfo, tree, offset);
10735 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
10736 offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
10738 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
10739 offset = fErrorPDU(tvb, pinfo, tree, offset);
10741 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
10742 offset = fRejectPDU(tvb, pinfo, tree, offset);
10744 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
10745 offset = fAbortPDU(tvb, pinfo, tree, offset);
10752 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
10754 guint8 flag, bacapp_type;
10755 guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
10756 tvbuff_t *new_tvb = NULL;
10758 guint8 bacapp_seqno = 0;
10759 guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
10760 guint8 bacapp_invoke_id = 0;
10762 proto_tree *bacapp_tree = NULL;
10765 proto_item *tt = 0;
10768 /* Strings for BACnet Statistics */
10769 const gchar errstr[] = "ERROR: ";
10770 const gchar rejstr[] = "REJECTED: ";
10771 const gchar abortstr[] = "ABORTED: ";
10772 const gchar sackstr[] = " (SimpleAck)";
10773 const gchar cackstr[] = " (ComplexAck)";
10774 const gchar uconfsreqstr[] = " (Unconfirmed Service Request)";
10775 const gchar confsreqstr[] = " (Confirmed Service Request)";
10777 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
10778 col_clear(pinfo->cinfo, COL_INFO);
10780 flag = tvb_get_guint8(tvb, 0);
10781 bacapp_type = (flag >> 4) & 0x0f;
10783 /* show some descriptive text in the INFO column */
10784 col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
10785 val_to_str_const(bacapp_type, BACnetTypeName, "# unknown APDU #"));
10787 bacinfo.service_type = NULL;
10788 bacinfo.invoke_id = NULL;
10789 bacinfo.instance_ident = NULL;
10790 bacinfo.object_ident = NULL;
10792 switch (bacapp_type) {
10793 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10794 /* segmented messages have 2 additional bytes */
10795 if (flag & BACAPP_SEGMENTED_REQUEST) {
10798 /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
10799 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10800 bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
10801 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
10802 bacapp_service = tvb_get_guint8(tvb, offset + 5);
10805 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
10806 bacapp_service = tvb_get_guint8(tvb, offset + 3);
10808 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
10809 val_to_str_const(bacapp_service,
10810 BACnetConfirmedServiceChoice,
10811 bacapp_unknown_service_str),
10814 updateBacnetInfoValue(BACINFO_INVOKEID,
10815 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10817 updateBacnetInfoValue(BACINFO_SERVICE,
10818 wmem_strconcat(wmem_packet_scope(),
10819 val_to_str_const(bacapp_service,
10820 BACnetConfirmedServiceChoice,
10821 bacapp_unknown_service_str),
10822 confsreqstr, NULL));
10824 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
10825 bacapp_service = tvb_get_guint8(tvb, offset + 1);
10826 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
10827 val_to_str_const(bacapp_service,
10828 BACnetUnconfirmedServiceChoice,
10829 bacapp_unknown_service_str));
10831 updateBacnetInfoValue(BACINFO_SERVICE,
10832 wmem_strconcat(wmem_packet_scope(),
10833 val_to_str_const(bacapp_service,
10834 BACnetUnconfirmedServiceChoice,
10835 bacapp_unknown_service_str),
10836 uconfsreqstr, NULL));
10838 case BACAPP_TYPE_SIMPLE_ACK:
10839 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10840 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10841 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10842 val_to_str_const(bacapp_service,
10843 BACnetConfirmedServiceChoice,
10844 bacapp_unknown_service_str),
10847 updateBacnetInfoValue(BACINFO_INVOKEID,
10848 wmem_strdup_printf(wmem_packet_scope(),
10849 "Invoke ID: %d", bacapp_invoke_id));
10851 updateBacnetInfoValue(BACINFO_SERVICE,
10852 wmem_strconcat(wmem_packet_scope(),
10853 val_to_str_const(bacapp_service,
10854 BACnetConfirmedServiceChoice,
10855 bacapp_unknown_service_str),
10858 case BACAPP_TYPE_COMPLEX_ACK:
10859 /* segmented messages have 2 additional bytes */
10860 if (flag & BACAPP_SEGMENTED_REQUEST) {
10863 /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
10864 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10865 bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
10866 /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
10867 bacapp_service = tvb_get_guint8(tvb, offset + 4);
10870 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10871 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10873 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10874 val_to_str_const(bacapp_service,
10875 BACnetConfirmedServiceChoice,
10876 bacapp_unknown_service_str),
10879 updateBacnetInfoValue(BACINFO_INVOKEID,
10880 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10882 updateBacnetInfoValue(BACINFO_SERVICE,
10883 wmem_strconcat(wmem_packet_scope(),
10884 val_to_str_const(bacapp_service,
10885 BACnetConfirmedServiceChoice,
10886 bacapp_unknown_service_str),
10889 case BACAPP_TYPE_SEGMENT_ACK:
10890 /* nothing more to add */
10892 case BACAPP_TYPE_ERROR:
10893 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10894 bacapp_service = tvb_get_guint8(tvb, offset + 2);
10895 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10896 val_to_str_const(bacapp_service,
10897 BACnetConfirmedServiceChoice,
10898 bacapp_unknown_service_str),
10901 updateBacnetInfoValue(BACINFO_INVOKEID,
10902 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10904 updateBacnetInfoValue(BACINFO_SERVICE,
10905 wmem_strconcat(wmem_packet_scope(),
10907 val_to_str_const(bacapp_service,
10908 BACnetConfirmedServiceChoice,
10909 bacapp_unknown_service_str),
10912 case BACAPP_TYPE_REJECT:
10913 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10914 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10915 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10916 val_to_split_str(bacapp_reason,
10918 BACnetRejectReason,
10919 ASHRAE_Reserved_Fmt,
10920 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10922 updateBacnetInfoValue(BACINFO_INVOKEID,
10923 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10925 updateBacnetInfoValue(BACINFO_SERVICE,
10926 wmem_strconcat(wmem_packet_scope(), rejstr,
10927 val_to_split_str(bacapp_reason, 64,
10928 BACnetRejectReason,
10929 ASHRAE_Reserved_Fmt,
10930 Vendor_Proprietary_Fmt),
10933 case BACAPP_TYPE_ABORT:
10934 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
10935 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
10936 col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
10937 val_to_split_str(bacapp_reason,
10940 ASHRAE_Reserved_Fmt,
10941 Vendor_Proprietary_Fmt), bacapp_invoke_id);
10943 updateBacnetInfoValue(BACINFO_INVOKEID,
10944 wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
10946 updateBacnetInfoValue(BACINFO_SERVICE,
10947 wmem_strconcat(wmem_packet_scope(), abortstr,
10948 val_to_split_str(bacapp_reason,
10951 ASHRAE_Reserved_Fmt,
10952 Vendor_Proprietary_Fmt),
10957 /* nothing more to add */
10961 save_fragmented = pinfo->fragmented;
10963 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA);
10964 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
10967 do_the_dissection(tvb, pinfo, bacapp_tree);
10969 fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
10970 /* not resetting the offset so the remaining can be done */
10972 if (fragment) { /* fragmented */
10973 fragment_head *frag_msg;
10975 pinfo->fragmented = TRUE;
10977 frag_msg = fragment_add_seq_check(&msg_reassembly_table,
10980 bacapp_invoke_id, /* ID for fragments belonging together */
10982 bacapp_seqno, /* fragment sequence number */
10983 tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
10984 flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
10985 new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
10986 "Reassembled BACapp", frag_msg, &msg_frag_items,
10989 if (new_tvb) { /* Reassembled */
10990 col_append_str(pinfo->cinfo, COL_INFO,
10991 " (Message Reassembled)");
10992 } else { /* Not last packet of reassembled Short Message */
10993 col_append_fstr(pinfo->cinfo, COL_INFO,
10994 " (Message fragment %u)", bacapp_seqno);
10996 if (new_tvb) { /* take it all */
10997 switch (bacapp_type) {
10998 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
10999 fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
11001 case BACAPP_TYPE_COMPLEX_ACK:
11002 fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
11011 pinfo->fragmented = save_fragmented;
11014 tap_queue_packet(bacapp_tap, pinfo, &bacinfo);
11018 bacapp_init_routine(void)
11020 reassembly_table_init(&msg_reassembly_table,
11021 &addresses_reassembly_table_functions);
11025 proto_register_bacapp(void)
11027 static hf_register_info hf[] = {
11029 { "APDU Type", "bacapp.type",
11030 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
11032 { &hf_bacapp_pduflags,
11033 { "PDU Flags", "bacapp.pduflags",
11034 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
11037 { "Segmented Request", "bacapp.segmented_request",
11038 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
11041 { "More Segments", "bacapp.more_segments",
11042 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
11045 { "SA", "bacapp.SA",
11046 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
11048 { &hf_bacapp_max_adpu_size,
11049 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
11050 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
11052 { &hf_bacapp_response_segments,
11053 { "Max Response Segments accepted", "bacapp.response_segments",
11054 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
11056 { &hf_bacapp_objectType,
11057 { "Object Type", "bacapp.objectType",
11058 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
11060 { &hf_bacapp_instanceNumber,
11061 { "Instance Number", "bacapp.instance_number",
11062 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
11064 { &hf_BACnetPropertyIdentifier,
11065 { "Property Identifier", "bacapp.property_identifier",
11066 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
11068 { &hf_BACnetVendorIdentifier,
11069 { "Vendor Identifier", "bacapp.vendor_identifier",
11070 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &BACnetVendorIdentifiers_ext, 0, NULL, HFILL }
11072 { &hf_BACnetRestartReason,
11073 { "Restart Reason", "bacapp.restart_reason",
11074 FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
11076 { &hf_bacapp_invoke_id,
11077 { "Invoke ID", "bacapp.invoke_id",
11078 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11080 { &hf_bacapp_sequence_number,
11081 { "Sequence Number", "bacapp.sequence_number",
11082 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11084 { &hf_bacapp_window_size,
11085 { "Proposed Window Size", "bacapp.window_size",
11086 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
11088 { &hf_bacapp_service,
11089 { "Service Choice", "bacapp.confirmed_service",
11090 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
11092 { &hf_bacapp_uservice,
11093 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
11094 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
11097 { "NAK", "bacapp.NAK",
11098 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
11101 { "SRV", "bacapp.SRV",
11102 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
11104 { &hf_Device_Instance_Range_Low_Limit,
11105 { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
11106 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
11108 { &hf_Device_Instance_Range_High_Limit,
11109 { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
11110 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
11112 { &hf_BACnetRejectReason,
11113 { "Reject Reason", "bacapp.reject_reason",
11114 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
11116 { &hf_BACnetAbortReason,
11117 { "Abort Reason", "bacapp.abort_reason",
11118 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
11120 { &hf_BACnetApplicationTagNumber,
11121 { "Application Tag Number",
11122 "bacapp.application_tag_number",
11123 FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
11126 { &hf_BACnetContextTagNumber,
11127 { "Context Tag Number",
11128 "bacapp.context_tag_number",
11129 FT_UINT8, BASE_DEC, NULL, 0xF0,
11132 { &hf_BACnetExtendedTagNumber,
11133 { "Extended Tag Number",
11134 "bacapp.extended_tag_number",
11135 FT_UINT8, BASE_DEC, NULL, 0,
11138 { &hf_BACnetNamedTag,
11140 "bacapp.named_tag",
11141 FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
11144 { &hf_BACnetCharacterSet,
11145 { "String Character Set",
11146 "bacapp.string_character_set",
11147 FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet), 0,
11150 { &hf_BACnetTagClass,
11151 { "Tag Class", "bacapp.tag_class",
11152 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
11154 { &hf_bacapp_tag_lvt,
11155 { "Length Value Type",
11157 FT_UINT8, BASE_DEC, NULL, 0,
11160 { &hf_bacapp_tag_ProcessId,
11161 { "ProcessIdentifier", "bacapp.processId",
11162 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
11164 { &hf_bacapp_tag_IPV4,
11165 { "IPV4", "bacapp.IPV4",
11166 FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
11168 { &hf_bacapp_tag_IPV6,
11169 { "IPV6", "bacapp.IPV6",
11170 FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
11172 { &hf_bacapp_tag_PORT,
11173 { "Port", "bacapp.Port",
11174 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
11176 {&hf_msg_fragments,
11177 {"Message fragments", "bacapp.fragments",
11178 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11180 {"Message fragment", "bacapp.fragment",
11181 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11182 {&hf_msg_fragment_overlap,
11183 {"Message fragment overlap", "bacapp.fragment.overlap",
11184 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11185 {&hf_msg_fragment_overlap_conflicts,
11186 {"Message fragment overlapping with conflicting data",
11187 "bacapp.fragment.overlap.conflicts",
11188 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11189 {&hf_msg_fragment_multiple_tails,
11190 {"Message has multiple tail fragments",
11191 "bacapp.fragment.multiple_tails",
11192 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11193 {&hf_msg_fragment_too_long_fragment,
11194 {"Message fragment too long", "bacapp.fragment.too_long_fragment",
11195 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11196 {&hf_msg_fragment_error,
11197 {"Message defragmentation error", "bacapp.fragment.error",
11198 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11199 {&hf_msg_fragment_count,
11200 {"Message fragment count", "bacapp.fragment.count",
11201 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
11202 {&hf_msg_reassembled_in,
11203 {"Reassembled in", "bacapp.reassembled.in",
11204 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
11205 {&hf_msg_reassembled_length,
11206 {"Reassembled BACapp length", "bacapp.reassembled.length",
11207 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
11209 static gint *ett[] = {
11211 &ett_bacapp_control,
11220 static ei_register_info ei[] = {
11221 { &ei_bacapp_bad_length, { "bacapp.bad_length", PI_MALFORMED, PI_ERROR, "Wrong length indicated", EXPFILL }},
11224 expert_module_t* expert_bacapp;
11226 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
11227 "BACapp", "bacapp");
11229 proto_register_field_array(proto_bacapp, hf, array_length(hf));
11230 proto_register_subtree_array(ett, array_length(ett));
11231 expert_bacapp = expert_register_protocol(proto_bacapp);
11232 expert_register_field_array(expert_bacapp, ei, array_length(ei));
11233 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
11234 register_init_routine(&bacapp_init_routine);
11236 bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
11237 "BACapp Vendor Identifier",
11238 FT_UINT8, BASE_HEX);
11240 /* Register BACnet Statistic trees */
11241 register_bacapp_stat_trees();
11242 bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
11246 * Editor modelines - http://www.wireshark.org/tools/modelines.html
11249 * c-basic-offset: 4
11251 * indent-tabs-mode: nil
11254 * vi: set shiftwidth=4 tabstop=8 expandtab:
11255 * :indentSize=4:tabSize=8:noTabs=true: