Use MAC address documentation range in filter examples
[metze/wireshark/wip.git] / epan / dissectors / packet-bacapp.c
index 6941e041de382921d234038c4d850ad0c13febef..1abf510e8c781d4d57b56af36923bd004779b393 100644 (file)
@@ -4,16 +4,12 @@
  * Enhanced by Steve Karg, 2005, <skarg[AT]users.sourceforge.net>, Atlanta
  * Enhanced by Herbert Lischka, 2005, <lischka[AT]kieback-peter.de>, Berlin
  * Enhanced by Felix Kraemer, 2010, <sauter-cumulus[AT]de.sauter-bc.com>,
- *     Sauter-Cumulus GmbH, Freiburg
- *
- * $Id$
+ *  Sauter-Cumulus GmbH, Freiburg
  *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald[AT]wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- * Copied from README.developer,v 1.23
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
+#include "config.h"
 
 #include <epan/packet.h>
+#include <epan/to_str.h>
 #include <epan/reassemble.h>
 #include <epan/expert.h>
 #include <epan/stats_tree.h>
@@ -45,21 +38,16 @@ static int bacapp_tap = -1;
 
 /* formerly bacapp.h  contains definitions and forward declarations */
 
-#ifndef FAULT
-#define FAULT                  proto_tree_add_text(subtree, tvb, offset, tvb_length(tvb) - offset, "something is going wrong here !!"); \
-       offset = tvb_length(tvb);
-#endif
-
 /* BACnet PDU Types */
-#define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0
-#define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1
-#define BACAPP_TYPE_SIMPLE_ACK 2
-#define BACAPP_TYPE_COMPLEX_ACK 3
-#define BACAPP_TYPE_SEGMENT_ACK 4
-#define BACAPP_TYPE_ERROR 5
-#define BACAPP_TYPE_REJECT 6
-#define BACAPP_TYPE_ABORT 7
-#define MAX_BACAPP_TYPE 8
+#define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST                   0
+#define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST                 1
+#define BACAPP_TYPE_SIMPLE_ACK                                  2
+#define BACAPP_TYPE_COMPLEX_ACK                                 3
+#define BACAPP_TYPE_SEGMENT_ACK                                 4
+#define BACAPP_TYPE_ERROR                                       5
+#define BACAPP_TYPE_REJECT                                      6
+#define BACAPP_TYPE_ABORT                                       7
+#define MAX_BACAPP_TYPE                                         8
 
 #define BACAPP_SEGMENTED_REQUEST 0x08
 #define BACAPP_MORE_SEGMENTS 0x04
@@ -79,42 +67,42 @@ static int bacapp_tap = -1;
  *  reject-PDU                  [6] BACnet-Reject-PDU,
  *  abort-PDU                   [7] BACnet-Abort-PDU
  * }
- * @param tvb
- * @param pinfo
- * @param tree
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
  **/
 static void
 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
 /**
  * ConfirmedRequest-PDU ::= SEQUENCE {
- *     pdu-type                                        [0] Unsigned (0..15), -- 0 for this PDU Type
- *  segmentedMessage                   [1] BOOLEAN,
- *  moreFollows                                        [2] BOOLEAN,
- *  segmented-response-accepted        [3] BOOLEAN,
- *  reserved                                   [4] Unsigned (0..3), -- must be set zero
- *  max-segments-accepted              [5] Unsigned (0..7), -- as per 20.1.2.4
- *  max-APDU-length-accepted   [5] Unsigned (0..15), -- as per 20.1.2.5
- *  invokeID                                   [6] Unsigned (0..255),
- *  sequence-number                            [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
- *  proposed-window-size               [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
- *  service-choice                             [9] BACnetConfirmedServiceChoice,
- *  service-request                            [10] BACnet-Confirmed-Service-Request OPTIONAL
+ *  pdu-type                    [0] Unsigned (0..15), -- 0 for this PDU Type
+ *  segmentedMessage            [1] BOOLEAN,
+ *  moreFollows                 [2] BOOLEAN,
+ *  segmented-response-accepted [3] BOOLEAN,
+ *  reserved                    [4] Unsigned (0..3), -- must be set zero
+ *  max-segments-accepted       [5] Unsigned (0..7), -- as per 20.1.2.4
+ *  max-APDU-length-accepted    [5] Unsigned (0..15), -- as per 20.1.2.5
+ *  invokeID                    [6] Unsigned (0..255),
+ *  sequence-number             [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg
+ *  proposed-window-size        [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg
+ *  service-choice              [9] BACnetConfirmedServiceChoice,
+ *  service-request             [10] BACnet-Confirmed-Service-Request OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @param ack - indocates whether working on request or ack
  * @param svc - output variable to return service choice
  * @param tt  - output varable to return service choice item
@@ -122,19 +110,19 @@ fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint
  */
 static guint
 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 ack,
-                               gint *svc, proto_item **tt);
+                gint *svc, proto_item **tt);
 
 /**
  * Unconfirmed-Request-PDU ::= SEQUENCE {
- *     pdu-type                [0] Unsigned (0..15), -- 1 for this PDU type
- *  reserved           [1] Unsigned (0..15), -- must be set zero
- *  service-choice     [2] BACnetUnconfirmedServiceChoice,
- *  service-request    [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
+ *  pdu-type        [0] Unsigned (0..15), -- 1 for this PDU type
+ *  reserved        [1] Unsigned (0..15), -- must be set zero
+ *  service-choice  [2] BACnetUnconfirmedServiceChoice,
+ *  service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -142,15 +130,15 @@ fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
 
 /**
  * SimpleACK-PDU ::= SEQUENCE {
- *     pdu-type                [0] Unsigned (0..15), -- 2 for this PDU type
- *  reserved           [1] Unsigned (0..15), -- must be set zero
- *  invokeID           [2] Unsigned (0..255),
- *  service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
+ *  pdu-type            [0] Unsigned (0..15), -- 2 for this PDU type
+ *  reserved            [1] Unsigned (0..15), -- must be set zero
+ *  invokeID            [2] Unsigned (0..255),
+ *  service-ACK-choice  [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -158,20 +146,20 @@ fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 
 /**
  * ComplexACK-PDU ::= SEQUENCE {
- *     pdu-type                                [0] Unsigned (0..15), -- 3 for this PDU Type
- *  segmentedMessage           [1] BOOLEAN,
- *  moreFollows                                [2] BOOLEAN,
- *  reserved                           [3] Unsigned (0..3), -- must be set zero
- *  invokeID                           [4] Unsigned (0..255),
- *  sequence-number                    [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
- *  proposed-window-size       [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
- *  service-ACK-choice                 [7] BACnetConfirmedServiceChoice,
- *  service-ACK                                [8] BACnet-Confirmed-Service-Request  -- Context-specific tags 0..8 are NOT used in header encoding
+ *  pdu-type                [0] Unsigned (0..15), -- 3 for this PDU Type
+ *  segmentedMessage        [1] BOOLEAN,
+ *  moreFollows             [2] BOOLEAN,
+ *  reserved                [3] Unsigned (0..3), -- must be set zero
+ *  invokeID                [4] Unsigned (0..255),
+ *  sequence-number         [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg
+ *  proposed-window-size    [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg
+ *  service-ACK-choice      [7] BACnetConfirmedServiceChoice,
+ *  service-ACK             [8] BACnet-Confirmed-Service-Request  -- Context-specific tags 0..8 are NOT used in header encoding
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -179,18 +167,18 @@ fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset
 
 /**
  * SegmentACK-PDU ::= SEQUENCE {
- *     pdu-type                                [0] Unsigned (0..15), -- 4 for this PDU Type
- *  reserved                           [1] Unsigned (0..3), -- must be set zero
- *  negative-ACK                       [2] BOOLEAN,
- *  server                                     [3] BOOLEAN,
- *  original-invokeID          [4] Unsigned (0..255),
- *  sequence-number                    [5] Unsigned (0..255),
- *  actual-window-size         [6] Unsigned (0..127)
+ *  pdu-type                [0] Unsigned (0..15), -- 4 for this PDU Type
+ *  reserved                [1] Unsigned (0..3), -- must be set zero
+ *  negative-ACK            [2] BOOLEAN,
+ *  server                  [3] BOOLEAN,
+ *  original-invokeID       [4] Unsigned (0..255),
+ *  sequence-number         [5] Unsigned (0..255),
+ *  actual-window-size      [6] Unsigned (0..127)
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -198,16 +186,16 @@ fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset
 
 /**
  * Error-PDU ::= SEQUENCE {
- *     pdu-type                                [0] Unsigned (0..15), -- 5 for this PDU Type
- *  reserved                           [1] Unsigned (0..3), -- must be set zero
- *  original-invokeID          [2] Unsigned (0..255),
- *  error-choice                       [3] BACnetConfirmedServiceChoice,
- *  error                                      [4] BACnet-Error
+ *  pdu-type                [0] Unsigned (0..15), -- 5 for this PDU Type
+ *  reserved                [1] Unsigned (0..3), -- must be set zero
+ *  original-invokeID       [2] Unsigned (0..255),
+ *  error-choice            [3] BACnetConfirmedServiceChoice,
+ *  error                   [4] BACnet-Error
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -215,15 +203,15 @@ fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * Reject-PDU ::= SEQUENCE {
- *     pdu-type                                [0] Unsigned (0..15), -- 6 for this PDU Type
- *  reserved                           [1] Unsigned (0..3), -- must be set zero
- *  original-invokeID          [2] Unsigned (0..255),
- *  reject-reason                      [3] BACnetRejectReason
+ *  pdu-type                [0] Unsigned (0..15), -- 6 for this PDU Type
+ *  reserved                [1] Unsigned (0..3), -- must be set zero
+ *  original-invokeID       [2] Unsigned (0..255),
+ *  reject-reason           [3] BACnetRejectReason
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -231,16 +219,16 @@ fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * Abort-PDU ::= SEQUENCE {
- *     pdu-type                                [0] Unsigned (0..15), -- 7 for this PDU Type
- *  reserved                           [1] Unsigned (0..3), -- must be set zero
- *  server                                     [2] BOOLEAN,
- *  original-invokeID          [3] Unsigned (0..255),
- *  abort-reason                       [4] BACnetAbortReason
+ *  pdu-type                [0] Unsigned (0..15), -- 7 for this PDU Type
+ *  reserved                [1] Unsigned (0..3), -- must be set zero
+ *  server                  [2] BOOLEAN,
+ *  original-invokeID       [3] Unsigned (0..255),
+ *  abort-reason            [4] BACnetAbortReason
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -248,259 +236,264 @@ fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree
- * @param tvb
- * @param tree
- * @param offset
- * @param label
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param label the label of this item
  * @return modified offset
  */
 static guint
-fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
+fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
 
 /**
  * 20.2.5, adds the label with max 64Bit signed Integer Value to tree
- * @param tvb
- * @param tree
- * @param offset
- * @param label
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param label the label of this item
  * @return modified offset
  */
 static guint
-fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
+fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
 
 /**
  * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame
- * @param tvb
- * @param tree
- * @param offset
- * @param label
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param label the label of this item
  * @param lvt length of String
  * @return modified offset
  */
 static guint
-fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
+fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt);
 
 /**
  * 20.2.12, adds the label with Date Value to tree
- * @param tvb
- * @param tree
- * @param offset
- * @param label
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param label the label of this item
  * @return modified offset
  */
 static guint
-fDate    (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
+fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
 
 /**
  * 20.2.13, adds the label with Time Value to tree
- * @param tvb
- * @param tree
- * @param offset
- * @param label
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param label the label of this item
  * @return modified offset
  */
 static guint
-fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
+fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
 
 /**
  * 20.2.14, adds Object Identifier to tree
  * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnet-Confirmed-Service-Request ::= CHOICE {
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
- * @param service_choice
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param service_choice the service choice
  * @return offset
  */
 static guint
-fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
+fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
 
 /**
  * BACnet-Confirmed-Service-ACK ::= CHOICE {
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
- * @param service_choice
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param service_choice the service choice
  * @return offset
  */
 static guint
-fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
+fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
 
 /**
  * AcknowledgeAlarm-Request ::= SEQUENCE {
- *     acknowledgingProcessIdentifier  [0]     Unsigned32,
- *     eventObjectIdentifier   [1] BACnetObjectIdentifer,
- *     eventStateAcknowledge   [2] BACnetEventState,
- *     timeStamp       [3] BACnetTimeStamp,
- *     acknowledgementSource   [4] Character String,
- *  timeOfAcknowledgement      [5] BACnetTimeStamp
+ *  acknowledgingProcessIdentifier [0] Unsigned32,
+ *  eventObjectIdentifier          [1] BACnetObjectIdentifer,
+ *  eventStateAcknowledge          [2] BACnetEventState,
+ *  timeStamp                      [3] BACnetTimeStamp,
+ *  acknowledgementSource          [4] Character String,
+ *  timeOfAcknowledgement          [5] BACnetTimeStamp
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ConfirmedCOVNotification-Request ::= SEQUENCE {
- *     subscriberProcessIdentifier     [0]     Unsigned32,
- *     initiatingDeviceIdentifier      [1] BACnetObjectIdentifer,
- *     monitoredObjectIdentifier       [2] BACnetObjectIdentifer,
- *     timeRemaining   [3] unsigned,
- *     listOfValues    [4] SEQUENCE OF BACnetPropertyValues
+ *  subscriberProcessIdentifier [0] Unsigned32,
+ *  initiatingDeviceIdentifier  [1] BACnetObjectIdentifer,
+ *  monitoredObjectIdentifier   [2] BACnetObjectIdentifer,
+ *  timeRemaining               [3] unsigned,
+ *  listOfValues                [4] SEQUENCE OF BACnetPropertyValues
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ConfirmedEventNotification-Request ::= SEQUENCE {
- *     ProcessIdentifier       [0]     Unsigned32,
- *     initiatingDeviceIdentifier      [1] BACnetObjectIdentifer,
- *     eventObjectIdentifier   [2] BACnetObjectIdentifer,
- *     timeStamp       [3] BACnetTimeStamp,
- *     notificationClass       [4] unsigned,
- *     priority        [5] unsigned8,
- *     eventType       [6] BACnetEventType,
- *     messageText     [7] CharacterString OPTIONAL,
- *     notifyType      [8] BACnetNotifyType,
- *     ackRequired     [9] BOOLEAN OPTIONAL,
- *     fromState       [10] BACnetEventState OPTIONAL,
- *     toState [11] BACnetEventState,
- *     eventValues     [12] BACnetNotificationParameters OPTIONAL
+ *  ProcessIdentifier           [0] Unsigned32,
+ *  initiatingDeviceIdentifier  [1] BACnetObjectIdentifer,
+ *  eventObjectIdentifier       [2] BACnetObjectIdentifer,
+ *  timeStamp                   [3] BACnetTimeStamp,
+ *  notificationClass           [4] unsigned,
+ *  priority                    [5] unsigned8,
+ *  eventType                   [6] BACnetEventType,
+ *  messageText                 [7] CharacterString OPTIONAL,
+ *  notifyType                  [8] BACnetNotifyType,
+ *  ackRequired                 [9] BOOLEAN OPTIONAL,
+ *  fromState                  [10] BACnetEventState OPTIONAL,
+ *  toState                    [11] BACnetEventState,
+ *  eventValues                [12] BACnetNotificationParameters OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo,  proto_tree *tree, guint offset);
+fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo,  proto_tree *tree, guint offset);
 
 /**
  * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
- *     objectIdentifier        BACnetObjectIdentifer,
- *     alarmState      BACnetEventState,
- *     acknowledgedTransitions  BACnetEventTransitionBits
+ *  objectIdentifier         BACnetObjectIdentifer,
+ *  alarmState               BACnetEventState,
+ *  acknowledgedTransitions  BACnetEventTransitionBits
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * GetEnrollmentSummary-Request ::= SEQUENCE {
- *     acknowledgmentFilter    [0]     ENUMERATED {
- *      all (0),
- *      acked   (1),
- *      not-acked   (2)
+ *  acknowledgmentFilter    [0] ENUMERATED {
+ *      all       (0),
+ *      acked     (1),
+ *      not-acked (2)
  *      },
- *     enrollmentFilter        [1] BACnetRecipientProcess OPTIONAL,
- *     eventStateFilter        [2] ENUMERATED {
- *      offnormal   (0),
- *      fault   (1),
- *      normal  (2),
- *      all (3),
- *      active  (4)
+ *  enrollmentFilter        [1] BACnetRecipientProcess OPTIONAL,
+ *  eventStateFilter        [2] ENUMERATED {
+ *      offnormal (0),
+ *      fault     (1),
+ *      normal    (2),
+ *      all       (3),
+ *      active    (4)
  *      },
- *     eventTypeFilter [3] BACnetEventType OPTIONAL,
- *     priorityFilter  [4] SEQUENCE {
+ *  eventTypeFilter         [3] BACnetEventType OPTIONAL,
+ *  priorityFilter          [4] SEQUENCE {
  *      minPriority [0] Unsigned8,
  *      maxPriority [1] Unsigned8
  *      } OPTIONAL,
- *  notificationClassFilter    [5] Unsigned OPTIONAL
+ *  notificationClassFilter [5] Unsigned OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
- *     objectIdentifier        BACnetObjectIdentifer,
- *     eventType       BACnetEventType,
- *     eventState      BACnetEventState,
- *     priority    Unsigned8,
+ *  objectIdentifier    BACnetObjectIdentifer,
+ *  eventType           BACnetEventType,
+ *  eventState          BACnetEventState,
+ *  priority            Unsigned8,
  *  notificationClass   Unsigned OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * GetEventInformation-Request ::= SEQUENCE {
- *     lastReceivedObjectIdentifier    [0] BACnetObjectIdentifer
+ *  lastReceivedObjectIdentifier    [0] BACnetObjectIdentifer
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * GetEventInformation-ACK ::= SEQUENCE {
- *     listOfEventSummaries    [0] listOfEventSummaries,
- *  moreEvents  [1] BOOLEAN
+ *  listOfEventSummaries [0] listOfEventSummaries,
+ *  moreEvents           [1] BOOLEAN
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * LifeSafetyOperation-Request ::= SEQUENCE {
- *     requestingProcessIdentifier     [0]     Unsigned32
- *     requestingSource        [1] CharacterString
- *     request [2] BACnetLifeSafetyOperation
- *     objectIdentifier        [3] BACnetObjectIdentifier OPTIONAL
+ *  requestingProcessIdentifier [0] Unsigned32
+ *  requestingSource            [1] CharacterString
+ *  request                     [2] BACnetLifeSafetyOperation
+ *  objectIdentifier            [3] BACnetObjectIdentifier OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -508,17 +501,15 @@ fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
 /**
  * SubscribeCOV-Request ::= SEQUENCE {
- *     subscriberProcessIdentifier     [0]     Unsigned32
- *     monitoredObjectIdentifier       [1] BACnetObjectIdentifier
- *     issueConfirmedNotifications     [2] BOOLEAN OPTIONAL
- *     lifetime        [3] Unsigned OPTIONAL
+ *  subscriberProcessIdentifier [0] Unsigned32
+ *  monitoredObjectIdentifier   [1] BACnetObjectIdentifier
+ *  issueConfirmedNotifications [2] BOOLEAN OPTIONAL
+ *  lifetime                    [3] Unsigned OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
- * @param label
- * @param src
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -526,17 +517,17 @@ fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint
 
 /**
  * SubscribeCOVProperty-Request ::= SEQUENCE {
- *     subscriberProcessIdentifier     [0]     Unsigned32
- *     monitoredObjectIdentifier       [1] BACnetObjectIdentifier
- *     issueConfirmedNotifications     [2] BOOLEAN OPTIONAL
- *     lifetime        [3] Unsigned OPTIONAL
- *     monitoredPropertyIdentifier     [4] BACnetPropertyReference OPTIONAL
- *     covIncrement    [5] Unsigned OPTIONAL
+ *  subscriberProcessIdentifier [0] Unsigned32
+ *  monitoredObjectIdentifier   [1] BACnetObjectIdentifier
+ *  issueConfirmedNotifications [2] BOOLEAN OPTIONAL
+ *  lifetime                    [3] Unsigned OPTIONAL
+ *  monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL
+ *  covIncrement                [5] Unsigned OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -544,22 +535,22 @@ fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 
 /**
  * AtomicReadFile-Request ::= SEQUENCE {
- *     fileIdentifier  BACnetObjectIdentifier,
- *  accessMethod       CHOICE {
- *     streamAccess    [0] SEQUENCE {
- *             fileStartPosition       INTEGER,
- *                     requestedOctetCount     Unsigned
- *                     },
- *             recordAccess    [1] SEQUENCE {
- *                     fileStartRecord INTEGER,
- *                     requestedRecordCount    Unsigned
- *                     }
- *             }
+ *  fileIdentifier  BACnetObjectIdentifier,
+ *  accessMethod    CHOICE {
+ *      streamAccess    [0] SEQUENCE {
+ *          fileStartPosition   INTEGER,
+ *          requestedOctetCount Unsigned
+ *          },
+ *      recordAccess    [1] SEQUENCE {
+ *          fileStartRecord      INTEGER,
+ *          requestedRecordCount Unsigned
+ *          }
+ *      }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -567,47 +558,47 @@ fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
 
 /**
  * AtomicWriteFile-ACK ::= SEQUENCE {
- *     endOfFile       BOOLEAN,
- *  accessMethod       CHOICE {
- *     streamAccess    [0] SEQUENCE {
- *             fileStartPosition       INTEGER,
- *                     fileData        OCTET STRING
- *                     },
- *             recordAccess    [1] SEQUENCE {
- *                     fileStartRecord INTEGER,
- *                     returnedRecordCount     Unsigned,
- *                     fileRecordData  SEQUENCE OF OCTET STRING
- *                     }
- *             }
+ *  endOfFile   BOOLEAN,
+ *  accessMethod    CHOICE {
+ *      streamAccess    [0] SEQUENCE {
+ *          fileStartPosition   INTEGER,
+ *          fileData            OCTET STRING
+ *          },
+ *      recordAccess    [1] SEQUENCE {
+ *          fileStartRecord     INTEGER,
+ *          returnedRecordCount Unsigned,
+ *          fileRecordData      SEQUENCE OF OCTET STRING
+ *          }
+ *      }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * AtomicWriteFile-Request ::= SEQUENCE {
- *     fileIdentifier  BACnetObjectIdentifier,
- *  accessMethod       CHOICE {
- *     streamAccess    [0] SEQUENCE {
- *             fileStartPosition       INTEGER,
- *                     fileData        OCTET STRING
- *                     },
- *             recordAccess    [1] SEQUENCE {
- *                     fileStartRecord INTEGER,
- *                     recordCount     Unsigned,
- *                     fileRecordData  SEQUENCE OF OCTET STRING
- *                     }
- *             }
+ *  fileIdentifier  BACnetObjectIdentifier,
+ *  accessMethod    CHOICE {
+ *      streamAccess    [0] SEQUENCE {
+ *          fileStartPosition  INTEGER,
+ *          fileData           OCTET STRING
+ *          },
+ *      recordAccess    [1] SEQUENCE {
+ *          fileStartRecord    INTEGER,
+ *          recordCount        Unsigned,
+ *          fileRecordData     SEQUENCE OF OCTET STRING
+ *          }
+ *      }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -615,28 +606,29 @@ fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gui
 
 /**
  * AtomicWriteFile-ACK ::= SEQUENCE {
- *             fileStartPosition       [0] INTEGER,
- *             fileStartRecord [1] INTEGER,
+ *      fileStartPosition [0] INTEGER,
+ *      fileStartRecord   [1] INTEGER,
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * AddListElement-Request ::= SEQUENCE {
- *     objectIdentifier        [0] BACnetObjectIdentifier,
- *  propertyIdentifier  [1] BACnetPropertyIdentifier,
- *  propertyArrayIndex  [2] Unsigned OPTIONAL, -- used only with array datatype
- *  listOfElements  [3] ABSTRACT-SYNTAX.&Type
+ *  objectIdentifier   [0] BACnetObjectIdentifier,
+ *  propertyIdentifier [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
+ *  listOfElements     [3] ABSTRACT-SYNTAX.&Type
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -644,13 +636,13 @@ fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
 
 /**
  * CreateObject-Request ::= SEQUENCE {
- *     objectSpecifier [0] ObjectSpecifier,
- *  listOfInitialValues        [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
+ *  objectSpecifier     [0] ObjectSpecifier,
+ *  listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param subtree the sub tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -658,23 +650,23 @@ fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, gui
 
 /**
  * CreateObject-Request ::= BACnetObjectIdentifier
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * DeleteObject-Request ::= SEQUENCE {
- *     ObjectIdentifier        BACnetObjectIdentifer
+ *  ObjectIdentifier    BACnetObjectIdentifer
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -682,14 +674,14 @@ fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint
 
 /**
  * ReadProperty-Request ::= SEQUENCE {
- *     objectIdentifier        [0]     BACnetObjectIdentifier,
- *     propertyIdentifier      [1] BACnetPropertyIdentifier,
- *     propertyArrayIndex      [2] Unsigned OPTIONAL, -- used only with array datatype
+ *  objectIdentifier    [0] BACnetObjectIdentifier,
+ *  propertyIdentifier  [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex  [2] Unsigned OPTIONAL, -- used only with array datatype
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -697,29 +689,29 @@ fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint
 
 /**
  * ReadProperty-ACK ::= SEQUENCE {
- *     objectIdentifier        [0]     BACnetObjectIdentifier,
- *     propertyIdentifier      [1] BACnetPropertyIdentifier,
- *     propertyArrayIndex      [2] Unsigned OPTIONAL, -- used only with array datatype
- *     propertyValue   [3] ABSTRACT-SYNTAX.&Type
+ *  objectIdentifier   [0] BACnetObjectIdentifier,
+ *  propertyIdentifier [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
+ *  propertyValue      [3] ABSTRACT-SYNTAX.&Type
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ReadPropertyConditional-Request ::= SEQUENCE {
- *     objectSelectionCriteria [0] objectSelectionCriteria,
- *     listOfPropertyReferences        [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
+ *  objectSelectionCriteria  [0] objectSelectionCriteria,
+ *  listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param subtree the  sub tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -727,25 +719,25 @@ fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *s
 
 /**
  * ReadPropertyConditional-ACK ::= SEQUENCE {
- *     listOfPReadAccessResults        SEQUENCE OF ReadAccessResult OPTIONAL
+ *  listOfPReadAccessResults    SEQUENCE OF ReadAccessResult OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ReadPropertyMultiple-Request ::= SEQUENCE {
- *  listOfReadAccessSpecs      SEQUENCE OF ReadAccessSpecification
+ *  listOfReadAccessSpecs   SEQUENCE OF ReadAccessSpecification
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param subtree the sub tree to append this item to
+ * @param offset the offset in the tvb
  * @return offset modified
  */
 static guint
@@ -753,75 +745,75 @@ fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subt
 
 /**
  * ReadPropertyMultiple-Ack ::= SEQUENCE {
- *  listOfReadAccessResults    SEQUENCE OF ReadAccessResult
+ *  listOfReadAccessResults SEQUENCE OF ReadAccessResult
  * }
- * @param tvb
- * @parma pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return offset modified
  */
 static guint
-fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ReadRange-Request ::= SEQUENCE {
- *     objectIdentifier        [0] BACnetObjectIdentifier,
- *  propertyIdentifier [1] BACnetPropertyIdentifier,
- *  propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
- *     range   CHOICE {
- *             byPosition      [3] SEQUENCE {
- *                     referencedIndex Unsigned,
- *                     count INTEGER
- *                     },
- *             byTime  [4] SEQUENCE {
- *                     referenceTime BACnetDateTime,
- *                     count INTEGER
- *                     },
- *             timeRange       [5] SEQUENCE {
- *                     beginningTime BACnetDateTime,
- *                     endingTime BACnetDateTime
- *                     },
- *             } OPTIONAL
+ *  objectIdentifier    [0] BACnetObjectIdentifier,
+ *  propertyIdentifier  [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex  [2] Unsigned OPTIONAL, -- used only with array datatype
+ *  range   CHOICE {
+ *      byPosition  [3] SEQUENCE {
+ *          referencedIndex Unsigned,
+ *          count INTEGER
+ *          },
+ *      byTime      [4] SEQUENCE {
+ *          referenceTime BACnetDateTime,
+ *          count INTEGER
+ *          },
+ *      timeRange   [5] SEQUENCE {
+ *          beginningTime BACnetDateTime,
+ *          endingTime BACnetDateTime
+ *          },
+ *      } OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ReadRange-ACK ::= SEQUENCE {
- *     objectIdentifier        [0] BACnetObjectIdentifier,
- *  propertyIdentifier [1] BACnetPropertyIdentifier,
- *  propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
- *  resultFlags        [3] BACnetResultFlags,
- *  itemCount  [4] Unsigned,
- *  itemData   [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
+ *  objectIdentifier   [0] BACnetObjectIdentifier,
+ *  propertyIdentifier [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
+ *  resultFlags        [3] BACnetResultFlags,
+ *  itemCount          [4] Unsigned,
+ *  itemData           [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * RemoveListElement-Request ::= SEQUENCE {
- *     objectIdentifier        [0]     BACnetObjectIdentifier,
- *     propertyIdentifier      [1] BACnetPropertyIdentifier,
- *     propertyArrayIndex      [2] Unsigned OPTIONAL, -- used only with array datatype
- *     listOfElements  [3] ABSTRACT-SYNTAX.&Type
+ *  objectIdentifier    [0] BACnetObjectIdentifier,
+ *  propertyIdentifier  [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex  [2] Unsigned OPTIONAL, -- used only with array datatype
+ *  listOfElements  [3] ABSTRACT-SYNTAX.&Type
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -829,16 +821,16 @@ fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
 
 /**
  * WriteProperty-Request ::= SEQUENCE {
- *     objectIdentifier        [0]     BACnetObjectIdentifier,
- *     propertyIdentifier      [1] BACnetPropertyIdentifier,
- *     propertyArrayIndex      [2] Unsigned OPTIONAL, -- used only with array datatype
- *     propertyValue   [3] ABSTRACT-SYNTAX.&Type
- *  priority   [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
+ *  objectIdentifier   [0] BACnetObjectIdentifier,
+ *  propertyIdentifier [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
+ *  propertyValue      [3] ABSTRACT-SYNTAX.&Type
+ *  priority           [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -846,12 +838,12 @@ fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint
 
 /**
  * WritePropertyMultiple-Request ::= SEQUENCE {
- *     listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
+ *  listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -859,31 +851,32 @@ fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
 
 /**
  * DeviceCommunicationControl-Request ::= SEQUENCE {
- *     timeDuration    [0] Unsigned16 OPTIONAL,
- *  enable-disable     [1] ENUMERATED {
- *             enable (0),
- *             disable (1)
- *             },
- *  password   [2] CharacterString (SIZE(1..20)) OPTIONAL
+ *  timeDuration    [0] Unsigned16 OPTIONAL,
+ *  enable-disable  [1] ENUMERATED {
+ *      enable  (0),
+ *      disable (1)
+ *      },
+ *  password        [2] CharacterString (SIZE(1..20)) OPTIONAL
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
+fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ConfirmedPrivateTransfer-Request ::= SEQUENCE {
- *     vendorID        [0]     Unsigned,
- *     serviceNumber   [1] Unsigned,
- *     serviceParameters       [2] ABSTRACT-SYNTAX.&Type OPTIONAL
+ *  vendorID          [0] Unsigned,
+ *  serviceNumber     [1] Unsigned,
+ *  serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -891,14 +884,14 @@ fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 
 /**
  * ConfirmedPrivateTransfer-ACK ::= SEQUENCE {
- *     vendorID        [0]     Unsigned,
- *     serviceNumber   [1] Unsigned,
- *     resultBlock     [2] ABSTRACT-SYNTAX.&Type OPTIONAL
+ *  vendorID      [0] Unsigned,
+ *  serviceNumber [1] Unsigned,
+ *  resultBlock   [2] ABSTRACT-SYNTAX.&Type OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -907,20 +900,20 @@ fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 /**
  * ConfirmedTextMessage-Request ::=  SEQUENCE {
  *  textMessageSourceDevice [0] BACnetObjectIdentifier,
- *  messageClass [1] CHOICE {
- *      numeric [0] Unsigned,
+ *  messageClass            [1] CHOICE {
+ *      numeric   [0] Unsigned,
  *      character [1] CharacterString
  *      } OPTIONAL,
- *  messagePriority [2] ENUMERATED {
+ *  messagePriority         [2] ENUMERATED {
  *      normal (0),
  *      urgent (1)
  *      },
  *  message [3] CharacterString
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -928,34 +921,35 @@ fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 
 /**
  * ReinitializeDevice-Request ::= SEQUENCE {
- *  reinitializedStateOfDevice [0] ENUMERATED {
- *             coldstart (0),
- *             warmstart (1),
- *             startbackup (2),
- *             endbackup (3),
- *             startrestore (4),
- *             endrestore (5),
- *             abortrestor (6)
- *             },
- *  password   [1] CharacterString (SIZE(1..20)) OPTIONAL
+ *  reinitializedStateOfDevice  [0] ENUMERATED {
+ *      coldstart    (0),
+ *      warmstart    (1),
+ *      startbackup  (2),
+ *      endbackup    (3),
+ *      startrestore (4),
+ *      endrestore   (5),
+ *      abortrestor  (6)
+ *      },
+ *  password                    [1] CharacterString (SIZE(1..20)) OPTIONAL
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset);
+fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * VTOpen-Request ::= SEQUENCE {
- *  vtClass    BACnetVTClass,
- *  localVTSessionIdentifier   Unsigned8
+ *  vtClass BACnetVTClass,
+ *  localVTSessionIdentifier    Unsigned8
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -963,200 +957,202 @@ fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset
 
 /**
  * VTOpen-ACK ::= SEQUENCE {
- *  remoteVTSessionIdentifier  Unsigned8
+ *  remoteVTSessionIdentifier   Unsigned8
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * VTClose-Request ::= SEQUENCE {
- *  listOfRemoteVTSessionIdentifiers   SEQUENCE OF Unsigned8
+ *  listOfRemoteVTSessionIdentifiers    SEQUENCE OF Unsigned8
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * VTData-Request ::= SEQUENCE {
- *  vtSessionIdentifier        Unsigned8,
- *  vtNewData  OCTET STRING,
- *  vtDataFlag Unsigned (0..1)
+ *  vtSessionIdentifier Unsigned8,
+ *  vtNewData           OCTET STRING,
+ *  vtDataFlag          Unsigned (0..1)
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * VTData-ACK ::= SEQUENCE {
- *  allNewDataAccepted [0] BOOLEAN,
- *  acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
+ *  allNewDataAccepted  [0] BOOLEAN,
+ *  acceptedOctetCount  [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = FALSE
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * Authenticate-Request ::= SEQUENCE {
- *  pseudoRandomNumber [0] Unsigned32,
- *  excpectedInvokeID  [1] Unsigned8 OPTIONAL,
- *  operatorName       [2] CharacterString OPTIONAL,
- *  operatorPassword   [3] CharacterString (SIZE(1..20)) OPTIONAL,
- *  startEncypheredSession     [4] BOOLEAN OPTIONAL
+ *  pseudoRandomNumber     [0] Unsigned32,
+ *  excpectedInvokeID      [1] Unsigned8 OPTIONAL,
+ *  operatorName           [2] CharacterString OPTIONAL,
+ *  operatorPassword       [3] CharacterString (SIZE(1..20)) OPTIONAL,
+ *  startEncypheredSession [4] BOOLEAN OPTIONAL
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * Authenticate-ACK ::= SEQUENCE {
- *  modifiedRandomNumber       Unsigned32,
+ *  modifiedRandomNumber    Unsigned32,
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * RequestKey-Request ::= SEQUENCE {
- *  requestingDeviceIdentifier BACnetObjectIdentifier,
- *  requestingDeviceAddress    BACnetAddress,
- *  remoteDeviceIdentifier     BACnetObjectIdentifier,
- *  remoteDeviceAddress        BACnetAddress
+ *  requestingDeviceIdentifier BACnetObjectIdentifier,
+ *  requestingDeviceAddress    BACnetAddress,
+ *  remoteDeviceIdentifier     BACnetObjectIdentifier,
+ *  remoteDeviceAddress        BACnetAddress
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * Unconfirmed-Service-Request ::= CHOICE {
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
- * @param service_choice
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param service_choice the service choice
  * @return modified offset
  */
 static guint
-fUnconfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
+fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice);
 
 /**
  * UnconfirmedCOVNotification-Request ::= SEQUENCE {
- *     subscriberProcessIdentifier     [0]     Unsigned32,
- *     initiatingDeviceIdentifier      [1] BACnetObjectIdentifer,
- *     monitoredObjectIdentifier       [2] BACnetObjectIdentifer,
- *     timeRemaining   [3] unsigned,
- *     listOfValues    [4] SEQUENCE OF BACnetPropertyValues
+ *  subscriberProcessIdentifier [0] Unsigned32,
+ *  initiatingDeviceIdentifier  [1] BACnetObjectIdentifer,
+ *  monitoredObjectIdentifier   [2] BACnetObjectIdentifer,
+ *  timeRemaining               [3] unsigned,
+ *  listOfValues                [4] SEQUENCE OF BACnetPropertyValues
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * UnconfirmedEventNotification-Request ::= SEQUENCE {
- *     ProcessIdentifier       [0]     Unsigned32,
- *     initiatingDeviceIdentifier      [1] BACnetObjectIdentifer,
- *     eventObjectIdentifier   [2] BACnetObjectIdentifer,
- *     timeStamp       [3] BACnetTimeStamp,
- *     notificationClass       [4] unsigned,
- *     priority        [5] unsigned8,
- *     eventType       [6] BACnetEventType,
- *     messageText     [7] CharacterString OPTIONAL,
- *     notifyType      [8] BACnetNotifyType,
- *     ackRequired     [9] BOOLEAN OPTIONAL,
- *     fromState       [10] BACnetEventState OPTIONAL,
- *     toState [11] BACnetEventState,
- *     eventValues     [12] BACnetNotificationParameters OPTIONAL
+ *  ProcessIdentifier           [0] Unsigned32,
+ *  initiatingDeviceIdentifier  [1] BACnetObjectIdentifer,
+ *  eventObjectIdentifier       [2] BACnetObjectIdentifer,
+ *  timeStamp                   [3] BACnetTimeStamp,
+ *  notificationClass           [4] unsigned,
+ *  priority                    [5] unsigned8,
+ *  eventType                   [6] BACnetEventType,
+ *  messageText                 [7] CharacterString OPTIONAL,
+ *  notifyType                  [8] BACnetNotifyType,
+ *  ackRequired                 [9] BOOLEAN OPTIONAL,
+ *  fromState                  [10] BACnetEventState OPTIONAL,
+ *  toState                    [11] BACnetEventState,
+ *  eventValues                [12] BACnetNotificationParameters OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * I-Am-Request ::= SEQUENCE {
- *     aAmDeviceIdentifier     BACnetObjectIdentifier,
- *  maxAPDULengthAccepted      Unsigned,
- *     segmentationSupported   BACnetSegmentation,
- *     vendorID        Unsigned
+ *  aAmDeviceIdentifier BACnetObjectIdentifier,
+ *  maxAPDULengthAccepted   Unsigned,
+ *  segmentationSupported   BACnetSegmentation,
+ *  vendorID    Unsigned
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fIAmRequest  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 
 /**
  * I-Have-Request ::= SEQUENCE {
- *     deviceIdentifier        BACnetObjectIdentifier,
- *  objectIdentifier   BACnetObjectIdentifier,
- *     objectName      CharacterString
+ *  deviceIdentifier  BACnetObjectIdentifier,
+ *  objectIdentifier  BACnetObjectIdentifier,
+ *  objectName        CharacterString
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fIHaveRequest  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * UnconfirmedPrivateTransfer-Request ::= SEQUENCE {
- *     vendorID        [0]     Unsigned,
- *     serviceNumber   [1] Unsigned,
- *     serviceParameters       [2] ABSTRACT-SYNTAX.&Type OPTIONAL
+ *  vendorID          [0] Unsigned,
+ *  serviceNumber     [1] Unsigned,
+ *  serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -1165,20 +1161,20 @@ fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 /**
  * UnconfirmedTextMessage-Request ::=  SEQUENCE {
  *  textMessageSourceDevice [0] BACnetObjectIdentifier,
- *  messageClass [1] CHOICE {
- *      numeric [0] Unsigned,
+ *  messageClass            [1] CHOICE {
+ *      numeric   [0] Unsigned,
  *      character [1] CharacterString
  *      } OPTIONAL,
- *  messagePriority [2] ENUMERATED {
+ *  messagePriority         [2] ENUMERATED {
  *      normal (0),
  *      urgent (1)
  *      },
- *  message [3] CharacterString
+ *  message                 [3] CharacterString
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -1188,74 +1184,76 @@ fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
  * TimeSynchronization-Request ::=  SEQUENCE {
  *  BACnetDateTime
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fTimeSynchronizationRequest  (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * UTCTimeSynchronization-Request ::=  SEQUENCE {
  *  BACnetDateTime
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fUTCTimeSynchronizationRequest  (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * Who-Has-Request ::=  SEQUENCE {
  *  limits SEQUENCE {
- *      deviceInstanceRangeLowLimit [0] Unsigned (0..4194303),
+ *      deviceInstanceRangeLowLimit  [0] Unsigned (0..4194303),
  *      deviceInstanceRangeHighLimit [1] Unsigned (0..4194303)
  *      } OPTIONAL,
  *  object CHOICE {
- *      objectIdentifier [2] BACnetObjectIdentifier,
- *      objectName [3] CharacterString
+ *      objectIdentifier             [2] BACnetObjectIdentifier,
+ *      objectName                   [3] CharacterString
  *      }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * Who-Is-Request ::= SEQUENCE {
- *     deviceInstanceRangeLowLimit     [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
- *     deviceInstanceRangeHighLimit    [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
+ *  deviceInstanceRangeLowLimit  [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
+ *  deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9,
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fWhoIsRequest  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fWhoIsRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnet-Error ::= CHOICE {
- *  addListElement          [8] ChangeList-Error,
- *  removeListElement       [9] ChangeList-Error,
+ *  addListElement           [8] ChangeList-Error,
+ *  removeListElement        [9] ChangeList-Error,
  *  writePropertyMultiple   [16] WritePropertyMultiple-Error,
  *  confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error,
  *  vtClose                 [22] VTClose-Error,
  *  readRange               [26] ObjectAccessService-Error
- *                      [default] Error
+ *                          [default] Error
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
- * @param service
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param service the service
  * @return modified offset
  */
 static guint
@@ -1264,24 +1262,24 @@ fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
 /**
  * Dissect a BACnetError in a context tag
  *
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ChangeList-Error ::= SEQUENCE {
- *    errorType     [0] Error,
- *    firstFailedElementNumber  [1] Unsigned
+ *    errorType                [0] Error,
+ *    firstFailedElementNumber [1] Unsigned
  *    }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -1289,14 +1287,14 @@ fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offs
 
 /**
  * CreateObject-Error ::= SEQUENCE {
- *    errorType     [0] Error,
- *    firstFailedElementNumber  [1] Unsigned
+ *    errorType                [0] Error,
+ *    firstFailedElementNumber [1] Unsigned
  *    }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -1304,16 +1302,16 @@ fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint of
 
 /**
  * ConfirmedPrivateTransfer-Error ::= SEQUENCE {
- *    errorType     [0] Error,
- *    vendorID      [1] Unsigned,
- *    serviceNumber [2] Unsigned,
- *    errorParameters   [3] ABSTRACT-SYNTAX.&Type OPTIONAL
+ *    errorType       [0] Error,
+ *    vendorID        [1] Unsigned,
+ *    serviceNumber   [2] Unsigned,
+ *    errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL
  *    }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -1321,14 +1319,14 @@ fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 /**
  * WritePropertyMultiple-Error ::= SEQUENCE {
- *    errorType     [0] Error,
- *    firstFailedWriteAttempt  [1] Unsigned
+ *    errorType               [0] Error,
+ *    firstFailedWriteAttempt [1] Unsigned
  *    }
  * }
- * @param tvb
- * @pram pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -1336,14 +1334,14 @@ fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
 /**
  * VTClose-Error ::= SEQUENCE {
- *    errorType     [0] Error,
- *    listOfVTSessionIdentifiers  [1] SEQUENCE OF Unsigned8 OPTIONAL
+ *    errorType                  [0] Error,
+ *    listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL
  *    }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -1351,15 +1349,15 @@ fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 
 /**
  * BACnet Application Types chapter 20.2.1
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
- * @param label
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param label the label of this item
  * @return modified offset
  */
 static guint
-fApplicationTypes   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
+fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
 
 /**
  * BACnetActionCommand ::= SEQUENCE {
@@ -1373,135 +1371,139 @@ fApplicationTypes   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint
  *  quitOnFailure       [7] BOOLEAN,
  *  writeSuccessful     [8] BOOLEAN
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
- * @param matching tag number
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param tag_match the tag number
  * @return modified offset
  */
 static guint
-fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
+fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match);
 
 /**
  * BACnetActionList ::= SEQUENCE {
  *  action  [0] SEQUENCE of BACnetActionCommand
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /** BACnetAddress ::= SEQUENCE {
  *  network-number  Unsigned16, -- A value 0 indicates the local network
  *  mac-address     OCTET STRING -- A string of length 0 indicates a broadcast
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetAddressBinding ::= SEQUENCE {
- *     deviceObjectID  BACnetObjectIdentifier
- *     deviceAddress   BacnetAddress
+ *  deviceObjectID  BACnetObjectIdentifier
+ *  deviceAddress   BacnetAddress
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetCalendarEntry ::= CHOICE {
- *     date        [0] Date,
- *     dateRange   [1] BACnetDateRange,
+ *  date        [0] Date,
+ *  dateRange   [1] BACnetDateRange,
  *  weekNDay    [2] BacnetWeekNday
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fCalendarEntry (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetClientCOV ::= CHOICE {
- *     real-increment  REAL,
- *     default-increment   NULL
+ *  real-increment  REAL,
+ *  default-increment   NULL
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 
 /**
  * BACnetDailySchedule ::= SEQUENCE {
  *  day-schedule    [0] SENQUENCE OF BACnetTimeValue
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetWeeklySchedule ::= SEQUENCE {
  *  week-schedule    SENQUENCE SIZE (7) OF BACnetDailySchedule
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetDateRange ::= SEQUENCE {
  *  StartDate   Date,
  *  EndDate     Date
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetDateTime ::= SEQUENCE {
  *  date   Date,
  *  time   Time
  * }
- * @param tvb
- * @param tree
- * @param offset
- * @param label
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param label the label of this item
  * @return modified offset
  */
 static guint
-fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
+fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
 
 /**
  * BACnetDestination ::= SEQUENCE {
@@ -1513,14 +1515,14 @@ fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
  *  issueConfirmedNotifications BOOLEAN,
  *  transitions BACnetEventTransitionBits
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetDeviceObjectPropertyReference ::= SEQUENCE {
@@ -1529,371 +1531,519 @@ fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
  *  propertyArrayIndex  [2] Unsigend OPTIONAL,
  *  deviceIdentifier    [3] BACnetObjectIdentifier OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+
+/**
+ * BACnetObjectPropertyReference ::= SEQUENCE {
+ *  objectIdentifier    [0] BACnetObjectIdentifier,
+ *  propertyIdentifier  [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex  [2] Unsigend OPTIONAL,
+ * }
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @return modified offset
+ */
+static guint
+fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetDeviceObjectReference ::= SEQUENCE {
  *  deviceIdentifier    [0] BACnetObjectIdentifier OPTIONAL,
  *  objectIdentifier    [1] BACnetObjectIdentifier
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetEventParameter ::= CHOICE {
- *     change-of-bitstring [0] SEQUENCE {
- *     time-delay [0] Unsigned,
- *     bitmask [1] BIT STRING,
- *     list-of-bitstring-values [2] SEQUENCE OF BIT STRING
- *     },
- *  change-of-state [1] SEQUENCE {
- *     time-delay [0] Unsigned,
- *     list-of-values [1] SEQUENCE OF BACnetPropertyStates
- *     },
- *   change-of-value [2] SEQUENCE {
- *     time-delay [0] Unsigned,
- *     cov-criteria [1] CHOICE {
- *             bitmask [0] BIT STRING,
- *             referenced-property-increment [1] REAL
- *                     }
- *             },
- *     command-failure [3] SEQUENCE {
- *             time-delay [0] Unsigned,
- *             feedback-property-reference [1] BACnetDeviceObjectPropertyReference
- *             },
- *     floating-limit [4] SEQUENCE {
- *             time-delay [0] Unsigned,
- *             setpoint-reference [1] BACnetDeviceObjectPropertyReference,
- *             low-diff-limit [2] REAL,
- *             high-diff-limit [3] REAL,
- *             deadband [4] REAL
- *             },
- *     out-of-range [5] SEQUENCE {
- *             time-delay [0] Unsigned,
- *             low-limit [1] REAL,
- *             high-limit [2] REAL,
- *             deadband [3] REAL
- *             },
- *     buffer-ready [7] SEQUENCE {
- *             notification-threshold [0] Unsigned,
- *             previous-notification-count [1] Unsigned32
- *             }
- *     change-of-life-safety [8] SEQUENCE {
- *             time-delay [0] Unsigned,
- *             list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
- *             list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState,
- *             mode-property-reference [3] BACnetDeviceObjectPropertyReference
- *             }
- *     }
- * @param tvb
- * @param tree
- * @param offset
+ *  change-of-bitstring             [0] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      bitmask                          [1] BIT STRING,
+ *      list-of-bitstring-values         [2] SEQUENCE OF BIT STRING
+ *      },
+ *  change-of-state                 [1] SEQUENCE {
+ *      time-delay     [0] Unsigned,
+ *      list-of-values [1] SEQUENCE OF BACnetPropertyStates
+ *      },
+ *  change-of-value                 [2] SEQUENCE {
+ *      time-delay   [0] Unsigned,
+ *      cov-criteria [1] CHOICE {
+ *          bitmask                       [0] BIT STRING,
+ *          referenced-property-increment [1] REAL
+ *          }
+ *      },
+ *  command-failure                 [3] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      feedback-property-reference      [1] BACnetDeviceObjectPropertyReference
+ *      },
+ *  floating-limit                  [4] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      setpoint-reference               [1] BACnetDeviceObjectPropertyReference,
+ *      low-diff-limit                   [2] REAL,
+ *      high-diff-limit                  [3] REAL,
+ *      deadband                         [4] REAL
+ *      },
+ *  out-of-range                    [5] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      low-limit                        [1] REAL,
+ *      high-limit                       [2] REAL,
+ *      deadband                         [3] REAL
+ *      },
+ *  -- context tag 7 is deprecated
+ *  change-of-life-safety           [8] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState,
+ *      list-of-alarm-values             [2] SEQUENCE OF BACnetLifeSafetyState,
+ *      mode-property-reference          [3] BACnetDeviceObjectPropertyReference
+ *      },
+ *  extended                        [9] SEQUENCE {
+ *      vendor-id                        [0] Unsigned16,
+ *      extended-event-type              [1] Unsigned,
+ *      parameters                       [2] SEQUENCE OF CHOICE {
+ *          null        NULL,
+ *          real        REAL,
+ *          integer     Unsigned,
+ *          boolean     BOOLEAN,
+ *          double      Double,
+ *          octet       OCTET STRING,
+ *          bitstring   BIT STRING,
+ *          enum        ENUMERATED,
+ *          reference   [0] BACnetDeviceObjectPropertyReference
+ *          }
+ *      },
+ *  buffer-ready                    [10] SEQUENCE {
+ *      notification-threshold           [0] Unsigned,
+ *      previous-notification-count      [1] Unsigned32
+ *      },
+ * unsigned-range                   [11] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      low-limit                        [1] Unsigned,
+ *      high-limit                       [2] Unsigned,
+ *      }
+ * -- context tag 12 is reserved for future addenda
+ * access-event                     [13] SEQUENCE {
+ *      list-of-access-events            [0] SEQUENCE OF BACnetAccessEvent,
+ *      access-event-time-reference      [1] BACnetDeviceObjectPropertyReference
+ *      }
+ * double-out-of-range              [14] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      low-limit                        [1] Double,
+ *      high-limit                       [2] Double,
+ *      deadband                         [3] Double
+ *  }
+ *  signed-out-of-range             [15] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      low-limit                        [1] INTEGER,
+ *      high-limit                       [2] INTEGER,
+ *      deadband                         [3] Unsigned
+ *  }
+ *  unsigned-out-of-range           [16] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      low-limit                        [1] Unsigned,
+ *      high-limit                       [2] Unsigned,
+ *      deadband                         [3] Unsigned
+ *   }
+ *  change-of-characterstring       [17] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      list-of-alarm-values             [1] SEQUENCE OF CharacterString,
+ *   }
+ *  change-of-status-flags          [18] SEQUENCE {
+ *      time-delay                       [0] Unsigned,
+ *      selected-flags                   [1] BACnetStatusFlags
+ *   }
+ * }
+ * @param tvb the tv buffer of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 
 
 /**
  * BACnetLogRecord ::= SEQUENCE {
- *     timestamp [0] BACnetDateTime,
- *     logDatum [1] CHOICE {
- *             log-status [0] BACnetLogStatus,
- *             boolean-value [1] BOOLEAN,
- *             real-value [2] REAL,
- *             enum-value [3] ENUMERATED, -- Optionally limited to 32 bits
- *             unsigned-value [4] Unsigned, -- Optionally limited to 32 bits
- *             signed-value [5] INTEGER, -- Optionally limited to 32 bits
- *             bitstring-value [6] BIT STRING,-- Optionally limited to 32 bits
- *             null-value [7] NULL,
- *             failure [8] Error,
- *             time-change [9] REAL,
- *             any-value [10] ABSTRACT-SYNTAX.&Type -- Optional
- *             }
- *     statusFlags [2] BACnetStatusFlags OPTIONAL
+ *  timestamp   [0] BACnetDateTime,
+ *  logDatum    [1] CHOICE {
+ *      log-status      [0] BACnetLogStatus,
+ *      boolean-value   [1] BOOLEAN,
+ *      real-value      [2] REAL,
+ *      enum-value      [3] ENUMERATED, -- Optionally limited to 32 bits
+ *      unsigned-value  [4] Unsigned, -- Optionally limited to 32 bits
+ *      signed-value    [5] INTEGER, -- Optionally limited to 32 bits
+ *      bitstring-value [6] BIT STRING, -- Optionally limited to 32 bits
+ *      null-value      [7] NULL,
+ *      failure         [8] Error,
+ *      time-change     [9] REAL,
+ *      any-value       [10] ABSTRACT-SYNTAX.&Type -- Optional
+ *      }
+ *  statusFlags [2] BACnetStatusFlags OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
+/**
+ * BACnetEventLogRecord ::= SEQUENCE {
+ *  timestamp [0] BACnetDateTime,
+ *  logDatum  [1] CHOICE {
+ *      log-status   [0] BACnetLogStatus,
+ *      notification [1] ConfirmedEventNotification-Request,
+ *      time-change  [2] REAL,
+ *      }
+ * }
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @return modified offset
+ */
+static guint
+fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+
+static guint
+fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetNotificationParameters ::= CHOICE {
- *     change-of-bitstring     [0]     SEQUENCE {
- *      referenced-bitstring    [0] BIT STRING,
- *      status-flags    [1] BACnetStatusFlags
+ *  change-of-bitstring [0] SEQUENCE {
+ *      referenced-bitstring [0] BIT STRING,
+ *      status-flags         [1] BACnetStatusFlags
  *      },
- *  change-of-state [1]        SEQUENCE {
- *      new-state   [0] BACnetPropertyStatus,
- *      status-flags    [1] BACnetStatusFlags
+ *  change-of-state [1] SEQUENCE {
+ *      new-state            [0] BACnetPropertyStatus,
+ *      status-flags         [1] BACnetStatusFlags
  *      },
- *  change-of-value [2]        SEQUENCE {
- *      new-value   [0] CHOICE {
- *          changed-bits   [0] BIT STRING,
- *          changed-value    [1] REAL
+ *  change-of-value [2] SEQUENCE {
+ *      new-value            [0] CHOICE {
+ *          changed-bits        [0] BIT STRING,
+ *          changed-value       [1] REAL
  *          },
- *      status-flags    [1] BACnetStatusFlags
+ *      status-flags         [1] BACnetStatusFlags
  *      },
- *  command-failure [3]        SEQUENCE {
- *      command-value   [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
- *      status-flags    [1] BACnetStatusFlags
- *      feedback-value    [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
+ *  command-failure [3] SEQUENCE {
+ *      command-value        [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property
+ *      status-flags         [1] BACnetStatusFlags
+ *      feedback-value       [2] ABSTRACT-SYNTAX.&Type -- depends on ref property
  *      },
- *  floating-limit [4] SEQUENCE {
- *      reference-value   [0] REAL,
- *      status-flags    [1] BACnetStatusFlags
- *      setpoint-value   [2] REAL,
- *      error-limit   [3] REAL
+ *  floating-limit [4]  SEQUENCE {
+ *      reference-value      [0] REAL,
+ *      status-flags         [1] BACnetStatusFlags
+ *      setpoint-value       [2] REAL,
+ *      error-limit          [3] REAL
  *      },
- *  out-of-range [5]   SEQUENCE {
- *      exceeding-value   [0] REAL,
- *      status-flags    [1] BACnetStatusFlags
- *      deadband   [2] REAL,
- *      exceeded-limit   [0] REAL
+ *  out-of-range [5]    SEQUENCE {
+ *      exceeding-value      [0] REAL,
+ *      status-flags         [1] BACnetStatusFlags
+ *      deadband             [2] REAL,
+ *      exceeded-limit       [3] REAL
  *      },
  *  complex-event-type  [6] SEQUENCE OF BACnetPropertyValue,
- *  buffer-ready [7]   SEQUENCE {
- *      buffer-device   [0] BACnetObjectIdentifier,
- *      buffer-object    [1] BACnetObjectIdentifier
- *      previous-notification   [2] BACnetDateTime,
- *      current-notification   [3] BACnetDateTime
- *      },
- *  change-of-life-safety [8]  SEQUENCE {
- *      new-state   [0] BACnetLifeSafetyState,
- *      new-mode    [1] BACnetLifeSafetyState
- *      status-flags   [2] BACnetStatusFlags,
+ * -- complex tag 7 is deprecated
+ *  change-of-life-safety [8]   SEQUENCE {
+ *      new-state            [0] BACnetLifeSafetyState,
+ *      new-mode             [1] BACnetLifeSafetyState
+ *      status-flags         [2] BACnetStatusFlags,
  *      operation-expected   [3] BACnetLifeSafetyOperation
- *      }
+ *      },
+ *  extended [9]   SEQUENCE {
+ *      vendor-id            [0] Unsigned16,
+ *      extended-event-type  [1] Unsigned,
+ *      parameters           [2] SEQUENCE OF CHOICE {
+ *          null                NULL,
+ *          real                REAL,
+ *          integer             Unsigned,
+ *          boolean             BOOLEAN,
+ *          double              Double,
+ *          octet               OCTET STRING,
+ *          bitstring           BIT STRING,
+ *          enum                ENUMERATED,
+ *          propertyValue       [0] BACnetDeviceObjectPropertyValue
+ *          }
+ *      },
+ *  buffer-ready [10]    SEQUENCE {
+ *      buffer-property      [0] BACnetDeviceObjectPropertyReference,
+ *      previous-notification[1] Unsigned32,
+ *      current-notification [2] BACneUnsigned32tDateTime
+ *      },
+ *  unsigned-range [11]    SEQUENCE {
+ *      exceeding-value      [0] Unsigned,
+ *      status-flags         [1] BACnetStatusFlags,
+ *      exceeded-limit       [2] Unsigned
+ *      },
+ * -- context tag 12 is reserved for future addenda
+ *  access-event [13]    SEQUENCE {
+ *      access-event          [0] BACnetAccessEvent,
+ *      status-flags          [1] BACnetStatusFlags,
+ *      access-event-tag      [2] Unsigned,
+ *      access-event-time     [3] BACnetTimeStamp,
+ *      access-credential     [4] BACnetDeviceObjectReference,
+ *      authentication-factor [5] BACnetAuthenticationFactor OPTIONAL
+ *      },
+ *  double-out-of-range [14]    SEQUENCE {
+ *      exceeding-value      [0] Double,
+ *      status-flags         [1] BACnetStatusFlags
+ *      deadband             [2] Double,
+ *      exceeded-limit       [3] Double
+ *      },
+ *  signed-out-of-range [15]    SEQUENCE {
+ *      exceeding-value      [0] INTEGER,
+ *      status-flags         [1] BACnetStatusFlags
+ *      deadband             [2] Unsigned,
+ *      exceeded-limit       [3] INTEGER
+ *      },
+ *  unsigned-out-of-range [16]    SEQUENCE {
+ *      exceeding-value      [0] Unsigned,
+ *      status-flags         [1] BACnetStatusFlags
+ *      deadband             [2] Unsigned,
+ *      exceeded-limit       [3] Unsigned
+ *      },
+ *  change-of-characterstring [17]    SEQUENCE {
+ *      changed-value        [0] CharacterString,
+ *      status-flags         [1] BACnetStatusFlags
+ *      alarm-value          [2] CharacterString
+ *      },
+ *  change-of-status-flags [18]    SEQUENCE {
+ *      present-value        [0] ABSTRACT-SYNTAX.&Type OPTIONAL,
+ *                              -- depends on referenced property
+ *      referenced-flags     [1] BACnetStatusFlags
+ *      },
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetObjectPropertyReference ::= SEQUENCE {
- *     objectIdentifier        [0] BACnetObjectIdentifier,
- *     propertyIdentifier      [1] BACnetPropertyIdentifier,
- *     propertyArrayIndex      [2] Unsigned OPTIONAL, -- used only with array datatype
+ *  objectIdentifier    [0] BACnetObjectIdentifier,
+ *  propertyIdentifier  [1] BACnetPropertyIdentifier,
+ *  propertyArrayIndex  [2] Unsigned OPTIONAL, -- used only with array datatype
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 #if 0
 /**
  * BACnetObjectPropertyValue ::= SEQUENCE {
- *             objectIdentifier [0] BACnetObjectIdentifier,
- *             propertyIdentifier [1] BACnetPropertyIdentifier,
- *             propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
- *                             -- if omitted with an array the entire array is referenced
- *             value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
- *             priority [4] Unsigned (1..16) OPTIONAL
+ *      objectIdentifier   [0] BACnetObjectIdentifier,
+ *      propertyIdentifier [1] BACnetPropertyIdentifier,
+ *      propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
+ *                                                -- if omitted with an array the entire array is referenced
+ *      value              [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property
+ *      priority           [4] Unsigned (1..16) OPTIONAL
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, guint offset);
 #endif
 
 /**
  * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 static guint
-fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
+fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list);
 
 /**
  * BACnetPropertyReference ::= SEQUENCE {
- *     propertyIdentifier      [0] BACnetPropertyIdentifier,
- *     propertyArrayIndex      [1] Unsigned OPTIONAL, -- used only with array datatype
+ *  propertyIdentifier  [0] BACnetPropertyIdentifier,
+ *  propertyArrayIndex  [1] Unsigned OPTIONAL, -- used only with array datatype
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
+fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list);
 
 /* static guint
-fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
+fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset); */
 
 static guint
-fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 static guint
-fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetPropertyValue ::= SEQUENCE {
- *             PropertyIdentifier [0] BACnetPropertyIdentifier,
- *             propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
- *                             -- if omitted with an array the entire array is referenced
- *             value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
- *             priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
+ *      PropertyIdentifier [0] BACnetPropertyIdentifier,
+ *      propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes
+ *                                                -- if omitted with an array the entire array is referenced
+ *      value              [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property
+ *      priority           [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 static guint
-fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
+fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset);
 
 /**
  * BACnet Application PDUs chapter 21
  * BACnetRecipient::= CHOICE {
- *     device  [0] BACnetObjectIdentifier
- *     address [1] BACnetAddress
+ *  device  [0] BACnetObjectIdentifier
+ *  address [1] BACnetAddress
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnet Application PDUs chapter 21
  * BACnetRecipientProcess::= SEQUENCE {
- *     recipient       [0] BACnetRecipient
- *     processID       [1] Unsigned32
+ *  recipient   [0] BACnetRecipient
+ *  processID   [1] Unsigned32
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 static guint
-fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 #if 0
 /**
  * BACnetSessionKey ::= SEQUENCE {
- *     sessionKey      OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
- *     peerAddress     BACnetAddress
+ *  sessionKey  OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum
+ *  peerAddress BACnetAddress
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  * @todo check if checksum is displayed correctly
  */
 static guint
-fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fSessionKey(tvbuff_t *tvb, proto_tree *tree, guint offset);
 #endif
 
 /**
  * BACnetSpecialEvent ::= SEQUENCE {
- *     period          CHOICE {
- *             calendarEntry           [0] BACnetCalendarEntry,
- *             calendarRefernce        [1] BACnetObjectIdentifier
- *             },
- *             listOfTimeValues        [2] SEQUENCE OF BACnetTimeValue,
- *             eventPriority           [3] Unsigned (1..16)
+ *  period      CHOICE {
+ *      calendarEntry       [0] BACnetCalendarEntry,
+ *      calendarRefernce    [1] BACnetObjectIdentifier
+ *      },
+ *      listOfTimeValues    [2] SEQUENCE OF BACnetTimeValue,
+ *      eventPriority       [3] Unsigned (1..16)
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetTimeStamp ::= CHOICE {
- *     time                    [0] Time,
- *     sequenceNumber  [1] Unsigned (0..65535),
- *     dateTime                [2] BACnetDateTime
+ *  time            [0] Time,
+ *  sequenceNumber  [1] Unsigned (0..65535),
+ *  dateTime        [2] BACnetDateTime
  * }
- * @param tvb
- * @param tree
- * @param offset
- * @param label
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
+ * @param label the label of this item
  * @return modified offset
  */
 static guint
-fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
+fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
+
+static guint
+fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnetTimeValue ::= SEQUENCE {
- *     time    Time,
- *     value   ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
+ *  time    Time,
+ *  value   ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 #if 0
 /**
  * BACnetVTSession ::= SEQUENCE {
- *     local-vtSessionID       Unsigned8,
- *     remote-vtSessionID      Unsigned8,
- *     remote-vtAddress        BACnetAddress
+ *  local-vtSessionID   Unsigned8,
+ *  remote-vtSessionID  Unsigned8,
+ *  remote-vtAddress    BACnetAddress
  * }
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fVTSession(tvbuff_t *tvb, proto_tree *tree, guint offset);
 #endif
 
 /**
@@ -1909,79 +2059,81 @@ fVTSession (tvbuff_t *tvb, proto_tree *tree, guint offset);
  * -- third octet dayOfWeek (1..7) where 1 = Monday
  * -- 7 = Sunday
  * -- X'FF' = any day of week
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ReadAccessResult ::= SEQUENCE {
- *     objectIdentifier        [0] BACnetObjectIdentifier,
- *     listOfResults   [1] SEQUENCE OF SEQUENCE {
- *             propertyIdentifier      [2] BACnetPropertyIdentifier,
- *             propertyArrayIndex      [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
- *             readResult      CHOICE {
- *                     propertyValue   [4] ABSTRACT-SYNTAX.&Type,
- *                     propertyAccessError     [5] Error
- *             }
+ *  objectIdentifier            [0] BACnetObjectIdentifier,
+ *  listOfResults               [1] SEQUENCE OF SEQUENCE {
+ *      propertyIdentifier      [2] BACnetPropertyIdentifier,
+ *      propertyArrayIndex      [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced
+ *      readResult  CHOICE {
+ *          propertyValue       [4] ABSTRACT-SYNTAX.&Type,
+ *          propertyAccessError [5] Error
+ *      }
  *  } OPTIONAL
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * ReadAccessSpecification ::= SEQUENCE {
- *     objectIdentifier        [0] BACnetObjectIdentifier,
- *     listOfPropertyReferences        [1] SEQUENCE OF BACnetPropertyReference
+ *  objectIdentifier         [0] BACnetObjectIdentifier,
+ *  listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param subtree the subtree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
+fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
 
 /**
  * WriteAccessSpecification ::= SEQUENCE {
- *     objectIdentifier        [0] BACnetObjectIdentifier,
- *     listOfProperty  [1] SEQUENCE OF BACnetPropertyValue
+ *  objectIdentifier [0] BACnetObjectIdentifier,
+ *  listOfProperty   [1] SEQUENCE OF BACnetPropertyValue
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param subtree the sub tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
+fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
 
 
 /********************************************************* Helper functions *******************************************/
 
 /**
  * extracts the tag number from the tag header.
- * @param tvb "TestyVirtualBuffer"
- * @param offset in actual tvb
+ * @param tvb the tv buffer of the current data "TestyVirtualBuffer"
+ * @param offset the offset in the tvb in actual tvb
  * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number
  */
 static guint
-fTagNo (tvbuff_t *tvb, guint offset);
+fTagNo(tvbuff_t *tvb, guint offset);
 
 /**
  * splits Tag Header coresponding to 20.2.1 General Rules For BACnet Tags
- * @param tvb = "TestyVirtualBuffer"
- * @param offset = offset in actual tvb
+ * @param tvb the tv buffer of the current data = "TestyVirtualBuffer"
+ * @param pinfo the packet info of the current data = packet info
+ * @param offset the offset in the tvb = offset in actual tvb
  * @return tag_no BACnet 20.2.1.2 Tag Number
  * @return class_tag BACnet 20.2.1.1 Class
  * @return lvt BACnet 20.2.1.3 Length/Value/Type
@@ -1989,106 +2141,107 @@ fTagNo (tvbuff_t *tvb, guint offset);
  */
 
 static guint
-fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
+fTagHeader(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* class_tag, guint32 *lvt);
 
 
 /**
  * adds processID with max 32Bit unsigned Integer Value to tree
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * adds timeSpan with max 32Bit unsigned Integer Value to tree
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
+fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
 
 /**
  * BACnet Application PDUs chapter 21
  * BACnetPropertyIdentifier::= ENUMERATED {
- *      @see bacapp_property_identifier
+ *   @see bacapp_property_identifier
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
- * @param tt returnvalue of this item
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * BACnet Application PDUs chapter 21
  * BACnetPropertyArrayIndex::= ENUMERATED {
- *      @see bacapp_property_array_index
+ *   @see bacapp_property_array_index
  * }
- * @param tvb
- * @param tree
- * @param offset
- * @param tt returnvalue of this item
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset);
+fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * listOfEventSummaries ::= SEQUENCE OF SEQUENCE {
- *     objectIdentifier        [0] BACnetObjectIdentifier,
- *  eventState  [1] BACnetEventState,
+ *  objectIdentifier        [0] BACnetObjectIdentifier,
+ *  eventState              [1] BACnetEventState,
  *  acknowledgedTransitions [2] BACnetEventTransitionBits,
- *  eventTimeStamps [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
- *  notifyType  [4] BACnetNotifyType,
- *  eventEnable [5] BACnetEventTransitionBits,
- *  eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned
+ *  eventTimeStamps         [3] SEQURNCE SIZE (3) OF BACnetTimeStamps,
+ *  notifyType              [4] BACnetNotifyType,
+ *  eventEnable             [5] BACnetEventTransitionBits,
+ *  eventPriorities         [6] SEQUENCE SIZE (3) OF Unsigned
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * SelectionCriteria ::= SEQUENCE {
- *     propertyIdentifier      [0] BACnetPropertyIdentifier,
- *     propertyArrayIndex      [1] Unsigned OPTIONAL, -- used only with array datatype
- *  relationSpecifier  [2] ENUMERATED { bacapp_relationSpecifier },
- *  comparisonValue    [3] ABSTRACT-SYNTAX.&Type
+ *  propertyIdentifier [0] BACnetPropertyIdentifier,
+ *  propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype
+ *  relationSpecifier  [2] ENUMERATED { bacapp_relationSpecifier },
+ *  comparisonValue    [3] ABSTRACT-SYNTAX.&Type
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 /**
  * objectSelectionCriteria ::= SEQUENCE {
- *     selectionLogic  [0] ENUMERATED { bacapp_selectionLogic },
- *     listOfSelectionCriteria [1] SelectionCriteria
+ *  selectionLogic          [0] ENUMERATED { bacapp_selectionLogic },
+ *  listOfSelectionCriteria [1] SelectionCriteria
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param subtree the sub tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
-fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
+fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset);
 
 /**
  * BACnet-Error ::= SEQUENCE {
@@ -2096,10 +2249,10 @@ fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree
  *    error-code  ENUMERATED {}
  *    }
  * }
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  */
 static guint
@@ -2108,31 +2261,32 @@ fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 /**
  * Generic handler for context tagged values.  Mostly for handling
  * vendor-defined properties and services.
- * @param tvb
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  * @todo beautify this ugly construct
  */
 static guint
-fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label);
+fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label);
 
 /**
  * realizes some ABSTRACT-SYNTAX.&Type
- * @param tvb
- * @param pinfo
- * @param tree
- * @param offset
+ * @param tvb the tv buffer of the current data
+ * @param pinfo the packet info of the current data
+ * @param tree the tree to append this item to
+ * @param offset the offset in the tvb
  * @return modified offset
  * @todo beautify this ugly construct
  */
 static guint
-fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
+fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
 
 
 static guint
-fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
-       const value_string *src);
+fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
+    const value_string *src);
 
 /**
  * register_bacapp
@@ -2146,166 +2300,212 @@ proto_register_bacapp(void);
 void
 proto_reg_handoff_bacapp(void);
 
-/**
- * converts XXX coded strings to UTF-8
- * else 'in' is copied to 'out'
- * @param in  -- pointer to string
- * @param inbytesleft
- * @param out -- pointer to string
- * @param outbytesleft
- * @param fromcoding
- * @return count of modified characters of returned string, -1 for errors
- */
-static guint32
-fConvertXXXtoUTF8(gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding);
-
-static void
-uni_to_string(char * data, gsize str_length, char *dest_buf);
-
 /* <<<< formerly bacapp.h */
 
-/* some hashes for segmented messages */
-static GHashTable *msg_fragment_table = NULL;
-static GHashTable *msg_reassembled_table = NULL;
+/* reassembly table for segmented messages */
+static reassembly_table msg_reassembly_table;
 
 /* some necessary forward function prototypes */
 static guint
-fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
-       const gchar *label, const value_string *vs);
+fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
+    const gchar *label, const value_string *vs);
 
-static const char *bacapp_unknown_service_str = "unknown service";
-static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
-static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
+static const char *bacapp_unknown_service_str = "unknown service";  /* Usage: no format specifiers */
+static const char ASHRAE_Reserved_Fmt[] = "(%d) Reserved for Use by ASHRAE";
+static const char Vendor_Proprietary_Fmt[] = "(%d) Vendor Proprietary Value";
 
 static const value_string
 BACnetTypeName[] = {
-       {0, "Confirmed-REQ"},
-       {1, "Unconfirmed-REQ"},
-       {2, "Simple-ACK"},
-       {3, "Complex-ACK"},
-       {4, "Segment-ACK"},
-       {5, "Error"},
-       {6, "Reject"},
-       {7, "Abort"},
-       {0, NULL }
+    0, "Confirmed-REQ"},
+    1, "Unconfirmed-REQ"},
+    2, "Simple-ACK"},
+    3, "Complex-ACK"},
+    4, "Segment-ACK"},
+    5, "Error"},
+    6, "Reject"},
+    7, "Abort"},
+    0, NULL }
 };
 
 static const true_false_string segments_follow = {
-       "Segmented Request",
-       "Unsegmented Request"
+    "Segmented Request",
+    "Unsegmented Request"
 };
 
 static const true_false_string more_follow = {
-       "More Segments Follow",
-       "No More Segments Follow"
+    "More Segments Follow",
+    "No More Segments Follow"
 };
 
 static const true_false_string segmented_accept = {
-       "Segmented Response accepted",
-       "Segmented Response not accepted"
+    "Segmented Response accepted",
+    "Segmented Response not accepted"
 };
 
 static const true_false_string
 BACnetTagClass = {
-       "Context Specific Tag",
-       "Application Tag"
+    "Context Specific Tag",
+    "Application Tag"
 };
 
 static const value_string
 BACnetMaxSegmentsAccepted [] = {
-       {0,"Unspecified"},
-       {1,"2 segments"},
-       {2,"4 segments"},
-       {3,"8 segments"},
-       {4,"16 segments"},
-       {5,"32 segments"},
-       {6,"64 segments"},
-       {7,"Greater than 64 segments"},
-       {0,NULL }
+    { 0,  "Unspecified"},
+    { 1,  "2 segments"},
+    { 2,  "4 segments"},
+    { 3,  "8 segments"},
+    { 4, "16 segments"},
+    { 5, "32 segments"},
+    { 6, "64 segments"},
+    { 7, "Greater than 64 segments"},
+    { 0, NULL }
 };
 
 static const value_string
 BACnetMaxAPDULengthAccepted [] = {
-       {0,"Up to MinimumMessageSize (50 octets)"},
-       {1,"Up to 128 octets"},
-       {2,"Up to 206 octets (fits in a LonTalk frame)"},
-       {3,"Up to 480 octets (fits in an ARCNET frame)"},
-       {4,"Up to 1024 octets"},
-       {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
-       {6,"reserved by ASHRAE"},
-       {7,"reserved by ASHRAE"},
-       {8,"reserved by ASHRAE"},
-       {9,"reserved by ASHRAE"},
-       {10,"reserved by ASHRAE"},
-       {11,"reserved by ASHRAE"},
-       {12,"reserved by ASHRAE"},
-       {13,"reserved by ASHRAE"},
-       {14,"reserved by ASHRAE"},
-       {15,"reserved by ASHRAE"},
-       {0,NULL}
+    {  0, "Up to MinimumMessageSize (50 octets)"},
+    {  1, "Up to 128 octets"},
+    {  2, "Up to 206 octets (fits in a LonTalk frame)"},
+    {  3, "Up to 480 octets (fits in an ARCNET frame)"},
+    {  4, "Up to 1024 octets"},
+    {  5, "Up to 1476 octets (fits in an ISO 8802-3 frame)"},
+    {  6, "reserved by ASHRAE"},
+    {  7, "reserved by ASHRAE"},
+    {  8, "reserved by ASHRAE"},
+    {  9, "reserved by ASHRAE"},
+    { 10, "reserved by ASHRAE"},
+    { 11, "reserved by ASHRAE"},
+    { 12, "reserved by ASHRAE"},
+    { 13, "reserved by ASHRAE"},
+    { 14, "reserved by ASHRAE"},
+    { 15, "reserved by ASHRAE"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetRejectReason [] = {
-       {0,"other"},
-       {1,"buffer-overflow"},
-       {2,"inconsistent-parameters"},
-       {3,"invalid-parameter-data-type"},
-       {4,"invalid-tag"},
-       {5,"missing-required-parameter"},
-       {6,"parameter-out-of-range"},
-       {7,"too-many-arguments"},
-       {8,"undefined-enumeration"},
-       {9,"unrecognized-service"},
-       {0,NULL}
+    {0, "other"},
+    {1, "buffer-overflow"},
+    {2, "inconsistent-parameters"},
+    {3, "invalid-parameter-data-type"},
+    {4, "invalid-tag"},
+    {5, "missing-required-parameter"},
+    {6, "parameter-out-of-range"},
+    {7, "too-many-arguments"},
+    {8, "undefined-enumeration"},
+    {9, "unrecognized-service"},
+    {0, NULL}
 };
 
 static const value_string
 BACnetRestartReason [] = {
-       {0,"unknown"},
-       {1,"coldstart"},
-       {2,"warmstart"},
-       {3,"detected-power-lost"},
-       {4,"detected-powered-off"},
-       {5,"hardware-watchdog"},
-       {6,"software-watchdog"},
-       {7,"suspended"},
-       {0,NULL}
+    { 0, "unknown"},
+    { 1, "coldstart"},
+    { 2, "warmstart"},
+    { 3, "detected-power-lost"},
+    { 4, "detected-powered-off"},
+    { 5, "hardware-watchdog"},
+    { 6, "software-watchdog"},
+    { 7, "suspended"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetApplicationTagNumber [] = {
-       {0,"Null"},
-       {1,"Boolean"},
-       {2,"Unsigned Integer"},
-       {3,"Signed Integer (2's complement notation)"},
-       {4,"Real (ANSI/IEE-754 floating point)"},
-       {5,"Double (ANSI/IEE-754 double precision floating point)"},
-       {6,"Octet String"},
-       {7,"Character String"},
-       {8,"Bit String"},
-       {9,"Enumerated"},
-       {10,"Date"},
-       {11,"Time"},
-       {12,"BACnetObjectIdentifier"},
-       {13,"reserved by ASHRAE"},
-       {14,"reserved by ASHRAE"},
-       {15,"reserved by ASHRAE"},
-       {0,NULL}
+    {  0, "Null"},
+    {  1, "Boolean"},
+    {  2, "Unsigned Integer"},
+    {  3, "Signed Integer (2's complement notation)"},
+    {  4, "Real (ANSI/IEE-754 floating point)"},
+    {  5, "Double (ANSI/IEE-754 double precision floating point)"},
+    {  6, "Octet String"},
+    {  7, "Character String"},
+    {  8, "Bit String"},
+    {  9, "Enumerated"},
+    { 10, "Date"},
+    { 11, "Time"},
+    { 12, "BACnetObjectIdentifier"},
+    { 13, "reserved by ASHRAE"},
+    { 14, "reserved by ASHRAE"},
+    { 15, "reserved by ASHRAE"},
+    { 0,  NULL}
 };
 
 static const value_string
 BACnetAction [] = {
-       {0,"direct"},
-       {1,"reverse"},
-       {0,NULL}
+    { 0, "direct"},
+    { 1, "reverse"},
+    { 0, NULL}
+};
+
+static const value_string
+BACnetAccessEvent [] = {
+    {  0, "none"},
+    {  1, "granted"},
+    {  2, "muster"},
+    {  3, "passback-detected"},
+    {  4, "duress"},
+    {  5, "trace"},
+    {  6, "lockout-max-attempts"},
+    {  7, "lockout-other"},
+    {  8, "lockout-relinquished"},
+    {  9, "lockout-by-higher-priority"},
+    { 10, "out-of-service"},
+    { 11, "out-of-service-relinquished"},
+    { 12, "accompaniment-by"},
+    { 13, "authentication-factor-read"},
+    { 14, "authorization-delayed"},
+    { 15, "verification-required"},
+    /* Enumerated values 128-511 are used for events
+     * which indicate that access has been denied. */
+    { 128, "denied-deny-all"},
+    { 129, "denied-unknown-credential"},
+    { 130, "denied-authentication-unavailable"},
+    { 131, "denied-authentication-factor-timeout"},
+    { 132, "denied-incorrect-authentication-factor"},
+    { 133, "denied-zone-no-access-rights"},
+    { 134, "denied-point-no-access-rights"},
+    { 135, "denied-no-access-rights"},
+    { 136, "denied-out-of-time-range"},
+    { 137, "denied-threat-level"},
+    { 138, "denied-passback"},
+    { 139, "denied-unexpected-location-usage"},
+    { 140, "denied-max-attempts"},
+    { 141, "denied-lower-occupancy-limit"},
+    { 142, "denied-upper-occupancy-limit"},
+    { 143, "denied-authentication-factor-lost"},
+    { 144, "denied-authentication-factor-stolen"},
+    { 145, "denied-authentication-factor-damaged"},
+    { 146, "denied-authentication-factor-destroyed"},
+    { 147, "denied-authentication-factor-disabled"},
+    { 148, "denied-authentication-factor-error"},
+    { 149, "denied-credential-unassigned"},
+    { 150, "denied-credential-not-provisioned"},
+    { 151, "denied-credential-not-yet-active"},
+    { 152, "denied-credential-expired"},
+    { 153, "denied-credential-manual-disable"},
+    { 154, "denied-credential-lockout"},
+    { 155, "denied-credential-max-days"},
+    { 156, "denied-credential-max-uses"},
+    { 157, "denied-credential-inactivity"},
+    { 158, "denied-credential-disabled"},
+    { 159, "denied-no-accompaniment"},
+    { 160, "denied-incorrect-accompaniment"},
+    { 161, "denied-lockout"},
+    { 162, "denied-verification-failed"},
+    { 163, "denied-verification-timeout"},
+    { 164, "denied-other"},
+    { 0,  NULL}
+/* Enumerated values 0-512 are reserved for definition by ASHRAE.
+   Enumerated values 512-65535 may be used by others subject to
+   procedures and constraints described in Clause 23. */
 };
 
 static const value_string
 BACnetFileAccessMethod [] = {
-       {0,"record-access"},
-       {1,"stream-access"},
-       {0,NULL}
+    { 0, "record-access"},
+    { 1, "stream-access"},
+    { 0, NULL}
 };
 
 /* For some reason, BACnet defines the choice parameter
@@ -2314,60 +2514,60 @@ BACnetFileAccessMethod [] = {
 */
 static const value_string
 BACnetFileAccessOption [] = {
-       {0,"stream access"},
-       {1,"record access"},
-       {0,NULL}
+    { 0, "stream access"},
+    { 1, "record access"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetFileStartOption [] = {
-       {0, "File Start Position: "},
-       {1, "File Start Record: "},
-       {0, NULL}
+    0, "File Start Position: "},
+    1, "File Start Record: "},
+    0, NULL}
 };
 
 static const value_string
 BACnetFileRequestCount [] = {
-       {0, "Requested Octet Count: "},
-       {1, "Requested Record Count: "},
-       {0, NULL}
+    0, "Requested Octet Count: "},
+    1, "Requested Record Count: "},
+    0, NULL}
 };
 
 static const value_string
 BACnetFileWriteInfo [] = {
-       {0, "File Data: "},
-       {1, "Record Count: "},
-       {0, NULL}
+    0, "File Data: "},
+    1, "Record Count: "},
+    0, NULL}
 };
 
 static const value_string
 BACnetAbortReason [] = {
-       {0,"other"},
-       {1,"buffer-overflow"},
-       {2,"invalid-apdu-in-this-state"},
-       {3,"preempted-by-higher-priority-task"},
-       {4,"segmentation-not-supported"},
-       {0,NULL}
+    { 0, "other"},
+    { 1, "buffer-overflow"},
+    { 2, "invalid-apdu-in-this-state"},
+    { 3, "preempted-by-higher-priority-task"},
+    { 4, "segmentation-not-supported"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetLifeSafetyMode [] = {
-       {0,"off"},
-       {1,"on"},
-       {2,"test"},
-       {3,"manned"},
-       {4,"unmanned"},
-       {5,"armed"},
-       {6,"disarmed"},
-       {7,"prearmed"},
-       {8,"slow"},
-       {9,"fast"},
-       {10,"disconnected"},
-       {11,"enabled"},
-       {12,"disabled"},
-       {13,"atomic-release-disabled"},
-       {14,"default"},
-       {0,NULL}
+    {  0, "off"},
+    {  1, "on"},
+    {  2, "test"},
+    {  3, "manned"},
+    {  4, "unmanned"},
+    {  5, "armed"},
+    {  6, "disarmed"},
+    {  7, "prearmed"},
+    {  8, "slow"},
+    {  9, "fast"},
+    { 10, "disconnected"},
+    { 11, "enabled"},
+    { 12, "disabled"},
+    { 13, "atomic-release-disabled"},
+    { 14, "default"},
+    { 0,  NULL}
 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
    Enumerated values 256-65535 may be used by others subject to
    procedures and constraints described in Clause 23. */
@@ -2375,56 +2575,58 @@ BACnetLifeSafetyMode [] = {
 
 static const value_string
 BACnetLifeSafetyOperation [] = {
-       {0,"none"},
-       {1,"silence"},
-       {2,"silence-audible"},
-       {3,"silence-visual"},
-       {4,"reset"},
-       {5,"reset-alarm"},
-       {6,"reset-fault"},
-       {7,"unsilence"},
-       {8,"unsilence-audible"},
-       {9,"unsilence-visual"},
-       {0,NULL}
+    { 0, "none"},
+    { 1, "silence"},
+    { 2, "silence-audible"},
+    { 3, "silence-visual"},
+    { 4, "reset"},
+    { 5, "reset-alarm"},
+    { 6, "reset-fault"},
+    { 7, "unsilence"},
+    { 8, "unsilence-audible"},
+    { 9, "unsilence-visual"},
+    { 0, NULL}
 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
    Enumerated values 64-65535 may be used by others subject to
    procedures and constraints described in Clause 23. */
 };
 
+#if 0
 static const value_string
 BACnetLimitEnable [] = {
-       {0,"lowLimitEnable"},
-       {1,"highLimitEnable"},
-       {0,NULL}
+    { 0, "lowLimitEnable"},
+    { 1, "highLimitEnable"},
+    { 0, NULL}
 };
+#endif
 
 static const value_string
 BACnetLifeSafetyState [] = {
-       {0,"quiet"},
-       {1,"pre-alarm"},
-       {2,"alarm"},
-       {3,"fault"},
-       {4,"fault-pre-alarm"},
-       {5,"fault-alarm"},
-       {6,"not-ready"},
-       {7,"active"},
-       {8,"tamper"},
-       {9,"test-alarm"},
-       {10,"test-active"},
-       {11,"test-fault"},
-       {12,"test-fault-alarm"},
-       {13,"holdup"},
-       {14,"duress"},
-       {15,"tamper-alarm"},
-       {16,"abnormal"},
-       {17,"emergency-power"},
-       {18,"delayed"},
-       {19,"blocked"},
-       {20,"local-alarm"},
-       {21,"general-alarm"},
-       {22,"supervisory"},
-       {23,"test-supervisory"},
-       {0,NULL}
+    {  0, "quiet"},
+    {  1, "pre-alarm"},
+    {  2, "alarm"},
+    {  3, "fault"},
+    {  4, "fault-pre-alarm"},
+    {  5, "fault-alarm"},
+    {  6, "not-ready"},
+    {  7, "active"},
+    {  8, "tamper"},
+    {  9, "test-alarm"},
+    { 10, "test-active"},
+    { 11, "test-fault"},
+    { 12, "test-fault-alarm"},
+    { 13, "holdup"},
+    { 14, "duress"},
+    { 15, "tamper-alarm"},
+    { 16, "abnormal"},
+    { 17, "emergency-power"},
+    { 18, "delayed"},
+    { 19, "blocked"},
+    { 20, "local-alarm"},
+    { 21, "general-alarm"},
+    { 22, "supervisory"},
+    { 23, "test-supervisory"},
+    { 0,  NULL}
 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
    Enumerated values 256-65535 may be used by others subject to
    procedures and constraints described in Clause 23. */
@@ -2432,143 +2634,145 @@ BACnetLifeSafetyState [] = {
 
 static const value_string
 BACnetConfirmedServiceChoice [] = {
-       {0,"acknowledgeAlarm"},
-       {1,"confirmedCOVNotification"},
-       {2,"confirmedEventNotification"},
-       {3,"getAlarmSummary"},
-       {4,"getEnrollmentSummary"},
-       {5,"subscribeCOV"},
-       {6,"atomicReadFile"},
-       {7,"atomicWriteFile"},
-       {8,"addListElement"},
-       {9,"removeListElement"},
-       {10,"createObject"},
-       {11,"deleteObject"},
-       {12,"readProperty"},
-       {13,"readPropertyConditional"},
-       {14,"readPropertyMultiple"},
-       {15,"writeProperty"},
-       {16,"writePropertyMultiple"},
-       {17,"deviceCommunicationControl"},
-       {18,"confirmedPrivateTransfer"},
-       {19,"confirmedTextMessage"},
-       {20,"reinitializeDevice"},
-       {21,"vtOpen"},
-       {22,"vtClose"},
-       {23,"vtData"},
-       {24,"authenticate"},
-       {25,"requestKey"},
-       {26,"readRange"},
-       {27,"lifeSafetyOperation"},
-       {28,"subscribeCOVProperty"},
-       {29,"getEventInformation"},
-       {30,"reserved by ASHRAE"},
-       {0, NULL}
+    {  0, "acknowledgeAlarm"},
+    {  1, "confirmedCOVNotification"},
+    {  2, "confirmedEventNotification"},
+    {  3, "getAlarmSummary"},
+    {  4, "getEnrollmentSummary"},
+    {  5, "subscribeCOV"},
+    {  6, "atomicReadFile"},
+    {  7, "atomicWriteFile"},
+    {  8, "addListElement"},
+    {  9, "removeListElement"},
+    { 10, "createObject"},
+    { 11, "deleteObject"},
+    { 12, "readProperty"},
+    { 13, "readPropertyConditional"},
+    { 14, "readPropertyMultiple"},
+    { 15, "writeProperty"},
+    { 16, "writePropertyMultiple"},
+    { 17, "deviceCommunicationControl"},
+    { 18, "confirmedPrivateTransfer"},
+    { 19, "confirmedTextMessage"},
+    { 20, "reinitializeDevice"},
+    { 21, "vtOpen"},
+    { 22, "vtClose"},
+    { 23, "vtData"},
+    { 24, "authenticate"},
+    { 25, "requestKey"},
+    { 26, "readRange"},
+    { 27, "lifeSafetyOperation"},
+    { 28, "subscribeCOVProperty"},
+    { 29, "getEventInformation"},
+    { 30, "reserved by ASHRAE"},
+    { 0,  NULL}
 };
 
 static const value_string
 BACnetReliability [] = {
-       {0,"no-fault-detected"},
-       {1,"no-sensor"},
-       {2,"over-range"},
-       {3,"under-range"},
-       {4,"open-loop"},
-       {5,"shorted-loop"},
-       {6,"no-output"},
-       {7,"unreliable-other"},
-       {8,"process-error"},
-       {9,"multi-state-fault"},
-       {10,"configuration-error"},
-       /* enumeration value 11 is reserved for a future addendum */
-       {12,"communication-failure"},
-       {13,"member-fault"},
-       {0,NULL}
+    {  0, "no-fault-detected"},
+    {  1, "no-sensor"},
+    {  2, "over-range"},
+    {  3, "under-range"},
+    {  4, "open-loop"},
+    {  5, "shorted-loop"},
+    {  6, "no-output"},
+    {  7, "unreliable-other"},
+    {  8, "process-error"},
+    {  9, "multi-state-fault"},
+    { 10, "configuration-error"},
+    /* enumeration value 11 is reserved for a future addendum */
+    { 12, "communication-failure"},
+    { 13, "member-fault"},
+    { 0,  NULL}
 };
 
 static const value_string
 BACnetUnconfirmedServiceChoice [] = {
-       {0,"i-Am"},
-       {1,"i-Have"},
-       {2,"unconfirmedCOVNotification"},
-       {3,"unconfirmedEventNotification"},
-       {4,"unconfirmedPrivateTransfer"},
-       {5,"unconfirmedTextMessage"},
-       {6,"timeSynchronization"},
-       {7,"who-Has"},
-       {8,"who-Is"},
-       {9,"utcTimeSynchonization"},
-       {0,NULL}
+    { 0, "i-Am"},
+    { 1, "i-Have"},
+    { 2, "unconfirmedCOVNotification"},
+    { 3, "unconfirmedEventNotification"},
+    { 4, "unconfirmedPrivateTransfer"},
+    { 5, "unconfirmedTextMessage"},
+    { 6, "timeSynchronization"},
+    { 7, "who-Has"},
+    { 8, "who-Is"},
+    { 9, "utcTimeSynchronization"},
+    { 0, NULL}
 };
 
+#if 0
 static const value_string
 BACnetUnconfirmedServiceRequest [] = {
-       {0,"i-Am-Request"},
-       {1,"i-Have-Request"},
-       {2,"unconfirmedCOVNotification-Request"},
-       {3,"unconfirmedEventNotification-Request"},
-       {4,"unconfirmedPrivateTransfer-Request"},
-       {5,"unconfirmedTextMessage-Request"},
-       {6,"timeSynchronization-Request"},
-       {7,"who-Has-Request"},
-       {8,"who-Is-Request"},
-       {9,"utcTimeSynchonization-Request"},
-       {0,NULL}
+    { 0, "i-Am-Request"},
+    { 1, "i-Have-Request"},
+    { 2, "unconfirmedCOVNotification-Request"},
+    { 3, "unconfirmedEventNotification-Request"},
+    { 4, "unconfirmedPrivateTransfer-Request"},
+    { 5, "unconfirmedTextMessage-Request"},
+    { 6, "timeSynchronization-Request"},
+    { 7, "who-Has-Request"},
+    { 8, "who-Is-Request"},
+    { 9, "utcTimeSynchonization-Request"},
+    { 0, NULL}
 };
+#endif
 
 static const value_string
 BACnetObjectType [] = {
-       {0,"analog-input"},
-       {1,"analog-output"},
-       {2,"analog-value"},
-       {3,"binary-input"},
-       {4,"binary-output"},
-       {5,"binary-value"},
-       {6,"calendar"},
-       {7,"command"},
-       {8,"device"},
-       {9,"event-enrollment"},
-       {10,"file"},
-       {11,"group"},
-       {12,"loop"},
-       {13,"multi-state-input"},
-       {14,"multi-state-output"},
-       {15,"notification-class"},
-       {16,"program"},
-       {17,"schedule"},
-       {18,"averaging"},
-       {19,"multi-state-value"},
-       {20,"trend-log"},
-       {21,"life-safety-point"},
-       {22,"life-safety-zone"},
-       {23,"accumulator"},
-       {24,"pulse-converter"},
-       {25,"event-log"},
-       {26,"global-group"},
-       {27,"trend-log-multiple"},
-       {28,"load-control"},
-       {29,"structured-view"},
-       {30,"access-door"},             /* 30-37 added with addanda 135-2008j */
-       /* value 31 is unassigned */
-       {32,"access-credential"},
-       {33,"access-point"},
-       {34,"access-rights"},
-       {35,"access-user"},
-       {36,"access-zone"},
-       {37,"credential-data-input"},
-       {38,"network-security"},
-       {39,"bitstring-value"},         /* 39-50 added with addenda 135-2008w */
-       {40,"characterstring-value"},
-       {41,"date-pattern-value"},
-       {42,"date-value"},
-       {43,"datetime-pattern-value"},
-       {44,"datetime-value"},
-       {45,"integer-value"},
-       {46,"large-analog-value"},
-       {47,"octetstring-value"},
-       {48,"positive-integer-value"},
-       {49,"time-pattern-value"},
-       {50,"time-value"},
-       {0, NULL}
+    {  0, "analog-input"},
+    {  1, "analog-output"},
+    {  2, "analog-value"},
+    {  3, "binary-input"},
+    {  4, "binary-output"},
+    {  5, "binary-value"},
+    {  6, "calendar"},
+    {  7, "command"},
+    {  8, "device"},
+    {  9, "event-enrollment"},
+    { 10, "file"},
+    { 11, "group"},
+    { 12, "loop"},
+    { 13, "multi-state-input"},
+    { 14, "multi-state-output"},
+    { 15, "notification-class"},
+    { 16, "program"},
+    { 17, "schedule"},
+    { 18, "averaging"},
+    { 19, "multi-state-value"},
+    { 20, "trend-log"},
+    { 21, "life-safety-point"},
+    { 22, "life-safety-zone"},
+    { 23, "accumulator"},
+    { 24, "pulse-converter"},
+    { 25, "event-log"},
+    { 26, "global-group"},
+    { 27, "trend-log-multiple"},
+    { 28, "load-control"},
+    { 29, "structured-view"},
+    { 30, "access-door"},     /* 30-37 added with addanda 135-2008j */
+    /* value 31 is unassigned */
+    { 32, "access-credential"},
+    { 33, "access-point"},
+    { 34, "access-rights"},
+    { 35, "access-user"},
+    { 36, "access-zone"},
+    { 37, "credential-data-input"},
+    { 38, "network-security"},
+    { 39, "bitstring-value"},     /* 39-50 added with addenda 135-2008w */
+    { 40, "characterstring-value"},
+    { 41, "date-pattern-value"},
+    { 42, "date-value"},
+    { 43, "datetime-pattern-value"},
+    { 44, "datetime-value"},
+    { 45, "integer-value"},
+    { 46, "large-analog-value"},
+    { 47, "octetstring-value"},
+    { 48, "positive-integer-value"},
+    { 49, "time-pattern-value"},
+    { 50, "time-value"},
+    { 0,  NULL}
 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
    Enumerated values 128-1023 may be used by others subject to
    the procedures and constraints described in Clause 23. */
@@ -2576,244 +2780,244 @@ BACnetObjectType [] = {
 
 static const value_string
 BACnetEngineeringUnits [] = {
-       {0,"Sq Meters"},
-       {1,"Sq Feet"},
-       {2,"Milliamperes"},
-       {3,"Amperes"},
-       {4,"Ohms"},
-       {5,"Volts"},
-       {6,"Kilovolts"},
-       {7,"Megavolts"},
-       {8,"Volt Amperes"},
-       {9,"Kilovolt Amperes"},
-       {10,"Megavolt Amperes"},
-       {11,"Volt Amperes Reactive"},
-       {12,"Kilovolt Amperes Reactive"},
-       {13,"Megavolt Amperes Reactive"},
-       {14,"Degrees Phase"},
-       {15,"Power Factor"},
-       {16,"Joules"},
-       {17,"Kilojoules"},
-       {18,"Watt Hours"},
-       {19,"Kilowatt Hours"},
-       {20,"BTUs"},
-       {21,"Therms"},
-       {22,"Ton Hours"},
-       {23,"Joules Per Kg Dry Air"},
-       {24,"BTUs Per Pound Dry Air"},
-       {25,"Cycles Per Hour"},
-       {26,"Cycles Per Minute"},
-       {27,"Hertz"},
-       {28,"Grams Of Water Per Kilogram Dry Air"},
-       {29,"Relative Humidity"},
-       {30,"Millimeters"},
-       {31,"Meters"},
-       {32,"Inches"},
-       {33,"Feed"},
-       {34,"Watts Per Sq Foot"},
-       {35,"Watts Per Sq meter"},
-       {36,"Lumens"},
-       {37,"Lux"},
-       {38,"Foot Candles"},
-       {39,"Kilograms"},
-       {40,"Pounds Mass"},
-       {41,"Tons"},
-       {42,"Kgs per Second"},
-       {43,"Kgs Per Minute"},
-       {44,"Kgs Per Hour"},
-       {45,"Pounds Mass Per Minute"},
-       {46,"Pounds Mass Per Hour"},
-       {47,"Watt"},
-       {48,"Kilowatts"},
-       {49,"Megawatts"},
-       {50,"BTUs Per Hour"},
-       {51,"Horsepower"},
-       {52,"Tons Refrigeration"},
-       {53,"Pascals"},
-       {54,"Kilopascals"},
-       {55,"Bars"},
-       {56,"Pounds Force Per Square Inch"},
-       {57,"Centimeters Of Water"},
-       {58,"Inches Of Water"},
-       {59,"Millimeters Of Mercury"},
-       {60,"Centimeters Of Mercury"},
-       {61,"Inches Of Mercury"},
-       {62,"Degrees Celsius"},
-       {63,"Degrees Kelvin"},
-       {64,"Degrees Fahrenheit"},
-       {65,"Degree Days Celsius"},
-       {66,"Degree Days Fahrenheit"},
-       {67,"Years"},
-       {68,"Months"},
-       {69,"Weeks"},
-       {70,"Days"},
-       {71,"Hours"},
-       {72,"Minutes"},
-       {73,"Seconds"},
-       {74,"Meters Per Second"},
-       {75,"Kilometers Per Hour"},
-       {76,"Feed Per Second"},
-       {77,"Feet Per Minute"},
-       {78,"Miles Per Hour"},
-       {79,"Cubic Feet"},
-       {80,"Cubic Meters"},
-       {81,"Imperial Gallons"},
-       {82,"Liters"},
-       {83,"US Gallons"},
-       {84,"Cubic Feet Per Minute"},
-       {85,"Cubic Meters Per Second"},
-       {86,"Imperial Gallons Per Minute"},
-       {87,"Liters Per Second"},
-       {88,"Liters Per Minute"},
-       {89,"US Gallons Per Minute"},
-       {90,"Degrees Angular"},
-       {91,"Degrees Celsius Per Hour"},
-       {92,"Degrees Celsius Per Minute"},
-       {93,"Degrees Fahrenheit Per Hour"},
-       {94,"Degrees Fahrenheit Per Minute"},
-       {95,"No Units"},
-       {96,"Parts Per Million"},
-       {97,"Parts Per Billion"},
-       {98,"Percent"},
-       {99,"Pecent Per Second"},
-       {100,"Per Minute"},
-       {101,"Per Second"},
-       {102,"Psi Per Degree Fahrenheit"},
-       {103,"Radians"},
-       {104,"Revolutions Per Min"},
-       {105,"Currency1"},
-       {106,"Currency2"},
-       {107,"Currency3"},
-       {108,"Currency4"},
-       {109,"Currency5"},
-       {110,"Currency6"},
-       {111,"Currency7"},
-       {112,"Currency8"},
-       {113,"Currency9"},
-       {114,"Currency10"},
-       {115,"Sq Inches"},
-       {116,"Sq Centimeters"},
-       {117,"BTUs Per Pound"},
-       {118,"Centimeters"},
-       {119,"Pounds Mass Per Second"},
-       {120,"Delta Degrees Fahrenheit"},
-       {121,"Delta Degrees Kelvin"},
-       {122,"Kilohms"},
-       {123,"Megohms"},
-       {124,"Millivolts"},
-       {125,"Kilojoules Per Kg"},
-       {126,"Megajoules"},
-       {127,"Joules Per Degree Kelvin"},
-       {128,"Joules Per Kg Degree Kelvin"},
-       {129,"Kilohertz"},
-       {130,"Megahertz"},
-       {131,"Per Hour"},
-       {132,"Milliwatts"},
-       {133,"Hectopascals"},
-       {134,"Millibars"},
-       {135,"Cubic Meters Per Hour"},
-       {136,"Liters Per Hour"},
-       {137,"KWatt Hours Per Square Meter"},
-       {138,"KWatt Hours Per Square Foot"},
-       {139,"Megajoules Per Square Meter"},
-       {140,"Megajoules Per Square Foot"},
-       {141,"Watts Per Sq Meter Degree Kelvin"},
-       {142,"Cubic Feet Per Second"},
-       {143,"Percent Obstruction Per Foot"},
-       {144,"Percent Obstruction Per Meter"},
-       {145,"milliohms"},
-       {146,"megawatt-hours"},
-       {147,"kilo-btus"},
-       {148,"mega-btus"},
-       {149,"kilojoules-per-kilogram-dry-air"},
-       {150,"megajoules-per-kilogram-dry-air"},
-       {151,"kilojoules-per-degree-Kelvin"},
-       {152,"megajoules-per-degree-Kelvin"},
-       {153,"newton"},
-       {154,"grams-per-second"},
-       {155,"grams-per-minute"},
-       {156,"tons-per-hour"},
-       {157,"kilo-btus-per-hour"},
-       {158,"hundredths-seconds"},
-       {159,"milliseconds"},
-       {160,"newton-meters"},
-       {161,"millimeters-per-second"},
-       {162,"millimeters-per-minute"},
-       {163,"meters-per-minute"},
-       {164,"meters-per-hour"},
-       {165,"cubic-meters-per-minute"},
-       {166,"meters-per-second-per-second"},
-       {167,"amperes-per-meter"},
-       {168,"amperes-per-square-meter"},
-       {169,"ampere-square-meters"},
-       {170,"farads"},
-       {171,"henrys"},
-       {172,"ohm-meters"},
-       {173,"siemens"},
-       {174,"siemens-per-meter"},
-       {175,"teslas"},
-       {176,"volts-per-degree-Kelvin"},
-       {177,"volts-per-meter"},
-       {178,"webers"},
-       {179,"candelas"},
-       {180,"candelas-per-square-meter"},
-       {181,"degrees-Kelvin-per-hour"},
-       {182,"degrees-Kelvin-per-minute"},
-       {183,"joule-seconds"},
-       {184,"radians-per-second"},
-       {185,"square-meters-per-Newton"},
-       {186,"kilograms-per-cubic-meter"},
-       {187,"newton-seconds"},
-       {188,"newtons-per-meter"},
-       {189,"watts-per-meter-per-degree-Kelvin"},
-       {190,"micro-siemens"},
-       {191,"cubic-feet-per-hour"},
-       {192,"us-gallons-per-hour"},
-       {193,"kilometers"},
-       {194,"micrometers"},
-       {195,"grams"},
-       {196,"milligrams"},
-       {197,"milliliters"},
-       {198,"milliliters-per-second"},
-       {199,"decibels"},
-       {200,"decibels-millivolt"},
-       {201,"decibels-volt"},
-       {202,"millisiemens"},
-       {203,"watt-hours-reactive"},
-       {204,"kilowatt-hours-reactive"},
-       {205,"megawatt-hours-reactive"},
-       {206,"millimeters-of-water"},
-       {207,"per-mille"},
-       {208,"grams-per-gram"},
-       {209,"kilograms-per-kilogram"},
-       {210,"grams-per-kilogram"},
-       {211,"milligrams-per-gram"},
-       {212,"milligrams-per-kilogram"},
-       {213,"grams-per-milliliter"},
-       {214,"grams-per-liter"},
-       {215,"milligrams-per-liter"},
-       {216,"micrograms-per-liter"},
-       {217,"grams-per-cubic-meter"},
-       {218,"milligrams-per-cubic-meter"},
-       {219,"micrograms-per-cubic-meter"},
-       {220,"nanograms-per-cubic-meter"},
-       {221,"grams-per-cubic-centimeter"},
-       {222,"becquerels"},
-       {223,"kilobecquerels"},
-       {224,"megabecquerels"},
-       {225,"gray"},
-       {226,"milligray"},
-       {227,"microgray"},
-       {228,"sieverts"},
-       {229,"millisieverts"},
-       {230,"microsieverts"},
-       {231,"microsieverts-per-hour"},
-       {232,"decibels-a"},
-       {233,"nephelometric-turbidity-unit"},
-       {234,"pH"},
-       {235,"grams-per-square-meter"},
-       {236,"minutes-per-degree-kelvin"},
-       {0,NULL}
+    {   0, "Sq Meters"},
+    {   1, "Sq Feet"},
+    {   2, "Milliamperes"},
+    {   3, "Amperes"},
+    {   4, "Ohms"},
+    {   5, "Volts"},
+    {   6, "Kilovolts"},
+    {   7, "Megavolts"},
+    {   8, "Volt Amperes"},
+    {   9, "Kilovolt Amperes"},
+    {  10, "Megavolt Amperes"},
+    {  11, "Volt Amperes Reactive"},
+    {  12, "Kilovolt Amperes Reactive"},
+    {  13, "Megavolt Amperes Reactive"},
+    {  14, "Degrees Phase"},
+    {  15, "Power Factor"},
+    {  16, "Joules"},
+    {  17, "Kilojoules"},
+    {  18, "Watt Hours"},
+    {  19, "Kilowatt Hours"},
+    {  20, "BTUs"},
+    {  21, "Therms"},
+    {  22, "Ton Hours"},
+    {  23, "Joules Per Kg Dry Air"},
+    {  24, "BTUs Per Pound Dry Air"},
+    {  25, "Cycles Per Hour"},
+    {  26, "Cycles Per Minute"},
+    {  27, "Hertz"},
+    {  28, "Grams Of Water Per Kilogram Dry Air"},
+    {  29, "Relative Humidity"},
+    {  30, "Millimeters"},
+    {  31, "Meters"},
+    {  32, "Inches"},
+    {  33, "Feed"},
+    {  34, "Watts Per Sq Foot"},
+    {  35, "Watts Per Sq meter"},
+    {  36, "Lumens"},
+    {  37, "Lux"},
+    {  38, "Foot Candles"},
+    {  39, "Kilograms"},
+    {  40, "Pounds Mass"},
+    {  41, "Tons"},
+    {  42, "Kgs per Second"},
+    {  43, "Kgs Per Minute"},
+    {  44, "Kgs Per Hour"},
+    {  45, "Pounds Mass Per Minute"},
+    {  46, "Pounds Mass Per Hour"},
+    {  47, "Watt"},
+    {  48, "Kilowatts"},
+    {  49, "Megawatts"},
+    {  50, "BTUs Per Hour"},
+    {  51, "Horsepower"},
+    {  52, "Tons Refrigeration"},
+    {  53, "Pascals"},
+    {  54, "Kilopascals"},
+    {  55, "Bars"},
+    {  56, "Pounds Force Per Square Inch"},
+    {  57, "Centimeters Of Water"},
+    {  58, "Inches Of Water"},
+    {  59, "Millimeters Of Mercury"},
+    {  60, "Centimeters Of Mercury"},
+    {  61, "Inches Of Mercury"},
+    {  62, "Degrees Celsius"},
+    {  63, "Degrees Kelvin"},
+    {  64, "Degrees Fahrenheit"},
+    {  65, "Degree Days Celsius"},
+    {  66, "Degree Days Fahrenheit"},
+    {  67, "Years"},
+    {  68, "Months"},
+    {  69, "Weeks"},
+    {  70, "Days"},
+    {  71, "Hours"},
+    {  72, "Minutes"},
+    {  73, "Seconds"},
+    {  74, "Meters Per Second"},
+    {  75, "Kilometers Per Hour"},
+    {  76, "Feed Per Second"},
+    {  77, "Feet Per Minute"},
+    {  78, "Miles Per Hour"},
+    {  79, "Cubic Feet"},
+    {  80, "Cubic Meters"},
+    {  81, "Imperial Gallons"},
+    {  82, "Liters"},
+    {  83, "US Gallons"},
+    {  84, "Cubic Feet Per Minute"},
+    {  85, "Cubic Meters Per Second"},
+    {  86, "Imperial Gallons Per Minute"},
+    {  87, "Liters Per Second"},
+    {  88, "Liters Per Minute"},
+    {  89, "US Gallons Per Minute"},
+    {  90, "Degrees Angular"},
+    {  91, "Degrees Celsius Per Hour"},
+    {  92, "Degrees Celsius Per Minute"},
+    {  93, "Degrees Fahrenheit Per Hour"},
+    {  94, "Degrees Fahrenheit Per Minute"},
+    {  95, "No Units"},
+    {  96, "Parts Per Million"},
+    {  97, "Parts Per Billion"},
+    {  98, "Percent"},
+    {  99, "Pecent Per Second"},
+    { 100, "Per Minute"},
+    { 101, "Per Second"},
+    { 102, "Psi Per Degree Fahrenheit"},
+    { 103, "Radians"},
+    { 104, "Revolutions Per Min"},
+    { 105, "Currency1"},
+    { 106, "Currency2"},
+    { 107, "Currency3"},
+    { 108, "Currency4"},
+    { 109, "Currency5"},
+    { 110, "Currency6"},
+    { 111, "Currency7"},
+    { 112, "Currency8"},
+    { 113, "Currency9"},
+    { 114, "Currency10"},
+    { 115, "Sq Inches"},
+    { 116, "Sq Centimeters"},
+    { 117, "BTUs Per Pound"},
+    { 118, "Centimeters"},
+    { 119, "Pounds Mass Per Second"},
+    { 120, "Delta Degrees Fahrenheit"},
+    { 121, "Delta Degrees Kelvin"},
+    { 122, "Kilohms"},
+    { 123, "Megohms"},
+    { 124, "Millivolts"},
+    { 125, "Kilojoules Per Kg"},
+    { 126, "Megajoules"},
+    { 127, "Joules Per Degree Kelvin"},
+    { 128, "Joules Per Kg Degree Kelvin"},
+    { 129, "Kilohertz"},
+    { 130, "Megahertz"},
+    { 131, "Per Hour"},
+    { 132, "Milliwatts"},
+    { 133, "Hectopascals"},
+    { 134, "Millibars"},
+    { 135, "Cubic Meters Per Hour"},
+    { 136, "Liters Per Hour"},
+    { 137, "KWatt Hours Per Square Meter"},
+    { 138, "KWatt Hours Per Square Foot"},
+    { 139, "Megajoules Per Square Meter"},
+    { 140, "Megajoules Per Square Foot"},
+    { 141, "Watts Per Sq Meter Degree Kelvin"},
+    { 142, "Cubic Feet Per Second"},
+    { 143, "Percent Obstruction Per Foot"},
+    { 144, "Percent Obstruction Per Meter"},
+    { 145, "milliohms"},
+    { 146, "megawatt-hours"},
+    { 147, "kilo-btus"},
+    { 148, "mega-btus"},
+    { 149, "kilojoules-per-kilogram-dry-air"},
+    { 150, "megajoules-per-kilogram-dry-air"},
+    { 151, "kilojoules-per-degree-Kelvin"},
+    { 152, "megajoules-per-degree-Kelvin"},
+    { 153, "newton"},
+    { 154, "grams-per-second"},
+    { 155, "grams-per-minute"},
+    { 156, "tons-per-hour"},
+    { 157, "kilo-btus-per-hour"},
+    { 158, "hundredths-seconds"},
+    { 159, "milliseconds"},
+    { 160, "newton-meters"},
+    { 161, "millimeters-per-second"},
+    { 162, "millimeters-per-minute"},
+    { 163, "meters-per-minute"},
+    { 164, "meters-per-hour"},
+    { 165, "cubic-meters-per-minute"},
+    { 166, "meters-per-second-per-second"},
+    { 167, "amperes-per-meter"},
+    { 168, "amperes-per-square-meter"},
+    { 169, "ampere-square-meters"},
+    { 170, "farads"},
+    { 171, "henrys"},
+    { 172, "ohm-meters"},
+    { 173, "siemens"},
+    { 174, "siemens-per-meter"},
+    { 175, "teslas"},
+    { 176, "volts-per-degree-Kelvin"},
+    { 177, "volts-per-meter"},
+    { 178, "webers"},
+    { 179, "candelas"},
+    { 180, "candelas-per-square-meter"},
+    { 181, "degrees-Kelvin-per-hour"},
+    { 182, "degrees-Kelvin-per-minute"},
+    { 183, "joule-seconds"},
+    { 184, "radians-per-second"},
+    { 185, "square-meters-per-Newton"},
+    { 186, "kilograms-per-cubic-meter"},
+    { 187, "newton-seconds"},
+    { 188, "newtons-per-meter"},
+    { 189, "watts-per-meter-per-degree-Kelvin"},
+    { 190, "micro-siemens"},
+    { 191, "cubic-feet-per-hour"},
+    { 192, "us-gallons-per-hour"},
+    { 193, "kilometers"},
+    { 194, "micrometers"},
+    { 195, "grams"},
+    { 196, "milligrams"},
+    { 197, "milliliters"},
+    { 198, "milliliters-per-second"},
+    { 199, "decibels"},
+    { 200, "decibels-millivolt"},
+    { 201, "decibels-volt"},
+    { 202, "millisiemens"},
+    { 203, "watt-hours-reactive"},
+    { 204, "kilowatt-hours-reactive"},
+    { 205, "megawatt-hours-reactive"},
+    { 206, "millimeters-of-water"},
+    { 207, "per-mille"},
+    { 208, "grams-per-gram"},
+    { 209, "kilograms-per-kilogram"},
+    { 210, "grams-per-kilogram"},
+    { 211, "milligrams-per-gram"},
+    { 212, "milligrams-per-kilogram"},
+    { 213, "grams-per-milliliter"},
+    { 214, "grams-per-liter"},
+    { 215, "milligrams-per-liter"},
+    { 216, "micrograms-per-liter"},
+    { 217, "grams-per-cubic-meter"},
+    { 218, "milligrams-per-cubic-meter"},
+    { 219, "micrograms-per-cubic-meter"},
+    { 220, "nanograms-per-cubic-meter"},
+    { 221, "grams-per-cubic-centimeter"},
+    { 222, "becquerels"},
+    { 223, "kilobecquerels"},
+    { 224, "megabecquerels"},
+    { 225, "gray"},
+    { 226, "milligray"},
+    { 227, "microgray"},
+    { 228, "sieverts"},
+    { 229, "millisieverts"},
+    { 230, "microsieverts"},
+    { 231, "microsieverts-per-hour"},
+    { 232, "decibels-a"},
+    { 233, "nephelometric-turbidity-unit"},
+    { 234, "pH"},
+    { 235, "grams-per-square-meter"},
+    { 236, "minutes-per-degree-kelvin"},
+    { 0,   NULL}
 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
    Enumerated values 256-65535 may be used by others subject to
    the procedures and constraints described in Clause 23. */
@@ -2821,122 +3025,122 @@ BACnetEngineeringUnits [] = {
 
 static const value_string
 BACnetErrorCode [] = {
-       {0,"other"},
-       {1,"authentication-failed"},
-       {2,"configuration-in-progress"},
-       {3,"device-busy"},
-       {4,"dynamic-creation-not-supported"},
-       {5,"file-access-denied"},
-       {6,"incompatible-security-levels"},
-       {7,"inconsistent-parameters"},
-       {8,"inconsistent-selection-criterion"},
-       {9,"invalid-data-type"},
-       {10,"invalid-file-access-method"},
-       {11,"invalid-file-start-position"},
-       {12,"invalid-operator-name"},
-       {13,"invalid-parameter-data-type"},
-       {14,"invalid-time-stamp"},
-       {15,"key-generation-error"},
-       {16,"missing-required-parameter"},
-       {17,"no-objects-of-specified-type"},
-       {18,"no-space-for-object"},
-       {19,"no-space-to-add-list-element"},
-       {20,"no-space-to-write-property"},
-       {21,"no-vt-sessions-available"},
-       {22,"property-is-not-a-list"},
-       {23,"object-deletion-not-permitted"},
-       {24,"object-identifier-already-exists"},
-       {25,"operational-problem"},
-       {26,"password-failure"},
-       {27,"read-access-denied"},
-       {28,"security-not-supported"},
-       {29,"service-request-denied"},
-       {30,"timeout"},
-       {31,"unknown-object"},
-       {32,"unknown-property"},
-       {33,"removed enumeration"},
-       {34,"unknown-vt-class"},
-       {35,"unknown-vt-session"},
-       {36,"unsupported-object-type"},
-       {37,"value-out-of-range"},
-       {38,"vt-session-already-closed"},
-       {39,"vt-session-termination-failure"},
-       {40,"write-access-denied"},
-       {41,"character-set-not-supported"},
-       {42,"invalid-array-index"},
-       {43,"cov-subscription-failed"},
-       {44,"not-cov-property"},
-       {45,"optional-functionality-not-supported"},
-       {46,"invalid-configuration-data"},
-       {47,"datatype-not-supported"},
-       {48,"duplicate-name"},
-       {49,"duplicate-object-id"},
-       {50,"property-is-not-an-array"},
-       {73,"invalid-event-state"},
-       {74,"no-alarm-configured"},
-       {75,"log-buffer-full"},
-       {76,"logged-value-purged"},
-       {77,"no-property-specified"},
-       {78,"not-configured-for-triggered-logging"},
-       {79,"unknown-subscription"},
-       {80,"parameter-out-of-range"},
-       {81,"list-element-not-found"},
-       {82,"busy"},
-       {83,"communication-disabled"},
-       {84,"success"},
-       {85,"access-denied"},
-       {86,"bad-destination-address"},
-       {87,"bad-destination-device-id"},
-       {88,"bad-signature"},
-       {89,"bad-source-address"},
-       {90,"bad-timestamp"},
-       {91,"cannot-use-key"},
-       {92,"cannot-verify-message-id"},
-       {93,"correct-key-revision"},
-       {94,"destination-device-id-required"},
-       {95,"duplicate-message"},
-       {96,"encryption-not-configured"},
-       {97,"encryption-required"},
-       {98,"incorrect-key"},
-       {99,"invalid-key-data"},
-       {100,"key-update-in-progress"},
-       {101,"malformed-message"},
-       {102,"not-key-server"},
-       {103,"security-not-configured"},
-       {104,"source-security-required"},
-       {105,"too-many-keys"},
-       {106,"unknown-authentication-type"},
-       {107,"unknown-key"},
-       {108,"unknown-key-revision"},
-       {109,"unknown-source-message"},
-       {110,"not-router-to-dnet"},
-       {111,"router-busy"},
-       {112,"unknown-network-message"},
-       {113,"message-too-long"},
-       {114,"security-error"},
-       {115,"addressing-error"},
-       {116,"write-bdt-failed"},
-       {117,"read-bdt-failed"},
-       {118,"register-foreign-device-failed"},
-       {119,"read-fdt-failed"},
-       {120,"delete-fdt-entry-failed"},
-       {121,"distribute-broadcast-failed"},
-       {122,"unknown-file-size"},
-       {123,"abort-apdu-too-long"},
-       {124,"abort-application-exceeded-reply-time"},
-       {125,"abort-out-of-resources"},
-       {126,"abort-tsm-timeout"},
-       {127,"abort-window-size-out-of-range"},
-       {128,"file-full"},
-       {129,"inconsistent-configuration"},
-       {130,"inconsistent-object-type"},
-       {131,"internal-error"},
-       {132,"not-configured"},
-       {133,"out-of-memory"},
-       {134,"value-too-long"},
-       {135,"abort-insufficient-security"},
-       {136,"abort-security-error"},
-       {0, NULL}
+    {   0, "other"},
+    {   1, "authentication-failed"},
+    {   2, "configuration-in-progress"},
+    {   3, "device-busy"},
+    {   4, "dynamic-creation-not-supported"},
+    {   5, "file-access-denied"},
+    {   6, "incompatible-security-levels"},
+    {   7, "inconsistent-parameters"},
+    {   8, "inconsistent-selection-criterion"},
+    {   9, "invalid-data-type"},
+    {  10, "invalid-file-access-method"},
+    {  11, "invalid-file-start-position"},
+    {  12, "invalid-operator-name"},
+    {  13, "invalid-parameter-data-type"},
+    {  14, "invalid-time-stamp"},
+    {  15, "key-generation-error"},
+    {  16, "missing-required-parameter"},
+    {  17, "no-objects-of-specified-type"},
+    {  18, "no-space-for-object"},
+    {  19, "no-space-to-add-list-element"},
+    {  20, "no-space-to-write-property"},
+    {  21, "no-vt-sessions-available"},
+    {  22, "property-is-not-a-list"},
+    {  23, "object-deletion-not-permitted"},
+    {  24, "object-identifier-already-exists"},
+    {  25, "operational-problem"},
+    {  26, "password-failure"},
+    {  27, "read-access-denied"},
+    {  28, "security-not-supported"},
+    {  29, "service-request-denied"},
+    {  30, "timeout"},
+    {  31, "unknown-object"},
+    {  32, "unknown-property"},
+    {  33, "removed enumeration"},
+    {  34, "unknown-vt-class"},
+    {  35, "unknown-vt-session"},
+    {  36, "unsupported-object-type"},
+    {  37, "value-out-of-range"},
+    {  38, "vt-session-already-closed"},
+    {  39, "vt-session-termination-failure"},
+    {  40, "write-access-denied"},
+    {  41, "character-set-not-supported"},
+    {  42, "invalid-array-index"},
+    {  43, "cov-subscription-failed"},
+    {  44, "not-cov-property"},
+    {  45, "optional-functionality-not-supported"},
+    {  46, "invalid-configuration-data"},
+    {  47, "datatype-not-supported"},
+    {  48, "duplicate-name"},
+    {  49, "duplicate-object-id"},
+    {  50, "property-is-not-an-array"},
+    {  73, "invalid-event-state"},
+    {  74, "no-alarm-configured"},
+    {  75, "log-buffer-full"},
+    {  76, "logged-value-purged"},
+    {  77, "no-property-specified"},
+    {  78, "not-configured-for-triggered-logging"},
+    {  79, "unknown-subscription"},
+    {  80, "parameter-out-of-range"},
+    {  81, "list-element-not-found"},
+    {  82, "busy"},
+    {  83, "communication-disabled"},
+    {  84, "success"},
+    {  85, "access-denied"},
+    {  86, "bad-destination-address"},
+    {  87, "bad-destination-device-id"},
+    {  88, "bad-signature"},
+    {  89, "bad-source-address"},
+    {  90, "bad-timestamp"},
+    {  91, "cannot-use-key"},
+    {  92, "cannot-verify-message-id"},
+    {  93, "correct-key-revision"},
+    {  94, "destination-device-id-required"},
+    {  95, "duplicate-message"},
+    {  96, "encryption-not-configured"},
+    {  97, "encryption-required"},
+    {  98, "incorrect-key"},
+    {  99, "invalid-key-data"},
+    { 100, "key-update-in-progress"},
+    { 101, "malformed-message"},
+    { 102, "not-key-server"},
+    { 103, "security-not-configured"},
+    { 104, "source-security-required"},
+    { 105, "too-many-keys"},
+    { 106, "unknown-authentication-type"},
+    { 107, "unknown-key"},
+    { 108, "unknown-key-revision"},
+    { 109, "unknown-source-message"},
+    { 110, "not-router-to-dnet"},
+    { 111, "router-busy"},
+    { 112, "unknown-network-message"},
+    { 113, "message-too-long"},
+    { 114, "security-error"},
+    { 115, "addressing-error"},
+    { 116, "write-bdt-failed"},
+    { 117, "read-bdt-failed"},
+    { 118, "register-foreign-device-failed"},
+    { 119, "read-fdt-failed"},
+    { 120, "delete-fdt-entry-failed"},
+    { 121, "distribute-broadcast-failed"},
+    { 122, "unknown-file-size"},
+    { 123, "abort-apdu-too-long"},
+    { 124, "abort-application-exceeded-reply-time"},
+    { 125, "abort-out-of-resources"},
+    { 126, "abort-tsm-timeout"},
+    { 127, "abort-window-size-out-of-range"},
+    { 128, "file-full"},
+    { 129, "inconsistent-configuration"},
+    { 130, "inconsistent-object-type"},
+    { 131, "internal-error"},
+    { 132, "not-configured"},
+    { 133, "out-of-memory"},
+    { 134, "value-too-long"},
+    { 135, "abort-insufficient-security"},
+    { 136, "abort-security-error"},
+    { 0,   NULL}
 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
    Enumerated values 256-65535 may be used by others subject to the
    procedures and constraints described in Clause 23. */
@@ -2944,345 +3148,345 @@ BACnetErrorCode [] = {
 
 static const value_string
 BACnetPropertyIdentifier [] = {
-       {0,"acked-transition"},
-       {1,"ack-required"},
-       {2,"action"},
-       {3,"action-text"},
-       {4,"active-text"},
-       {5,"active-vt-session"},
-       {6,"alarm-value"},
-       {7,"alarm-values"},
-       {8,"all"},
-       {9,"all-write-successful"},
-       {10,"apdu-segment-timeout"},
-       {11,"apdu-timeout"},
-       {12,"application-software-version"},
-       {13,"archive"},
-       {14,"bias"},
-       {15,"change-of-state-count"},
-       {16,"change-of-state-time"},
-       {17,"notification-class"},
-       {18,"the property in this place was deleted"},
-       {19,"controlled-variable-reference"},
-       {20,"controlled-variable-units"},
-       {21,"controlled-variable-value"},
-       {22,"cov-increment"},
-       {23,"datelist"},
-       {24,"daylights-savings-status"},
-       {25,"deadband"},
-       {26,"derivative-constant"},
-       {27,"derivative-constant-units"},
-       {28,"description"},
-       {29,"description-of-halt"},
-       {30,"device-address-binding"},
-       {31,"device-type"},
-       {32,"effective-period"},
-       {33,"elapsed-active-time"},
-       {34,"error-limit"},
-       {35,"event-enable"},
-       {36,"event-state"},
-       {37,"event-type"},
-       {38,"exception-schedule"},
-       {39,"fault-values"},
-       {40,"feedback-value"},
-       {41,"file-access-method"},
-       {42,"file-size"},
-       {43,"file-type"},
-       {44,"firmware-revision"},
-       {45,"high-limit"},
-       {46,"inactive-text"},
-       {47,"in-progress"},
-       {48,"instance-of"},
-       {49,"integral-constant"},
-       {50,"integral-constant-units"},
-       {51,"issue-confirmed-notifications"},
-       {52,"limit-enable"},
-       {53,"list-of-group-members"},
-       {54,"list-of-object-property-references"},
-       {55,"list-of-session-keys"},
-       {56,"local-date"},
-       {57,"local-time"},
-       {58,"location"},
-       {59,"low-limit"},
-       {60,"manipulated-variable-reference"},
-       {61,"maximum-output"},
-       {62,"max-apdu-length-accepted"},
-       {63,"max-info-frames"},
-       {64,"max-master"},
-       {65,"max-pres-value"},
-       {66,"minimum-off-time"},
-       {67,"minimum-on-time"},
-       {68,"minimum-output"},
-       {69,"min-pres-value"},
-       {70,"model-name"},
-       {71,"modification-date"},
-       {72,"notify-type"},
-       {73,"number-of-APDU-retries"},
-       {74,"number-of-states"},
-       {75,"object-identifier"},
-       {76,"object-list"},
-       {77,"object-name"},
-       {78,"object-property-reference"},
-       {79,"object-type"},
-       {80,"optional"},
-       {81,"out-of-service"},
-       {82,"output-units"},
-       {83,"event-parameters"},
-       {84,"polarity"},
-       {85,"present-value"},
-       {86,"priority"},
-       {87,"priority-array"},
-       {88,"priority-for-writing"},
-       {89,"process-identifier"},
-       {90,"program-change"},
-       {91,"program-location"},
-       {92,"program-state"},
-       {93,"proportional-constant"},
-       {94,"proportional-constant-units"},
-       {95,"protocol-conformance-class"},
-       {96,"protocol-object-types-supported"},
-       {97,"protocol-services-supported"},
-       {98,"protocol-version"},
-       {99,"read-only"},
-       {100,"reason-for-halt"},
-       {101,"recipient"},
-       {102,"recipient-list"},
-       {103,"reliability"},
-       {104,"relinquish-default"},
-       {105,"required"},
-       {106,"resolution"},
-       {107,"segmentation-supported"},
-       {108,"setpoint"},
-       {109,"setpoint-reference"},
-       {110,"state-text"},
-       {111,"status-flags"},
-       {112,"system-status"},
-       {113,"time-delay"},
-       {114,"time-of-active-time-reset"},
-       {115,"time-of-state-count-reset"},
-       {116,"time-synchronization-recipients"},
-       {117,"units"},
-       {118,"update-interval"},
-       {119,"utc-offset"},
-       {120,"vendor-identifier"},
-       {121,"vendor-name"},
-       {122,"vt-class-supported"},
-       {123,"weekly-schedule"},
-       {124,"attempted-samples"},
-       {125,"average-value"},
-       {126,"buffer-size"},
-       {127,"client-cov-increment"},
-       {128,"cov-resubscription-interval"},
-       {129,"current-notify-time"},
-       {130,"event-time-stamp"},
-       {131,"log-buffer"},
-       {132,"log-device-object-property"},
-       {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
-       {134,"log-interval"},
-       {135,"maximum-value"},
-       {136,"minimum-value"},
-       {137,"notification-threshold"},
-       {138,"previous-notify-time"},
-       {139,"protocol-revision"},
-       {140,"records-since-notification"},
-       {141,"record-count"},
-       {142,"start-time"},
-       {143,"stop-time"},
-       {144,"stop-when-full"},
-       {145,"total-record-count"},
-       {146,"valid-samples"},
-       {147,"window-interval"},
-       {148,"window-samples"},
-       {149,"maximum-value-time-stamp"},
-       {150,"minimum-value-time-stamp"},
-       {151,"variance-value"},
-       {152,"active-cov-subscriptions"},
-       {153,"backup-failure-timeout"},
-       {154,"configuration-files"},
-       {155,"database-revision"},
-       {156,"direct-reading"},
-       {157,"last-restore-time"},
-       {158,"maintenance-required"},
-       {159,"member-of"},
-       {160,"mode"},
-       {161,"operation-expected"},
-       {162,"setting"},
-       {163,"silenced"},
-       {164,"tracking-value"},
-       {165,"zone-members"},
-       {166,"life-safety-alarm-values"},
-       {167,"max-segments-accepted"},
-       {168,"profile-name"},
-       {169,"auto-slave-discovery"},
-       {170,"manual-slave-address-binding"},
-       {171,"slave-address-binding"},
-       {172,"slave-proxy-enable"},
-       {173,"last-notify-record"},             /* bug 4117 */
-       {174,"schedule-default"},
-       {175,"accepted-modes"},
-       {176,"adjust-value"},
-       {177,"count"},
-       {178,"count-before-change"},
-       {179,"count-change-time"},
-       {180,"cov-period"},
-       {181,"input-reference"},
-       {182,"limit-monitoring-interval"},
-       {183,"logging-device"},
-       {184,"logging-record"},
-       {185,"prescale"},
-       {186,"pulse-rate"},
-       {187,"scale"},
-       {188,"scale-factor"},
-       {189,"update-time"},
-       {190,"value-before-change"},
-       {191,"value-set"},
-       {192,"value-change-time"},
-       {193,"align-intervals"},
-       {194,"group-member-names"},
-       {195,"interval-offset"},
-       {196,"last-restart-reason"},
-       {197,"logging-type"},
-       {198,"member-status-flags"},
-       {199,"notification-period"},
-       {200,"previous-notify-record"},
-       {201,"requested-update-interval"},
-       {202,"restart-notification-recipients"},
-       {203,"time-of-device-restart"},
-       {204,"time-synchronization-interval"},
-       {205,"trigger"},
-       {206,"UTC-time-synchronization-recipients"},
-       {207,"node-subtype"},
-       {208,"node-type"},
-       {209,"structured-object-list"},
-       {210,"subordinate-annotations"},
-       {211,"subordinate-list"},
-       {212,"actual-shed-level"},
-       {213,"duty-window"},
-       {214,"expected-shed-level"},
-       {215,"full-duty-baseline"},
-       {216,"node-subtype"},
-       {217,"node-type"},
-       {218,"requested-shed-level"},
-       {219,"shed-duration"},
-       {220,"shed-level-descriptions"},
-       {221,"shed-levels"},
-       {222,"state-description"},
-       /* enumeration values 223-225 are unassigned */
-       {226,"door-alarm-state"},
-       {227,"door-extended-pulse-time"},
-       {228,"door-members"},
-       {229,"door-open-too-long-time"},
-       {230,"door-pulse-time"},
-       {231,"door-status"},
-       {232,"door-unlock-delay-time"},
-       {233,"lock-status"},
-       {234,"masked-alarm-values"},
-       {235,"secured-status"},
-       /* enumeration values 236-243 are unassigned */
-       {244,"absentee-limit"},         /* added with addenda 135-2008j */
-       {245,"access-alarm-events"},
-       {246,"access-doors"},
-       {247,"access-event"},
-       {248,"access-event-authentication-factor"},
-       {249,"access-event-credential"},
-       {250,"access-event-time"},
-       {251,"access-transaction-events"},
-       {252,"accompaniment"},
-       {253,"accompaniment-time"},
-       {254,"activation-time"},
-       {255,"active-authentication-policy"},
-       {256,"assigned-access-rights"},
-       {257,"authentication-factors"},
-       {258,"authentication-policy-list"},
-       {259,"authentication-policy-names"},
-       {260,"authentication-status"},
-       {261,"authorization-mode"},
-       {262,"belongs-to"},
-       {263,"credential-disable"},
-       {264,"credential-status"},
-       {265,"credentials"},
-       {266,"credentials-in-zone"},
-       {267,"days-remaining"},
-       {268,"entry-points"},
-       {269,"exit-points"},
-       {270,"expiry-time"},
-       {271,"extended-time-enable"},
-       {272,"failed-attempt-events"},
-       {273,"failed-attempts"},
-       {274,"failed-attempts-time"},
-       {275,"last-access-event"},
-       {276,"last-access-point"},
-       {277,"last-credential-added"},
-       {278,"last-credential-added-time"},
-       {279,"last-credential-removed"},
-       {280,"last-credential-removed-time"},
-       {281,"last-use-time"},
-       {282,"lockout"},
-       {283,"lockout-relinquish-time"},
-       {284,"master-exemption"},
-       {285,"max-failed-attempts"},
-       {286,"members"},
-       {287,"muster-point"},
-       {288,"negative-access-rules"},
-       {289,"number-of-authentication-policies"},
-       {290,"occupancy-count"},
-       {291,"occupancy-count-adjust"},
-       {292,"occupancy-count-enable"},
-       {293,"occupancy-exemption"},
-       {294,"occupancy-lower-limit"},
-       {295,"occupancy-lower-limit-enforced"},
-       {296,"occupancy-state"},
-       {297,"occupancy-upper-limit"},
-       {298,"occupancy-upper-limit-enforced"},
-       {299,"passback-exemption"},
-       {300,"passback-mode"},
-       {301,"passback-timeout"},
-       {302,"positive-access-rules"},
-       {303,"reason-for-disable"},
-       {304,"supported-formats"},
-       {305,"supported-format-classes"},
-       {306,"threat-authority"},
-       {307,"threat-level"},
-       {308,"trace-flag"},
-       {309,"transaction-notification-class"},
-       {310,"user-external-identifier"},
-       {311,"user-information-reference"},
-       /* enumeration values 312-316 are unassigned */
-       {317,"user-name"},
-       {318,"user-type"},
-       {319,"uses-remaining"},
-       {320,"zone-from"},
-       {321,"zone-to"},
-       {322,"access-event-tag"},
-       {323,"global-identifier"},
-       /* enumeration values 324-325 reserved for future addenda */
-       {326,"verification-time"},
-       {327,"base-device-security-policy"},
-       {328,"distribution-key-revision"},
-       {329,"do-not-hide"},
-       {330,"key-sets"},
-       {331,"last-key-server"},
-       {332,"network-access-security-policies"},
-       {333,"packet-reorder-time"},
-       {334,"security-pdu-timeout"},
-       {335,"security-time-window"},
-       {336,"supported-security-algorithms"},
-       {337,"update-key-set-timeout"},
-       {338,"backup-and-restore-state"},
-       {339,"backup-preparation-time"},
-       {340,"restore-completion-time"},
-       {341,"restore-preparation-time"},
-       {342,"bit-mask"},               /* addenda 135-2008w */
-       {343,"bit-text"},
-       {344,"is-utc"},
-       {345,"group-members"},
-       {346,"group-member-names"},
-       {347,"member-status-flags"},
-       {348,"requested-update-interval"},
-       {349,"covu-period"},
-       {350,"covu-recipients"},
-       {351,"event-message-texts"},
-       {0, NULL}
+    {   0, "acked-transition"},
+    {   1, "ack-required"},
+    {   2, "action"},
+    {   3, "action-text"},
+    {   4, "active-text"},
+    {   5, "active-vt-session"},
+    {   6, "alarm-value"},
+    {   7, "alarm-values"},
+    {   8, "all"},
+    {   9, "all-writes-successful"},
+    {  10, "apdu-segment-timeout"},
+    {  11, "apdu-timeout"},
+    {  12, "application-software-version"},
+    {  13, "archive"},
+    {  14, "bias"},
+    {  15, "change-of-state-count"},
+    {  16, "change-of-state-time"},
+    {  17, "notification-class"},
+    {  18, "the property in this place was deleted"},
+    {  19, "controlled-variable-reference"},
+    {  20, "controlled-variable-units"},
+    {  21, "controlled-variable-value"},
+    {  22, "cov-increment"},
+    {  23, "datelist"},
+    {  24, "daylights-savings-status"},
+    {  25, "deadband"},
+    {  26, "derivative-constant"},
+    {  27, "derivative-constant-units"},
+    {  28, "description"},
+    {  29, "description-of-halt"},
+    {  30, "device-address-binding"},
+    {  31, "device-type"},
+    {  32, "effective-period"},
+    {  33, "elapsed-active-time"},
+    {  34, "error-limit"},
+    {  35, "event-enable"},
+    {  36, "event-state"},
+    {  37, "event-type"},
+    {  38, "exception-schedule"},
+    {  39, "fault-values"},
+    {  40, "feedback-value"},
+    {  41, "file-access-method"},
+    {  42, "file-size"},
+    {  43, "file-type"},
+    {  44, "firmware-revision"},
+    {  45, "high-limit"},
+    {  46, "inactive-text"},
+    {  47, "in-process"},
+    {  48, "instance-of"},
+    {  49, "integral-constant"},
+    {  50, "integral-constant-units"},
+    {  51, "issue-confirmed-notifications"},
+    {  52, "limit-enable"},
+    {  53, "list-of-group-members"},
+    {  54, "list-of-object-property-references"},
+    {  55, "list-of-session-keys"},
+    {  56, "local-date"},
+    {  57, "local-time"},
+    {  58, "location"},
+    {  59, "low-limit"},
+    {  60, "manipulated-variable-reference"},
+    {  61, "maximum-output"},
+    {  62, "max-apdu-length-accepted"},
+    {  63, "max-info-frames"},
+    {  64, "max-master"},
+    {  65, "max-pres-value"},
+    {  66, "minimum-off-time"},
+    {  67, "minimum-on-time"},
+    {  68, "minimum-output"},
+    {  69, "min-pres-value"},
+    {  70, "model-name"},
+    {  71, "modification-date"},
+    {  72, "notify-type"},
+    {  73, "number-of-APDU-retries"},
+    {  74, "number-of-states"},
+    {  75, "object-identifier"},
+    {  76, "object-list"},
+    {  77, "object-name"},
+    {  78, "object-property-reference"},
+    {  79, "object-type"},
+    {  80, "optional"},
+    {  81, "out-of-service"},
+    {  82, "output-units"},
+    {  83, "event-parameters"},
+    {  84, "polarity"},
+    {  85, "present-value"},
+    {  86, "priority"},
+    {  87, "priority-array"},
+    {  88, "priority-for-writing"},
+    {  89, "process-identifier"},
+    {  90, "program-change"},
+    {  91, "program-location"},
+    {  92, "program-state"},
+    {  93, "proportional-constant"},
+    {  94, "proportional-constant-units"},
+    {  95, "protocol-conformance-class"},
+    {  96, "protocol-object-types-supported"},
+    {  97, "protocol-services-supported"},
+    {  98, "protocol-version"},
+    {  99, "read-only"},
+    { 100, "reason-for-halt"},
+    { 101, "recipient"},
+    { 102, "recipient-list"},
+    { 103, "reliability"},
+    { 104, "relinquish-default"},
+    { 105, "required"},
+    { 106, "resolution"},
+    { 107, "segmentation-supported"},
+    { 108, "setpoint"},
+    { 109, "setpoint-reference"},
+    { 110, "state-text"},
+    { 111, "status-flags"},
+    { 112, "system-status"},
+    { 113, "time-delay"},
+    { 114, "time-of-active-time-reset"},
+    { 115, "time-of-state-count-reset"},
+    { 116, "time-synchronization-recipients"},
+    { 117, "units"},
+    { 118, "update-interval"},
+    { 119, "utc-offset"},
+    { 120, "vendor-identifier"},
+    { 121, "vendor-name"},
+    { 122, "vt-class-supported"},
+    { 123, "weekly-schedule"},
+    { 124, "attempted-samples"},
+    { 125, "average-value"},
+    { 126, "buffer-size"},
+    { 127, "client-cov-increment"},
+    { 128, "cov-resubscription-interval"},
+    { 129, "current-notify-time"},
+    { 130, "event-time-stamp"},
+    { 131, "log-buffer"},
+    { 132, "log-device-object-property"},
+    { 133, "enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
+    { 134, "log-interval"},
+    { 135, "maximum-value"},
+    { 136, "minimum-value"},
+    { 137, "notification-threshold"},
+    { 138, "previous-notify-time"},
+    { 139, "protocol-revision"},
+    { 140, "records-since-notification"},
+    { 141, "record-count"},
+    { 142, "start-time"},
+    { 143, "stop-time"},
+    { 144, "stop-when-full"},
+    { 145, "total-record-count"},
+    { 146, "valid-samples"},
+    { 147, "window-interval"},
+    { 148, "window-samples"},
+    { 149, "maximum-value-time-stamp"},
+    { 150, "minimum-value-time-stamp"},
+    { 151, "variance-value"},
+    { 152, "active-cov-subscriptions"},
+    { 153, "backup-failure-timeout"},
+    { 154, "configuration-files"},
+    { 155, "database-revision"},
+    { 156, "direct-reading"},
+    { 157, "last-restore-time"},
+    { 158, "maintenance-required"},
+    { 159, "member-of"},
+    { 160, "mode"},
+    { 161, "operation-expected"},
+    { 162, "setting"},
+    { 163, "silenced"},
+    { 164, "tracking-value"},
+    { 165, "zone-members"},
+    { 166, "life-safety-alarm-values"},
+    { 167, "max-segments-accepted"},
+    { 168, "profile-name"},
+    { 169, "auto-slave-discovery"},
+    { 170, "manual-slave-address-binding"},
+    { 171, "slave-address-binding"},
+    { 172, "slave-proxy-enable"},
+    { 173, "last-notify-record"},     /* bug 4117 */
+    { 174, "schedule-default"},
+    { 175, "accepted-modes"},
+    { 176, "adjust-value"},
+    { 177, "count"},
+    { 178, "count-before-change"},
+    { 179, "count-change-time"},
+    { 180, "cov-period"},
+    { 181, "input-reference"},
+    { 182, "limit-monitoring-interval"},
+    { 183, "logging-device"},
+    { 184, "logging-record"},
+    { 185, "prescale"},
+    { 186, "pulse-rate"},
+    { 187, "scale"},
+    { 188, "scale-factor"},
+    { 189, "update-time"},
+    { 190, "value-before-change"},
+    { 191, "value-set"},
+    { 192, "value-change-time"},
+    { 193, "align-intervals"},
+    { 194, "group-member-names"},
+    { 195, "interval-offset"},
+    { 196, "last-restart-reason"},
+    { 197, "logging-type"},
+    { 198, "member-status-flags"},
+    { 199, "notification-period"},
+    { 200, "previous-notify-record"},
+    { 201, "requested-update-interval"},
+    { 202, "restart-notification-recipients"},
+    { 203, "time-of-device-restart"},
+    { 204, "time-synchronization-interval"},
+    { 205, "trigger"},
+    { 206, "UTC-time-synchronization-recipients"},
+    { 207, "node-subtype"},
+    { 208, "node-type"},
+    { 209, "structured-object-list"},
+    { 210, "subordinate-annotations"},
+    { 211, "subordinate-list"},
+    { 212, "actual-shed-level"},
+    { 213, "duty-window"},
+    { 214, "expected-shed-level"},
+    { 215, "full-duty-baseline"},
+    { 216, "node-subtype"},
+    { 217, "node-type"},
+    { 218, "requested-shed-level"},
+    { 219, "shed-duration"},
+    { 220, "shed-level-descriptions"},
+    { 221, "shed-levels"},
+    { 222, "state-description"},
+    /* enumeration values 223-225 are unassigned */
+    { 226, "door-alarm-state"},
+    { 227, "door-extended-pulse-time"},
+    { 228, "door-members"},
+    { 229, "door-open-too-long-time"},
+    { 230, "door-pulse-time"},
+    { 231, "door-status"},
+    { 232, "door-unlock-delay-time"},
+    { 233, "lock-status"},
+    { 234, "masked-alarm-values"},
+    { 235, "secured-status"},
+    /* enumeration values 236-243 are unassigned */
+    { 244, "absentee-limit"},     /* added with addenda 135-2008j */
+    { 245, "access-alarm-events"},
+    { 246, "access-doors"},
+    { 247, "access-event"},
+    { 248, "access-event-authentication-factor"},
+    { 249, "access-event-credential"},
+    { 250, "access-event-time"},
+    { 251, "access-transaction-events"},
+    { 252, "accompaniment"},
+    { 253, "accompaniment-time"},
+    { 254, "activation-time"},
+    { 255, "active-authentication-policy"},
+    { 256, "assigned-access-rights"},
+    { 257, "authentication-factors"},
+    { 258, "authentication-policy-list"},
+    { 259, "authentication-policy-names"},
+    { 260, "authentication-status"},
+    { 261, "authorization-mode"},
+    { 262, "belongs-to"},
+    { 263, "credential-disable"},
+    { 264, "credential-status"},
+    { 265, "credentials"},
+    { 266, "credentials-in-zone"},
+    { 267, "days-remaining"},
+    { 268, "entry-points"},
+    { 269, "exit-points"},
+    { 270, "expiry-time"},
+    { 271, "extended-time-enable"},
+    { 272, "failed-attempt-events"},
+    { 273, "failed-attempts"},
+    { 274, "failed-attempts-time"},
+    { 275, "last-access-event"},
+    { 276, "last-access-point"},
+    { 277, "last-credential-added"},
+    { 278, "last-credential-added-time"},
+    { 279, "last-credential-removed"},
+    { 280, "last-credential-removed-time"},
+    { 281, "last-use-time"},
+    { 282, "lockout"},
+    { 283, "lockout-relinquish-time"},
+    { 284, "master-exemption"},
+    { 285, "max-failed-attempts"},
+    { 286, "members"},
+    { 287, "muster-point"},
+    { 288, "negative-access-rules"},
+    { 289, "number-of-authentication-policies"},
+    { 290, "occupancy-count"},
+    { 291, "occupancy-count-adjust"},
+    { 292, "occupancy-count-enable"},
+    { 293, "occupancy-exemption"},
+    { 294, "occupancy-lower-limit"},
+    { 295, "occupancy-lower-limit-enforced"},
+    { 296, "occupancy-state"},
+    { 297, "occupancy-upper-limit"},
+    { 298, "occupancy-upper-limit-enforced"},
+    { 299, "passback-exemption"},
+    { 300, "passback-mode"},
+    { 301, "passback-timeout"},
+    { 302, "positive-access-rules"},
+    { 303, "reason-for-disable"},
+    { 304, "supported-formats"},
+    { 305, "supported-format-classes"},
+    { 306, "threat-authority"},
+    { 307, "threat-level"},
+    { 308, "trace-flag"},
+    { 309, "transaction-notification-class"},
+    { 310, "user-external-identifier"},
+    { 311, "user-information-reference"},
+    /* enumeration values 312-316 are unassigned */
+    { 317, "user-name"},
+    { 318, "user-type"},
+    { 319, "uses-remaining"},
+    { 320, "zone-from"},
+    { 321, "zone-to"},
+    { 322, "access-event-tag"},
+    { 323, "global-identifier"},
+    /* enumeration values 324-325 reserved for future addenda */
+    { 326, "verification-time"},
+    { 327, "base-device-security-policy"},
+    { 328, "distribution-key-revision"},
+    { 329, "do-not-hide"},
+    { 330, "key-sets"},
+    { 331, "last-key-server"},
+    { 332, "network-access-security-policies"},
+    { 333, "packet-reorder-time"},
+    { 334, "security-pdu-timeout"},
+    { 335, "security-time-window"},
+    { 336, "supported-security-algorithms"},
+    { 337, "update-key-set-timeout"},
+    { 338, "backup-and-restore-state"},
+    { 339, "backup-preparation-time"},
+    { 340, "restore-completion-time"},
+    { 341, "restore-preparation-time"},
+    { 342, "bit-mask"},       /* addenda 135-2008w */
+    { 343, "bit-text"},
+    { 344, "is-utc"},
+    { 345, "group-members"},
+    { 346, "group-member-names"},
+    { 347, "member-status-flags"},
+    { 348, "requested-update-interval"},
+    { 349, "covu-period"},
+    { 350, "covu-recipients"},
+    { 351, "event-message-texts"},
+    { 0,   NULL}
 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
    Enumerated values 512-4194303 may be used by others subject to
    the procedures and constraints described in Clause 23. */
@@ -3290,190 +3494,193 @@ BACnetPropertyIdentifier [] = {
 
 static const value_string
 BACnetBinaryPV [] = {
-       {0,"inactive"},
-       {1,"active"},
-       {0,NULL}
+    { 0, "inactive"},
+    { 1, "active"},
+    { 0, NULL}
 };
 
 
-#define ANSI_X34 0
-#define IBM_MS_DBCS 1
-#define JIS_C_6226 2
-#define ISO_10646_UCS4 3
-#define ISO_10646_UCS2 4
-#define ISO_18859_1 5
+#define ANSI_X3_4      0 /* ANSI X3.4, a/k/a "ASCII"; full UTF-8 since 2010 */
+                         /* See, for example, ANSI/ASHRAE Addendum k to ANSI/ASHRAE Standard 135-2008 */
+                         /* XXX - I've seen captures using this for ISO 8859-1 */
+#define IBM_MS_DBCS    1 /* "IBM/Microsoft DBCS"; was there only one such DBCS? */
+#define JIS_C_6226     2 /* JIS C 6226 */
+#define ISO_10646_UCS4 3 /* ISO 10646 (UCS-4) - 4-byte Unicode */
+#define ISO_10646_UCS2 4 /* ISO 10646 (UCS-2) - 2-byte Unicode Basic Multilingual Plane (not UTF-16, presumably) */
+#define ISO_8859_1     5 /* ISO 8859-1 */
 static const value_string
 BACnetCharacterSet [] = {
-       {ANSI_X34,      "ANSI X3.4 / UTF-8 (since 2010)"},
-       {IBM_MS_DBCS,   "IBM/Microsoft DBCS"},
-       {JIS_C_6226,    "JIS C 6226"},
-       {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
-       {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
-       {ISO_18859_1,   "ISO 18859-1"},
-       {0,             NULL}
+    { ANSI_X3_4,      "ANSI X3.4 / UTF-8 (since 2010)"},
+    { IBM_MS_DBCS,    "IBM/Microsoft DBCS"},
+    { JIS_C_6226,     "JIS C 6226"},
+    { ISO_10646_UCS4, "ISO 10646 (UCS-4)"},
+    { ISO_10646_UCS2, "ISO 10646 (UCS-2)"},
+    { ISO_8859_1,     "ISO 8859-1"},
+    { 0,     NULL}
 };
 
 static const value_string
 BACnetStatusFlags [] = {
-       {0,"in-alarm"},
-       {1,"fault"},
-       {2,"overridden"},
-       {3,"out-of-service"},
-       {0,NULL}
+    { 0, "in-alarm"},
+    { 1, "fault"},
+    { 2, "overridden"},
+    { 3, "out-of-service"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetMessagePriority [] = {
-       {0,"normal"},
-       {1,"urgent"},
-       {0,NULL}
+    { 0, "normal"},
+    { 1, "urgent"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetAcknowledgementFilter [] = {
-       {0,"all"},
-       {1,"acked"},
-       {2,"not-acked"},
-       {0,NULL}
+    { 0, "all"},
+    { 1, "acked"},
+    { 2, "not-acked"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetResultFlags [] = {
-       {0,"firstitem"},
-       {1,"lastitem"},
-       {2,"moreitems"},
-       {0,NULL}
+    { 0, "firstitem"},
+    { 1, "lastitem"},
+    { 2, "moreitems"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetRelationSpecifier [] = {
-       {0,"equal"},
-       {1,"not-equal"},
-       {2,"less-than"},
-       {3,"greater-than"},
-       {4,"less-than-or-equal"},
-       {5,"greater-than-or-equal"},
-       {0,NULL}
+    { 0, "equal"},
+    { 1, "not-equal"},
+    { 2, "less-than"},
+    { 3, "greater-than"},
+    { 4, "less-than-or-equal"},
+    { 5, "greater-than-or-equal"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetSelectionLogic [] = {
-       {0,"and"},
-       {1,"or"},
-       {2,"all"},
-       {0,NULL}
+    { 0, "and"},
+    { 1, "or"},
+    { 2, "all"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetEventStateFilter [] = {
-       {0,"offnormal"},
-       {1,"fault"},
-       {2,"normal"},
-       {3,"all"},
-       {4,"active"},
-       {0,NULL}
+    { 0, "offnormal"},
+    { 1, "fault"},
+    { 2, "normal"},
+    { 3, "all"},
+    { 4, "active"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetEventTransitionBits [] = {
-       {0,"to-offnormal"},
-       {1,"to-fault"},
-       {2,"to-normal"},
-       {0,NULL}
+    { 0, "to-offnormal"},
+    { 1, "to-fault"},
+    { 2, "to-normal"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetSegmentation [] = {
-       {0,"segmented-both"},
-       {1,"segmented-transmit"},
-       {2,"segmented-receive"},
-       {3,"no-segmentation"},
-       {0,NULL}
+    { 0, "segmented-both"},
+    { 1, "segmented-transmit"},
+    { 2, "segmented-receive"},
+    { 3, "no-segmentation"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetSilencedState [] = {
-       {0,"unsilenced"},
-       {1,"audible-silenced"},
-       {2,"visible-silenced"},
-       {3,"all-silenced"},
-       {0,NULL}
+    { 0, "unsilenced"},
+    { 1, "audible-silenced"},
+    { 2, "visible-silenced"},
+    { 3, "all-silenced"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetDeviceStatus [] = {
-       {0,"operational"},
-       {1,"operational-read-only"},
-       {2,"download-required"},
-       {3,"download-in-progress"},
-       {4,"non-operational"},
-       {5,"backup-in-progress"},
-       {0,NULL}
+    { 0, "operational"},
+    { 1, "operational-read-only"},
+    { 2, "download-required"},
+    { 3, "download-in-progress"},
+    { 4, "non-operational"},
+    { 5, "backup-in-progress"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetEnableDisable [] = {
-       {0,"enable"},
-       {1,"disable"},
-       {2,"disable-initiation"},
-       {0,NULL}
+    { 0, "enable"},
+    { 1, "disable"},
+    { 2, "disable-initiation"},
+    { 0, NULL}
 };
 
 static const value_string
 months [] = {
-       {1,"January" },
-       {2,"February" },
-       {3,"March" },
-       {4,"April" },
-       {5,"May" },
-       {6,"June" },
-       {7,"July" },
-       {8,"August" },
-       {9,"September" },
-       {10,"October" },
-       {11,"November" },
-       {12,"December" },
-       {255,"any month" },
-       {0,NULL }
+    {   1, "January" },
+    {   2, "February" },
+    {   3, "March" },
+    {   4, "April" },
+    {   5, "May" },
+    {   6, "June" },
+    {   7, "July" },
+    {   8, "August" },
+    {   9, "September" },
+    {  10, "October" },
+    {  11, "November" },
+    {  12, "December" },
+    { 255, "any month" },
+    { 0,   NULL }
 };
 
 static const value_string
 weekofmonth [] = {
-       {1,"days numbered 1-7" },
-       {2,"days numbered 8-14" },
-       {3,"days numbered 15-21" },
-       {4,"days numbered 22-28" },
-       {5,"days numbered 29-31" },
-       {6,"last 7 days of this month" },
-       {255,"any week of this month" },
-       {0,NULL }
+    {   1, "days numbered 1-7" },
+    {   2, "days numbered 8-14" },
+    {   3, "days numbered 15-21" },
+    {   4, "days numbered 22-28" },
+    {   5, "days numbered 29-31" },
+    {   6, "last 7 days of this month" },
+    { 255, "any week of this month" },
+    { 0,   NULL }
 };
 
 /* note: notification class object recipient-list uses
    different day-of-week enum */
 static const value_string
 day_of_week [] = {
-       {1,"Monday" },
-       {2,"Tuesday" },
-       {3,"Wednesday" },
-       {4,"Thursday" },
-       {5,"Friday" },
-       {6,"Saturday" },
-       {7,"Sunday" },
-       {255,"any day of week" },
-       {0,NULL }
+    {   1, "Monday" },
+    {   2, "Tuesday" },
+    {   3, "Wednesday" },
+    {   4, "Thursday" },
+    {   5, "Friday" },
+    {   6, "Saturday" },
+    {   7, "Sunday" },
+    { 255, "any day of week" },
+    { 0,   NULL }
 };
 
 static const value_string
 BACnetErrorClass [] = {
-       {0,"device" },
-       {1,"object" },
-       {2,"property" },
-       {3,"resources" },
-       {4,"security" },
-       {5,"services" },
-       {6,"vt" },
-       {0,NULL }
+    { 0, "device" },
+    { 1, "object" },
+    { 2, "property" },
+    { 3, "resources" },
+    { 4, "security" },
+    { 5, "services" },
+    { 6, "vt" },
+    { 7, "communication" },
+    { 0, NULL }
 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
    Enumerated values64-65535 may be used by others subject to
    the procedures and constraints described in Clause 23. */
@@ -3481,36 +3688,36 @@ BACnetErrorClass [] = {
 
 static const value_string
 BACnetVTClass [] = {
-       {0,"default-terminal" },
-       {1,"ansi-x3-64" },
-       {2,"dec-vt52" },
-       {3,"dec-vt100" },
-       {4,"dec-vt200" },
-       {5,"hp-700-94" },
-       {6,"ibm-3130" },
-       {0,NULL }
+    { 0, "default-terminal" },
+    { 1, "ansi-x3-64" },
+    { 2, "dec-vt52" },
+    { 3, "dec-vt100" },
+    { 4, "dec-vt200" },
+    { 5, "hp-700-94" },
+    { 6, "ibm-3130" },
+    { 0, NULL }
 };
 
 static const value_string
 BACnetEventType [] = {
-       {0,"change-of-bitstring" },
-       {1,"change-of-state" },
-       {2,"change-of-value" },
-       {3,"command-failure" },
-       {4,"floating-limit" },
-       {5,"out-of-range" },
-       {6,"complex-event-type" },
-       {7,"buffer-ready" },
-       {8,"change-of-life-safety" },
-       {9,"extended" },
-       {10,"buffer-ready" },
-       {11,"unsigned-range" },
-       {14,"double-out-of-range"},             /* added with addenda 135-2008w */
-       {15,"signed-out-of-range"},
-       {16,"unsigned-out-of-range"},
-       {17,"change-of-characterstring"},
-       {18,"change-of-status-flags"},
-       {0,NULL }
+    {  0, "change-of-bitstring" },
+    {  1, "change-of-state" },
+    {  2, "change-of-value" },
+    {  3, "command-failure" },
+    {  4, "floating-limit" },
+    {  5, "out-of-range" },
+    {  6, "complex-event-type" },
+    {  7, "(deprecated)buffer-ready" },
+    {  8, "change-of-life-safety" },
+    {  9, "extended" },
+    { 10, "buffer-ready" },
+    { 11, "unsigned-range" },
+    { 14, "double-out-of-range"},     /* added with addenda 135-2008w */
+    { 15, "signed-out-of-range"},
+    { 16, "unsigned-out-of-range"},
+    { 17, "change-of-characterstring"},
+    { 18, "change-of-status-flags"},
+    { 0,  NULL }
 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
    Enumerated values 64-65535 may be used by others subject to
    the procedures and constraints described in Clause 23.
@@ -3521,13 +3728,13 @@ BACnetEventType [] = {
 
 static const value_string
 BACnetEventState [] = {
-       {0,"normal" },
-       {1,"fault" },
-       {2,"offnormal" },
-       {3,"high-limit" },
-       {4,"low-limit" },
-       {5,"life-safety-alarm" },
-       {0,NULL }
+    { 0, "normal" },
+    { 1, "fault" },
+    { 2, "offnormal" },
+    { 3, "high-limit" },
+    { 4, "low-limit" },
+    { 5, "life-safety-alarm" },
+    { 0, NULL }
 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
    Enumerated values 64-65535 may be used by others subject to
    the procedures and constraints described in Clause 23.  */
@@ -3535,113 +3742,115 @@ BACnetEventState [] = {
 
 static const value_string
 BACnetLogStatus [] = {
-       {0,"log-disabled" },
-       {1,"buffer-purged" },
-       {2,"log-interrupted"},
-       {0,NULL }
+    { 0, "log-disabled" },
+    { 1, "buffer-purged" },
+    { 2, "log-interrupted"},
+    { 0, NULL }
 };
 
 static const value_string
 BACnetMaintenance [] = {
-       {0,"none" },
-       {1,"periodic-test" },
-       {2,"need-service-operational" },
-       {3,"need-service-inoperative" },
-       {0,NULL }
+    { 0, "none" },
+    { 1, "periodic-test" },
+    { 2, "need-service-operational" },
+    { 3, "need-service-inoperative" },
+    { 0, NULL }
 };
 
 static const value_string
 BACnetNotifyType [] = {
-       {0,"alarm" },
-       {1,"event" },
-       {2,"ack-notification" },
-       {0,NULL }
+    { 0, "alarm" },
+    { 1, "event" },
+    { 2, "ack-notification" },
+    { 0, NULL }
 };
 
 static const value_string
 BACnetServicesSupported [] = {
-       {0,"acknowledgeAlarm"},
-       {1,"confirmedCOVNotification"},
-       {2,"confirmedEventNotification"},
-       {3,"getAlarmSummary"},
-       {4,"getEnrollmentSummary"},
-       {5,"subscribeCOV"},
-       {6,"atomicReadFile"},
-       {7,"atomicWriteFile"},
-       {8,"addListElement"},
-       {9,"removeListElement"},
-       {10,"createObject"},
-       {11,"deleteObject"},
-       {12,"readProperty"},
-       {13,"readPropertyConditional"},
-       {14,"readPropertyMultiple"},
-       {15,"writeProperty"},
-       {16,"writePropertyMultiple"},
-       {17,"deviceCommunicationControl"},
-       {18,"confirmedPrivateTransfer"},
-       {19,"confirmedTextMessage"},
-       {20,"reinitializeDevice"},
-       {21,"vtOpen"},
-       {22,"vtClose"},
-       {23,"vtData"},
-       {24,"authenticate"},
-       {25,"requestKey"},
-       {26,"i-Am"},
-       {27,"i-Have"},
-       {28,"unconfirmedCOVNotification"},
-       {29,"unconfirmedEventNotification"},
-       {30,"unconfirmedPrivateTransfer"},
-       {31,"unconfirmedTextMessage"},
-       {32,"timeSynchronization"},
-       {33,"who-Has"},
-       {34,"who-Is"},
-       {35,"readRange"},
-       {36,"utcTimeSynchronization"},
-       {37,"lifeSafetyOperation"},
-       {38,"subscribeCOVProperty"},
-       {39,"getEventInformation"},
-       {0, NULL}
+    {  0, "acknowledgeAlarm"},
+    {  1, "confirmedCOVNotification"},
+    {  2, "confirmedEventNotification"},
+    {  3, "getAlarmSummary"},
+    {  4, "getEnrollmentSummary"},
+    {  5, "subscribeCOV"},
+    {  6, "atomicReadFile"},
+    {  7, "atomicWriteFile"},
+    {  8, "addListElement"},
+    {  9, "removeListElement"},
+    { 10, "createObject"},
+    { 11, "deleteObject"},
+    { 12, "readProperty"},
+    { 13, "readPropertyConditional"},
+    { 14, "readPropertyMultiple"},
+    { 15, "writeProperty"},
+    { 16, "writePropertyMultiple"},
+    { 17, "deviceCommunicationControl"},
+    { 18, "confirmedPrivateTransfer"},
+    { 19, "confirmedTextMessage"},
+    { 20, "reinitializeDevice"},
+    { 21, "vtOpen"},
+    { 22, "vtClose"},
+    { 23, "vtData"},
+    { 24, "authenticate"},
+    { 25, "requestKey"},
+    { 26, "i-Am"},
+    { 27, "i-Have"},
+    { 28, "unconfirmedCOVNotification"},
+    { 29, "unconfirmedEventNotification"},
+    { 30, "unconfirmedPrivateTransfer"},
+    { 31, "unconfirmedTextMessage"},
+    { 32, "timeSynchronization"},
+    { 33, "who-Has"},
+    { 34, "who-Is"},
+    { 35, "readRange"},
+    { 36, "utcTimeSynchronization"},
+    { 37, "lifeSafetyOperation"},
+    { 38, "subscribeCOVProperty"},
+    { 39, "getEventInformation"},
+    { 0,  NULL}
 };
 
 static const value_string
 BACnetPropertyStates [] = {
-       {0,"boolean-value"},
-       {1,"binary-value"},
-       {2,"event-type"},
-       {3,"polarity"},
-       {4,"program-change"},
-       {5,"program-state"},
-       {6,"reason-for-halt"},
-       {7,"reliability"},
-       {8,"state"},
-       {9,"system-status"},
-       {10,"units"},
-       {11,"unsigned-value"},
-       {12,"life-safety-mode"},
-       {13,"life-safety-state"},
-       {14,"restart-reason"},
-       {15,"door-alarm-state"},
-       {16,"action"},
-       {17,"door-secured-status"},
-       {18,"door-status"},
-       {19,"door-value"},
-       {20,"file-access-method"},
-       {21,"lock-status"},
-       {22,"life-safety-operation"},
-       {23,"maintenance"},
-       {24,"node-type"},
-       {25,"notify-type"},
-       {26,"security-level"},
-       {27,"shed-state"},
-       {28,"silenced-state"},
-       /* context tag 29 reserved for future addenda */
-       {30,"access-event"},
-       {31,"zone-occupancy-state"},
-       {32,"access-credential-disable-reason"},
-       {33,"access-credential-disable"},
-       {34,"authentication-status"},
-       {36,"backup-state"},
-       {0,NULL}
+    {  0, "boolean-value"},
+    {  1, "binary-value"},
+    {  2, "event-type"},
+    {  3, "polarity"},
+    {  4, "program-change"},
+    {  5, "program-state"},
+    {  6, "reason-for-halt"},
+    {  7, "reliability"},
+    {  8, "state"},
+    {  9, "system-status"},
+    { 10, "units"},
+    { 11, "unsigned-value"},
+    { 12, "life-safety-mode"},
+    { 13, "life-safety-state"},
+    { 14, "restart-reason"},
+    { 15, "door-alarm-state"},
+    { 16, "action"},
+    { 17, "door-secured-status"},
+    { 18, "door-status"},
+    { 19, "door-value"},
+    { 20, "file-access-method"},
+    { 21, "lock-status"},
+    { 22, "life-safety-operation"},
+    { 23, "maintenance"},
+    { 24, "node-type"},
+    { 25, "notify-type"},
+    { 26, "security-level"},
+    { 27, "shed-state"},
+    { 28, "silenced-state"},
+    /* context tag 29 reserved for future addenda */
+    { 29, "unknown-29"},
+    { 30, "access-event"},
+    { 31, "zone-occupancy-state"},
+    { 32, "access-credential-disable-reason"},
+    { 33, "access-credential-disable"},
+    { 34, "authentication-status"},
+    { 35, "unknown-35"},
+    { 36, "backup-state"},
+    { 0, NULL}
 /* Tag values 0-63 are reserved for definition by ASHRAE.
    Tag values of 64-254 may be used by others to accommodate
    vendor specific properties that have discrete or enumerated values,
@@ -3650,12 +3859,12 @@ BACnetPropertyStates [] = {
 
 static const value_string
 BACnetProgramError [] = {
-       {0,"normal"},
-       {1,"load-failed"},
-       {2,"internal"},
-       {3,"program"},
-       {4,"other"},
-       {0,NULL}
+    { 0, "normal"},
+    { 1, "load-failed"},
+    { 2, "internal"},
+    { 3, "program"},
+    { 4, "other"},
+    { 0, NULL}
 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
    Enumerated values 64-65535 may be used by others subject to
    the procedures and constraints described in Clause 23. */
@@ -3663,609 +3872,940 @@ BACnetProgramError [] = {
 
 static const value_string
 BACnetProgramRequest [] = {
-       {0,"ready"},
-       {1,"load"},
-       {2,"run"},
-       {3,"halt"},
-       {4,"restart"},
-       {4,"unload"},
-       {0,NULL}
+    { 0, "ready"},
+    { 1, "load"},
+    { 2, "run"},
+    { 3, "halt"},
+    { 4, "restart"},
+    { 4, "unload"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetProgramState [] = {
-       {0,"idle"},
-       {1,"loading"},
-       {2,"running"},
-       {3,"waiting"},
-       {4,"halted"},
-       {4,"unloading"},
-       {0,NULL}
+    { 0, "idle"},
+    { 1, "loading"},
+    { 2, "running"},
+    { 3, "waiting"},
+    { 4, "halted"},
+    { 4, "unloading"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetReinitializedStateOfDevice [] = {
-       {0,"coldstart"},
-       {1,"warmstart"},
-       {2,"startbackup"},
-       {3,"endbackup"},
-       {4,"startrestore"},
-       {5,"endrestore"},
-       {6,"abortrestore"},
-       {0,NULL}
+    { 0, "coldstart"},
+    { 1, "warmstart"},
+    { 2, "startbackup"},
+    { 3, "endbackup"},
+    { 4, "startrestore"},
+    { 5, "endrestore"},
+    { 6, "abortrestore"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetPolarity [] = {
-       {0,"normal"},
-       {1,"reverse"},
-       {0,NULL}
+    { 0, "normal"},
+    { 1, "reverse"},
+    { 0, NULL}
 };
 
 static const value_string
 BACnetTagNames[] = {
-       { 5, "Extended Value" },
-       { 6, "Opening Tag" },
-       { 7, "Closing Tag" },
-       { 0, NULL }
+    { 5, "Extended Value" },
+    { 6, "Opening Tag" },
+    { 7, "Closing Tag" },
+    { 0, NULL }
 };
 
 static const value_string
 BACnetReadRangeOptions[] = {
-       { 3, "range byPosition" },
-       { 4, "range byTime" },
-       { 5, "range timeRange" },
-       { 6, "range bySequenceNumber" },
-       { 7, "range byTime" },
-       { 0, NULL }
+    { 3, "range byPosition" },
+    { 4, "range byTime" },
+    { 5, "range timeRange" },
+    { 6, "range bySequenceNumber" },
+    { 7, "range byTime" },
+    { 0, NULL }
 };
 
 /* Present_Value for Load Control Object */
 static const value_string
 BACnetShedState[] = {
-       { 0, "shed-inactive" },
-       { 1, "shed-request-pending" },
-       { 2, "shed-compliant" },
-       { 3, "shed-non-compliant" },
-       { 0, NULL }
+    { 0, "shed-inactive" },
+    { 1, "shed-request-pending" },
+    { 2, "shed-compliant" },
+    { 3, "shed-non-compliant" },
+    { 0, NULL }
+};
+
+static const value_string
+BACnetNodeType [] = {
+    { 0, "unknown" },
+    { 1, "system" },
+    { 2, "network" },
+    { 3, "device" },
+    { 4, "organizational" },
+    { 5, "area" },
+    { 6, "equipment" },
+    { 7, "point" },
+    { 8, "collection" },
+    { 9, "property" },
+    { 10, "functional" },
+    { 11, "other" },
+    { 0, NULL }
+};
+
+static const value_string
+BACnetLoggingType [] = {
+    { 0, "polled" },
+    { 1, "cov" },
+    { 2, "triggered" },
+    { 0, NULL }
 };
 
+static const value_string
+BACnetDoorStatus [] = {
+    { 0, "closed" },
+    { 1, "opened" },
+    { 2, "unknown" },
+    { 0, NULL }
+};
+
+static const value_string
+BACnetLockStatus [] = {
+    { 0, "locked" },
+    { 1, "unlocked" },
+    { 2, "fault" },
+    { 3, "unknown" },
+    { 0, NULL }
+};
+
+static const value_string
+BACnetDoorSecuredStatus [] = {
+    { 0, "secured" },
+    { 1, "unsecured" },
+    { 2, "unknown" },
+    { 0, NULL }
+};
+
+static const value_string
+BACnetDoorAlarmState [] = {
+    { 0, "normal" },
+    { 1, "alarm" },
+    { 2, "door-open-too-long" },
+    { 3, "forced-open" },
+    { 4, "tamper" },
+    { 5, "door-fault" },
+    { 6, "lock-down" },
+    { 7, "free-access" },
+    { 8, "egress-open" },
+    { 0, NULL }
+};
+
+static const value_string
+BACnetAccumulatorStatus [] = {
+    { 0, "normal" },
+    { 1, "starting" },
+    { 2, "recovered" },
+    { 3, "abnormal" },
+    { 4, "failed" },
+    { 0, NULL }
+};
+
+/* These values are (manually) transferred from
+ * http://www.bacnet.org/VendorID/BACnet Vendor IDs.htm
+ * Version: "As of September 16, 2013"
+ */
+
 static const value_string
 BACnetVendorIdentifiers [] = {
-       { 0, "ASHRAE" },
-       { 1, "NIST" },
-       { 2, "The Trane Company" },
-       { 3, "McQuay International" },
-       { 4, "PolarSoft" },
-       { 5, "Johnson Controls, Inc." },
-       { 6, "American Auto-Matrix" },
-       { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
-       { 8, "Delta Controls" },
-       { 9, "Siemens Building Technologies, Inc." },
-       { 10, "Tour Andover Controls Corporation" },
-       { 11, "TAC" },
-       { 12, "Orion Analysis Corporation" },
-       { 13, "Teletrol Systems Inc." },
-       { 14, "Cimetrics Technology" },
-       { 15, "Cornell University" },
-       { 16, "United Technologies Carrier" },
-       { 17, "Honeywell Inc." },
-       { 18, "Alerton / Honeywell" },
-       { 19, "TAC AB" },
-       { 20, "Hewlett-Packard Company" },
-       { 21, "Dorsette's Inc." },
-       { 22, "Cerberus AG" },
-       { 23, "York Controls Group" },
-       { 24, "Automated Logic Corporation" },
-       { 25, "CSI Control Systems International" },
-       { 26, "Phoenix Controls Corporation" },
-       { 27, "Innovex Technologies, Inc." },
-       { 28, "KMC Controls, Inc." },
-       { 29, "Xn Technologies, Inc." },
-       { 30, "Hyundai Information Technology Co., Ltd." },
-       { 31, "Tokimec Inc." },
-       { 32, "Simplex" },
-       { 33, "North Communications Limited" },
-       { 34, "Notifier" },
-       { 35, "Reliable Controls Corporation" },
-       { 36, "Tridium Inc." },
-       { 37, "Sierra Monitor Corp." },
-       { 38, "Silicon Energy" },
-       { 39, "Kieback & Peter GmbH & Co KG" },
-       { 40, "Anacon Systems, Inc." },
-       { 41, "Systems Controls & Instruments, LLC" },
-       { 42, "Lithonia Lighting" },
-       { 43, "Micropower Manufacturing" },
-       { 44, "Matrix Controls" },
-       { 45, "METALAIRE" },
-       { 46, "ESS Engineering" },
-       { 47, "Sphere Systems Pty Ltd." },
-       { 48, "Walker Technologies Corporation" },
-       { 49, "H I Solutions, Inc." },
-       { 50, "MBS GmbH" },
-       { 51, "SAMSON AG" },
-       { 52, "Badger Meter Inc." },
-       { 53, "DAIKIN Industries Ltd." },
-       { 54, "NARA Controls Inc." },
-       { 55, "Mammoth Inc." },
-       { 56, "Liebert Corporation" },
-       { 57, "SEMCO Incorporated" },
-       { 58, "Air Monitor Corporation" },
-       { 59, "TRIATEK, Inc." },
-       { 60, "NexLight" },
-       { 61, "Multistack" },
-       { 62, "TSI Incorporated" },
-       { 63, "Weather-Rite, Inc." },
-       { 64, "Dunham-Bush" },
-       { 65, "Reliance Electric" },
-       { 66, "LCS Inc." },
-       { 67, "Regulator Australia PTY Ltd." },
-       { 68, "Touch-Plate Lighting Controls" },
-       { 69, "Amann GmbH" },
-       { 70, "RLE Technologies" },
-       { 71, "Cardkey Systems" },
-       { 72, "SECOM Co., Ltd." },
-       { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
-       { 74, "KNX Association cvba" },
-       { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
-       { 76, "Nohmi Bosai, Ltd." },
-       { 77, "Carel S.p.A." },
-       { 78, "AirSense Technology, Inc." },
-       { 79, "Hochiki Corporation" },
-       { 80, "Fr. Sauter AG" },
-       { 81, "Matsushita Electric Works, Ltd." },
-       { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
-       { 83, "Mitsubishi Heavy Industries, Ltd." },
-       { 84, "ITT Bell & Gossett" },
-       { 85, "Yamatake Building Systems Co., Ltd." },
-       { 86, "The Watt Stopper, Inc." },
-       { 87, "Aichi Tokei Denki Co., Ltd." },
-       { 88, "Activation Technologies, LLC" },
-       { 89, "Saia-Burgess Controls, Ltd." },
-       { 90, "Hitachi, Ltd." },
-       { 91, "Novar Corp./Trend Control Systems Ltd." },
-       { 92, "Mitsubishi Electric Lighting Corporation" },
-       { 93, "Argus Control Systems, Ltd." },
-       { 94, "Kyuki Corporation" },
-       { 95, "Richards-Zeta Building Intelligence, Inc." },
-       { 96, "Scientech R&D, Inc." },
-       { 97, "VCI Controls, Inc." },
-       { 98, "Toshiba Corporation" },
-       { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
-       { 100, "Custom Mechanical Equipment, LLC" },
-       { 101, "ClimateMaster" },
-       { 102, "ICP Panel-Tec, Inc." },
-       { 103, "D-Tek Controls" },
-       { 104, "NEC Engineering, Ltd." },
-       { 105, "PRIVA BV" },
-       { 106, "Meidensha Corporation" },
-       { 107, "JCI Systems Integration Services" },
-       { 108, "Freedom Corporation" },
-       { 109, "Neuberger Gebaudeautomation GmbH" },
-       { 110, "Sitronix" },
-       { 111, "Leviton Manufacturing" },
-       { 112, "Fujitsu Limited" },
-       { 113, "Emerson Network Power" },
-       { 114, "S. A. Armstrong, Ltd." },
-       { 115, "Visonet AG" },
-       { 116, "M&M Systems, Inc." },
-       { 117, "Custom Software Engineering" },
-       { 118, "Nittan Company, Limited" },
-       { 119, "Elutions Inc. (Wizcon Systems SAS)" },
-       { 120, "Pacom Systems Pty., Ltd." },
-       { 121, "Unico, Inc." },
-       { 122, "Ebtron, Inc." },
-       { 123, "Scada Engine" },
-       { 124, "AC Technology Corporation" },
-       { 125, "Eagle Technology" },
-       { 126, "Data Aire, Inc." },
-       { 127, "ABB, Inc." },
-       { 128, "Transbit Sp. z o. o." },
-       { 129, "Toshiba Carrier Corporation" },
-       { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
-       { 131, "Tokai Soft" },
-       { 132, "Lumisys" },
-       { 133, "Veris Industries" },
-       { 134, "Centaurus Prime" },
-       { 135, "Sand Network Systems" },
-       { 136, "Regulvar, Inc." },
-       { 137, "Fastek International, Ltd." },
-       { 138, "PowerCold Comfort Air Solutions, Inc." },
-       { 139, "I Controls" },
-       { 140, "Viconics Electronics, Inc." },
-       { 141, "Yaskawa Electric America, Inc." },
-       { 142, "Plueth Regelsysteme" },
-       { 143, "Digitale Mess- und Steuersysteme AG" },
-       { 144, "Fujitsu General Limited" },
-       { 145, "Project Engineering S.r.l." },
-       { 146, "Sanyo Electric Co., Ltd." },
-       { 147, "Integrated Information Systems, Inc." },
-       { 148, "Temco Controls, Ltd." },
-       { 149, "Airtek Technologies, Inc." },
-       { 150, "Advantech Corporation" },
-       { 151, "Titan Products, Ltd." },
-       { 152, "Regel Partners" },
-       { 153, "National Environmental Product" },
-       { 154, "Unitec Corporation" },
-       { 155, "Kanden Engineering Company" },
-       { 156, "Messner Gebaudetechnik GmbH" },
-       { 157, "Integrated.CH" },
-       { 158, "EH Price Limited" },
-       { 159, "SE-Elektronic GmbH" },
-       { 160, "Rockwell Automation" },
-       { 161, "Enflex Corp." },
-       { 162, "ASI Controls" },
-       { 163, "SysMik GmbH Dresden" },
-       { 164, "HSC Regelungstechnik GmbH" },
-       { 165, "Smart Temp Australia Pty. Ltd." },
-       { 166, "PCI Lighting Control Systems" },
-       { 167, "Duksan Mecasys Co., Ltd." },
-       { 168, "Fuji IT Co., Ltd." },
-       { 169, "Vacon Plc" },
-       { 170, "Leader Controls" },
-       { 171, "Cylon Controls, Ltd." },
-       { 172, "Compas" },
-       { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
-       { 174, "Building Control Integrators" },
-       { 175, "ITG Worldwide (M) Sdn Bhd" },
-       { 176, "Lutron Electronics Co., Inc." },
-       { 177, "Cooper-Atkins Corporation" },
-       { 178, "LOYTEC Electronics GmbH" },
-       { 179, "ProLon" },
-       { 180, "Mega Controls Limited" },
-       { 181, "Micro Control Systems, Inc." },
-       { 182, "Kiyon, Inc." },
-       { 183, "Dust Networks" },
-       { 184, "Advanced Building Automation Systems" },
-       { 185, "Hermos AG" },
-       { 186, "CEZIM" },
-       { 187, "Softing" },
-       { 188, "Lynxspring" },
-       { 189, "Schneider Toshiba Inverter Europe" },
-       { 190, "Danfoss Drives A/S" },
-       { 191, "Eaton Corporation" },
-       { 192, "Matyca S.A." },
-       { 193, "Botech AB" },
-       { 194, "Noveo, Inc." },
-       { 195, "AMEV" },
-       { 196, "Yokogawa Electric Corporation" },
-       { 197, "GFR Gesellschaft fur Regelungstechnik" },
-       { 198, "Exact Logic" },
-       { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
-       { 200, "Kandenko Co., Ltd." },
-       { 201, "DTF, Daten-Technik Fries" },
-       { 202, "Klimasoft, Ltd." },
-       { 203, "Toshiba Schneider Inverter Corporation" },
-       { 204, "Control Applications, Ltd." },
-       { 205, "KDT Systems Co., Ltd." },
-       { 206, "Onicon Incorporated" },
-       { 207, "Automation Displays, Inc." },
-       { 208, "Control Solutions, Inc." },
-       { 209, "Remsdaq Limited" },
-       { 210, "NTT Facilities, Inc." },
-       { 211, "VIPA GmbH" },
-       { 212, "TSC21 Association of Japan" },
-       { 213, "BBP Energie Ltee" },
-       { 214, "HRW Limited" },
-       { 215, "Lighting Control & Design, Inc." },
-       { 216, "Mercy Electronic and Electrical Industries" },
-       { 217, "Samsung SDS Co., Ltd" },
-       { 218, "Impact Facility Solutions, Inc." },
-       { 219, "Aircuity" },
-       { 220, "Control Techniques, Ltd." },
-       { 221, "Evolve Control Systems, LLC" },
-       { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
-       { 223, "Cerus Industrial" },
-       { 224, "Chloride Power Protection Company" },
-       { 225, "Computrols, Inc." },
-       { 226, "Phoenix Contact GmbH & Co. KG" },
-       { 227, "Grundfos Management A/S" },
-       { 228, "Ridder Drive Systems" },
-       { 229, "Soft Device SDN BHD" },
-       { 230, "Integrated Control Technology Limited" },
-       { 231, "AIRxpert Systems, Inc." },
-       { 232, "Microtrol Limited" },
-       { 233, "Red Lion Controls" },
-       { 234, "Digital Electronics Corporation" },
-       { 235, "Ennovatis GmbH" },
-       { 236, "Serotonin Software Technologies, Inc." },
-       { 237, "LS Industrial Systems Co., Ltd." },
-       { 238, "Square D Company" },
-       { 239, "S Squared Innovations, Inc." },
-       { 240, "Aricent Ltd." },
-       { 241, "EtherMetrics, LLC" },
-       { 242, "Industrial Control Communications, Inc." },
-       { 243, "Paragon Controls, Inc." },
-       { 244, "A. O. Smith Corporation" },
-       { 245, "Contemporary Control Systems, Inc." },
-       { 246, "Intesis Software SL" },
-       { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
-       { 248, "Heat-Timer Corporation" },
-       { 249, "Ingrasys Technology, Inc." },
-       { 250, "Costerm Building Automation" },
-       { 251, "Wilo AG" },
-       { 252, "Embedia Technologies Corp." },
-       { 253, "Technilog" },
-       { 254, "HR Controls Ltd. & Co. KG" },
-       { 255, "Lennox International, Inc." },
-       { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
-       { 257, "Thermomax, Ltd." },
-       { 258, "ELCON Electronic Control, Ltd." },
-       { 259, "Larmia Control AB" },
-       { 260, "BACnet Stack at SourceForge" },
-       { 261, "G4S Security Services A/S" },
-       { 262, "Sitek S.p.A." },
-       { 263, "Cristal Controles" },
-       { 264, "Regin AB" },
-       { 265, "Dimension Software, Inc. " },
-       { 266, "SynapSense Corporation" },
-       { 267, "Beijing Nantree Electronic Co., Ltd." },
-       { 268, "Camus Hydronics Ltd." },
-       { 269, "Kawasaki Heavy Industries, Ltd. " },
-       { 270, "Critical Environment Technologies" },
-       { 271, "ILSHIN IBS Co., Ltd." },
-       { 272, "ELESTA Energy Control AG" },
-       { 273, "KROPMAN Installatietechniek" },
-       { 274, "Baldor Electric Company" },
-       { 275, "INGA mbH" },
-       { 276, "GE Consumer & Industrial" },
-       { 277, "Functional Devices, Inc." },
-       { 278, "ESAC" },
-       { 279, "M-System Co., Ltd." },
-       { 280, "Yokota Co., Ltd." },
-       { 281, "Hitranse Technology Co., LTD" },
-       { 282, "Federspiel Controls" },
-       { 283, "Kele, Inc." },
-       { 284, "Opera Electronics, Inc." },
-       { 285, "Gentec" },
-       { 286, "Embedded Science Labs, LLC" },
-       { 287, "Parker Hannifin Corporation" },
-       { 288, "MaCaPS International Limited" },
-       { 289, "Link4 Corporation" },
-       { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
-       { 291, "Pribusin, Inc." },
-       { 292, "Advantage Controls" },
-       { 293, "Critical Room Control" },
-       { 294, "LEGRAND" },
-       { 295, "Tongdy Control Technology Co., Ltd." },
-       { 296, "ISSARO Integrierte Systemtechnik" },
-       { 297, "Pro-Dev Industries" },
-       { 298, "DRI-STEEM" },
-       { 299, "Creative Electronic GmbH" },
-       { 300, "Swegon AB" },
-       { 301, "Jan Brachacek" },
-       { 302, "Hitachi Appliances, Inc." },
-       { 303, "Real Time Automation, Inc." },
-       { 304, "ITEC Hankyu-Hanshin Co." },
-       { 305, "Cyrus E&M Engineering Co., Ltd." },
-       { 306, "Racine Federated, Inc." },
-       { 307, "Verari Systems, Inc." },
-       { 308, "Elesta GmbH Building Automation" },
-       { 309, "Securiton" },
-       { 310, "OSlsoft, Inc." },
-       { 311, "Hanazeder Electronic GmbH" },
-       { 312, "Honeywell Security Deutschland, Novar GmbH" },
-       { 313, "Siemens Energy & Automation, Inc." },
-       { 314, "ETM Professional Control GmbH" },
-       { 315, "Meitav-tec, Ltd." },
-       { 316, "Janitza Electronics GmbH" },
-       { 317, "MKS Nordhausen" },
-       { 318, "De Gier Drive Systems B.V." },
-       { 319, "Cypress Envirosystems" },
-       { 320, "SMARTron s.r.o." },
-       { 321, "Verari Systems, Inc." },
-       { 322, "K-W Electronic Service, Inc." },
-       { 323, "ALFA-SMART Energy Management" },
-       { 324, "Telkonet, Inc." },
-       { 325, "Securiton GmbH" },
-       { 326, "Cemtrex, Inc." },
-       { 327, "Performance Technologies, Inc." },
-       { 328, "Xtralis (Aust) Pty Ltd" },
-       { 329, "TROX GmbH" },
-       { 330, "Beijing Hysine Technology Co., Ltd" },
-       { 331, "RCK Controls, Inc." },
-       { 332, "ACELIA" },
-       { 333, "Novar/Honeywell" },
-       { 334, "The S4 Group, Inc." },
-       { 335, "Schneider Electric" },
-       { 336, "LHA Systems" },
-       { 337, "GHM engineering Group, Inc." },
-       { 338, "Cllimalux S.A." },
-       { 339, "VAISALA Oyj" },
-       { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
-       { 342, "POWERPEG NSI Limited" },
-       { 343, "BACnet Interoperability Testing Services, Inc." },
-       { 344, "Teco a.s." },
-       { 345, "Plexus Technology Limited"},
-       { 346, "Energy Focus, Inc."},
-       { 347, "Powersmiths International Corp."},
-       { 348, "Nichibei Co., Ltd."},
-       { 349, "HKC Technology Ltd."},
-       { 350, "Ovation Networks, Inc."},
-       { 351, "Setra Systems"},
-       { 352, "AVG Automation"},
-       { 353, "ZXC Ltd."},
-       { 354, "Byte Sphere"},
-       { 355, "Generiton Co., Ltd."},
-       { 356, "Holter Regelarmaturen GmbH & Co. KG"},
-       { 357, "Bedford Instruments, LLC"},
-       { 358, "Standair Inc."},
-       { 359, "WEG Automation - R&D"},
-       { 360, "Prolon Control Systems ApS"},
-       { 361, "Inneasoft"},
-       { 362, "ConneXSoft GmbH"},
-       { 363, "CEAG Notlichtsysteme GmbH"},
-       { 364, "Distech Controls Inc."},
-       { 365, "Industrial Technology Research Institute"},
-       { 366, "ICONICS, Inc."},
-       { 367, "IQ Controls s.c."},
-       { 368, "OJ Electronics A/S"},
-       { 369, "Rolbit Ltd."},
-       { 370, "Synapsys Solutions Ltd."},
-       { 371, "ACME Engineering Prod. Ltd."},
-       { 372, "Zener Electric Pty, Ltd."},
-       { 373, "Selectronix, Inc."},
-       { 374, "Gorbet & Banerjee, LLC."},
-       { 375, "IME"},
-       { 376, "Stephen H. Dawson Computer Service"},
-       { 377, "Accutrol, LLC"},
-       { 378, "Schneider Elektronik GmbH"},
-       { 379, "Alpha-Inno Tec GmbH"},
-       { 380, "ADMMicro, Inc."},
-       { 381, "Greystone Energy Systems, Inc."},
-       { 382, "CAP Technologie"},
-       { 383, "KeRo Systems"},
-       { 384, "Domat Control System s.r.o."},
-       { 385, "Efektronics Pty. Ltd."},
-       { 386, "Hekatron Vertriebs GmbH"},
-       { 387, "Securiton AG"},
-       { 388, "Carlo Gavazzi Controls SpA"},
-       { 389, "Chipkin Automation Systems"},
-       { 390, "Savant Systems, LLC"},
-       { 391, "Simmtronic Lighting Controls"},
-       { 392, "Abelko Innovation AB"},
-       { 393, "Seresco Technologies Inc."},
-       { 394, "IT Watchdogs"},
-       { 395, "Automation Assist Japan Corp."},
-       { 396, "Thermokon Sensortechnik GmbH"},
-       { 397, "EGauge Systems, LLC"},
-       { 398, "Quantum Automation (ASIA) PTE, Ltd."},
-       { 399, "Toshiba Lighting & Technology Corp."},
-       { 400, "SPIN Engenharia de Automaca Ltda."},
-       { 401, "Logistics Systems & Software Services India PVT. Ltd."},
-       { 402, "Delta Controls Integration Products"},
-       { 403, "Focus Media"},
-       { 404, "LUMEnergi Inc."},
-       { 405, "Kara Systems"},
-       { 406, "RF Code, Inc."},
-       { 407, "Fatek Automation Corp."},
-       { 408, "JANDA Software Company, LLC"},
-       { 409, "Open System Solutions Limited"},
-       { 410, "Intelec Systems PTY Ltd."},
-       { 411, "Ecolodgix, LLC"},
-       { 412, "Douglas Lighting Controls"},
-       { 413, "iSAtech GmbH intelligente Sensoren Aktoren technologie"},
-       { 414, "AREAL"},
-       { 415, "Beckhoff Automation GmbH"},
-       { 416, "IPAS GmbH"},
-       { 417, "KE2 Therm Solutions"},
-       { 418, "Base2Products"},
-       { 419, "DTL Controls, LLC"},
-       { 420, "INNCOM International, Inc."},
-       { 421, "BTR Netcom GmbH"},
-       { 422, "Greentrol Automation, Inc"},
-       { 423, "BELIMO Automation AG"},
-       { 424, "Samsung Heavy Industries Co, Ltd"},
-       { 425, "Triacta Power Technologies, Inc."},
-       { 426, "Globestar Systems"},
-       { 427, "MLB Advanced Media, LP"},
-       { 428, "SWG Stuckmann Wirtschaftliche Gebaudesysteme GmbH"},
-       { 429, "SensorSwitch"},
-       { 430, "Multitek Power Limited"},
-       { 431, "Aquametro AG"},
-       { 432, "LG Electronics Inc."},
-       { 433, "Electronic Theatre Controls, Inc."},
-       { 434, "Mitsubishi Electric Corporation Nagoya Works"},
-       { 435, "Delta Electronics, Inc."},
-       { 436, "Elma Kurtalj, Ltd."},
-       { 437, "ADT Fire and Security Sp. A.o.o."},
-       { 438, "Nedap Security Management"},
-       { 439, "ESC Automation Inc."},
-       { 440, "DSP4YOU Ltd."},
-       { 441, "GE Sensing and Inspection Technologies"},
-       { 442, "Embedded Systems SIA"},
-       { 443, "BEFEGA GmbH"},
-       { 444, "Baseline Inc."},
-       { 445, "M2M Systems Integrators"},
-       { 446, "OEMCtrl"},
-       { 447, "Clarkson Controls Limited"},
-       { 448, "Rogerwell Control System Limited"},
-       { 449, "SCL Elements"},
-       { 450, "Hitachi Ltd."},
-       { 451, "Newron System SA"},
-       { 452, "BEVECO Gebouwautomatisering BV"},
-       { 453, "Streamside Solutions"},
-       { 454, "Yellowstone Soft"},
-       { 455, "Oztech Intelligent Systems Pty Ltd."},
-       { 456, "Novelan GmbH"},
-       { 457, "Flexim Americas Corporation"},
-       { 458, "ICP DAS Co., Ltd."},
-       { 459, "CARMA Industries Inc."},
-       { 460, "Log-One Ltd."},
-       { 461, "TECO Electric & Machinery Co., Ltd."},
-       { 462, "ConnectEx, Inc."},
-       { 463, "Turbo DDC Sudwest"},
-       { 464, "Quatrosense Environmental Ltd."},
-       { 465, "Fifth Light Technology Ltd."},
-       { 466, "Scientific Solutions, Ltd."},
-       { 467, "Controller Area Network Solutions (M) Sdn Bhd"},
-       { 468, "RESOL - Elektronische Regelungen GmbH"},
-       { 469, "RPBUS LLC"},
-       { 470, "BRS Sistemas Eletronicos"},
-       { 471, "WindowMaster A/S"},
-       { 472, "Sunlux Technologies Ltd."},
-       { 473, "Measurlogic"},
-       { 474, "Frimat GmbH"},
-       { 475, "Spirax Sarco"},
-       { 476, "Luxtron"},
-       { 477, "Raypak Inc"},
-       { 478, "Air Monitor Corporation"},
-       { 479, "Regler Och Webbteknik Sverige (ROWS)"},
-       { 480, "Intelligent Lighting Controls Inc."},
-       { 481, "Sanyo Electric Industry Co., Ltd"},
-       { 482, "E-Mon Energy Monitoring Products"},
-       { 483, "Digital Control Systems"},
-       { 484, "ATI Airtest Technologies, Inc."},
-       { 485, "SCS SA"},
-       { 486, "HMS Industrial Networks AB"},
-       { 487, "Shenzhen Universal Intellisys Co Ltd"},
-       { 488, "EK Intellisys Sdn Bhd"},
-       { 489, "SysCom"},
-       { 490, "Firecom, Inc."},
-       { 491, "ESA Elektroschaltanlagen Grimma GmbH"},
-       { 492, "Kumahira Co Ltd"},
-       { 493, "Hotraco"},
-       { 494, "SABO Elektronik GmbH"},
-       { 495, "Equip'Trans"},
-       { 496, "TCS Basys Controls"},
-       { 497, "FlowCon International A/S"},
-       { 498, "ThyssenKrupp Elevator Americas"},
-       { 499, "Abatement Technologies"},
-       { 500, "Continental Control Systems, LLC"},
-       { 501, "WISAG Automatisierungstechnik GmbH & Co KG"},
-       { 502, "EasyIO"},
-       { 503, "EAP-Electric GmbH"},
-       { 504, "Hardmeier"},
-       { 505, "Mircom Group of Companies"},
-       { 506, "Quest Controls"},
-       { 507, "Mestek, Inc"},
-       { 508, "Pulse Energy"},
-       { 509, "Tachikawa Corporation"},
-       { 510, "University of Nebraska-Lincoln"},
-       { 511, "Redwood Systems"},
-       { 512, "PASStec Industrie-Elektronik GmbH"},
-       { 513, "NgEK, Inc."},
-       { 514, "FAW Electronics Ltd"},
-       { 515, "Jireh Energy Tech Co., Ltd."},
-       { 516, "Enlighted Inc."},
-       { 517, "El-Piast Sp. Z o.o"},
-       { 518, "NetxAutomation Software GmbH"},
-       { 519, "Invertek Drives"},
-       { 520, "Deutschmann Automation GmbH & Co. KG"},
-       { 521, "EMU Electronic AG"},
-       { 522, "Phaedrus Limited"},
-       { 523, "Sigmatek GmbH & Co KG"},
-       { 524, "Marlin Controls"},
-       { 525, "Circutor, SA"},
-       { 526, "UTC Fire & Security"},
-       { 527, "DENT Instruments, Inc."},
-       { 528, "FHP Manufacturing Company - Bosch Group"},
-       { 529, "GE Intelligent Platforms"},
-       { 530, "Inner Range Pty Ltd"},
-       { 531, "GLAS Energy Technology"},
-       { 532, "MSR-Electronic-GmbH"},
-       { 0, NULL }
+    {   0, "ASHRAE" },
+    {   1, "NIST" },
+    {   2, "The Trane Company" },
+    {   3, "McQuay International" },
+    {   4, "PolarSoft" },
+    {   5, "Johnson Controls, Inc." },
+    {   6, "American Auto-Matrix" },
+    {   7, "Siemens Schweiz AG (Formerly: Landis & Staefa Division Europe)" },
+    {   8, "Delta Controls" },
+    {   9, "Siemens Schweiz AG" },
+    {  10, "Schneider Electric" },
+    {  11, "TAC" },
+    {  12, "Orion Analysis Corporation" },
+    {  13, "Teletrol Systems Inc." },
+    {  14, "Cimetrics Technology" },
+    {  15, "Cornell University" },
+    {  16, "United Technologies Carrier" },
+    {  17, "Honeywell Inc." },
+    {  18, "Alerton / Honeywell" },
+    {  19, "TAC AB" },
+    {  20, "Hewlett-Packard Company" },
+    {  21, "Dorsette's Inc." },
+    {  22, "Siemens Schweiz AG (Formerly: Cerberus AG)" },
+    {  23, "York Controls Group" },
+    {  24, "Automated Logic Corporation" },
+    {  25, "CSI Control Systems International" },
+    {  26, "Phoenix Controls Corporation" },
+    {  27, "Innovex Technologies, Inc." },
+    {  28, "KMC Controls, Inc." },
+    {  29, "Xn Technologies, Inc." },
+    {  30, "Hyundai Information Technology Co., Ltd." },
+    {  31, "Tokimec Inc." },
+    {  32, "Simplex" },
+    {  33, "North Building Technologies Limited" },
+    {  34, "Notifier" },
+    {  35, "Reliable Controls Corporation" },
+    {  36, "Tridium Inc." },
+    {  37, "Sierra Monitor Corporation/FieldServer Technologies" },
+    {  38, "Silicon Energy" },
+    {  39, "Kieback & Peter GmbH & Co KG" },
+    {  40, "Anacon Systems, Inc." },
+    {  41, "Systems Controls & Instruments, LLC" },
+    {  42, "Lithonia Lighting" },
+    {  43, "Micropower Manufacturing" },
+    {  44, "Matrix Controls" },
+    {  45, "METALAIRE" },
+    {  46, "ESS Engineering" },
+    {  47, "Sphere Systems Pty Ltd." },
+    {  48, "Walker Technologies Corporation" },
+    {  49, "H I Solutions, Inc." },
+    {  50, "MBS GmbH" },
+    {  51, "SAMSON AG" },
+    {  52, "Badger Meter Inc." },
+    {  53, "DAIKIN Industries Ltd." },
+    {  54, "NARA Controls Inc." },
+    {  55, "Mammoth Inc." },
+    {  56, "Liebert Corporation" },
+    {  57, "SEMCO Incorporated" },
+    {  58, "Air Monitor Corporation" },
+    {  59, "TRIATEK, LLC" },
+    {  60, "NexLight" },
+    {  61, "Multistack" },
+    {  62, "TSI Incorporated" },
+    {  63, "Weather-Rite, Inc." },
+    {  64, "Dunham-Bush" },
+    {  65, "Reliance Electric" },
+    {  66, "LCS Inc." },
+    {  67, "Regulator Australia PTY Ltd." },
+    {  68, "Touch-Plate Lighting Controls" },
+    {  69, "Amann GmbH" },
+    {  70, "RLE Technologies" },
+    {  71, "Cardkey Systems" },
+    {  72, "SECOM Co., Ltd." },
+    {  73, "ABB Gebaeudetechnik AG Bereich NetServ" },
+    {  74, "KNX Association cvba" },
+    {  75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
+    {  76, "Nohmi Bosai, Ltd." },
+    {  77, "Carel S.p.A." },
+    {  78, "UTC Fire & Security Espana, S.L." },
+    {  79, "Hochiki Corporation" },
+    {  80, "Fr. Sauter AG" },
+    {  81, "Matsushita Electric Works, Ltd." },
+    {  82, "Mitsubishi Electric Corporation, Inazawa Works" },
+    {  83, "Mitsubishi Heavy Industries, Ltd." },
+    {  84, "ITT Bell & Gossett" },
+    {  85, "Yamatake Building Systems Co., Ltd." },
+    {  86, "The Watt Stopper, Inc." },
+    {  87, "Aichi Tokei Denki Co., Ltd." },
+    {  88, "Activation Technologies, LLC" },
+    {  89, "Saia-Burgess Controls, Ltd." },
+    {  90, "Hitachi, Ltd." },
+    {  91, "Novar Corp./Trend Control Systems Ltd." },
+    {  92, "Mitsubishi Electric Lighting Corporation" },
+    {  93, "Argus Control Systems, Ltd." },
+    {  94, "Kyuki Corporation" },
+    {  95, "Richards-Zeta Building Intelligence, Inc." },
+    {  96, "Scientech R&D, Inc." },
+    {  97, "VCI Controls, Inc." },
+    {  98, "Toshiba Corporation" },
+    {  99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
+    { 100, "Custom Mechanical Equipment, LLC" },
+    { 101, "ClimateMaster" },
+    { 102, "ICP Panel-Tec, Inc." },
+    { 103, "D-Tek Controls" },
+    { 104, "NEC Engineering, Ltd." },
+    { 105, "PRIVA BV" },
+    { 106, "Meidensha Corporation" },
+    { 107, "JCI Systems Integration Services" },
+    { 108, "Freedom Corporation" },
+    { 109, "Neuberger Gebaeudeautomation GmbH" },
+    { 110, "Sitronix" },
+    { 111, "Leviton Manufacturing" },
+    { 112, "Fujitsu Limited" },
+    { 113, "Emerson Network Power" },
+    { 114, "S. A. Armstrong, Ltd." },
+    { 115, "Visonet AG" },
+    { 116, "M&M Systems, Inc." },
+    { 117, "Custom Software Engineering" },
+    { 118, "Nittan Company, Limited" },
+    { 119, "Elutions Inc. (Wizcon Systems SAS)" },
+    { 120, "Pacom Systems Pty., Ltd." },
+    { 121, "Unico, Inc." },
+    { 122, "Ebtron, Inc." },
+    { 123, "Scada Engine" },
+    { 124, "AC Technology Corporation" },
+    { 125, "Eagle Technology" },
+    { 126, "Data Aire, Inc." },
+    { 127, "ABB, Inc." },
+    { 128, "Transbit Sp. z o. o." },
+    { 129, "Toshiba Carrier Corporation" },
+    { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
+    { 131, "Tokai Soft" },
+    { 132, "Blue Ridge Technologies" },
+    { 133, "Veris Industries" },
+    { 134, "Centaurus Prime" },
+    { 135, "Sand Network Systems" },
+    { 136, "Regulvar, Inc." },
+    { 137, "AFDtek Division of Fastek International Inc." },
+    { 138, "PowerCold Comfort Air Solutions, Inc." },
+    { 139, "I Controls" },
+    { 140, "Viconics Electronics, Inc." },
+    { 141, "Yaskawa America, Inc." },
+    { 142, "DEOS control systems GmbH" },
+    { 143, "Digitale Mess- und Steuersysteme AG" },
+    { 144, "Fujitsu General Limited" },
+    { 145, "Project Engineering S.r.l." },
+    { 146, "Sanyo Electric Co., Ltd." },
+    { 147, "Integrated Information Systems, Inc." },
+    { 148, "Temco Controls, Ltd." },
+    { 149, "Airtek International Inc." },
+    { 150, "Advantech Corporation" },
+    { 151, "Titan Products, Ltd." },
+    { 152, "Regel Partners" },
+    { 153, "National Environmental Product" },
+    { 154, "Unitec Corporation" },
+    { 155, "Kanden Engineering Company" },
+    { 156, "Messner Gebaeudetechnik GmbH" },
+    { 157, "Integrated.CH" },
+    { 158, "Price Industries" },
+    { 159, "SE-Elektronic GmbH" },
+    { 160, "Rockwell Automation" },
+    { 161, "Enflex Corp." },
+    { 162, "ASI Controls" },
+    { 163, "SysMik GmbH Dresden" },
+    { 164, "HSC Regelungstechnik GmbH" },
+    { 165, "Smart Temp Australia Pty.  Ltd." },
+    { 166, "Cooper Controls" },
+    { 167, "Duksan Mecasys Co., Ltd." },
+    { 168, "Fuji IT Co., Ltd." },
+    { 169, "Vacon Plc" },
+    { 170, "Leader Controls" },
+    { 171, "Cylon Controls, Ltd." },
+    { 172, "Compas" },
+    { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
+    { 174, "Building Control Integrators" },
+    { 175, "ITG Worldwide (M) Sdn Bhd" },
+    { 176, "Lutron Electronics Co., Inc." },
+    { 177, "Cooper-Atkins Corporation" },
+    { 178, "LOYTEC Electronics GmbH" },
+    { 179, "ProLon" },
+    { 180, "Mega Controls Limited" },
+    { 181, "Micro Control Systems, Inc." },
+    { 182, "Kiyon, Inc." },
+    { 183, "Dust Networks" },
+    { 184, "Advanced Building Automation Systems" },
+    { 185, "Hermos AG" },
+    { 186, "CEZIM" },
+    { 187, "Softing" },
+    { 188, "Lynxspring, Inc." },
+    { 189, "Schneider Toshiba Inverter Europe" },
+    { 190, "Danfoss Drives A/S" },
+    { 191, "Eaton Corporation" },
+    { 192, "Matyca S.A." },
+    { 193, "Botech AB" },
+    { 194, "Noveo, Inc." },
+    { 195, "AMEV" },
+    { 196, "Yokogawa Electric Corporation" },
+    { 197, "GFR Gesellschaft fuer Regelungstechnik" },
+    { 198, "Exact Logic" },
+    { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
+    { 200, "Kandenko Co., Ltd." },
+    { 201, "DTF, Daten-Technik Fries" },
+    { 202, "Klimasoft, Ltd." },
+    { 203, "Toshiba Schneider Inverter Corporation" },
+    { 204, "Control Applications, Ltd." },
+    { 205, "KDT Systems Co., Ltd." },
+    { 206, "Onicon Incorporated" },
+    { 207, "Automation Displays, Inc." },
+    { 208, "Control Solutions, Inc." },
+    { 209, "Remsdaq Limited" },
+    { 210, "NTT Facilities, Inc." },
+    { 211, "VIPA GmbH" },
+    { 212, "TSC21 Association of Japan" },
+    { 213, "Strato Automation" },
+    { 214, "HRW Limited" },
+    { 215, "Lighting Control & Design, Inc." },
+    { 216, "Mercy Electronic and Electrical Industries" },
+    { 217, "Samsung SDS Co., Ltd" },
+    { 218, "Impact Facility Solutions, Inc." },
+    { 219, "Aircuity" },
+    { 220, "Control Techniques, Ltd." },
+    { 221, "OpenGeneral Pty., Ltd." },
+    { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
+    { 223, "Cerus Industrial" },
+    { 224, "Chloride Power Protection Company" },
+    { 225, "Computrols, Inc." },
+    { 226, "Phoenix Contact GmbH & Co. KG" },
+    { 227, "Grundfos Management A/S" },
+    { 228, "Ridder Drive Systems" },
+    { 229, "Soft Device SDN BHD" },
+    { 230, "Integrated Control Technology Limited" },
+    { 231, "AIRxpert Systems, Inc." },
+    { 232, "Microtrol Limited" },
+    { 233, "Red Lion Controls" },
+    { 234, "Digital Electronics Corporation" },
+    { 235, "Ennovatis GmbH" },
+    { 236, "Serotonin Software Technologies, Inc." },
+    { 237, "LS Industrial Systems Co., Ltd." },
+    { 238, "Square D Company" },
+    { 239, "S Squared Innovations, Inc." },
+    { 240, "Aricent Ltd." },
+    { 241, "EtherMetrics, LLC" },
+    { 242, "Industrial Control Communications, Inc." },
+    { 243, "Paragon Controls, Inc." },
+    { 244, "A. O. Smith Corporation" },
+    { 245, "Contemporary Control Systems, Inc." },
+    { 246, "Intesis Software SL" },
+    { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
+    { 248, "Heat-Timer Corporation" },
+    { 249, "Ingrasys Technology, Inc." },
+    { 250, "Costerm Building Automation" },
+    { 251, "WILO SE" },
+    { 252, "Embedia Technologies Corp." },
+    { 253, "Technilog" },
+    { 254, "HR Controls Ltd. & Co. KG" },
+    { 255, "Lennox International, Inc." },
+    { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
+    { 257, "Thermomax, Ltd." },
+    { 258, "ELCON Electronic Control, Ltd." },
+    { 259, "Larmia Control AB" },
+    { 260, "BACnet Stack at SourceForge" },
+    { 261, "G4S Security Services A/S" },
+    { 262, "Exor International S.p.A." },
+    { 263, "Cristal Controles" },
+    { 264, "Regin AB" },
+    { 265, "Dimension Software, Inc." },
+    { 266, "SynapSense Corporation" },
+    { 267, "Beijing Nantree Electronic Co., Ltd." },
+    { 268, "Camus Hydronics Ltd." },
+    { 269, "Kawasaki Heavy Industries, Ltd." },
+    { 270, "Critical Environment Technologies" },
+    { 271, "ILSHIN IBS Co., Ltd." },
+    { 272, "ELESTA Energy Control AG" },
+    { 273, "KROPMAN Installatietechniek" },
+    { 274, "Baldor Electric Company" },
+    { 275, "INGA mbH" },
+    { 276, "GE Consumer & Industrial" },
+    { 277, "Functional Devices, Inc." },
+    { 278, "ESAC" },
+    { 279, "M-System Co., Ltd." },
+    { 280, "Yokota Co., Ltd." },
+    { 281, "Hitranse Technology Co., LTD" },
+    { 282, "Federspiel Controls" },
+    { 283, "Kele, Inc." },
+    { 284, "Opera Electronics, Inc." },
+    { 285, "Gentec" },
+    { 286, "Embedded Science Labs, LLC" },
+    { 287, "Parker Hannifin Corporation" },
+    { 288, "MaCaPS International Limited" },
+    { 289, "Link4 Corporation" },
+    { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
+    { 291, "Pribusin, Inc." },
+    { 292, "Advantage Controls" },
+    { 293, "Critical Room Control" },
+    { 294, "LEGRAND" },
+    { 295, "Tongdy Control Technology Co., Ltd." },
+    { 296, "ISSARO Integrierte Systemtechnik" },
+    { 297, "Pro-Dev Industries" },
+    { 298, "DRI-STEEM" },
+    { 299, "Creative Electronic GmbH" },
+    { 300, "Swegon AB" },
+    { 301, "Jan Brachacek" },
+    { 302, "Hitachi Appliances, Inc." },
+    { 303, "Real Time Automation, Inc." },
+    { 304, "ITEC Hankyu-Hanshin Co." },
+    { 305, "Cyrus E&M Engineering Co., Ltd." },
+    { 306, "Badger Meter" },
+    { 307, "Cirrascale Corporation" },
+    { 308, "Elesta GmbH Building Automation" },
+    { 309, "Securiton" },
+    { 310, "OSlsoft, Inc." },
+    { 311, "Hanazeder Electronic GmbH" },
+    { 312, "Honeywell Security Deutschland, Novar GmbH" },
+    { 313, "Siemens Energy & Automation, Inc." },
+    { 314, "ETM Professional Control GmbH" },
+    { 315, "Meitav-tec, Ltd." },
+    { 316, "Janitza Electronics GmbH" },
+    { 317, "MKS Nordhausen" },
+    { 318, "De Gier Drive Systems B.V." },
+    { 319, "Cypress Envirosystems" },
+    { 320, "SMARTron s.r.o." },
+    { 321, "Verari Systems, Inc." },
+    { 322, "K-W Electronic Service, Inc." },
+    { 323, "ALFA-SMART Energy Management" },
+    { 324, "Telkonet, Inc." },
+    { 325, "Securiton GmbH" },
+    { 326, "Cemtrex, Inc." },
+    { 327, "Performance Technologies, Inc." },
+    { 328, "Xtralis (Aust) Pty Ltd" },
+    { 329, "TROX GmbH" },
+    { 330, "Beijing Hysine Technology Co., Ltd" },
+    { 331, "RCK Controls, Inc." },
+    { 332, "Distech Controls SAS" },
+    { 333, "Novar/Honeywell" },
+    { 334, "The S4 Group, Inc." },
+    { 335, "Schneider Electric" },
+    { 336, "LHA Systems" },
+    { 337, "GHM engineering Group, Inc." },
+    { 338, "Cllimalux S.A." },
+    { 339, "VAISALA Oyj" },
+    { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
+    { 341, "SCADAmetrics" },
+    { 342, "POWERPEG NSI Limited" },
+    { 343, "BACnet Interoperability Testing Services, Inc." },
+    { 344, "Teco a.s." },
+    { 345, "Plexus Technology, Inc." },
+    { 346, "Energy Focus, Inc." },
+    { 347, "Powersmiths International Corp." },
+    { 348, "Nichibei Co., Ltd." },
+    { 349, "HKC Technology Ltd." },
+    { 350, "Ovation Networks, Inc." },
+    { 351, "Setra Systems" },
+    { 352, "AVG Automation" },
+    { 353, "ZXC Ltd." },
+    { 354, "Byte Sphere" },
+    { 355, "Generiton Co., Ltd." },
+    { 356, "Holter Regelarmaturen GmbH & Co. KG" },
+    { 357, "Bedford Instruments, LLC" },
+    { 358, "Standair Inc." },
+    { 359, "WEG Automation - R&D" },
+    { 360, "Prolon Control Systems ApS" },
+    { 361, "Inneasoft" },
+    { 362, "ConneXSoft GmbH" },
+    { 363, "CEAG Notlichtsysteme GmbH" },
+    { 364, "Distech Controls Inc." },
+    { 365, "Industrial Technology Research Institute" },
+    { 366, "ICONICS, Inc." },
+    { 367, "IQ Controls s.c." },
+    { 368, "OJ Electronics A/S" },
+    { 369, "Rolbit Ltd." },
+    { 370, "Synapsys Solutions Ltd." },
+    { 371, "ACME Engineering Prod. Ltd." },
+    { 372, "Zener Electric Pty, Ltd." },
+    { 373, "Selectronix, Inc." },
+    { 374, "Gorbet & Banerjee, LLC." },
+    { 375, "IME" },
+    { 376, "Stephen H. Dawson Computer Service" },
+    { 377, "Accutrol, LLC" },
+    { 378, "Schneider Elektronik GmbH" },
+    { 379, "Alpha-Inno Tec GmbH" },
+    { 380, "ADMMicro, Inc." },
+    { 381, "Greystone Energy Systems, Inc." },
+    { 382, "CAP Technologie" },
+    { 383, "KeRo Systems" },
+    { 384, "Domat Control System s.r.o." },
+    { 385, "Efektronics Pty. Ltd." },
+    { 386, "Hekatron Vertriebs GmbH" },
+    { 387, "Securiton AG" },
+    { 388, "Carlo Gavazzi Controls SpA" },
+    { 389, "Chipkin Automation Systems" },
+    { 390, "Savant Systems, LLC" },
+    { 391, "Simmtronic Lighting Controls" },
+    { 392, "Abelko Innovation AB" },
+    { 393, "Seresco Technologies Inc." },
+    { 394, "IT Watchdogs" },
+    { 395, "Automation Assist Japan Corp." },
+    { 396, "Thermokon Sensortechnik GmbH" },
+    { 397, "EGauge Systems, LLC" },
+    { 398, "Quantum Automation (ASIA) PTE, Ltd." },
+    { 399, "Toshiba Lighting & Technology Corp." },
+    { 400, "SPIN Engenharia de Automacao Ltda." },
+    { 401, "Logistics Systems & Software Services India PVT. Ltd." },
+    { 402, "Delta Controls Integration Products" },
+    { 403, "Focus Media" },
+    { 404, "LUMEnergi Inc." },
+    { 405, "Kara Systems" },
+    { 406, "RF Code, Inc." },
+    { 407, "Fatek Automation Corp." },
+    { 408, "JANDA Software Company, LLC" },
+    { 409, "Open System Solutions Limited" },
+    { 410, "Intelec Systems PTY Ltd." },
+    { 411, "Ecolodgix, LLC" },
+    { 412, "Douglas Lighting Controls" },
+    { 413, "iSAtech GmbH" },
+    { 414, "AREAL" },
+    { 415, "Beckhoff Automation GmbH" },
+    { 416, "IPAS GmbH" },
+    { 417, "KE2 Therm Solutions" },
+    { 418, "Base2Products" },
+    { 419, "DTL Controls, LLC" },
+    { 420, "INNCOM International, Inc." },
+    { 421, "BTR Netcom GmbH" },
+    { 422, "Greentrol Automation, Inc" },
+    { 423, "BELIMO Automation AG" },
+    { 424, "Samsung Heavy Industries Co, Ltd" },
+    { 425, "Triacta Power Technologies, Inc." },
+    { 426, "Globestar Systems" },
+    { 427, "MLB Advanced Media, LP" },
+    { 428, "SWG Stuckmann Wirtschaftliche Gebaeudesysteme GmbH" },
+    { 429, "SensorSwitch" },
+    { 430, "Multitek Power Limited" },
+    { 431, "Aquametro AG" },
+    { 432, "LG Electronics Inc." },
+    { 433, "Electronic Theatre Controls, Inc." },
+    { 434, "Mitsubishi Electric Corporation Nagoya Works" },
+    { 435, "Delta Electronics, Inc." },
+    { 436, "Elma Kurtalj, Ltd." },
+    { 437, "ADT Fire and Security Sp. A.o.o." },
+    { 438, "Nedap Security Management" },
+    { 439, "ESC Automation Inc." },
+    { 440, "DSP4YOU Ltd." },
+    { 441, "GE Sensing and Inspection Technologies" },
+    { 442, "Embedded Systems SIA" },
+    { 443, "BEFEGA GmbH" },
+    { 444, "Baseline Inc." },
+    { 445, "M2M Systems Integrators" },
+    { 446, "OEMCtrl" },
+    { 447, "Clarkson Controls Limited" },
+    { 448, "Rogerwell Control System Limited" },
+    { 449, "SCL Elements" },
+    { 450, "Hitachi Ltd." },
+    { 451, "Newron System SA" },
+    { 452, "BEVECO Gebouwautomatisering BV" },
+    { 453, "Streamside Solutions" },
+    { 454, "Yellowstone Soft" },
+    { 455, "Oztech Intelligent Systems Pty Ltd." },
+    { 456, "Novelan GmbH" },
+    { 457, "Flexim Americas Corporation" },
+    { 458, "ICP DAS Co., Ltd." },
+    { 459, "CARMA Industries Inc." },
+    { 460, "Log-One Ltd." },
+    { 461, "TECO Electric & Machinery Co., Ltd." },
+    { 462, "ConnectEx, Inc." },
+    { 463, "Turbo DDC Suedwest" },
+    { 464, "Quatrosense Environmental Ltd." },
+    { 465, "Fifth Light Technology Ltd." },
+    { 466, "Scientific Solutions, Ltd." },
+    { 467, "Controller Area Network Solutions (M) Sdn Bhd" },
+    { 468, "RESOL - Elektronische Regelungen GmbH" },
+    { 469, "RPBUS LLC" },
+    { 470, "BRS Sistemas Eletronicos" },
+    { 471, "WindowMaster A/S" },
+    { 472, "Sunlux Technologies Ltd." },
+    { 473, "Measurlogic" },
+    { 474, "Frimat GmbH" },
+    { 475, "Spirax Sarco" },
+    { 476, "Luxtron" },
+    { 477, "Raypak Inc" },
+    { 478, "Air Monitor Corporation" },
+    { 479, "Regler Och Webbteknik Sverige (ROWS)" },
+    { 480, "Intelligent Lighting Controls Inc." },
+    { 481, "Sanyo Electric Industry Co., Ltd" },
+    { 482, "E-Mon Energy Monitoring Products" },
+    { 483, "Digital Control Systems" },
+    { 484, "ATI Airtest Technologies, Inc." },
+    { 485, "SCS SA" },
+    { 486, "HMS Industrial Networks AB" },
+    { 487, "Shenzhen Universal Intellisys Co Ltd" },
+    { 488, "EK Intellisys Sdn Bhd" },
+    { 489, "SysCom" },
+    { 490, "Firecom, Inc." },
+    { 491, "ESA Elektroschaltanlagen Grimma GmbH" },
+    { 492, "Kumahira Co Ltd" },
+    { 493, "Hotraco" },
+    { 494, "SABO Elektronik GmbH" },
+    { 495, "Equip'Trans" },
+    { 496, "TCS Basys Controls" },
+    { 497, "FlowCon International A/S" },
+    { 498, "ThyssenKrupp Elevator Americas" },
+    { 499, "Abatement Technologies" },
+    { 500, "Continental Control Systems, LLC" },
+    { 501, "WISAG Automatisierungstechnik GmbH & Co KG" },
+    { 502, "EasyIO" },
+    { 503, "EAP-Electric GmbH" },
+    { 504, "Hardmeier" },
+    { 505, "Mircom Group of Companies" },
+    { 506, "Quest Controls" },
+    { 507, "Mestek, Inc" },
+    { 508, "Pulse Energy" },
+    { 509, "Tachikawa Corporation" },
+    { 510, "University of Nebraska-Lincoln" },
+    { 511, "Redwood Systems" },
+    { 512, "PASStec Industrie-Elektronik GmbH" },
+    { 513, "NgEK, Inc." },
+    { 514, "FAW Electronics Ltd" },
+    { 515, "Jireh Energy Tech Co., Ltd." },
+    { 516, "Enlighted Inc." },
+    { 517, "El-Piast Sp. Z o.o" },
+    { 518, "NetxAutomation Software GmbH" },
+    { 519, "Invertek Drives" },
+    { 520, "Deutschmann Automation GmbH & Co. KG" },
+    { 521, "EMU Electronic AG" },
+    { 522, "Phaedrus Limited" },
+    { 523, "Sigmatek GmbH & Co KG" },
+    { 524, "Marlin Controls" },
+    { 525, "Circutor, SA" },
+    { 526, "UTC Fire & Security" },
+    { 527, "DENT Instruments, Inc." },
+    { 528, "FHP Manufacturing Company - Bosch Group" },
+    { 529, "GE Intelligent Platforms" },
+    { 530, "Inner Range Pty Ltd" },
+    { 531, "GLAS Energy Technology" },
+    { 532, "MSR-Electronic-GmbH" },
+    { 533, "Energy Control Systems, Inc." },
+    { 534, "EMT Controls" },
+    { 535, "Daintree Networks Inc." },
+    { 536, "EURO ICC d.o.o" },
+    { 537, "TE Connectivity Energy" },
+    { 538, "GEZE GmbH" },
+    { 539, "NEC Corporation" },
+    { 540, "Ho Cheung International Company Limited" },
+    { 541, "Sharp Manufacturing Systems Corporation" },
+    { 542, "DOT CONTROLS a.s." },
+    { 543, "BeaconMedaes" },
+    { 544, "Midea Commercial Aircon" },
+    { 545, "WattMaster Controls" },
+    { 546, "Kamstrup A/S" },
+    { 547, "CA Computer Automation GmbH" },
+    { 548, "Laars Heating Systems Company" },
+    { 549, "Hitachi Systems, Ltd." },
+    { 550, "Fushan AKE Electronic Engineering Co., Ltd." },
+    { 551, "Toshiba International Corporation" },
+    { 552, "Starman Systems, LLC" },
+    { 553, "Samsung Techwin Co., Ltd." },
+    { 554, "ISAS-Integrated Switchgear and Systems P/L" },
+    { 556, "Obvius" },
+    { 557, "Marek Guzik" },
+    { 558, "Vortek Instruments, LLC" },
+    { 559, "Universal Lighting Technologies" },
+    { 560, "Myers Power Products, Inc." },
+    { 561, "Vector Controls GmbH" },
+    { 562, "Crestron Electronics, Inc." },
+    { 563, "A&E Controls Limited" },
+    { 564, "Projektomontaza A.D." },
+    { 565, "Freeaire Refrigeration" },
+    { 566, "Aqua Cooler Pty Limited" },
+    { 567, "Basic Controls" },
+    { 568, "GE Measurement and Control Solutions Advanced Sensors" },
+    { 569, "EQUAL Networks" },
+    { 570, "Millennial Net" },
+    { 571, "APLI Ltd" },
+    { 572, "Electro Industries/GaugeTech" },
+    { 573, "SangMyung University" },
+    { 574, "Coppertree Analytics, Inc." },
+    { 575, "CoreNetiX GmbH" },
+    { 576, "Acutherm" },
+    { 577, "Dr. Riedel Automatisierungstechnik GmbH" },
+    { 578, "Shina System Co., Ltd" },
+    { 579, "Iqapertus" },
+    { 580, "PSE Technology" },
+    { 581, "BA Systems" },
+    { 582, "BTICINO" },
+    { 583, "Monico, Inc." },
+    { 584, "iCue" },
+    { 585, "tekmar Control Systems Ltd." },
+    { 586, "Control Technology Corporation" },
+    { 587, "GFAE GmbH" },
+    { 588, "BeKa Software GmbH" },
+    { 589, "Isoil Industria SpA" },
+    { 590, "Home Systems Consulting SpA" },
+    { 591, "Socomec" },
+    { 592, "Everex Communications, Inc." },
+    { 593, "Ceiec Electric Technology" },
+    { 594, "Atrila GmbH" },
+    { 595, "WingTechs" },
+    { 596, "Shenzhen Mek Intellisys Pte Ltd." },
+    { 597, "Nestfield Co., Ltd." },
+    { 598, "Swissphone Telecom AG" },
+    { 599, "PNTECH JSC" },
+    { 600, "Horner APG, LLC" },
+    { 601, "PVI Industries, LLC" },
+    { 602, "Ela-compil" },
+    { 603, "Pegasus Automation International LLC" },
+    { 604, "Wight Electronic Services Ltd." },
+    { 605, "Marcom" },
+    { 606, "Exhausto A/S" },
+    { 607, "Dwyer Instruments, Inc." },
+    { 608, "Link GmbH" },
+    { 609, "Oppermann Regelgerate GmbH" },
+    { 610, "NuAire, Inc." },
+    { 611, "Nortec Humidity, Inc." },
+    { 612, "Bigwood Systems, Inc." },
+    { 613, "Enbala Power Networks" },
+    { 614, "Inter Energy Co., Ltd." },
+    { 615, "ETC" },
+    { 616, "COMELEC S.A.R.L" },
+    { 617, "Pythia Technologies" },
+    { 618, "TrendPoint Systems, Inc." },
+    { 619, "AWEX" },
+    { 620, "Eurevia" },
+    { 621, "Kongsberg E-lon AS" },
+    { 622, "FlaktWoods" },
+    { 623, "E + E Elektronik GES M.B.H." },
+    { 624, "ARC Informatique" },
+    { 625, "SKIDATA AG" },
+    { 626, "WSW Solutions" },
+    { 627, "Trefon Electronic GmbH" },
+    { 628, "Dongseo System" },
+    { 629, "Kanontec Intelligence Technology Co., Ltd." },
+    { 630, "EVCO S.p.A." },
+    { 631, "Accuenergy (CANADA) Inc." },
+    { 632, "SoftDEL" },
+    { 633, "Orion Energy Systems, Inc." },
+    { 634, "Roboticsware" },
+    { 635, "DOMIQ Sp. z o.o." },
+    { 636, "Solidyne" },
+    { 637, "Elecsys Corporation" },
+    { 638, "Conditionaire International Pty. Limited" },
+    { 639, "Quebec, Inc." },
+    { 640, "Homerun Holdings" },
+    { 641, "Murata Americas" },
+    { 642, "Comptek" },
+    { 643, "Westco Systems, Inc." },
+    { 644, "Advancis Software & Services GmbH" },
+    { 645, "Intergrid, LLC" },
+    { 646, "Markerr Controls, Inc." },
+    { 647, "Toshiba Elevator and Building Systems Corporation" },
+    { 648, "Spectrum Controls, Inc." },
+    { 649, "Mkservice" },
+    { 650, "Fox Thermal Instruments" },
+    { 651, "SyxthSense Ltd" },
+    { 652, "DUHA System S R.O." },
+    { 653, "NIBE" },
+    { 654, "Melink Corporation" },
+    { 655, "Fritz-Haber-Institut" },
+    { 656, "MTU Onsite Energy GmbH, Gas Power Systems" },
+    { 657, "Omega Engineering, Inc." },
+    { 658, "Avelon" },
+    { 659, "Ywire Technologies, Inc." },
+    { 660, "M.R. Engineering Co., Ltd." },
+    { 661, "Lochinvar, LLC" },
+    { 662, "Sontay Limited" },
+    { 663, "GRUPA Slawomir Chelminski" },
+    { 664, "Arch Meter Corporation" },
+    { 665, "Senva, Inc." },
+    { 667, "FM-Tec" },
+    { 668, "Systems Specialists, Inc." },
+    { 669, "SenseAir" },
+    { 670, "AB IndustrieTechnik Srl" },
+    { 671, "Cortland Research, LLC" },
+    { 672, "MediaView" },
+    { 673, "VDA Elettronica" },
+    { 674, "CSS, Inc." },
+    { 675, "Tek-Air Systems, Inc." },
+    { 676, "ICDT" },
+    { 677, "The Armstrong Monitoring Corporation" },
+    { 678, "DIXELL S.r.l" },
+    { 679, "Lead System, Inc." },
+    { 680, "ISM EuroCenter S.A." },
+    { 681, "TDIS" },
+    { 682, "Trade FIDES" },
+    { 683, "Knuerr GmbH (Emerson Network Power)" },
+    { 684, "Resource Data Management" },
+    { 685, "Abies Technology, Inc." },
+    { 686, "Amalva" },
+    { 687, "MIRAE Electrical Mfg. Co., Ltd." },
+    { 688, "HunterDouglas Architectural Projects Scandinavia ApS" },
+    { 689, "RUNPAQ Group Co., Ltd" },
+    { 690, "Unicard SA" },
+    { 691, "IE Technologies" },
+    { 692, "Ruskin Manufacturing" },
+    { 693, "Calon Associates Limited" },
+    { 694, "Contec Co., Ltd." },
+    { 695, "iT GmbH" },
+    { 696, "Autani Corporation" },
+    { 697, "Christian Fortin" },
+    { 698, "HDL" },
+    { 699, "IPID Sp. Z.O.O Limited" },
+    { 700, "Fuji Electric Co., Ltd" },
+    { 701, "View, Inc." },
+    { 702, "Samsung S1 Corporation" },
+    { 703, "New Lift" },
+    { 704, "VRT Systems" },
+    { 705, "Motion Control Engineering, Inc." },
+    { 706, "Weiss Klimatechnik GmbH" },
+    { 707, "Elkon" },
+    { 708, "Eliwell Controls S.r.l." },
+    { 709, "Japan Computer Technos Corp" },
+    { 710, "Rational Network ehf" },
+    { 711, "Magnum Energy Solutions, LLC" },
+    { 712, "MelRok" },
+    { 713, "VAE Group" },
+    { 714, "LGCNS" },
+    { 715, "Berghof Automationstechnik GmbH" },
+    { 716, "Quark Communications, Inc." },
+    { 717, "Sontex" },
+    { 718, "mivune AG" },
+    { 719, "Panduit" },
+    { 720, "Smart Controls, LLC" },
+    { 721, "Compu-Aire, Inc." },
+    { 722, "Sierra" },
+    { 723, "ProtoSense Technologies" },
+    { 724, "Eltrac Technologies Pvt Ltd" },
+    { 725, "Bektas Invisible Controls GmbH" },
+    { 726, "Entelec" },
+    { 727, "Innexiv" },
+    { 728, "Covenant" },
+    { 729, "Davitor AB" },
+    { 730, "TongFang Technovator" },
+    { 731, "Building Robotics, Inc." },
+    { 732, "HSS-MSR UG" },
+    { 733, "FramTack LLC" },
+    { 734, "B. L. Acoustics, Ltd." },
+    { 735, "Traxxon Rock Drills, Ltd" },
+    { 736, "Franke" },
+    { 737, "Wurm GmbH & Co" },
+    { 738, "AddENERGIE" },
+    { 739, "Mirle Automation Corporation" },
+    { 740, "Ibis Networks" },
+    { 741, "ID-KARTA s.r.o." },
+    { 742, "Anaren, Inc." },
+    { 743, "Span, Incorporated" },
+    { 744, "Bosch Thermotechnology Corp" },
+    { 745, "DRC Technology S.A." },
+    { 746, "Shanghai Energy Building Technology Co, Ltd" },
+    { 747, "Fraport AG" },
+    { 748, "Flowgroup" },
+    { 749, "Skytron Energy, GmbH" },
+    { 750, "ALTEL Wicha, Golda Sp. J." },
+    { 751, "Drupal" },
+    { 752, "Axiomatic Technology, Ltd" },
+    { 753, "Bohnke + Partner" },
+    { 754, "Function 1" },
+    { 755, "Optergy Pty, Ltd" },
+    { 756, "LSI Virticus" },
+    { 757, "Konzeptpark GmbH" },
+    { 758, "Hubbell Building Automation, Inc." },
+    { 759, "eCurv, Inc." },
+    { 760, "Agnosys GmbH" },
+    { 761, "Shanghai Sunfull Automation Co., LTD" },
+    { 762, "Kurz Instruments, Inc." },
+    { 763, "Cias Elettronica S.r.l." },
+    { 764, "Multiaqua, Inc." },
+    { 765, "BlueBox" },
+    { 766, "Sensidyne" },
+    { 767, "Viessmann Elektronik GmbH" },
+    { 768, "ADFweb.com srl" },
+    { 769, "Gaylord Industries" },
+    { 770, "Majur Ltd." },
+    { 771, "Shanghai Huilin Technology Co., Ltd." },
+    { 772, "Exotronic" },
+    { 773, "Safecontrol spol s.r.o." },
+    { 774, "Amatis" },
+    { 775, "Universal Electric Corporation" },
+    { 776, "iBACnet" },
+    { 778, "Smartrise Engineering, Inc." },
+    { 779, "Miratron, Inc." },
+    { 780, "SmartEdge" },
+    { 781, "Mitsubishi Electric Australia Pty Ltd" },
+    { 782, "Triangle Research International Ptd Ltd" },
+    { 783, "Produal Oy" },
+    { 784, "Milestone Systems A/S" },
+    { 785, "Trustbridge" },
+    { 0, NULL }
 };
+static value_string_ext BACnetVendorIdentifiers_ext = VALUE_STRING_EXT_INIT(BACnetVendorIdentifiers);
 
 static int proto_bacapp = -1;
 static int hf_bacapp_type = -1;
@@ -4293,6 +4833,7 @@ static int hf_BACnetExtendedTagNumber = -1;
 static int hf_BACnetNamedTag = -1;
 static int hf_BACnetTagClass = -1;
 static int hf_BACnetCharacterSet = -1;
+static int hf_BACnetCodePage = -1;
 static int hf_bacapp_tag_lvt = -1;
 static int hf_bacapp_tag_ProcessId = -1;
 static int hf_bacapp_uservice = -1;
@@ -4323,7 +4864,9 @@ static gint ett_bacapp_tag = -1;
 static gint ett_bacapp_list = -1;
 static gint ett_bacapp_value = -1;
 
-static dissector_handle_t data_handle;
+static expert_field ei_bacapp_bad_length = EI_INIT;
+static expert_field ei_bacapp_bad_tag = EI_INIT;
+
 static gint32 propertyIdentifier = -1;
 static gint32 propertyArrayIndex = -1;
 static guint32 object_type = 4096;
@@ -4348,50 +4891,64 @@ static int st_node_packets_by_ip_src = -1;
 static void
 bacapp_packet_stats_tree_init(stats_tree* st)
 {
-       st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
-       st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
-       st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
+    st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0);
+    st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
+    st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
+}
+
+static gchar *
+bacapp_get_address_label(const char *tag, address *addr)
+{
+    gchar *addr_str, *label_str;
+
+    addr_str = address_to_str(NULL, addr);
+    label_str = wmem_strconcat(NULL, tag, addr_str, NULL);
+    wmem_free(NULL, addr_str);
+    return label_str;
 }
 
 static int
 bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
 {
-       int packets_for_this_dst;
-       int packets_for_this_src;
-       int service_for_this_dst;
-       int service_for_this_src;
-       int src_for_this_dst;
-       int dst_for_this_src;
-       int objectid_for_this_dst;
-       int objectid_for_this_src;
-       int instanceid_for_this_dst;
-       int instanceid_for_this_src;
-       gchar *dststr;
-       gchar *srcstr;
-       const bacapp_info_value_t *binfo = p;
-
-       srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
-       dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
-
-       tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
-       packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
-       packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
-       src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
-       dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
-       service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
-       service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
-       if (binfo->service_type) {
-               objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
-               objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
-               if (binfo->object_ident) {
-                       instanceid_for_this_dst=tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
-                       tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
-                       instanceid_for_this_src=tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
-                       tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
-               }
-       }
-
-       return 1;
+    int    packets_for_this_dst;
+    int    packets_for_this_src;
+    int    service_for_this_dst;
+    int    service_for_this_src;
+    int    src_for_this_dst;
+    int    dst_for_this_src;
+    int    objectid_for_this_dst;
+    int    objectid_for_this_src;
+    int    instanceid_for_this_dst;
+    int    instanceid_for_this_src;
+    gchar *dststr;
+    gchar *srcstr;
+    const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
+
+    srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
+    dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
+
+    tick_stat_node(st, st_str_packets_by_ip, 0, TRUE);
+    packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, TRUE);
+    packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, TRUE);
+    src_for_this_dst     = tick_stat_node(st, dststr, packets_for_this_dst, TRUE);
+    dst_for_this_src     = tick_stat_node(st, srcstr, packets_for_this_src, TRUE);
+    service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, TRUE);
+    service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, TRUE);
+    if (binfo->service_type) {
+        objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, TRUE);
+        objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, TRUE);
+        if (binfo->object_ident) {
+            instanceid_for_this_dst = tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, TRUE);
+            tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, FALSE);
+            instanceid_for_this_src = tick_stat_node(st, binfo->object_ident, objectid_for_this_src, TRUE);
+            tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, FALSE);
+        }
+    }
+
+    wmem_free(NULL, srcstr);
+    wmem_free(NULL, dststr);
+
+    return 1;
 }
 
 /* Stat: BACnet Packets sorted by Service */
@@ -4401,35 +4958,39 @@ static int st_node_packets_by_service = -1;
 static void
 bacapp_service_stats_tree_init(stats_tree* st)
 {
-       st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
+    st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0);
 }
 
 static int
 bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
 {
-       int servicetype;
-       int src,dst;
-       int objectid;
+    int    servicetype;
+    int    src, dst;
+    int    objectid;
+
+    gchar *dststr;
+    gchar *srcstr;
 
-       gchar *dststr;
-       gchar *srcstr;
-       const bacapp_info_value_t *binfo = p;
+    const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
 
-       srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
-       dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
+    srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
+    dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
 
-       tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
-       if (binfo->service_type) {
-               servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
-               src = tick_stat_node(st, srcstr, servicetype, TRUE);
-               dst = tick_stat_node(st, dststr, src, TRUE);
-               if (binfo->object_ident) {
-                       objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
-                       tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
-               }
-       }
+    tick_stat_node(st, st_str_packets_by_service, 0, TRUE);
+    if (binfo->service_type) {
+        servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, TRUE);
+        src         = tick_stat_node(st, srcstr, servicetype, TRUE);
+        dst         = tick_stat_node(st, dststr, src, TRUE);
+        if (binfo->object_ident) {
+            objectid = tick_stat_node(st, binfo->object_ident, dst, TRUE);
+            tick_stat_node(st, binfo->instance_ident, objectid, FALSE);
+        }
+    }
 
-       return 1;
+    wmem_free(NULL, srcstr);
+    wmem_free(NULL, dststr);
+
+    return 1;
 }
 
 /* Stat: BACnet Packets sorted by Object Type */
@@ -4439,72 +5000,79 @@ static int st_node_packets_by_objectid = -1;
 static void
 bacapp_objectid_stats_tree_init(stats_tree* st)
 {
-       st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
+    st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0);
 }
 
 static int
 bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
 {
-       int servicetype;
-       int src,dst;
-       int objectid;
+    int    servicetype;
+    int    src, dst;
+    int    objectid;
+
+    gchar *dststr;
+    gchar *srcstr;
+    const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
 
-       gchar *dststr;
-       gchar *srcstr;
-       const bacapp_info_value_t *binfo = p;
+    srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
+    dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
 
-       srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
-       dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
+    tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
+    if (binfo->object_ident) {
+        objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
+        src = tick_stat_node(st, srcstr, objectid, TRUE);
+        dst = tick_stat_node(st, dststr, src, TRUE);
+        if (binfo->service_type) {
+            servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
+            tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
+        }
+    }
 
-       tick_stat_node(st, st_str_packets_by_objectid, 0, TRUE);
-       if (binfo->object_ident) {
-               objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, TRUE);
-               src = tick_stat_node(st, srcstr, objectid, TRUE);
-               dst = tick_stat_node(st, dststr, src, TRUE);
-               if (binfo->service_type) {
-                       servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
-                       tick_stat_node(st, binfo->instance_ident, servicetype, FALSE);
-               }
-       }
+    wmem_free(NULL, srcstr);
+    wmem_free(NULL, dststr);
 
-       return 1;
+    return 1;
 }
 
 /* Stat: BACnet Packets sorted by Instance No */
-static const gchar* st_str_packets_by_instanceid = "BACnet Packets by Instance ID";
-static int st_node_packets_by_instanceid = -1;
+static const gchar* st_str_packets_by_instanceid  = "BACnet Packets by Instance ID";
+static int          st_node_packets_by_instanceid = -1;
 
 static void
 bacapp_instanceid_stats_tree_init(stats_tree* st)
 {
-       st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
+    st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0);
 }
 
 static int
 bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
 {
-       int servicetype;
-       int src,dst;
-       int instanceid;
+    int    servicetype;
+    int    src, dst;
+    int    instanceid;
+
+    gchar *dststr;
+    gchar *srcstr;
+    const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p;
+
+    srcstr = bacapp_get_address_label("Src: ", &pinfo->src);
+    dststr = bacapp_get_address_label("Dst: ", &pinfo->dst);
 
-       gchar *dststr;
-       gchar *srcstr;
-       const bacapp_info_value_t *binfo = p;
+    tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
+    if (binfo->object_ident) {
+        instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
+        src = tick_stat_node(st, srcstr, instanceid, TRUE);
+        dst = tick_stat_node(st, dststr, src, TRUE);
+        if (binfo->service_type) {
+            servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
+            tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
+        }
+    }
 
-       srcstr = ep_strconcat("Src: ", address_to_str(&pinfo->src), NULL);
-       dststr = ep_strconcat("Dst: ", address_to_str(&pinfo->dst), NULL);
+    wmem_free(NULL, srcstr);
+    wmem_free(NULL, dststr);
 
-       tick_stat_node(st, st_str_packets_by_instanceid, 0, TRUE);
-       if (binfo->object_ident) {
-               instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, TRUE);
-               src = tick_stat_node(st, srcstr, instanceid, TRUE);
-               dst = tick_stat_node(st, dststr, src, TRUE);
-               if (binfo->service_type) {
-                       servicetype = tick_stat_node(st, binfo->service_type, dst, TRUE);
-                       tick_stat_node(st, binfo->object_ident, servicetype, FALSE);
-               }
-       }
-       return 1;
+    return 1;
 }
 
 
@@ -4512,89 +5080,96 @@ bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t*
 static void
 register_bacapp_stat_trees(void)
 {
-       stats_tree_register("bacapp","bacapp_ip","BACnet/Packets sorted by IP", 0,
-               bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
-       stats_tree_register("bacapp","bacapp_service","BACnet/Packets sorted by Service", 0,
-               bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
-       stats_tree_register("bacapp","bacapp_objectid","BACnet/Packets sorted by Object Type", 0,
-               bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
-       stats_tree_register("bacapp","bacapp_instanceid","BACnet/Packets sorted by Instance ID", 0,
-               bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
+    stats_tree_register("bacapp", "bacapp_ip", "BACnet/Packets sorted by IP", 0,
+        bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL);
+    stats_tree_register("bacapp", "bacapp_service", "BACnet/Packets sorted by Service", 0,
+        bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL);
+    stats_tree_register("bacapp", "bacapp_objectid", "BACnet/Packets sorted by Object Type", 0,
+        bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL);
+    stats_tree_register("bacapp", "bacapp_instanceid", "BACnet/Packets sorted by Instance ID", 0,
+        bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL);
 }
 
-/* 'data' must be ep_ allocated */
+/* 'data' must be allocated with wmem packet scope */
 static gint
-updateBacnetInfoValue(gint whichval, gchar *data)
-{
-       if (whichval == BACINFO_SERVICE) {
-               bacinfo.service_type = data;
-               return 0;
-       }
-       if (whichval == BACINFO_INVOKEID) {
-               bacinfo.invoke_id = data;
-               return 0;
-       }
-       if (whichval == BACINFO_OBJECTID) {
-               bacinfo.object_ident = data;
-               return 0;
-       }
-       if (whichval == BACINFO_INSTANCEID) {
-               bacinfo.instance_ident = data;
-               return 0;
-       }
-       return -1;
+updateBacnetInfoValue(gint whichval, const gchar *data)
+{
+    if (whichval == BACINFO_SERVICE) {
+        bacinfo.service_type = data;
+        return 0;
+    }
+    if (whichval == BACINFO_INVOKEID) {
+        bacinfo.invoke_id = data;
+        return 0;
+    }
+    if (whichval == BACINFO_OBJECTID) {
+        bacinfo.object_ident = data;
+        return 0;
+    }
+    if (whichval == BACINFO_INSTANCEID) {
+        bacinfo.instance_ident = data;
+        return 0;
+    }
+    return -1;
 }
 
 static const fragment_items msg_frag_items = {
-       /* Fragment subtrees */
-       &ett_msg_fragment,
-       &ett_msg_fragments,
-       /* Fragment fields */
-       &hf_msg_fragments,
-       &hf_msg_fragment,
-       &hf_msg_fragment_overlap,
-       &hf_msg_fragment_overlap_conflicts,
-       &hf_msg_fragment_multiple_tails,
-       &hf_msg_fragment_too_long_fragment,
-       &hf_msg_fragment_error,
-       &hf_msg_fragment_count,
-       /* Reassembled in field */
-       &hf_msg_reassembled_in,
-       /* Reassembled length field */
-       &hf_msg_reassembled_length,
-       /* Tag */
-       "Message fragments"
+    /* Fragment subtrees */
+    &ett_msg_fragment,
+    &ett_msg_fragments,
+    /* Fragment fields */
+    &hf_msg_fragments,
+    &hf_msg_fragment,
+    &hf_msg_fragment_overlap,
+    &hf_msg_fragment_overlap_conflicts,
+    &hf_msg_fragment_multiple_tails,
+    &hf_msg_fragment_too_long_fragment,
+    &hf_msg_fragment_error,
+    &hf_msg_fragment_count,
+    /* Reassembled in field */
+    &hf_msg_reassembled_in,
+    /* Reassembled length field */
+    &hf_msg_reassembled_length,
+    /* Reassembled data field */
+    NULL,
+    /* Tag */
+    "Message fragments"
 };
 
-/* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
-static const guint MaxAPDUSize [] = { 50,128,206,480,1024,1476 };
-
 #if 0
+/* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */
 /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */
+static const guint MaxAPDUSize [] = { 50, 128, 206, 480, 1024, 1476 };
+
 static guint
 fGetMaxAPDUSize(guint8 idx)
 {
-       /* only 16 values are defined, so use & 0x0f */
-       /* check the size of the Array, deliver either the entry
-          or the first entry if idx is outside of the array (bug 3736 comment#7) */
+    /* only 16 values are defined, so use & 0x0f */
+    /* check the size of the Array, deliver either the entry
+       or the first entry if idx is outside of the array (bug 3736 comment#7) */
 
-       if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
-               return MaxAPDUSize[0];
-       else
-               return MaxAPDUSize[idx & 0x0f];
+    if ((idx & 0x0f) >= (gint)(sizeof(MaxAPDUSize)/sizeof(guint)))
+        return MaxAPDUSize[0];
+    else
+        return MaxAPDUSize[idx & 0x0f];
 }
 #endif
 
+static const char*
+val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
+    const char *fmt, const char *split_fmt)
+    G_GNUC_PRINTF(4, 0)
+    G_GNUC_PRINTF(5, 0);
 
 /* Used when there are ranges of reserved and proprietary enumerations */
 static const char*
 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
-       const char *fmt, const char *split_fmt)
+    const char *fmt, const char *split_fmt)
 {
-       if (val < split_val)
-               return val_to_str(val, vs, fmt);
-       else
-               return val_to_str(val, vs, split_fmt);
+    if (val < split_val)
+        return val_to_str(val, vs, fmt);
+    else
+        return val_to_str(val, vs, split_fmt);
 }
 
 /* from clause 20.2.1.3.2 Constructed Data */
@@ -4602,19 +5177,19 @@ val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
 static gboolean
 tag_is_extended_value(guint8 tag)
 {
-       return (tag & 0x07) == 5;
+    return (tag & 0x07) == 5;
 }
 
 static gboolean
 tag_is_opening(guint8 tag)
 {
-       return (tag & 0x07) == 6;
+    return (tag & 0x07) == 6;
 }
 
 static gboolean
 tag_is_closing(guint8 tag)
 {
-       return (tag & 0x07) == 7;
+    return (tag & 0x07) == 7;
 }
 
 /* from clause 20.2.1.1 Class
@@ -4623,77 +5198,76 @@ tag_is_closing(guint8 tag)
 static gboolean
 tag_is_context_specific(guint8 tag)
 {
-       return (tag & 0x08) != 0;
+    return (tag & 0x08) != 0;
 }
 
 static gboolean
 tag_is_extended_tag_number(guint8 tag)
 {
-       return ((tag & 0xF0) == 0xF0);
+    return ((tag & 0xF0) == 0xF0);
 }
 
 static guint32
 object_id_type(guint32 object_identifier)
 {
-       return ((object_identifier >> 22) & 0x3FF);
+    return ((object_identifier >> 22) & 0x3FF);
 }
 
 static guint32
 object_id_instance(guint32 object_identifier)
 {
-       return (object_identifier & 0x3FFFFF);
+    return (object_identifier & 0x3FFFFF);
 }
 
 static guint
-fTagNo (tvbuff_t *tvb, guint offset)
+fTagNo(tvbuff_t *tvb, guint offset)
 {
-       return (guint)(tvb_get_guint8(tvb, offset) >> 4);
+    return (guint)(tvb_get_guint8(tvb, offset) >> 4);
 }
 
 static gboolean
-fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
-{
-       gboolean valid = TRUE;
-
-       switch (lvt) {
-               case 1:
-                       *val = tvb_get_guint8(tvb, offset);
-                       break;
-               case 2:
-                       *val = tvb_get_ntohs(tvb, offset);
-                       break;
-               case 3:
-                       *val = tvb_get_ntoh24(tvb, offset);
-                       break;
-               case 4:
-                       *val = tvb_get_ntohl(tvb, offset);
-                       break;
-               default:
-                       valid = FALSE;
-                       break;
-       }
-
-       return valid;
+fUnsigned32(tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
+{
+    gboolean valid = TRUE;
+
+    switch (lvt) {
+    case 1:
+        *val = tvb_get_guint8(tvb, offset);
+        break;
+    case 2:
+        *val = tvb_get_ntohs(tvb, offset);
+        break;
+    case 3:
+        *val = tvb_get_ntoh24(tvb, offset);
+        break;
+    case 4:
+        *val = tvb_get_ntohl(tvb, offset);
+        break;
+    default:
+        valid = FALSE;
+        break;
+    }
+
+    return valid;
 }
 
 static gboolean
-fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
+fUnsigned64(tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
 {
-       gboolean valid = FALSE;
-       gint64 value = 0;
-       guint8 data, i;
+    gboolean valid = FALSE;
+    gint64   value = 0;
+    guint8   data, i;
 
-       if (lvt && (lvt <= 8)) {
-               valid = TRUE;
-               data = tvb_get_guint8(tvb, offset);
-               for (i = 0; i < lvt; i++) {
-                       data = tvb_get_guint8(tvb, offset+i);
-                       value = (value << 8) + data;
-               }
-               *val = value;
-       }
+    if (lvt && (lvt <= 8)) {
+        valid = TRUE;
+        for (i = 0; i < lvt; i++) {
+            data = tvb_get_guint8(tvb, offset+i);
+            value = (value << 8) + data;
+        }
+        *val = value;
+    }
 
-       return valid;
+    return valid;
 }
 
 /* BACnet Signed Value uses 2's complement notation, but with a twist:
@@ -4703,913 +5277,914 @@ fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
    octet is 0, and the first octet shall not be X'FF' if the most
    significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
 static gboolean
-fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
-{
-       gboolean valid = FALSE;
-       gint64 value = 0;
-       guint8 data;
-       guint32 i;
-
-       /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
-       if (lvt && (lvt <= 7)) {
-               valid = TRUE;
-               data = tvb_get_guint8(tvb, offset);
-               if ((data & 0x80) != 0)
-                       value = (-1 << 8) | data;
-               else
-                       value = data;
-               for (i = 1; i < lvt; i++) {
-                       data = tvb_get_guint8(tvb, offset+i);
-                       value = (value << 8) + data;
-               }
-               *val = value;
-       }
-
-       return valid;
-}
-
-static guint
-fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
-       guint8 *tag_no, guint8* tag_info, guint32 *lvt)
-{
-       guint8 tag;
-       guint8 value;
-       guint tag_len = 1;
-       guint lvt_len = 1; /* used for tree display of lvt */
-       guint lvt_offset; /* used for tree display of lvt */
-       proto_item *ti;
-       proto_tree *subtree;
-
-       lvt_offset = offset;
-       tag = tvb_get_guint8(tvb, offset);
-       *tag_info = 0;
-       *lvt = tag & 0x07;
-       /* To solve the problem of lvt values of 6/7 being indeterminate - it */
-       /* can mean open/close tag or length of 6/7 after the length is */
-       /* computed below - store whole tag info, not just context bit. */
-       if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
-       *tag_no = tag >> 4;
-       if (tag_is_extended_tag_number(tag)) {
-               *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
-       }
-       if (tag_is_extended_value(tag)) {       /* length is more than 4 Bytes */
-               lvt_offset += tag_len;
-               value = tvb_get_guint8(tvb, lvt_offset);
-               tag_len++;
-               if (value == 254) { /* length is encoded with 16 Bits */
-                       *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
-                       tag_len += 2;
-                       lvt_len += 2;
-               } else if (value == 255) { /* length is encoded with 32 Bits */
-                       *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
-                       tag_len += 4;
-                       lvt_len += 4;
-               } else
-                       *lvt = value;
-       }
-
-       if (tree) {
-               if (tag_is_opening(tag))
-                       ti = proto_tree_add_text(tree, tvb, offset, tag_len, "{[%u]", *tag_no );
-               else if (tag_is_closing(tag))
-                       ti = proto_tree_add_text(tree, tvb, offset, tag_len, "}[%u]", *tag_no );
-               else if (tag_is_context_specific(tag)) {
-                       ti = proto_tree_add_text(tree, tvb, offset, tag_len,
-                               "Context Tag: %u, Length/Value/Type: %u",
-                               *tag_no, *lvt);
-               } else
-                       ti = proto_tree_add_text(tree, tvb, offset, tag_len,
-                               "Application Tag: %s, Length/Value/Type: %u",
-                               val_to_str(*tag_no,
-                                       BACnetApplicationTagNumber,
-                                       ASHRAE_Reserved_Fmt),
-                                       *lvt);
-
-               subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-               /* details if needed */
-               proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
-               if (tag_is_extended_tag_number(tag)) {
-                       proto_tree_add_uint_format(subtree,
-                                       hf_BACnetContextTagNumber,
-                                       tvb, offset, 1, tag,
-                                       "Extended Tag Number");
-                       proto_tree_add_item(subtree,
-                               hf_BACnetExtendedTagNumber,
-                               tvb, offset + 1, 1, ENC_BIG_ENDIAN);
-               } else {
-                       if (tag_is_context_specific(tag))
-                               proto_tree_add_item(subtree,
-                                       hf_BACnetContextTagNumber,
-                                       tvb, offset, 1, ENC_BIG_ENDIAN);
-                       else
-                               proto_tree_add_item(subtree,
-                                       hf_BACnetApplicationTagNumber,
-                                       tvb, offset, 1, ENC_BIG_ENDIAN);
-               }
-               if (tag_is_closing(tag) || tag_is_opening(tag))
-                       proto_tree_add_item(subtree,
-                               hf_BACnetNamedTag,
-                               tvb, offset, 1, ENC_BIG_ENDIAN);
-               else if (tag_is_extended_value(tag)) {
-                       proto_tree_add_item(subtree,
-                               hf_BACnetNamedTag,
-                               tvb, offset, 1, ENC_BIG_ENDIAN);
-                       proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
-                               tvb, lvt_offset, lvt_len, *lvt);
-               } else
-                       proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
-                               tvb, lvt_offset, lvt_len, *lvt);
-       }
-
-       return tag_len;
-}
-
-static guint
-fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
-       guint32 *lvt)
-{
-       return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
-}
-
-static guint
-fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_item *ti;
-       proto_tree *subtree;
-
-       ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset + 1;
-}
-
-static guint
-fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt = 0;
-       proto_item *ti;
-       proto_tree *subtree;
-       guint bool_len = 1;
-
-       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (tag_info && lvt == 1) {
-               lvt = tvb_get_guint8(tvb, offset+1);
-               ++bool_len;
-       }
-
-       ti = proto_tree_add_text(tree, tvb, offset, bool_len,
-               "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset + bool_len;
-}
-
-static guint
-fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       guint64 val = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
+fSigned64(tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
+{
+    gboolean valid = FALSE;
+    gint64   value = 0;
+    guint8   data;
+    guint32  i;
+
+    /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
+    if (lvt && (lvt <= 7)) {
+        valid = TRUE;
+        data = tvb_get_guint8(tvb, offset);
+        if ((data & 0x80) != 0)
+            value = (-1 << 8) | data;
+        else
+            value = data;
+        for (i = 1; i < lvt; i++) {
+            data = tvb_get_guint8(tvb, offset+i);
+            value = (value << 8) + data;
+        }
+        *val = value;
+    }
+
+    return valid;
+}
+
+static guint
+fTagHeaderTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+    guint offset, guint8 *tag_no, guint8* tag_info, guint32 *lvt)
+{
+    proto_item *ti = NULL;
+    guint8      tag;
+    guint8      value;
+    guint       tag_len = 1;
+    guint       lvt_len = 1;    /* used for tree display of lvt */
+    guint       lvt_offset;     /* used for tree display of lvt */
+
+    lvt_offset = offset;
+    tag        = tvb_get_guint8(tvb, offset);
+    *tag_info  = 0;
+    *lvt       = tag & 0x07;
+
+    /* To solve the problem of lvt values of 6/7 being indeterminate - it */
+    /* can mean open/close tag or length of 6/7 after the length is */
+    /* computed below - store whole tag info, not just context bit. */
+    if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
+    *tag_no = tag >> 4;
+    if (tag_is_extended_tag_number(tag)) {
+        *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
+    }
+    if (tag_is_extended_value(tag)) {       /* length is more than 4 Bytes */
+        lvt_offset += tag_len;
+        value = tvb_get_guint8(tvb, lvt_offset);
+        tag_len++;
+        if (value == 254) { /* length is encoded with 16 Bits */
+            *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
+            tag_len += 2;
+            lvt_len += 2;
+        } else if (value == 255) { /* length is encoded with 32 Bits */
+            *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
+            tag_len += 4;
+            lvt_len += 4;
+        } else
+            *lvt = value;
+    }
+
+    if (tree) {
+        proto_tree *subtree;
+        if (tag_is_opening(tag)) {
+            subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len,
+                    ett_bacapp_tag, &ti, "{[%u]", *tag_no );
+        } else if (tag_is_closing(tag)) {
+            subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len,
+                    ett_bacapp_tag, &ti, "}[%u]", *tag_no );
+        } else if (tag_is_context_specific(tag)) {
+            subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len,
+                    ett_bacapp_tag, &ti,
+                    "Context Tag: %u, Length/Value/Type: %u", *tag_no, *lvt);
+        } else {
+            subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len,
+                    ett_bacapp_tag, &ti,
+                    "Application Tag: %s, Length/Value/Type: %u",
+                    val_to_str(*tag_no, BACnetApplicationTagNumber,
+                        ASHRAE_Reserved_Fmt),
+                    *lvt);
+        }
+
+        /* details if needed */
+        proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN);
+        if (tag_is_extended_tag_number(tag)) {
+            proto_tree_add_uint_format(subtree,
+                                       hf_BACnetContextTagNumber,
+                                       tvb, offset, 1, tag,
+                                       "Extended Tag Number");
+            proto_tree_add_item(subtree,
+                                hf_BACnetExtendedTagNumber,
+                                tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+        } else {
+            if (tag_is_context_specific(tag))
+                proto_tree_add_item(subtree,
+                                    hf_BACnetContextTagNumber,
+                                    tvb, offset, 1, ENC_BIG_ENDIAN);
+            else
+                proto_tree_add_item(subtree,
+                                    hf_BACnetApplicationTagNumber,
+                                    tvb, offset, 1, ENC_BIG_ENDIAN);
+        }
+        if (tag_is_closing(tag) || tag_is_opening(tag))
+            proto_tree_add_item(subtree,
+                                hf_BACnetNamedTag,
+                                tvb, offset, 1, ENC_BIG_ENDIAN);
+        else if (tag_is_extended_value(tag)) {
+            proto_tree_add_item(subtree,
+                                hf_BACnetNamedTag,
+                                tvb, offset, 1, ENC_BIG_ENDIAN);
+            proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
+                                tvb, lvt_offset, lvt_len, *lvt);
+        } else
+            proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
+                                tvb, lvt_offset, lvt_len, *lvt);
+    } /* if (tree) */
+
+    if (*lvt > tvb_reported_length(tvb)) {
+        expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
+                               "LVT length too long: %d > %d", *lvt,
+                               tvb_reported_length(tvb));
+        *lvt = 1;
+    }
+
+    return tag_len;
+}
+
+static guint
+fTagHeader(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint8 *tag_no, guint8* tag_info,
+    guint32 *lvt)
+{
+    return fTagHeaderTree(tvb, pinfo, NULL, offset, tag_no, tag_info, lvt);
+}
+
+static guint
+fNullTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree;
+
+    subtree = proto_tree_add_subtree_format(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "%sNULL", label);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset + 1;
+}
+
+static guint
+fBooleanTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    guint8      tag_no, tag_info;
+    guint32     lvt      = 0;
+    proto_tree *subtree;
+    guint       bool_len = 1;
+
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (tag_info && lvt == 1) {
+        lvt = tvb_get_guint8(tvb, offset+1);
+        ++bool_len;
+    }
+
+    subtree = proto_tree_add_subtree_format(tree, tvb, offset, bool_len,
+                             ett_bacapp_tag, NULL, "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset + bool_len;
+}
+
+static guint
+fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    guint64     val = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_len;
+    proto_tree *subtree;
 
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       /* only support up to an 8 byte (64-bit) integer */
-       if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
-       else
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s - %u octets (Unsigned)", label, lvt);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    /* only support up to an 8 byte (64-bit) integer */
+    if (fUnsigned64(tvb, offset + tag_len, lvt, &val))
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL, "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
+    else
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL, "%s - %u octets (Unsigned)", label, lvt);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
 
-       return offset+tag_len+lvt;
+    return offset+tag_len+lvt;
 }
 
 static guint
-fDevice_Instance (tvbuff_t *tvb, proto_tree *tree, guint offset, int hf)
+fDevice_Instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, int hf)
 {
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
+    guint8      tag_no, tag_info;
+    guint32     lvt, safe_lvt;
+    guint       tag_len;
+    proto_item *ti;
+    proto_tree *subtree;
 
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, lvt, ENC_BIG_ENDIAN);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
 
-       return offset+tag_len+lvt;
+    if (lvt > 4)
+        safe_lvt = 4;
+    else
+        safe_lvt = lvt;
+
+    ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, safe_lvt, ENC_BIG_ENDIAN);
+
+    if (lvt != safe_lvt)
+        expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
+                "This field claims to be an impossible %u bytes, while the max is %u", lvt, safe_lvt);
+
+    subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset+tag_len+lvt;
 }
 
 /* set split_val to zero when not needed */
 static guint
-fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
-       const value_string *vs, guint32 split_val)
+fEnumeratedTagSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+    guint offset, const gchar *label, const value_string *vs, guint32 split_val)
 {
-       guint32 val = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
+    guint32     val = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_len;
+    proto_tree *subtree;
 
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       /* only support up to a 4 byte (32-bit) enumeration */
-       if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
-               if (vs)
-                       ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                               "%s %s", label, val_to_split_str(val, split_val, vs,
-                               ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
-               else
-                       ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                               "%s %u", label, val);
-       } else {
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s - %u octets (enumeration)", label, lvt);
-       }
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    /* only support up to a 4 byte (32-bit) enumeration */
+    if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) {
+        if (vs)
+            subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+                ett_bacapp_tag, NULL, "%s %s", label, val_to_split_str(val, split_val, vs,
+                ASHRAE_Reserved_Fmt, Vendor_Proprietary_Fmt));
+        else
+            subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+                ett_bacapp_tag, NULL, "%s %u", label, val);
+    } else {
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL, "%s - %u octets (enumeration)", label, lvt);
+    }
 
-       return offset+tag_len+lvt;
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset+tag_len+lvt;
 }
 
 static guint
-fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
-               const value_string *vs)
+fEnumeratedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+        guint offset, const gchar *label, const value_string *vs)
 {
-       return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
+    return fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, vs, 0);
 }
 
 static guint
-fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
+fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
 {
-       gint64 val = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
+    gint64      val = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_len;
+    proto_tree *subtree;
 
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (fSigned64 (tvb, offset + tag_len, lvt, &val))
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
-       else
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s - %u octets (Signed)", label, lvt);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (fSigned64(tvb, offset + tag_len, lvt, &val))
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL, "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
+    else
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL, "%s - %u octets (Signed)", label, lvt);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
 
-       return offset+tag_len+lvt;
+    return offset+tag_len+lvt;
 }
 
 static guint
-fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
+fRealTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
 {
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       gfloat f_val;
-       proto_item *ti;
-       proto_tree *subtree;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_len;
+    gfloat      f_val;
+    proto_tree *subtree;
 
-       tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
-       f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
-       ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
-               "%s%f (Real)", label, f_val);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
+    subtree = proto_tree_add_subtree_format(tree, tvb, offset, 4+tag_len,
+        ett_bacapp_tag, NULL, "%s%f (Real)", label, f_val);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
 
-       return offset+tag_len+4;
+    return offset+tag_len+4;
 }
 
 static guint
-fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
+fDoubleTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
 {
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       gdouble d_val;
-       proto_item *ti;
-       proto_tree *subtree;
+    guint8 tag_no, tag_info;
+    guint32 lvt;
+    guint tag_len;
+    gdouble d_val;
+    proto_tree *subtree;
+
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
+    subtree = proto_tree_add_subtree_format(tree, tvb, offset, 8+tag_len,
+        ett_bacapp_tag, NULL, "%s%f (Double)", label, d_val);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
 
-       tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
-       d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
-       ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
-               "%s%f (Double)", label, d_val);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
+    return offset+tag_len+8;
+}
 
-       return offset+tag_len+8;
-}
-
-static guint
-fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
-{
-       guint32 val = 0, lvt;
-       guint8 tag_no, tag_info;
-       proto_item *ti;
-       proto_tree *subtree;
-       guint tag_len;
-
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
-               ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
-                       tvb, offset, lvt+tag_len, val);
-       else
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "Process Identifier - %u octets (Signed)", lvt);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-       offset += tag_len + lvt;
+static guint
+fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint32     val = 0, lvt;
+    guint8      tag_no, tag_info;
+    proto_item *ti;
+    proto_tree *subtree;
+    guint       tag_len;
+
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (fUnsigned32(tvb, offset+tag_len, lvt, &val))
+    {
+        ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
+            tvb, offset, lvt+tag_len, val);
+        subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
+    }
+    else
+    {
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL, "Process Identifier - %u octets (Signed)", lvt);
+    }
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+    offset += tag_len + lvt;
 
-       return offset;
+    return offset;
 }
 
 static guint
-fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
+fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    guint32     val = 0, lvt;
+    guint8      tag_no, tag_info;
+    proto_tree *subtree;
+    guint       tag_len;
+
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (fUnsigned32(tvb, offset+tag_len, lvt, &val))
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL,
+            "%s (hh.mm.ss): %d.%02d.%02d%s",
+            label,
+            (val / 3600), ((val % 3600) / 60), (val % 60),
+            val == 0 ? " (indefinite)" : "");
+    else
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL,
+            "%s - %u octets (Signed)", label, lvt);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset+tag_len+lvt;
+}
+
+static guint
+fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint32     month, weekOfMonth, dayOfWeek;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_len;
+    proto_tree *subtree;
+
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    month = tvb_get_guint8(tvb, offset+tag_len);
+    weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
+    dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
+    subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+                 ett_bacapp_tag, NULL, "%s %s, %s",
+                 val_to_str(month, months, "month (%d) not found"),
+                 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
+                 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset+tag_len+lvt;
+}
+
+static guint
+fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    guint32     year, month, day, weekday;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_len;
+    proto_tree *subtree;
+
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    year    = tvb_get_guint8(tvb, offset+tag_len);
+    month   = tvb_get_guint8(tvb, offset+tag_len+1);
+    day     = tvb_get_guint8(tvb, offset+tag_len+2);
+    weekday = tvb_get_guint8(tvb, offset+tag_len+3);
+    if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL,
+            "%sany", label);
+    }
+    else if (year != 255) {
+        year += 1900;
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL,
+            "%s%s %d, %d, (Day of Week = %s)",
+            label, val_to_str(month,
+                months,
+                "month (%d) not found"),
+            day, year, val_to_str(weekday,
+                day_of_week,
+                "(%d) not found"));
+    } else {
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL,
+            "%s%s %d, any year, (Day of Week = %s)",
+            label, val_to_str(month, months, "month (%d) not found"),
+            day, val_to_str(weekday, day_of_week, "(%d) not found"));
+    }
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset+tag_len+lvt;
+}
+
+static guint
+fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    guint32     hour, minute, second, msec, lvt;
+    guint8      tag_no, tag_info;
+    guint       tag_len;
+    proto_tree *subtree;
+
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    hour    = tvb_get_guint8(tvb, offset+tag_len);
+    minute  = tvb_get_guint8(tvb, offset+tag_len+1);
+    second  = tvb_get_guint8(tvb, offset+tag_len+2);
+    msec    = tvb_get_guint8(tvb, offset+tag_len+3);
+    if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset,
+            lvt+tag_len, ett_bacapp_tag, NULL,
+            "%sany", label);
+    else
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL,
+            "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
+            label,
+            hour > 12 ? hour - 12 : hour,
+            minute, second, msec,
+            hour >= 12 ? "P.M." : "A.M.",
+            hour, minute, second, msec);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset+tag_len+lvt;
+}
+
+static guint
+fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
 {
-       guint32 val = 0, lvt;
-       guint8 tag_no, tag_info;
-       proto_item *ti;
-       proto_tree *subtree;
-       guint tag_len;
-
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-               "%s (hh.mm.ss): %d.%02d.%02d%s",
-               label,
-               (val / 3600), ((val % 3600) / 60), (val % 60),
-               val == 0 ? " (indefinite)" : "");
-       else
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s - %u octets (Signed)", label, lvt);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset+tag_len+lvt;
-}
-
-static guint
-fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
-{
-       guint32 month, weekOfMonth, dayOfWeek;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
-
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       month = tvb_get_guint8(tvb, offset+tag_len);
-       weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
-       dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
-       ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
-                                val_to_str(month, months, "month (%d) not found"),
-                                val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
-                                val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset+tag_len+lvt;
-}
-
-static guint
-fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       guint32 year, month, day, weekday;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
-
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       year = tvb_get_guint8(tvb, offset+tag_len);
-       month = tvb_get_guint8(tvb, offset+tag_len+1);
-       day = tvb_get_guint8(tvb, offset+tag_len+2);
-       weekday = tvb_get_guint8(tvb, offset+tag_len+3);
-       if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) {
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%sany", label);
-       }
-       else if (year != 255) {
-               year += 1900;
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s%s %d, %d, (Day of Week = %s)",
-                       label, val_to_str(month,
-                               months,
-                               "month (%d) not found"),
-                       day, year, val_to_str(weekday,
-                               day_of_week,
-                               "(%d) not found"));
-       } else {
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s%s %d, any year, (Day of Week = %s)",
-                       label, val_to_str(month, months, "month (%d) not found"),
-                       day, val_to_str(weekday, day_of_week, "(%d) not found"));
-       }
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset+tag_len+lvt;
-}
-
-static guint
-fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       guint32 hour, minute, second, msec, lvt;
-       guint8 tag_no, tag_info;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
-
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       hour = tvb_get_guint8(tvb, offset+tag_len);
-       minute = tvb_get_guint8(tvb, offset+tag_len+1);
-       second = tvb_get_guint8(tvb, offset+tag_len+2);
-       msec = tvb_get_guint8(tvb, offset+tag_len+3);
-       if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
-               ti = proto_tree_add_text(tree, tvb, offset,
-                       lvt+tag_len, "%sany", label);
-       else
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
-                       label,
-                       hour > 12 ? hour - 12 : hour,
-                       minute, second, msec,
-                       hour >= 12 ? "P.M." : "A.M.",
-                       hour, minute, second, msec);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset+tag_len+lvt;
-}
+    proto_tree *subtree = tree;
+
+    if (label != NULL) {
+        subtree = proto_tree_add_subtree(subtree, tvb, offset, 10, ett_bacapp_value, NULL, label);
+    }
+    offset = fDate(tvb, pinfo, subtree, offset, "Date: ");
+    return fTime(tvb, pinfo, subtree, offset, "Time: ");
+}
 
 static guint
-fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       if (label != NULL) {
-               tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
-               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-       }
-       offset = fDate (tvb,subtree,offset,"Date: ");
-       return fTime (tvb,subtree,offset,"Time: ");
-}
-
-static guint
-fTimeValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {   /* closing Tag, but not for me */
-                       return offset;
-               }
-               offset = fTime    (tvb,tree,offset,"Time: ");
-               offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
-
-               if (offset==lastoffset) break;    /* exit loop if nothing happens inside */
-       }
-       return offset;
-}
-
-static guint
-fCalendarEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       switch (fTagNo(tvb, offset)) {
-       case 0: /* Date */
-               offset = fDate    (tvb, tree, offset, "Date: ");
-               break;
-       case 1: /* dateRange */
-               offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-               offset = fDateRange (tvb, tree, offset);
-               offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-               break;
-       case 2: /* BACnetWeekNDay */
-               offset = fWeekNDay (tvb, tree, offset);
-               break;
-       default:
-               return offset;
-       }
+fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint lastoffset = 0;
+    guint8 tag_no, tag_info;
+    guint32 lvt;
 
-       return offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {   /* closing Tag, but not for me */
+            return offset;
+        }
+        offset = fTime(tvb, pinfo, tree, offset, "Time: ");
+        offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: ");
+
+        if (offset == lastoffset) break;    /* exit loop if nothing happens inside */
+    }
+    return offset;
+}
+
+static guint
+fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    switch (fTagNo(tvb, offset)) {
+    case 0: /* Date */
+        offset = fDate(tvb, pinfo, tree, offset, "Date: ");
+        break;
+    case 1: /* dateRange */
+        offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+        offset  = fDateRange(tvb, pinfo, tree, offset);
+        offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+        break;
+    case 2: /* BACnetWeekNDay */
+        offset = fWeekNDay(tvb, pinfo, tree, offset);
+        break;
+    default:
+        return offset;
+    }
+
+    return offset;
+}
+
+static guint
+fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
+{
+    guint32     lvt     = 0;
+    proto_tree* subtree = tree;
+
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {
+        subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventTimeStamps");
+
+        offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: ");
+        offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: ");
+        offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: ");
+    }
+    return offset;
 }
 
 static guint
-fTimeStamp (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
+fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
 {
-       guint8 tag_no = 0, tag_info = 0;
-       guint32 lvt = 0;
+    guint8  tag_no = 0, tag_info = 0;
+    guint32 lvt    = 0;
 
-       if (tvb_reported_length_remaining(tvb, offset) > 0) {   /* don't loop, it's a CHOICE */
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* time */
-                       offset = fTime (tvb, tree, offset, label?label:"timestamp: ");
-                       break;
-               case 1: /* sequenceNumber */
-                       offset = fUnsignedTag (tvb, tree, offset,
-                               label?label:"sequence Number: ");
-                       break;
-               case 2: /* dateTime */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fDateTime (tvb, tree, offset, label?label:"timestamp: ");
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               default:
-                       return offset;
-               }
-       }
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {   /* don't loop, it's a CHOICE */
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* time */
+            offset = fTime(tvb, pinfo, tree, offset, label?label:"time: ");
+            break;
+        case 1: /* sequenceNumber */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset,
+                label?label:"sequence number: ");
+            break;
+        case 2: /* dateTime */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fDateTime(tvb, pinfo, tree, offset, label?label:"date time: ");
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            return offset;
+        }
+    }
 
-       return offset;
+    return offset;
 }
 
 
 static guint
-fClientCOV (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       if (tvb_reported_length_remaining(tvb, offset) > 0) {
-               offset = fApplicationTypes(tvb,pinfo,tree,offset, "increment: ");
-       }
-       return offset;
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {
+        offset = fApplicationTypes(tvb, pinfo, tree, offset, "increment: ");
+    }
+    return offset;
 }
 
 static const value_string
 BACnetDaysOfWeek [] = {
-       {0,"Monday" },
-       {1,"Tuesday" },
-       {2,"Wednesday" },
-       {3,"Thursday" },
-       {4,"Friday" },
-       {5,"Saturday" },
-       {6,"Sunday" },
-       {0,NULL }
+    { 0, "Monday" },
+    { 1, "Tuesday" },
+    { 2, "Wednesday" },
+    { 3, "Thursday" },
+    { 4, "Friday" },
+    { 5, "Saturday" },
+    { 6, "Sunday" },
+    { 0, NULL }
 };
 
 static guint
-fDestination (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       if (tvb_reported_length_remaining(tvb, offset) > 0) {
-               offset = fApplicationTypesEnumerated(tvb,pinfo,tree,offset,
-                       "valid Days: ", BACnetDaysOfWeek);
-               offset = fTime (tvb,tree,offset,"from time: ");
-               offset = fTime (tvb,tree,offset,"to time: ");
-               offset = fRecipient (tvb,pinfo,tree,offset);
-               offset = fProcessId (tvb,tree,offset);
-               offset = fApplicationTypes (tvb,pinfo,tree,offset,
-                       "issue confirmed notifications: ");
-               offset = fBitStringTagVS (tvb,tree,offset,
-                       "transitions: ", BACnetEventTransitionBits);
-       }
-       return offset;
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {
+        offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
+                                             "valid Days: ", BACnetDaysOfWeek);
+        offset = fTime(tvb, pinfo, tree, offset, "from time: ");
+        offset = fTime(tvb, pinfo, tree, offset, "to time: ");
+        offset = fRecipient(tvb, pinfo, tree, offset);
+        offset = fProcessId(tvb, pinfo, tree, offset);
+        offset = fApplicationTypes(tvb, pinfo, tree, offset,
+                                    "issue confirmed notifications: ");
+        offset = fBitStringTagVS(tvb, pinfo, tree, offset,
+                                  "transitions: ", BACnetEventTransitionBits);
+    }
+    return offset;
 }
 
 
 static guint
-fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
+fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
 {
-       gchar *tmp;
-       guint start = offset;
-       guint8 tag_no, tag_info;
-       proto_tree* subtree = tree;
-       proto_item* ti = 0;
-
-       offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
+    gchar      *tmp;
+    guint       start   = offset;
+    guint8      tag_no, tag_info;
+    proto_tree *subtree = tree;
 
-       if (lvt > 0) {
-               tmp = tvb_bytes_to_str(tvb, offset, lvt);
-               ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
-               offset += lvt;
-       }
+    offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
 
-       if (ti)
-               subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
+    if (lvt > 0) {
+        tmp = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, lvt);
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt,
+                    ett_bacapp_tag, NULL, "%s %s", label, tmp);
+        offset += lvt;
+    }
 
-       fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
+    fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
 
-       return offset;
+    return offset;
 }
 
 static guint
-fMacAddress (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
+fMacAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
 {
-       gchar *tmp;
-       guint start = offset;
-       guint8 tag_no, tag_info;
-       proto_tree* subtree = tree;
-       proto_item* ti = 0;
-
-       offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-
-       ti = proto_tree_add_text(tree, tvb, offset, 6, "%s", label); /* just add the label, with the tagHeader information in its subtree */
-
-       if (lvt > 0) {
-               if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
-
-                       guint32 ip = tvb_get_ipv4(tvb, offset);
-                       guint16 port =  tvb_get_ntohs(tvb, offset+4);
-
-                       proto_tree_add_ipv4(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ip);
-                       proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, port);
-
-               } else {
-                       if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
-                       struct e_in6_addr addr;
-                       guint16 port =  tvb_get_ntohs(tvb, offset+16);
-                       tvb_get_ipv6(tvb, offset, &addr);
+    guint start = offset;
+    guint8 tag_no, tag_info;
+    proto_tree* subtree = tree;
 
-                       proto_tree_add_ipv6(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, (const guint8 *) &addr);
-                       proto_tree_add_uint(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, port);
+    offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
 
-                       } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
-                               tmp = tvb_bytes_to_str(tvb, offset, lvt);
-                               ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s", tmp);
-                       }
-               }
-               offset += lvt;
-       }
+    /* just add the label, with the tagHeader information in its subtree */
+    subtree = proto_tree_add_subtree(tree, tvb, offset, 6, ett_bacapp_tag, NULL, label);
 
-       if (ti)
-               subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
+    if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */
+        proto_tree_add_item(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ENC_BIG_ENDIAN);
+        proto_tree_add_item(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, ENC_BIG_ENDIAN);
+    } else if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */
+        proto_tree_add_item(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, ENC_NA);
+        proto_tree_add_item(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, ENC_BIG_ENDIAN);
+    } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */
+        subtree = proto_tree_add_subtree(tree, tvb, offset, lvt,
+                ett_bacapp_tag, NULL, tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, lvt));
+    }
+    offset += lvt;
 
-       fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
+    fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
 
-       return offset;
+    return offset;
 }
 
 static guint
-fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
+fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint offs;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   offs;
 
-       offset = fUnsignedTag (tvb, tree, offset, "network-number");
-       offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (lvt == 0) {
-               proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
-               offset += offs;
-       } else
-               offset = fMacAddress (tvb, tree, offset, "MAC-address: ", lvt);
+    offset = fUnsignedTag(tvb, pinfo, tree, offset, "network-number");
+    offs   = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (lvt == 0) {
+        proto_tree_add_text(tree, tvb, offset, offs, "MAC-address: broadcast");
+        offset += offs;
+    } else
+        offset  = fMacAddress(tvb, pinfo, tree, offset, "MAC-address: ", lvt);
 
-       return offset;
+    return offset;
 }
 
 static guint
-fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
+fSessionKey(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       offset = fOctetString (tvb,tree,offset,"session key: ", 8);
-       return fAddress (tvb,tree,offset);
+    offset = fOctetString(tvb, pinfo, tree, offset, "session key: ", 8);
+    return fAddress(tvb, pinfo, tree, offset);
 }
 
 static guint
-fObjectIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint8  tag_no, tag_info;
-       guint32 lvt;
-       guint tag_length;
-       proto_item *ti;
-       proto_tree *subtree;
-       guint32 object_id;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_length;
+    proto_tree *subtree;
+    guint32     object_id;
 
-       tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
-       object_id = tvb_get_ntohl(tvb,offset+tag_length);
-       object_type = object_id_type(object_id);
-       ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
-               "ObjectIdentifier: %s, %u",
-               val_to_split_str(object_type,
-                       128,
-                       BACnetObjectType,
-                       ASHRAE_Reserved_Fmt,
-                       Vendor_Proprietary_Fmt),
-               object_id_instance(object_id));
-       if (col_get_writable(pinfo->cinfo))
-               col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
-                       val_to_split_str(object_type,
-                               128,
-                               BACnetObjectType,
-                               ASHRAE_Reserved_Fmt,
-                               Vendor_Proprietary_Fmt),
-                               object_id_instance(object_id));
-
-       /* update BACnet Statistics */
-       updateBacnetInfoValue(BACINFO_OBJECTID,
-                             ep_strdup(val_to_split_str(object_type, 128,
-                                       BACnetObjectType, ASHRAE_Reserved_Fmt,
-                                       Vendor_Proprietary_Fmt)));
-       updateBacnetInfoValue(BACINFO_INSTANCEID, ep_strdup_printf("Instance ID: %u",
-                             object_id_instance(object_id)));
-
-       /* here are the details of how we arrived at the above text */
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-       offset += tag_length;
-       proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
-       proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
-       offset += 4;
-
-       return offset;
-}
-
-static guint
-fRecipient (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint8  tag_no, tag_info;
-       guint32 lvt;
-
-       fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
-       if (tag_no < 2) {
-               if (tag_no == 0) { /* device */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-               }
-               else {  /* address */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fAddress (tvb, tree, offset);
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-               }
-       }
-       return offset;
-}
-
-static guint
-fRecipientProcess (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8  tag_no, tag_info;
-       guint32 lvt;
-       proto_tree* orgtree = tree;
-       proto_item* tt;
-       proto_tree* subtree;
-
-       /* beginning of new item - indent and label */
-       tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Recipient Process" );
-       tree = proto_item_add_subtree(tt, ett_bacapp_value);
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* recipient */
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
-                       tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient");    /* add tree label and indent */
-                       subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                       offset = fRecipient (tvb, pinfo, subtree, offset);
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
-                       break;
-               case 1: /* processId */
-                       offset = fProcessId (tvb, tree, offset);
-                       lastoffset = offset;
-                       break;
-               default:
-                       break;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fCOVSubscription (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8  tag_no, tag_info;
-       guint32 lvt;
-       proto_tree* subtree;
-       proto_item *tt;
-       proto_tree* orgtree = tree;
-       guint itemno = 1;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info) ) {
-                       return offset;
-               }
-               switch (tag_no) {
-
-               case 0: /* recipient */
-                               /* beginning of new item in list */
-                               tt = proto_tree_add_text(orgtree, tvb, offset, 1, "Subscription %d",itemno);    /* add tree label and indent */
-                               itemno = itemno + 1;
-                               tree = proto_item_add_subtree(tt, ett_bacapp_value);
-
-                               tt = proto_tree_add_text(tree, tvb, offset, 1, "Recipient");    /* add tree label and indent */
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
-                               offset = fRecipientProcess (tvb, pinfo, subtree, offset);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);      /* show context close */
-                               subtree = tree; /* done with this level - return to previous tree */
-                       break;
-               case 1: /* MonitoredPropertyReference */
-                               tt = proto_tree_add_text(tree, tvb, offset, 1, "Monitored Property Reference");
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               subtree = tree;
-                       break;
-               case 2: /* IssueConfirmedNotifications - boolean */
-                       offset = fBooleanTag (tvb, tree, offset, "Issue Confirmed Notifications: ");
-                       break;
-               case 3: /* TimeRemaining */
-                       offset = fUnsignedTag (tvb, tree, offset, "Time Remaining: ");
-                       break;
-               case 4: /* COVIncrement */
-                       offset = fRealTag (tvb, tree, offset, "COV Increment: ");
-                       break;
-               default:
-                       break;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fAddressBinding (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-       return fAddress (tvb, tree, offset);
-}
-
-static guint
-fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
-{
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-
-       /* set the optional global properties to indicate not-used */
-       propertyArrayIndex = -1;
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info) ) {
-                       if (tag_no == tag_match) {
-                               return offset;
-                       }
-                       offset += len;
-                       subtree = tree;
-                       continue;
-               }
-               switch (tag_no) {
-
-               case 0: /* deviceIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 1: /* objectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 2: /* propertyIdentifier */
-                       offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 3: /* propertyArrayIndex */
-                       offset = fPropertyArrayIndex (tvb, subtree, offset);
-                       break;
-               case 4: /* propertyValue */
-                       offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
-                       break;
-               case 5: /* priority */
-                       offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
-                       break;
-               case 6: /* postDelay */
-                       offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
-                       break;
-               case 7: /* quitOnFailure */
-                       offset = fBooleanTag(tvb, subtree, offset,
-                               "Quit On Failure: ");
-                       break;
-               case 8: /* writeSuccessful */
-                       offset = fBooleanTag(tvb, subtree, offset,
-                               "Write Successful: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    tag_length  = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    object_id   = tvb_get_ntohl(tvb, offset+tag_length);
+    object_type = object_id_type(object_id);
+    subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_length + 4,
+        ett_bacapp_tag, NULL, "ObjectIdentifier: %s, %u",
+        val_to_split_str(object_type,
+            128,
+            BACnetObjectType,
+            ASHRAE_Reserved_Fmt,
+            Vendor_Proprietary_Fmt),
+        object_id_instance(object_id));
+
+    if (col_get_writable(pinfo->cinfo))
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ",
+            val_to_split_str(object_type,
+                128,
+                BACnetObjectType,
+                ASHRAE_Reserved_Fmt,
+                Vendor_Proprietary_Fmt),
+                object_id_instance(object_id));
+
+    /* update BACnet Statistics */
+    updateBacnetInfoValue(BACINFO_OBJECTID,
+                  wmem_strdup(wmem_packet_scope(),
+                    val_to_split_str(object_type, 128,
+                    BACnetObjectType, ASHRAE_Reserved_Fmt,
+                    Vendor_Proprietary_Fmt)));
+    updateBacnetInfoValue(BACINFO_INSTANCEID,
+                  wmem_strdup_printf(wmem_packet_scope(),
+                    "Instance ID: %u",
+                    object_id_instance(object_id)));
+
+    /* here are the details of how we arrived at the above text */
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+    offset += tag_length;
+    proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, ENC_BIG_ENDIAN);
+    proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, ENC_BIG_ENDIAN);
+    offset += 4;
+
+    return offset;
+}
+
+static guint
+fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (tag_no < 2) {
+        if (tag_no == 0) { /* device */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+        }
+        else {  /* address */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fAddress(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+        }
+    }
+    return offset;
+}
+
+static guint
+fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *orgtree    = tree;
+    proto_tree *subtree;
+
+    /* beginning of new item - indent and label */
+    tree = proto_tree_add_subtree(orgtree, tvb, offset, 1, ett_bacapp_value, NULL, "Recipient Process" );
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* recipient */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */
+            subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "Recipient");    /* add tree label and indent */
+            offset  = fRecipient(tvb, pinfo, subtree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */
+            break;
+        case 1: /* processId */
+            offset = fProcessId(tvb, pinfo, tree, offset);
+            lastoffset = offset;
+            break;
+        default:
+            break;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree;
+    proto_tree *orgtree    = tree;
+    guint       itemno     = 1;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info) ) {
+            return offset;
+        }
+        switch (tag_no) {
+
+        case 0: /* recipient */
+                /* beginning of new item in list */
+                tree = proto_tree_add_subtree_format(orgtree, tvb, offset, 1,
+                    ett_bacapp_value, NULL, "Subscription %d",itemno);    /* add tree label and indent */
+                itemno = itemno + 1;
+
+                subtree = proto_tree_add_subtree(tree, tvb, offset, 1,
+                    ett_bacapp_value, NULL, "Recipient");    /* add tree label and indent */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */
+                offset  = fRecipientProcess(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);  /* show context close */
+            break;
+        case 1: /* MonitoredPropertyReference */
+                subtree = proto_tree_add_subtree(tree, tvb, offset, 1,
+                    ett_bacapp_value, NULL, "Monitored Property Reference");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 2: /* IssueConfirmedNotifications - boolean */
+            offset = fBooleanTag(tvb, pinfo, tree, offset, "Issue Confirmed Notifications: ");
+            break;
+        case 3: /* TimeRemaining */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "Time Remaining: ");
+            break;
+        case 4: /* COVIncrement */
+            offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
+            break;
+        default:
+            break;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+    return fAddress(tvb, pinfo, tree, offset);
+}
+
+static guint
+fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_match)
+{
+    guint       lastoffset = 0, len;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree    = tree;
+
+    /* set the optional global properties to indicate not-used */
+    propertyArrayIndex = -1;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info) ) {
+            if (tag_no == tag_match) {
+                return offset;
+            }
+            offset += len;
+            subtree = tree;
+            continue;
+        }
+        switch (tag_no) {
+
+        case 0: /* deviceIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 1: /* objectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 2: /* propertyIdentifier */
+            offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 3: /* propertyArrayIndex */
+            offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
+            break;
+        case 4: /* propertyValue */
+            offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
+            break;
+        case 5: /* priority */
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
+            break;
+        case 6: /* postDelay */
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Post Delay: ");
+            break;
+        case 7: /* quitOnFailure */
+            offset = fBooleanTag(tvb, pinfo, subtree, offset,
+                "Quit On Failure: ");
+            break;
+        case 8: /* writeSuccessful */
+            offset = fBooleanTag(tvb, pinfo, subtree, offset,
+                "Write Successful: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 /* BACnetActionList ::= SEQUENCE{
@@ -5617,1106 +6192,1385 @@ fActionCommand (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offse
       }
 */
 static guint
-fActionList (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *ti;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       offset += len;
-                       subtree = tree;
-                       continue;
-               }
-               if (tag_is_opening(tag_info)) {
-                       ti = proto_tree_add_text(tree, tvb, offset, 1, "Action List");
-                       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-                       offset += fTagHeaderTree (tvb, subtree, offset,
-                               &tag_no, &tag_info, &lvt);
-               }
-               switch (tag_no) {
-                       case 0: /* BACnetActionCommand */
-                               offset = fActionCommand (tvb, pinfo, subtree, offset, tag_no);
-                               break;
-                       default:
-                               break;
-               }
-               if (offset == lastoffset) break;    /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fPropertyIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
-       const gchar *label = "Property Identifier";
-
-       propertyIdentifier = 0; /* global Variable */
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       /* can we decode this value? */
-       if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s: %s (%u)", label,
-                       val_to_split_str(propertyIdentifier, 512,
-                               BACnetPropertyIdentifier,
-                               ASHRAE_Reserved_Fmt,
-                               Vendor_Proprietary_Fmt), propertyIdentifier);
-               if (col_get_writable(pinfo->cinfo))
-                       col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
-                               val_to_split_str(propertyIdentifier, 512,
-                                       BACnetPropertyIdentifier,
-                                       ASHRAE_Reserved_Fmt,
-                                       Vendor_Proprietary_Fmt));
-       } else {
-               /* property identifiers cannot be larger than 22-bits */
-               return offset;
-       }
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-       proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
-               offset+tag_len, lvt, ENC_BIG_ENDIAN);
-
-       return offset+tag_len+lvt;
-}
-
-static guint
-fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
-
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "property Array Index (Unsigned) %u", propertyArrayIndex);
-       else
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "property Array Index - %u octets (Unsigned)", lvt);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset+tag_len+lvt;
-}
-
-static guint
-fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       guint8 tag_no, tag_info, character_set;
-       guint32 lvt, l;
-       gsize inbytesleft, outbytesleft = 512;
-       guint offs, extra = 1;
-       guint8 *str_val;
-       const char *coding;
-       guint8 bf_arr[512], *out = &bf_arr[0];
-       proto_item *ti;
-       proto_tree *subtree;
-       guint start = offset;
-
-       if (tvb_reported_length_remaining(tvb, offset) > 0) {
-
-               offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-
-               character_set = tvb_get_guint8(tvb, offset+offs);
-               /* Account for code page if DBCS */
-               if (character_set == 1) {
-                   extra = 3;
-               }
-               offset += (offs+extra);
-               lvt -= (extra);
-
-               do {
-                       inbytesleft = l = MIN(lvt, 255);
-                       /*
-                        * XXX - are we guaranteed that these encoding
-                        * names correspond, on *all* platforms with
-                        * iconv(), to the encodings we want?
-                        * If not (and perhaps even if so), we should
-                        * perhaps have our own iconv() implementation,
-                        * with a different name, so that we control the
-                        * encodings it supports and the names of those
-                        * encodings.
-                        *
-                        * We should also handle that in the general
-                        * string handling code, rather than making it
-                        * specific to the BACAPP dissector, as many
-                        * other dissectors need to handle various
-                        * character encodings.
-                        */
-                       str_val = tvb_get_ephemeral_string(tvb, offset, l);
-                       /** this decoding may be not correct for multi-byte characters, Lka */
-                       switch (character_set) {
-                       case ANSI_X34:
-                               fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UTF-8");
-                               coding = "UTF-8";
-                               break;
-                       case IBM_MS_DBCS:
-                               out = str_val;
-                               coding = "IBM MS DBCS";
-                               break;
-                       case JIS_C_6226:
-                               out = str_val;
-                               coding = "JIS C 6226";
-                               break;
-                       case ISO_10646_UCS4:
-                               fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
-                               coding = "ISO 10646 UCS-4";
-                               break;
-                       case ISO_10646_UCS2:
-                               fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
-                               coding = "ISO 10646 UCS-2";
-                               break;
-                       case ISO_18859_1:
-                               fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
-                               coding = "ISO 8859-1";
-                               break;
-                       default:
-                               out = str_val;
-                               coding = "unknown";
-                               break;
-                       }
-                       ti = proto_tree_add_text(tree, tvb, offset, l, "%s%s '%s'", label, coding, out);
-                       lvt-=l;
-                       offset+=l;
-               } while (lvt > 0);
-
-               subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-
-               fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
-               proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
-
-               if (character_set == 1) {
-                   proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
-               }
-               /* XXX - put the string value here */
-       }
-       return offset;
-}
-
-static guint
-fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
-       const value_string *src)
-{
-       guint8 tag_no, tag_info, tmp;
-       gint j, unused, skip;
-       guint start = offset;
-       guint offs;
-       guint32 lvt, i, numberOfBytes;
-       guint8 bf_arr[256];
-       proto_tree* subtree = tree;
-       proto_item* ti = 0;
-
-       offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
-       offset+=offs;
-       unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
-       ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
-                               "%s(Bit String)",
-                               label);
-       if (ti) {
-               subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       }
-       fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
-       proto_tree_add_text(subtree, tvb, offset, 1,
-                               "Unused bits: %u",
-                               unused);
-       skip = 0;
-       for (i = 0; i < numberOfBytes; i++) {
-               tmp = tvb_get_guint8(tvb, (offset)+i+1);
-               if (i == numberOfBytes-1) { skip = unused; }
-               for (j = 0; j < 8-skip; j++) {
-                       if (src != NULL) {
-                               if (tmp & (1 << (7 - j)))
-                                       proto_tree_add_text(subtree, tvb,
-                                               offset+i+1, 1,
-                                               "%s = TRUE",
-                                               val_to_str((guint) (i*8 +j),
-                                                       src,
-                                                       ASHRAE_Reserved_Fmt));
-                               else
-                                       proto_tree_add_text(subtree, tvb,
-                                               offset+i+1, 1,
-                                               "%s = FALSE",
-                                               val_to_str((guint) (i*8 +j),
-                                                       src,
-                                                       ASHRAE_Reserved_Fmt));
-                       } else {
-                               bf_arr[MIN(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
-                       }
-               }
-       }
-
-       if (src == NULL) {
-               bf_arr[MIN(255,numberOfBytes*8-unused)] = 0;
-               proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
-       }
-
-       offset+=lvt;
-
-       return offset;
-}
-
-static guint
-fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       return fBitStringTagVS (tvb, tree, offset, label, NULL);
+fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0, len;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree    = tree;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            subtree = tree;
+            if ( tag_no != 0 ) /* don't eat the closing property tag, just return */
+                return offset;
+            offset += len;
+            continue;
+        }
+        if (tag_is_opening(tag_info)) {
+            subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "Action List");
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
+                &tag_no, &tag_info, &lvt);
+        }
+        switch (tag_no) {
+        case 0: /* BACnetActionCommand */
+            offset = fActionCommand(tvb, pinfo, subtree, offset, tag_no);
+            break;
+        default:
+            break;
+        }
+        if (offset == lastoffset) break;    /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8       tag_no, tag_info;
+    guint32      lvt;
+    guint        tag_len;
+    proto_tree  *subtree;
+    const gchar *label = "Property Identifier";
+
+    propertyIdentifier = 0; /* global Variable */
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    /* can we decode this value? */
+    if (fUnsigned32(tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL,
+            "%s: %s (%u)", label,
+            val_to_split_str(propertyIdentifier, 512,
+                BACnetPropertyIdentifier,
+                ASHRAE_Reserved_Fmt,
+                Vendor_Proprietary_Fmt), propertyIdentifier);
+        if (col_get_writable(pinfo->cinfo))
+            col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
+                val_to_split_str(propertyIdentifier, 512,
+                    BACnetPropertyIdentifier,
+                    ASHRAE_Reserved_Fmt,
+                    Vendor_Proprietary_Fmt));
+    } else {
+        /* property identifiers cannot be larger than 22-bits */
+        return offset;
+    }
+
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+    proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
+        offset+tag_len, lvt, ENC_BIG_ENDIAN);
+
+    return offset+tag_len+lvt;
+}
+
+static guint
+fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_len;
+    proto_tree *subtree;
+
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (fUnsigned32(tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL, "property Array Index (Unsigned) %u", propertyArrayIndex);
+    else
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, NULL, "property Array Index - %u octets (Unsigned)", lvt);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset+tag_len+lvt;
+}
+
+static guint
+fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    guint8      tag_no, tag_info, character_set;
+    guint32     lvt, l;
+    guint       offs;
+    const char *coding;
+    guint8     *out;
+    proto_tree *subtree;
+    guint       start = offset;
+
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {
+
+        offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        offset += offs;
+
+        character_set = tvb_get_guint8(tvb, offset);
+        offset++;
+        lvt--;
+
+        /* Account for code page if DBCS */
+        if (character_set == IBM_MS_DBCS) {
+            offset += 2;
+            lvt -= 2;
+        }
+
+        do {
+            l = MIN(lvt, 256);
+            /*
+             * XXX - are we guaranteed that these encoding
+             * names correspond, on *all* platforms with
+             * iconv(), to the encodings we want?
+             * If not (and perhaps even if so), we should
+             * perhaps have our own iconv() implementation,
+             * with a different name, so that we control the
+             * encodings it supports and the names of those
+             * encodings.
+             *
+             * We should also handle that in the general
+             * string handling code, rather than making it
+             * specific to the BACAPP dissector, as many
+             * other dissectors need to handle various
+             * character encodings.
+             */
+            /** this decoding may be not correct for multi-byte characters, Lka */
+            switch (character_set) {
+            case ANSI_X3_4:
+                out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UTF_8);
+                coding = "UTF-8";
+                break;
+            case IBM_MS_DBCS:
+                out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
+                coding = "IBM MS DBCS";
+                break;
+            case JIS_C_6226:
+                out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
+                coding = "JIS C 6226";
+                break;
+            case ISO_10646_UCS4:
+                out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UCS_4|ENC_BIG_ENDIAN);
+                coding = "ISO 10646 UCS-4";
+                break;
+            case ISO_10646_UCS2:
+                out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_UCS_2|ENC_BIG_ENDIAN);
+                coding = "ISO 10646 UCS-2";
+                break;
+            case ISO_8859_1:
+                out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ISO_8859_1);
+                coding = "ISO 8859-1";
+                break;
+            default:
+                /* Assume this is some form of extended ASCII, with one-byte code points for ASCII characters */
+                out = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, l, ENC_ASCII);
+                coding = "unknown";
+                break;
+            }
+            subtree = proto_tree_add_subtree_format(tree, tvb, offset, l, ett_bacapp_tag, NULL,
+                                        "%s%s '%s'", label, coding, out);
+            lvt    -= l;
+            offset += l;
+        } while (lvt > 0);
+
+        fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
+        proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN);
+
+        if (character_set == IBM_MS_DBCS) {
+            proto_tree_add_item(subtree, hf_BACnetCodePage, tvb, start+offs+1, 2, ENC_BIG_ENDIAN);
+        }
+        /* XXX - put the string value here */
+    }
+    return offset;
+}
+
+static guint
+fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label,
+    const value_string *src)
+{
+    guint8      tag_no, tag_info, tmp;
+    gint        j, unused, skip;
+    guint       start = offset;
+    guint       offs;
+    guint32     lvt, i, numberOfBytes;
+    guint8      bf_arr[256];
+    proto_tree* subtree = tree;
+
+    offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
+    offset += offs;
+    unused  = tvb_get_guint8(tvb, offset); /* get the unused Bits */
+    subtree = proto_tree_add_subtree_format(tree, tvb, start, offs+lvt,
+                                  ett_bacapp_tag, NULL,
+                                  "%s(Bit String)", label);
+
+    fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
+    proto_tree_add_text(subtree, tvb, offset, 1,
+                "Unused bits: %u", unused);
+    memset(bf_arr, 0, 256);
+    skip = 0;
+    for (i = 0; i < numberOfBytes; i++) {
+        tmp = tvb_get_guint8(tvb, (offset)+i+1);
+        if (i == numberOfBytes-1) { skip = unused; }
+        for (j = 0; j < 8-skip; j++) {
+            if (src != NULL) {
+                if (tmp & (1 << (7 - j)))
+                    proto_tree_add_text(subtree, tvb,
+                        offset+i+1, 1,
+                        "%s = TRUE",
+                        val_to_str((guint) (i*8 +j),
+                            src,
+                            ASHRAE_Reserved_Fmt));
+                else
+                    proto_tree_add_text(subtree, tvb,
+                        offset+i+1, 1,
+                        "%s = FALSE",
+                        val_to_str((guint) (i*8 +j),
+                            src,
+                            ASHRAE_Reserved_Fmt));
+            } else {
+                bf_arr[MIN(255, (i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
+            }
+        }
+    }
+
+    if (src == NULL) {
+        bf_arr[MIN(255, numberOfBytes*8-unused)] = 0;
+        proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
+    }
+
+    offset += lvt;
+
+    return offset;
+}
+
+static guint
+fBitStringTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    return fBitStringTagVS(tvb, pinfo, tree, offset, label, NULL);
 }
 
 /* handles generic application types, as well as enumerated and enumerations
    with reserved and proprietarty ranges (split) */
 static guint
-fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
-       const gchar *label, const value_string *src, guint32 split_val)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-
-       if (tvb_reported_length_remaining(tvb, offset) > 0) {
-
-               tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (!tag_is_context_specific(tag_info)) {
-                       switch (tag_no) {
-                               case 0: /** NULL 20.2.2 */
-                                       offset = fNullTag(tvb, tree, offset, label);
-                                       break;
-                               case 1: /** BOOLEAN 20.2.3 */
-                                       offset = fBooleanTag(tvb, tree, offset, label);
-                                       break;
-                               case 2: /** Unsigned Integer 20.2.4 */
-                                       offset = fUnsignedTag(tvb, tree, offset, label);
-                                       break;
-                               case 3: /** Signed Integer 20.2.5 */
-                                       offset = fSignedTag(tvb, tree, offset, label);
-                                       break;
-                               case 4: /** Real 20.2.6 */
-                                       offset = fRealTag(tvb, tree, offset, label);
-                                       break;
-                               case 5: /** Double 20.2.7 */
-                                       offset = fDoubleTag(tvb, tree, offset, label);
-                                       break;
-                               case 6: /** Octet String 20.2.8 */
-                                       offset = fOctetString (tvb, tree, offset, label, lvt);
-                                       break;
-                               case 7: /** Character String 20.2.9 */
-                                       offset = fCharacterString (tvb,tree,offset,label);
-                                       break;
-                               case 8: /** Bit String 20.2.10 */
-                                       offset = fBitStringTagVS (tvb, tree, offset, label, src);
-                                       break;
-                               case 9: /** Enumerated 20.2.11 */
-                                       offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
-                                       break;
-                               case 10: /** Date 20.2.12 */
-                                       offset = fDate (tvb, tree, offset, label);
-                                       break;
-                               case 11: /** Time 20.2.13 */
-                                       offset = fTime (tvb, tree, offset, label);
-                                       break;
-                               case 12: /** BACnetObjectIdentifier 20.2.14 */
-                                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                                       break;
-                               case 13: /* reserved for ASHRAE */
-                               case 14:
-                               case 15:
-                                       proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
-                                       offset+=lvt+tag_len;
-                                       break;
-                               default:
-                                       break;
-                       }
-
-               }
-       }
-       return offset;
-}
-
-static guint
-fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-
-               switch (fTagNo(tvb,offset)) {
-               case 0: /* percent */
-                       offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
-                       break;
-               case 1: /* level */
-                       offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
-                       break;
-               case 2: /* amount */
-                       offset = fRealTag(tvb, tree, offset, "shed amount: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fApplicationTypesEnumerated (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
-       const gchar *label, const value_string *vs)
-{
-       return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
-}
-
-static guint
-fApplicationTypes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
-       const gchar *label)
-{
-       return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
-}
-
-static guint
-fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
-       gint tvb_len;
-
-       (void)label;
-       tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
-       /* cap the the suggested length in case of bad data */
-       tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
-       if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
-               lvt = tvb_len;
-       }
-       ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
-               "Context Value (as %u DATA octets)", lvt);
-
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset + tag_len + lvt;
-}
-
-static guint
-fAbstractSyntaxNType (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint lastoffset = 0, depth = 0;
-       char ar[256];
-
-       if (propertyIdentifier >= 0) {
-               g_snprintf (ar, sizeof(ar), "%s: ",
-                       val_to_split_str(propertyIdentifier, 512,
-                               BACnetPropertyIdentifier,
-                               ASHRAE_Reserved_Fmt,
-                               Vendor_Proprietary_Fmt));
-       } else {
-               g_snprintf (ar, sizeof(ar), "Abstract Type: ");
-       }
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
-                       if (depth <= 0) return offset;
-               }
-
-               /* Application Tags */
-               switch (propertyIdentifier) {
-               case 2: /* action */
-                       /* loop object is application tagged,
-                               command object is context tagged */
-                       if (tag_is_context_specific(tag_info)) {
-                               /* BACnetActionList */
-                               offset = fActionList (tvb, pinfo, tree,offset);
-                       } else {
-                               /* BACnetAction */
-                               offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
-                                       BACnetAction);
-                       }
-                       break;
-               case 30: /* BACnetAddressBinding */
-                       offset = fAddressBinding (tvb,pinfo,tree,offset);
-                       break;
-               case 54: /* list of object property reference */
-                       offset = fLOPR (tvb, pinfo, tree,offset);
-                       break;
-               case 55: /* list-of-session-keys */
-                       fSessionKey (tvb, tree, offset);
-                       break;
-               case 79: /* object-type */
-               case 96: /* protocol-object-types-supported */
-                       offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset, ar,
-                               BACnetObjectType, 128);
-                       break;
-               case 97: /* Protocol-Services-Supported */
-                       offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
-                               BACnetServicesSupported);
-                       break;
-               case 102: /* recipient-list */
-                       offset = fDestination (tvb, pinfo, tree, offset);
-                       break;
-               case 107: /* segmentation-supported */
-                       offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
-                               BACnetSegmentation);
-                       break;
-               case 111: /* Status-Flags */
-                       offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
-                               BACnetStatusFlags);
-                       break;
-               case 112: /* System-Status */
-                       offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
-                               BACnetDeviceStatus);
-                       break;
-               case 117: /* units */
-                       offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset, ar,
-                               BACnetEngineeringUnits);
-                       break;
-               case 87:        /* priority-array -- accessed as a BACnetARRAY */
-                       if (propertyArrayIndex == 0) {
-                               /* BACnetARRAY index 0 refers to the length
-                               of the array, not the elements of the array */
-                               offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
-                       } else {
-                               offset = fPriorityArray (tvb, pinfo, tree, offset);
-                       }
-                       break;
-               case 38:        /* exception-schedule */
-                       if (object_type < 128) {
-                               if (propertyArrayIndex == 0) {
-                                       /* BACnetARRAY index 0 refers to the length
-                                       of the array, not the elements of the array */
-                                       offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
-                               } else {
-                                       offset = fSpecialEvent (tvb,pinfo,tree,offset);
-                               }
-                       }
-                       break;
-               case 19:  /* controlled-variable-reference */
-               case 60:  /* manipulated-variable-reference */
-               case 109: /* Setpoint-Reference */
-               case 132: /* log-device-object-property */
-                       offset = fDeviceObjectPropertyReference (tvb, pinfo, tree, offset);
-                       break;
-               case 123:       /* weekly-schedule -- accessed as a BACnetARRAY */
-                       if (object_type < 128) {
-                               if (propertyArrayIndex == 0) {
-                                       /* BACnetARRAY index 0 refers to the length
-                                       of the array, not the elements of the array */
-                                       offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
-                               } else {
-                                       offset = fWeeklySchedule (tvb, pinfo, tree, offset);
-                               }
-                       }
-                       break;
-               case 127:       /* client COV increment */
-                       offset = fClientCOV (tvb, pinfo, tree, offset);
-                       break;
-               case 131:  /* log-buffer */
-                       offset = fLogRecord (tvb, pinfo, tree, offset);
-                       break;
-               case 159: /* member-of */
-               case 165: /* zone-members */
-                       offset = fDeviceObjectReference (tvb, pinfo, tree, offset);
-                       break;
-               case 196: /* last-restart-reason */
-                       offset = fRestartReason (tvb, pinfo, tree, offset);
-                       break;
-               case 212: /* actual-shed-level */
-               case 214: /* expected-shed-level */
-               case 218: /* requested-shed-level */
-                       offset = fShedLevel (tvb, tree, offset);
-                       break;
-               case 152: /* active-cov-subscriptions */
-                       offset = fCOVSubscription (tvb, pinfo, tree, offset);
-                       break;
-               case 23: /* date-list */
-                       offset = fCalendarEntry(tvb, tree, offset);
-                       break;
-               case 116: /* time-sychronization-recipients */
-                       offset = fRecipient(tvb, pinfo, tree, offset);
-                       break;
-               case 83: /* event-parameters */
-                       offset = fEventParameter(tvb, pinfo, tree, offset);
-                       break;
-               default:
-                       if (tag_info) {
-                               if (tag_is_opening(tag_info)) {
-                                       ++depth;
-                                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                               } else if (tag_is_closing(tag_info)) {
-                                       --depth;
-                                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                               } else {
-                                       offset = fContextTaggedValue(tvb, tree, offset, ar);
-                               }
-                       } else {
-                               offset = fApplicationTypes (tvb, pinfo, tree, offset, ar);
-                       }
-                       break;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-
-}
-
-static guint
-fPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
-{
-       guint8 tag_no;
-       guint32 lvt;
-
-       if (tag_is_opening(tag_info)) {
-               offset += fTagHeaderTree(tvb, tree, offset,
-                       &tag_no, &tag_info, &lvt);
-               offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
-               if (tvb_length_remaining(tvb, offset) > 0) {
-                       offset += fTagHeaderTree(tvb, tree, offset,
-                               &tag_no, &tag_info, &lvt);
-               }
-       } else {
-               proto_tree_add_text(tree, tvb, offset, tvb_length(tvb) - offset,
-                       "expected Opening Tag!"); \
-               offset = tvb_length(tvb);
-       }
-
-       return offset;
-}
-
-
-static guint
-fPropertyIdentifierValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
-{
-       guint lastoffset = offset;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
-       if (offset > lastoffset) {
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_no == tagoffset+2) {  /* Value - might not be present in ReadAccessResult */
-                       offset = fPropertyValue (tvb, pinfo, tree, offset, tag_info);
-               }
-       }
-       return offset;
-}
-
-static guint
-fBACnetPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
-               if (offset > lastoffset) {
-                       /* detect optional priority
-                       by looking to see if the next tag is context tag number 3 */
-                       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                       if (tag_is_context_specific(tag_info) && (tag_no == 3))
-                               offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+fApplicationTypesEnumeratedSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
+    const gchar *label, const value_string *src, guint32 split_val)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   tag_len;
+
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {
+
+        tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (!tag_is_context_specific(tag_info)) {
+            switch (tag_no) {
+            case 0: /** NULL 20.2.2 */
+                offset = fNullTag(tvb, pinfo, tree, offset, label);
+                break;
+            case 1: /** BOOLEAN 20.2.3 */
+                offset = fBooleanTag(tvb, pinfo, tree, offset, label);
+                break;
+            case 2: /** Unsigned Integer 20.2.4 */
+                offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
+                break;
+            case 3: /** Signed Integer 20.2.5 */
+                offset = fSignedTag(tvb, pinfo, tree, offset, label);
+                break;
+            case 4: /** Real 20.2.6 */
+                offset = fRealTag(tvb, pinfo, tree, offset, label);
+                break;
+            case 5: /** Double 20.2.7 */
+                offset = fDoubleTag(tvb, pinfo, tree, offset, label);
+                break;
+            case 6: /** Octet String 20.2.8 */
+                offset = fOctetString(tvb, pinfo, tree, offset, label, lvt);
+                break;
+            case 7: /** Character String 20.2.9 */
+                offset = fCharacterString(tvb, pinfo, tree, offset, label);
+                break;
+            case 8: /** Bit String 20.2.10 */
+                offset = fBitStringTagVS(tvb, pinfo, tree, offset, label, src);
+                break;
+            case 9: /** Enumerated 20.2.11 */
+                offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, src, split_val);
+                break;
+            case 10: /** Date 20.2.12 */
+                offset = fDate(tvb, pinfo, tree, offset, label);
+                break;
+            case 11: /** Time 20.2.13 */
+                offset = fTime(tvb, pinfo, tree, offset, label);
+                break;
+            case 12: /** BACnetObjectIdentifier 20.2.14 */
+                offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+                break;
+            case 13: /* reserved for ASHRAE */
+            case 14:
+            case 15:
+                proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
+                offset += lvt + tag_len;
+                break;
+            default:
+                break;
+            }
+
+        }
+    }
+    return offset;
+}
+
+static guint
+fShedLevel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* percent */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed percent: ");
+            break;
+        case 1: /* level */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed level: ");
+            break;
+        case 2: /* amount */
+            offset = fRealTag(tvb, pinfo, tree, offset, "shed amount: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
+    const gchar *label, const value_string *vs)
+{
+    return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0);
+}
+
+static guint
+fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
+    const gchar *label)
+{
+    return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0);
+}
+
+static guint
+fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
+{
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       tag_len;
+    proto_tree *subtree;
+    gint        tvb_len;
+
+    (void)label;
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    /* cap the the suggested length in case of bad data */
+    tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len);
+    if ((tvb_len >= 0) && ((guint32)tvb_len < lvt)) {
+        lvt = tvb_len;
+    }
+    subtree = proto_tree_add_subtree_format(tree, tvb, offset+tag_len, lvt,
+        ett_bacapp_tag, NULL, "Context Value (as %u DATA octets)", lvt);
+
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset + tag_len + lvt;
+}
+/*
+BACnetPrescale ::= SEQUENCE {
+    multiplier  [0] Unsigned,
+moduloDivide    [1] Unsigned
+}
+*/
+static guint
+fPrescale(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info) ) {
+            return offset;
+            }
+        switch (tag_no) {
+        case 0: /* multiplier */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "Multiplier: ");
+            break;
+        case 1: /* moduloDivide */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "Modulo Divide: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+
+}
+/*
+BACnetScale ::= CHOICE {
+    floatScale  [0] REAL,
+integerScale    [1] INTEGER
+}
+*/
+static guint
+fScale(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info) ) {
+            return offset;
+            }
+        switch (tag_no) {
+        case 0: /* floatScale */
+            offset = fRealTag(tvb, pinfo, tree, offset, "Float Scale: ");
+            break;
+        case 1: /* integerScale */
+            offset = fSignedTag(tvb, pinfo, tree, offset, "Integer Scale: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+/*
+BACnetAccumulatorRecord ::= SEQUENCE {
+    timestamp       [0] BACnetDateTime,
+    presentValue        [1] Unsigned,
+    accumulatedValue    [2] Unsigned,
+    accumulatortStatus  [3] ENUMERATED {
+                    normal          (0),
+                    starting        (1),
+                    recovered       (2),
+                    abnormal        (3),
+                    failed          (4)
+                    }
+}
+*/
+static guint
+fLoggingRecord(tvbuff_t *tvb, packet_info *pinfo  _U_, proto_tree *tree, guint offset)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info) ) {
+            return offset;
+            }
+        switch (tag_no) {
+        case 0: /* timestamp */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fDateTime(tvb, pinfo, tree, offset, "Timestamp: ");
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 1: /* presentValue */
+            offset  = fUnsignedTag(tvb, pinfo, tree, offset, "Present Value: ");
+            break;
+        case 2: /* accumulatedValue */
+            offset  = fUnsignedTag(tvb, pinfo, tree, offset, "Accumulated Value: ");
+            break;
+        case 3: /* accumulatorStatus */
+            offset  = fEnumeratedTag(tvb, pinfo, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+/*
+ SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState
+*/
+static guint
+fSequenceOfEnums(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label, const value_string *vs)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info) ) {
+            return offset;
+            }
+        offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs);
+        if ( offset == lastoffset ) break;
+    }
+    return offset;
+}
+
+/*
+SEQ OF BACnetDeviceObjectReference (accessed as an array)
+}
+*/
+static guint
+fDoorMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info) ) {
+            return offset;
+            }
+        offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
+        if (offset == lastoffset) break;
+    }
+    return offset;
+}
+
+/*
+SEQ OF ReadAccessSpecification
+*/
+static guint
+fListOfGroupMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info) ) {
+            return offset;
+            }
+        offset = fReadAccessSpecification(tvb, pinfo, tree, offset);
+        if ( offset == lastoffset ) break;
+    }
+    return offset;
+}
+
+static guint
+fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+    guint   lastoffset = 0, depth = 0;
+    char    ar[256];
+    guint32 save_object_type;
+
+    if (propertyIdentifier >= 0) {
+        g_snprintf(ar, sizeof(ar), "%s: ",
+            val_to_split_str(propertyIdentifier, 512,
+                BACnetPropertyIdentifier,
+                ASHRAE_Reserved_Fmt,
+                Vendor_Proprietary_Fmt));
+    } else {
+        g_snprintf(ar, sizeof(ar), "Abstract Type: ");
+    }
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
+            if (depth <= 0) return offset;
+        }
+
+        /* Application Tags */
+        switch (propertyIdentifier) {
+        case 2: /* action */
+            /* loop object is application tagged,
+                command object is context tagged */
+            if (tag_is_context_specific(tag_info)) {
+                /* BACnetActionList */
+                offset = fActionList(tvb, pinfo, tree, offset);
+            } else {
+                /* BACnetAction */
+                offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
+                    BACnetAction);
+            }
+            break;
+        case 30: /* BACnetAddressBinding */
+            offset = fAddressBinding(tvb, pinfo, tree, offset);
+            break;
+        case 54: /* list of object property reference */
+            offset = fLOPR(tvb, pinfo, tree, offset);
+            break;
+        case 55: /* list-of-session-keys */
+            fSessionKey(tvb, pinfo, tree, offset);
+            break;
+        case 79: /* object-type */
+        case 96: /* protocol-object-types-supported */
+            offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar,
+                BACnetObjectType, 128);
+            break;
+        case 97: /* Protocol-Services-Supported */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
+                BACnetServicesSupported);
+            break;
+        case 102: /* recipient-list */
+            offset = fDestination(tvb, pinfo, tree, offset);
+            break;
+        case 107: /* segmentation-supported */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
+                BACnetSegmentation);
+            break;
+        case 111: /* Status-Flags */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
+                BACnetStatusFlags);
+            break;
+        case 112: /* System-Status */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
+                BACnetDeviceStatus);
+            break;
+        case 117: /* units */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar,
+                BACnetEngineeringUnits);
+            break;
+        case 87:    /* priority-array -- accessed as a BACnetARRAY */
+            if (propertyArrayIndex == 0) {
+                /* BACnetARRAY index 0 refers to the length
+                of the array, not the elements of the array */
+                offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
+            } else {
+                offset = fPriorityArray(tvb, pinfo, tree, offset);
+            }
+            break;
+        case 38:    /* exception-schedule */
+            if (object_type < 128) {
+                if (propertyArrayIndex == 0) {
+                    /* BACnetARRAY index 0 refers to the length
+                    of the array, not the elements of the array */
+                    offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
+                } else {
+                    offset = fSpecialEvent(tvb, pinfo, tree, offset);
+                }
+            }
+            break;
+        case 19:  /* controlled-variable-reference */
+        case 60:  /* manipulated-variable-reference */
+        case 132: /* log-device-object-property */
+            offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
+            break;
+        case 109: /* Setpoint-Reference */
+            /* setpoint-Reference is actually BACnetSetpointReference which is a SEQ of [0] */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 123:   /* weekly-schedule -- accessed as a BACnetARRAY */
+            if (object_type < 128) {
+                if (propertyArrayIndex == 0) {
+                    /* BACnetARRAY index 0 refers to the length
+                    of the array, not the elements of the array */
+                    offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
+                } else {
+                    offset = fWeeklySchedule(tvb, pinfo, tree, offset);
+                }
+            }
+            break;
+        case 127:   /* client COV increment */
+            offset = fClientCOV(tvb, pinfo, tree, offset);
+            break;
+        case 131:  /* log-buffer */
+            if ( object_type == 25 )
+                offset = fEventLogRecord(tvb, pinfo, tree, offset);
+            else if ( object_type == 27 )
+                offset = fLogMultipleRecord(tvb, pinfo, tree, offset);
+            else
+                offset = fLogRecord(tvb, pinfo, tree, offset);
+            break;
+        case 159: /* member-of */
+        case 165: /* zone-members */
+            offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
+            break;
+        case 196: /* last-restart-reason */
+            offset = fRestartReason(tvb, pinfo, tree, offset);
+            break;
+        case 212: /* actual-shed-level */
+        case 214: /* expected-shed-level */
+        case 218: /* requested-shed-level */
+            offset = fShedLevel(tvb, pinfo, tree, offset);
+            break;
+        case 152: /* active-cov-subscriptions */
+            offset = fCOVSubscription(tvb, pinfo, tree, offset);
+            break;
+        case 23: /* date-list */
+            offset = fCalendarEntry(tvb, pinfo, tree, offset);
+            break;
+        case 116: /* time-sychronization-recipients */
+            offset = fRecipient(tvb, pinfo, tree, offset);
+            break;
+        case 83: /* event-parameters */
+            offset = fEventParameter(tvb, pinfo, tree, offset);
+            break;
+        case 211: /* subordinate-list */
+            offset = fDeviceObjectReference(tvb, pinfo, tree, offset);
+            break;
+        case 130: /* event-time-stamp */
+            offset = fEventTimeStamps(tvb, pinfo, tree, offset);
+            break;
+        case 197: /* logging-type */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType);
+            break;
+        case 36: /* event-state */
+            offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64);
+            break;
+        case 103: /* reliability */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability);
+            break;
+        case 72: /* notify-type */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNotifyType);
+            break;
+        case 208: /* node-type */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType);
+            break;
+        case 231: /* door-status */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus);
+            break;
+        case 233: /* lock-status */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus);
+            break;
+        case 235: /* secured-status */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus);
+            break;
+        case 158: /* maintenance-required */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance);
+            break;
+        case 92: /* program-state */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState);
+            break;
+        case 90: /* program-change */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest);
+            break;
+        case 100: /* reason-for-halt */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError);
+            break;
+        case 160: /* mode */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode);
+            break;
+        case 163: /* silenced */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState);
+            break;
+        case 161: /* operation-expected */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation);
+            break;
+        case 164: /* tracking-value */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState);
+            break;
+        case 41: /* file-access-method */
+            offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod);
+            break;
+        case 185:  /* prescale */
+            offset = fPrescale(tvb, pinfo, tree, offset);
+            break;
+        case 187:  /* scale */
+            offset = fScale(tvb, pinfo, tree, offset);
+            break;
+        case 184: /* logging-record */
+            offset = fLoggingRecord(tvb, pinfo, tree, offset);
+            break;
+        case 228: /* door-members */
+            offset = fDoorMembers(tvb, pinfo, tree, offset);
+            break;
+        case 181: /* input-reference */
+            offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
+            break;
+        case 78: /* object-property-reference */
+            offset = fObjectPropertyReference(tvb, pinfo, tree, offset);
+            break;
+        case 234: /* masked-alarm-values */
+            offset = fSequenceOfEnums(tvb, pinfo, tree, offset, "masked-alarm-value: ", BACnetDoorAlarmState);
+            break;
+        case 53:    /* list-of-group-members */
+            save_object_type = object_type;
+            offset = fListOfGroupMembers(tvb, pinfo, tree, offset);
+            object_type = save_object_type;
+            break;
+        case 85:    /* present-value */
+            if ( object_type == 11 )    /* group object handling of present-value */
+            {
+                offset = fReadAccessResult(tvb, pinfo, tree, offset);
+                break;
+            }
+            /* intentially fall through here so don't reorder this case statement */
+        default:
+            if (tag_info) {
+                if (tag_is_opening(tag_info)) {
+                    ++depth;
+                    offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                } else if (tag_is_closing(tag_info)) {
+                    --depth;
+                    offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                } else {
+                    offset  = fContextTaggedValue(tvb, pinfo, tree, offset, ar);
+                }
+            } else {
+                offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
+            }
+            break;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+
+}
+
+static guint
+fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tag_info)
+{
+    guint8  tag_no;
+    guint32 lvt;
+
+    if (tag_is_opening(tag_info)) {
+        offset += fTagHeaderTree(tvb, pinfo, tree, offset,
+                                 &tag_no, &tag_info, &lvt);
+        offset  = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
+        if (tvb_reported_length_remaining(tvb, offset) > 0) {
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset,
+                                     &tag_no, &tag_info, &lvt);
+        }
+    } else {
+        proto_tree_add_text(tree, tvb, offset, tvb_reported_length(tvb) - offset,
+                            "expected Opening Tag!");
+        offset = tvb_reported_length(tvb);
+    }
+
+    return offset;
+}
+
+
+static guint
+fPropertyIdentifierValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset)
+{
+    guint   lastoffset = offset;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0);
+    if (offset > lastoffset) {
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_no == tagoffset+2) {  /* Value - might not be present in ReadAccessResult */
+            offset = fPropertyValue(tvb, pinfo, tree, offset, tag_info);
+        }
+    }
+    return offset;
+}
+
+static guint
+fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0);
+        if (offset > lastoffset) {
+            /* detect optional priority
+            by looking to see if the next tag is context tag number 3 */
+            fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+            if (tag_is_context_specific(tag_info) && (tag_no == 3))
+                offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: ");
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       offset += len;
-                       subtree = tree;
-                       continue;
-               }
-
-               switch (tag_no) {
-               case 0: /* ProcessId */
-                       offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
-                       break;
-               case 1: /* monitored ObjectId */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 2: /* issueConfirmedNotifications */
-                       offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
-                       break;
-               case 3: /* life time */
-                       offset = fTimeSpan (tvb,tree,offset,"life time");
-                       break;
-               case 4: /* monitoredPropertyIdentifier */
-                       if (tag_is_opening(tag_info)) {
-                               tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
-                               if (tt) {
-                                       subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               }
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               case 5: /* covIncrement */
-                       offset = fRealTag (tvb, tree, offset, "COV Increment: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    guint       lastoffset = 0, len;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            offset += len;
+            subtree = tree;
+            continue;
+        }
+
+        switch (tag_no) {
+        case 0: /* ProcessId */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "subscriber Process Id: ");
+            break;
+        case 1: /* monitored ObjectId */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 2: /* issueConfirmedNotifications */
+            offset = fBooleanTag(tvb, pinfo, tree, offset, "issue Confirmed Notifications: ");
+            break;
+        case 3: /* life time */
+            offset = fTimeSpan(tvb, pinfo, tree, offset, "life time");
+            break;
+        case 4: /* monitoredPropertyIdentifier */
+            if (tag_is_opening(tag_info)) {
+                subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "monitoredPropertyIdentifier");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        case 5: /* covIncrement */
+            offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
-}
-
-static guint
-fWhoHas (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+    return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
+}
+
+static guint
+fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
+    guint lastoffset = 0;
 
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
 
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* deviceInstanceLowLimit */
-                       offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
-                       break;
-               case 1: /* deviceInstanceHighLimit */
-                       offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
-                       break;
-               case 2: /* BACnetObjectId */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 3: /* messageText */
-                       offset = fCharacterString (tvb,tree,offset, "Object Name: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* deviceInstanceLowLimit */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance Low Limit: ");
+            break;
+        case 1: /* deviceInstanceHighLimit */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance High Limit: ");
+            break;
+        case 2: /* BACnetObjectId */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 3: /* messageText */
+            offset = fCharacterString(tvb, pinfo, tree, offset, "Object Name: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 
 static guint
-fDailySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
+fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
 {
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
 
-       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (tag_is_opening(tag_info) && tag_no == 0) {
-               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
-               while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                       if (tag_is_closing(tag_info)) {
-                               /* should be closing context tag 0 */
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               return offset;
-                       }
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (tag_is_opening(tag_info) && tag_no == 0) {
+        offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+            if (tag_is_closing(tag_info)) {
+                /* should be closing context tag 0 */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                return offset;
+            }
 
-                       offset = fTimeValue (tvb, pinfo, subtree, offset);
-                       if (offset == lastoffset) break;    /* nothing happened, exit loop */
-               }
-       } else if (tag_no == 0 && lvt == 0) {
-               /* not sure null (empty array element) is legal */
-               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-       }
-       return offset;
+            offset = fTimeValue(tvb, pinfo, subtree, offset);
+            if (offset == lastoffset) break;    /* nothing happened, exit loop */
+        }
+    } else if ((tag_no == 0) && (lvt == 0)) {
+        /* not sure null (empty array element) is legal */
+        offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+    }
+    return offset;
 }
 
 static guint
-fWeeklySchedule (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint i = 1; /* day of week array index */
-       proto_tree *subtree = tree;
-       proto_item *tt;
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    guint       i = 1; /* day of week array index */
+    proto_tree *subtree = tree;
 
-       if (propertyArrayIndex > 0) {
-               /* BACnetARRAY index 0 refers to the length
-               of the array, not the elements of the array.
-               BACnetARRAY index -1 is our internal flag that
-               the optional index was not used.
-               BACnetARRAY refers to this as all elements of the array.
-               If the optional index is specified for a BACnetARRAY,
-               then that specific array element is referenced. */
-               i = propertyArrayIndex;
-       }
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       return offset; /* outer encoding will print out closing tag */
-               }
-               tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
-               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-               offset = fDailySchedule (tvb, pinfo, subtree, offset);
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    if (propertyArrayIndex > 0) {
+        /* BACnetARRAY index 0 refers to the length
+        of the array, not the elements of the array.
+        BACnetARRAY index -1 is our internal flag that
+        the optional index was not used.
+        BACnetARRAY refers to this as all elements of the array.
+        If the optional index is specified for a BACnetARRAY,
+        then that specific array element is referenced. */
+        i = propertyArrayIndex;
+    }
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            return offset; /* outer encoding will print out closing tag */
+        }
+        subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_bacapp_value, NULL,
+                                val_to_str(i++, day_of_week, "day of week (%d) not found"));
+        offset = fDailySchedule(tvb, pinfo, subtree, offset);
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 
 static guint
-fUTCTimeSynchronizationRequest  (tvbuff_t *tvb, proto_tree *tree, guint offset)
+fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       if (tvb_reported_length_remaining(tvb, offset) <= 0)
-               return offset;
+    if (tvb_reported_length_remaining(tvb, offset) <= 0)
+        return offset;
 
-       return fDateTime (tvb, tree, offset, "UTC-Time: ");
+    return fDateTime(tvb, pinfo, tree, offset, "UTC-Time: ");
 }
 
 static guint
-fTimeSynchronizationRequest  (tvbuff_t *tvb, proto_tree *tree, guint offset)
+fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       if (tvb_reported_length_remaining(tvb, offset) <= 0)
-               return offset;
+    if (tvb_reported_length_remaining(tvb, offset) <= 0)
+        return offset;
 
-       return fDateTime (tvb, tree, offset, NULL);
+    return fDateTime(tvb, pinfo, tree, offset, NULL);
 }
 
 static guint
-fDateRange  (tvbuff_t *tvb, proto_tree *tree, guint offset)
+fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       if (tvb_reported_length_remaining(tvb, offset) <= 0)
-               return offset;
-       offset = fDate (tvb,tree,offset,"Start Date: ");
-       return fDate (tvb, tree, offset, "End Date: ");
+    if (tvb_reported_length_remaining(tvb, offset) <= 0)
+        return offset;
+    offset = fDate(tvb, pinfo, tree, offset, "Start Date: ");
+    return fDate(tvb, pinfo, tree, offset, "End Date: ");
 }
 
 static guint
-fVendorIdentifier (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fVendorIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint32 val = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
-       const gchar *label = "Vendor ID";
+    guint32      val   = 0;
+    guint8       tag_no, tag_info;
+    guint32      lvt;
+    guint        tag_len;
+    proto_item  *ti;
+    proto_tree  *subtree;
+    const gchar *label = "Vendor ID";
 
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s: %s (%u)", label,
-                       val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
-       else
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s - %u octets (Unsigned)", label, lvt);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (fUnsigned32(tvb, offset + tag_len, lvt, &val))
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, &ti, "%s: %s (%u)",
+            label,
+            val_to_str_ext_const(val, &BACnetVendorIdentifiers_ext, "Unknown Vendor"),
+            val);
+    else
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, &ti, "%s - %u octets (Unsigned)", label, lvt);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
 
-       if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1  and <= 2 are supported */
-               proto_item *expert_item;
-               expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
-               expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1 or 2, got %u", lvt);
-               PROTO_ITEM_SET_GENERATED(expert_item);
-               return offset+tag_len+lvt;
-       }
+    if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1  and <= 2 are supported */
+        expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
+                                "Wrong length indicated. Expected 1 or 2, got %u", lvt);
+        return offset+tag_len+lvt;
+    }
 
-       proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
-               offset+tag_len, lvt, ENC_BIG_ENDIAN);
+    proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
+        offset+tag_len, lvt, ENC_BIG_ENDIAN);
 
-       return offset+tag_len+lvt;
+    return offset+tag_len+lvt;
 }
 
 static guint
-fRestartReason (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint32 val = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint tag_len;
-       proto_item *ti;
-       proto_tree *subtree;
-       const gchar *label = "Restart Reason";
+    guint32      val   = 0;
+    guint8       tag_no, tag_info;
+    guint32      lvt;
+    guint        tag_len;
+    proto_item  *ti;
+    proto_tree  *subtree;
+    const gchar *label = "Restart Reason";
 
-       tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s: %s (%u)", label,
-                       val_to_str(val,BACnetRestartReason,"Unknown reason"), val);
-       else
-               ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
-                       "%s - %u octets (Unsigned)", label, lvt);
-       subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-       fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
+    tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (fUnsigned32(tvb, offset + tag_len, lvt, &val))
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, &ti, "%s: %s (%u)", label,
+            val_to_str_const(val, BACnetRestartReason, "Unknown reason"), val);
+    else
+        subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len,
+            ett_bacapp_tag, &ti, "%s - %u octets (Unsigned)", label, lvt);
+    fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
 
-       if (lvt != 1) {
-               proto_item *expert_item;
-               expert_item = proto_tree_add_text(tree, tvb, 0, lvt, "Wrong length indicated. Expected 1, got %u", lvt);
-               expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", lvt);
-               PROTO_ITEM_SET_GENERATED(expert_item);
-               return offset+tag_len+lvt;
-       }
+    if (lvt != 1) {
+        expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
+                                "Wrong length indicated. Expected 1, got %u", lvt);
+        return offset+tag_len+lvt;
+    }
 
-       proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
-               offset+tag_len, lvt, ENC_BIG_ENDIAN);
+    proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb,
+        offset+tag_len, lvt, ENC_BIG_ENDIAN);
 
-       return offset+tag_len+lvt;
+    return offset+tag_len+lvt;
 }
 
 static guint
 fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               switch (fTagNo(tvb, offset)) {
-
-               case 0: /* textMessageSourceDevice */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* messageClass */
-                       switch (fTagNo(tvb, offset)) {
-                       case 0: /* numeric */
-                               offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
-                               break;
-                       case 1: /* character */
-                               offset = fCharacterString (tvb, tree, offset, "message Class: ");
-                               break;
-                       }
-                       break;
-               case 2: /* messagePriority */
-                       offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
-                               BACnetMessagePriority);
-                       break;
-               case 3: /* message */
-                       offset = fCharacterString (tvb, tree, offset, "message: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    guint lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+
+        case 0: /* textMessageSourceDevice */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* messageClass */
+            switch (fTagNo(tvb, offset)) {
+            case 0: /* numeric */
+                offset = fUnsignedTag(tvb, pinfo, tree, offset, "message Class: ");
+                break;
+            case 1: /* character */
+                offset = fCharacterString(tvb, pinfo, tree, offset, "message Class: ");
+                break;
+            }
+            break;
+        case 2: /* messagePriority */
+            offset = fEnumeratedTag(tvb, pinfo, tree, offset, "message Priority: ",
+                BACnetMessagePriority);
+            break;
+        case 3: /* message */
+            offset = fCharacterString(tvb, pinfo, tree, offset, "message: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
+    return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
 }
 
 static guint
 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-       tvbuff_t *next_tvb;
-       guint vendor_identifier = 0;
-       guint service_number = 0;
-
-       lastoffset = offset;
-       len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
-       if (col_get_writable(pinfo->cinfo))
-               col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
-       offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
-
-       next_tvb = tvb_new_subset_remaining(tvb,offset);
-       if (dissector_try_uint(bacapp_dissector_table,
-           vendor_identifier, next_tvb, pinfo, tree)) {
-               /* we parsed it so skip over length and we are done */
-               offset += tvb_length(next_tvb);
-               return offset;
-       }
-
-       /* Not handled by vendor dissector */
-
-       /* exit loop if nothing happens inside */
-       while (tvb_reported_length_remaining(tvb, offset)) {
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       if (tag_no == 2) { /* Make sure it's the expected tag */
-                               offset += len;
-                               subtree = tree;
-                               continue;
-                       } else {
-                               break; /* End loop if incorrect closing tag */
-                       }
-               }
-               switch (tag_no) {
-
-                       /* vendorID is now parsed above */
-               case 1: /* serviceNumber */
-                       fUnsigned32(tvb, offset+len, lvt, &service_number);
-                       if (col_get_writable(pinfo->cinfo))
-                               col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ",       service_number);
-                       offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
-                       break;
-               case 2: /*serviceParameters */
-                       if (tag_is_opening(tag_info)) {
-                               tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               propertyIdentifier = -1;
-                               offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-
-       return offset;
+    guint       lastoffset, len;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+    tvbuff_t   *next_tvb;
+    guint       vendor_identifier = 0;
+    guint       service_number = 0;
+
+    len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    fUnsigned32(tvb, offset+len, lvt, &vendor_identifier);
+    if (col_get_writable(pinfo->cinfo))
+        col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier);
+    offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
+
+    next_tvb = tvb_new_subset_remaining(tvb, offset);
+    if (dissector_try_uint(bacapp_dissector_table,
+        vendor_identifier, next_tvb, pinfo, tree)) {
+        /* we parsed it so skip over length and we are done */
+        offset += tvb_reported_length(next_tvb);
+        return offset;
+    }
+
+    /* Not handled by vendor dissector */
+
+    /* exit loop if nothing happens inside */
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            if (tag_no == 2) { /* Make sure it's the expected tag */
+                offset += len;
+                subtree = tree;
+                continue;
+            } else {
+                break; /* End loop if incorrect closing tag */
+            }
+        }
+        switch (tag_no) {
+
+            /* vendorID is now parsed above */
+        case 1: /* serviceNumber */
+            fUnsigned32(tvb, offset+len, lvt, &service_number);
+            if (col_get_writable(pinfo->cinfo))
+                col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ",   service_number);
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: ");
+            break;
+        case 2: /*serviceParameters */
+            if (tag_is_opening(tag_info)) {
+                subtree = proto_tree_add_subtree(subtree, tvb, offset, 1,
+                        ett_bacapp_value, NULL, "service Parameters");
+                propertyIdentifier = -1;
+                offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+
+    return offset;
 }
 
 static guint
 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
+    return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
 }
 
 static guint
 fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
+    return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
 }
 
 static guint
 fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const gchar *label)
 {
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       if (label != NULL) {
-               tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
-               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-       }
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-
-               switch (tag_no) {
-               case 0: /* subscriberProcessId */
-                       offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
-                       break;
-               case 1: /* requestingSource */
-                       offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
-                       break;
-               case 2: /* request */
-                       offset = fEnumeratedTagSplit (tvb, tree, offset,
-                               "request: ", BACnetLifeSafetyOperation, 64);
-                       break;
-               case 3: /* objectId */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fBACnetPropertyStates(tvbuff_t *tvb, proto_tree *tree, guint offset)
-{
-       switch (fTagNo(tvb, offset))
-       {
-       case 0:
-               offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
-               break;
-       case 1:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "binary-value: ", BACnetBinaryPV, 2);
-               break;
-       case 2:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "event-type: ", BACnetEventType, 12);
-               break;
-       case 3:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "polarity: ", BACnetPolarity, 2);
-               break;
-       case 4:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "program-change: ", BACnetProgramRequest, 5);
-               break;
-       case 5:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "program-state: ", BACnetProgramState, 5);
-               break;
-       case 6:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "reason-for-halt: ", BACnetProgramError, 5);
-               break;
-       case 7:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "reliability: ", BACnetReliability, 10);
-               break;
-       case 8:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "state: ", BACnetEventState, 64);
-               break;
-       case 9:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "system-status: ", BACnetDeviceStatus, 64);
-               break;
-       case 10:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "units: ", BACnetEngineeringUnits, 2);
-               break;
-       case 11:
-               offset = fUnsignedTag(tvb, tree, offset, "unsigned-value: ");
-               break;
-       case 12:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "life-safety-mode: ", BACnetLifeSafetyMode, 64);
-               break;
-       case 13:
-               offset = fEnumeratedTagSplit (tvb, tree, offset,
-                       "life-safety-state: ", BACnetLifeSafetyState, 64);
-               break;
-       default:
-               break;
-       }
-       return offset;
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    if (label != NULL) {
+        subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, label);
+    }
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+
+        switch (tag_no) {
+        case 0: /* subscriberProcessId */
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "requesting Process Id: ");
+            break;
+        case 1: /* requestingSource */
+            offset = fCharacterString(tvb, pinfo, tree, offset, "requesting Source: ");
+            break;
+        case 2: /* request */
+            offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
+                "request: ", BACnetLifeSafetyOperation, 64);
+            break;
+        case 3: /* objectId */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+typedef struct _value_string_enum {
+    const value_string *valstr;
+} value_string_enum;
+
+static const value_string_enum
+BACnetPropertyStatesEnums[] = {
+    { NULL },
+    {BACnetBinaryPV },
+    {BACnetEventType },
+    {BACnetPolarity },
+    {BACnetProgramRequest },
+    {BACnetProgramState },
+    {BACnetProgramError },
+    {BACnetReliability },
+    {BACnetEventState },
+    {BACnetDeviceStatus },
+    {BACnetEngineeringUnits },
+    { NULL },
+    {BACnetLifeSafetyMode },
+    {BACnetLifeSafetyState },
+    {BACnetRestartReason },
+    {BACnetDoorAlarmState },
+    {BACnetAction },
+    {BACnetDoorSecuredStatus },
+    {BACnetDoorStatus },
+    { NULL }, /* {BACnetDoorValue }, */
+    {BACnetFileAccessMethod },
+    {BACnetLockStatus },
+    {BACnetLifeSafetyOperation },
+    {BACnetMaintenance },
+    {BACnetNodeType },
+    {BACnetNotifyType },
+    { NULL }, /* {BACnetSecurityLevel }, */
+    {BACnetShedState },
+    {BACnetSilencedState },
+    { NULL },
+    { NULL }, /* {BACnetAccessEvent }, */
+    { NULL }, /* {BACnetZoneOccupancyState }, */
+    { NULL }, /* {BACnetAccessCredentialDisableReason }, */
+    { NULL }, /* {BACnetAccessCredentialDisable }, */
+    { NULL }, /* {BACnetAuthenticationStatus }, */
+    { NULL },
+    { NULL }, /* {BACnetBackupState }, */
+};
+#define BACnetPropertyStatesEnums_Size 36
+
+static guint
+fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint offset)
+{
+    guint8       tag_no, tag_info;
+    guint32      lvt;
+    const gchar* label;
+
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    label = wmem_strdup_printf(wmem_packet_scope(), "%s: ",
+                               val_to_str_const( tag_no, VALS(BACnetPropertyStates), "Unknown State" ));
+
+    switch (tag_no) {
+    case 0:
+        offset = fBooleanTag(tvb, pinfo, tree, offset, label);
+        break;
+    case 11:
+        offset = fUnsignedTag(tvb, pinfo, tree, offset, label);
+        break;
+    default:
+        if ( (tag_no > BACnetPropertyStatesEnums_Size) ||
+            VALS(BACnetPropertyStatesEnums[tag_no].valstr) == NULL)
+        {
+            offset = fEnumeratedTag(tvb, pinfo, tree, offset, label, NULL);
+            /* don't use Abstract type here because it is context tagged and therefore we don't know app type */
+        }
+        else
+        {
+            offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label,
+                    VALS(BACnetPropertyStatesEnums[tag_no].valstr), 64);
+        }
+        break;
+    }
+    return offset;
 }
 
 
@@ -6730,46 +7584,61 @@ BACnetDeviceObjectPropertyValue ::= SEQUENCE {
       }
 */
 static guint
-fDeviceObjectPropertyValue (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {
-               lastoffset = offset;
-               /* check the tag.  A closing tag means we are done */
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       return offset;
-               }
-               switch (tag_no) {
-               case 0: /* deviceIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* objectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 2: /* propertyIdentifier */
-                       offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 3: /* arrayIndex - OPTIONAL */
-                       offset = fUnsignedTag (tvb, tree, offset,
-                               "arrayIndex: ");
-                       break;
-               case 4: /* value */
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+fDeviceObjectPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {
+        lastoffset = offset;
+        /* check the tag.  A closing tag means we are done */
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            return offset;
+        }
+        switch (tag_no) {
+        case 0: /* deviceIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* objectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 2: /* propertyIdentifier */
+            offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 3: /* arrayIndex - OPTIONAL */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset,
+                "arrayIndex: ");
+            break;
+        case 4: /* value */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
+/*
+BACnetDeviceObjectPropertyReference ::= SEQUENCE {
+      objectIdentifier       [0]      BACnetObjectIdentifier,
+      propertyIdentifier     [1]      BACnetPropertyIdentifier,
+      propertyArrayIndex     [2]      Unsigned OPTIONAL, -- used only with array datatype
+                                                                -- if omitted with an array then
+                                                                -- the entire array is referenced
+      deviceIdentifier       [3]      BACnetObjectIdentifier OPTIONAL
+      }
+*/
+static guint
+fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
+}
 
 /*
 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
@@ -6782,3341 +7651,3673 @@ BACnetDeviceObjectPropertyReference ::= SEQUENCE {
       }
 */
 static guint
-fDeviceObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {
-               lastoffset = offset;
-               /* check the tag.  A closing tag means we are done */
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       return offset;
-               }
-               switch (tag_no) {
-               case 0: /* objectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* propertyIdentifier */
-                       offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 2: /* arrayIndex - OPTIONAL */
-                       offset = fUnsignedTag (tvb, tree, offset,
-                               "arrayIndex: ");
-                       break;
-               case 3: /* deviceIdentifier - OPTIONAL */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fNotificationParameters (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = offset;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
-               tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
-       subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-       /* Opening tag for parameter choice */
-       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       switch (tag_no) {
-       case 0: /* change-of-bitstring */
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset = fBitStringTag (tvb, subtree, offset,
-                                       "referenced-bitstring: ");
-                               break;
-                       case 1:
-                               offset = fBitStringTagVS (tvb, subtree, offset,
-                                       "status-flags: ", BACnetStatusFlags);
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 1: /* change-of-state */
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fBACnetPropertyStates(tvb, subtree, offset);
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       case 1:
-                               offset = fBitStringTagVS (tvb, subtree, offset,
-                                       "status-flags: ", BACnetStatusFlags);
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 2: /* change-of-value */
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               switch (fTagNo(tvb, offset)) {
-                               case 0:
-                                       offset = fBitStringTag (tvb, subtree, offset,
-                                               "changed-bits: ");
-                                       break;
-                               case 1:
-                                       offset = fRealTag (tvb, subtree, offset,
-                                               "changed-value: ");
-                                       break;
-                               default:
-                                       break;
-                               }
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       case 1:
-                               offset = fBitStringTagVS (tvb, subtree, offset,
-                                       "status-flags: ", BACnetStatusFlags);
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 3: /* command-failure */
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0: /* "command-value: " */
-                               /* from BACnet Table 13-3,
-                                       Standard Object Property Values Returned in Notifications */
-                               propertyIdentifier = 85; /* PRESENT_VALUE */
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       case 1:
-                               offset = fBitStringTagVS (tvb, subtree, offset,
-                                       "status-flags: ", BACnetStatusFlags);
-                               break;
-                       case 2: /* "feedback-value: " */
-                               propertyIdentifier = 40; /* FEEDBACK_VALUE */
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 4: /* floating-limit */
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset = fRealTag (tvb, subtree, offset, "reference-value: ");
-                               break;
-                       case 1:
-                               offset = fBitStringTagVS (tvb, subtree, offset,
-                                       "status-flags: ", BACnetStatusFlags);
-                               break;
-                       case 2:
-                               offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
-                               break;
-                       case 3:
-                               offset = fRealTag (tvb, subtree, offset, "error-limit: ");
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 5: /* out-of-range */
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
-                               break;
-                       case 1:
-                               offset = fBitStringTagVS (tvb, subtree, offset,
-                                       "status-flags: ", BACnetStatusFlags);
-                               break;
-                       case 2:
-                               offset = fRealTag (tvb, subtree, offset, "deadband: ");
-                               break;
-                       case 3:
-                               offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-           break;
-       case 6:
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       offset =fBACnetPropertyValue (tvb,pinfo,subtree,offset);
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 7: /* buffer-ready */
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-device */
-                               break;
-                       case 1:
-                               offset = fObjectIdentifier (tvb, pinfo, subtree, offset); /* buffer-object */
-                               break;
-                       case 2:
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       case 3:
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fDateTime (tvb, subtree, offset, "current-notification: ");
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 8: /* change-of-life-safety */
-               while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset = fEnumeratedTagSplit (tvb, subtree, offset,
-                                       "new-state: ", BACnetLifeSafetyState, 256);
-                               break;
-                       case 1:
-                               offset = fEnumeratedTagSplit (tvb, subtree, offset,
-                                       "new-mode: ", BACnetLifeSafetyMode, 256);
-                               break;
-                       case 2:
-                               offset = fBitStringTagVS (tvb, subtree, offset,
-                                       "status-flags: ", BACnetStatusFlags);
-                               break;
-                       case 3:
-                               offset = fEnumeratedTagSplit (tvb, subtree, offset,
-                                       "operation-expected: ", BACnetLifeSafetyOperation, 64);
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 9: /* extended */
-               while (tvb_reported_length_remaining(tvb, offset)) {
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
-                               break;
-                       case 1:
-                               offset = fUnsignedTag (tvb, subtree, offset,
-                                       "extended-event-type: ");
-                               break;
-                       case 2: /* parameters */
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
-                               offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 10: /* buffer ready */
-               while (tvb_reported_length_remaining(tvb, offset)) {
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0: /* buffer-property */
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       case 1:
-                               offset = fUnsignedTag (tvb, subtree, offset,
-                                       "previous-notification: ");
-                               break;
-                       case 2:
-                               offset = fUnsignedTag (tvb, subtree, offset,
-                                       "current-notification: ");
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       case 11: /* unsigned range */
-               while (tvb_reported_length_remaining(tvb, offset)) {
-                       lastoffset = offset;
-                       switch (fTagNo(tvb, offset)) {
-                       case 0:
-                               offset = fUnsignedTag (tvb, subtree, offset,
-                                       "exceeding-value: ");
-                               break;
-                       case 1:
-                               offset = fBitStringTagVS (tvb, subtree, offset,
-                                       "status-flags: ", BACnetStatusFlags);
-                               break;
-                       case 2:
-                               offset = fUnsignedTag (tvb, subtree, offset,
-                                       "exceeded-limit: ");
-                       lastoffset = offset;
-                               break;
-                       default:
-                               break;
-                       }
-                       if (offset == lastoffset) break;     /* nothing happened, exit loop */
-               }
-               break;
-       default:
-               break;
-       }
-
-       /* Closing tag for parameter choice */
-       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       return offset;
-}
-
-static guint
-fEventParameter (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = offset;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       tt = proto_tree_add_text(subtree, tvb, offset, 0, "event parameters (%d) %s",
-               tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
-       subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-       /* Opening tag for parameter choice */
-       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-
-       switch (tag_no) {
-               case 0: /* change-of-bitstring */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                               if (tag_is_closing(tag_info)) {
-                                       break;
-                               }
-                               switch (tag_no) {
-                               case 0:
-                                       offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
-                                       break;
-                               case 1:
-                                       offset = fBitStringTag (tvb, subtree, offset, "bitmask: ");
-                                       break;
-                               case 2: /* SEQUENCE OF BIT STRING */
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                                               lastoffset = offset;
-                                               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                                               if (tag_is_closing(tag_info)) {
-                                                       break;
-                                               }
-                                       offset = fBitStringTag(tvb, subtree, offset,
-                                               "bitstring value: ");
-                                       }
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case 1: /* change-of-state */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                               if (tag_is_closing(tag_info)) {
-                                       break;
-                               }
-                               switch (tag_no) {
-                               case 0:
-                                       offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
-                                       break;
-                               case 1: /* SEQUENCE OF BACnetPropertyStates */
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                                               lastoffset = offset;
-                                               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                                               if (tag_is_closing(tag_info)) {
-                                                       break;
-                                               }
-                                               offset = fBACnetPropertyStates(tvb, subtree, offset);
-                                       }
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case 2: /* change-of-value */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               switch (fTagNo(tvb, offset)) {
-                               case 0:
-                                       offset = fTimeSpan   (tvb, subtree, offset, "Time Delay");
-                                       break;
-                               case 1: /* don't loop it, it's a CHOICE */
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       switch (fTagNo(tvb, offset)) {
-                                       case 0:
-                                               offset = fBitStringTag (tvb, subtree, offset, "bitmask: ");
-                                               break;
-                                       case 1:
-                                               offset = fRealTag (tvb, subtree, offset,
-                                                       "referenced Property Increment: ");
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case 3: /* command-failure */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               tag_no = fTagNo(tvb, offset);
-                               switch (tag_no) {
-                               case 0:
-                                       offset = fTimeSpan   (tvb, subtree, offset, "Time Delay");
-                                       break;
-                               case 1:
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case 4: /* floating-limit */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                               if (tag_is_closing(tag_info)) {
-                                       break;
-                               }
-                               switch (tag_no) {
-                               case 0:
-                                       offset = fTimeSpan   (tvb, subtree, offset, "Time Delay");
-                                       break;
-                               case 1:
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       offset = fDeviceObjectPropertyReference (tvb,pinfo,subtree,offset);
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       break;
-                               case 2:
-                                       offset = fRealTag (tvb, subtree, offset, "low diff limit: ");
-                                       break;
-                               case 3:
-                                       offset = fRealTag (tvb, subtree, offset, "high diff limit: ");
-                                       break;
-                               case 4:
-                                       offset = fRealTag (tvb, subtree, offset, "deadband: ");
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case 5: /* out-of-range */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               switch (fTagNo(tvb, offset)) {
-                               case 0:
-                                       offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
-                                       break;
-                               case 1:
-                                       offset = fRealTag (tvb, subtree, offset, "low limit: ");
-                                       break;
-                               case 2:
-                                       offset = fRealTag (tvb, subtree, offset, "high limit: ");
-                                       break;
-                               case 3:
-                                       offset = fRealTag (tvb, subtree, offset, "deadband: ");
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               /*  deprectated
-               case 6:
-                       offset = fBACnetPropertyValue (tvb,pinfo,tree,offset);
-                       break;
+fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {
+        lastoffset = offset;
+        /* check the tag.  A closing tag means we are done */
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            return offset;
+        }
+        switch (tag_no) {
+        case 0: /* objectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* propertyIdentifier */
+            offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 2: /* arrayIndex - OPTIONAL */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset,
+                "arrayIndex: ");
+            break;
+        case 3: /* deviceIdentifier - OPTIONAL */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = offset;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0,
+        ett_bacapp_value, NULL, "notification parameters (%d) %s",
+        tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
+    /* Opening tag for parameter choice */
+    offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    switch (tag_no) {
+    case 0: /* change-of-bitstring */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fBitStringTag(tvb, pinfo, subtree, offset,
+                    "referenced-bitstring: ");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 1: /* change-of-state */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 2: /* change-of-value */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                switch (fTagNo(tvb, offset)) {
+                case 0:
+                    offset = fBitStringTag(tvb, pinfo, subtree, offset,
+                        "changed-bits: ");
+                    break;
+                case 1:
+                    offset = fRealTag(tvb, pinfo, subtree, offset,
+                        "changed-value: ");
+                    break;
+                default:
+                    break;
+                }
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 3: /* command-failure */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0: /* "command-value: " */
+                /* from BACnet Table 13-3,
+                    Standard Object Property Values Returned in Notifications */
+                propertyIdentifier = 85; /* PRESENT_VALUE */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 2: /* "feedback-value: " */
+                propertyIdentifier = 40; /* FEEDBACK_VALUE */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 4: /* floating-limit */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "reference-value: ");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 2:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "setpoint-value: ");
+                break;
+            case 3:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "error-limit: ");
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 5: /* out-of-range */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 2:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            case 3:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 6:
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            offset =fBACnetPropertyValue(tvb, pinfo, subtree, offset);
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 7: /* deprecated (was 'buffer-ready', changed and moved to [10]) */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fObjectIdentifier(tvb, pinfo, subtree, offset); /* buffer-device */
+                break;
+            case 1:
+                offset = fObjectIdentifier(tvb, pinfo, subtree, offset); /* buffer-object */
+                break;
+            case 2:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fDateTime(tvb, pinfo, subtree, offset, "previous-notification: ");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 3:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fDateTime(tvb, pinfo, subtree, offset, "current-notification: ");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 8: /* change-of-life-safety */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
+                    "new-state: ", BACnetLifeSafetyState, 256);
+                break;
+            case 1:
+                offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
+                    "new-mode: ", BACnetLifeSafetyMode, 256);
+                break;
+            case 2:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 3:
+                offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
+                    "operation-expected: ", BACnetLifeSafetyOperation, 64);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 9: /* extended */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
+                break;
+            case 1:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset,
+                    "extended-event-type: ");
+                break;
+            case 2: /* parameters */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: ");
+                offset  = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 10: /* buffer ready */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0: /* buffer-property */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 1:
+                offset  = fUnsignedTag(tvb, pinfo, subtree, offset,
+                    "previous-notification: ");
+                break;
+            case 2:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset,
+                    "current-notification: ");
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 11: /* unsigned range */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset,
+                    "exceeding-value: ");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 2:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset,
+                    "exceeded-limit: ");
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+        /* 12 reserved */
+    case 13: /* access-event */
+        break;
+    case 14: /* double-out-of-range */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 2:
+                offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            case 3:
+                offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 15: /* signed-out-of-range */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 2:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            case 3:
+                offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 16: /* unsigned-out-of-range */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeding-value: ");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 2:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            case 3:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: ");
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 17: /* change-of-characterstring */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                 /* changed-value (CharacterString) */
+                offset  = fCharacterString(tvb, pinfo, subtree, offset, "changed-value: ");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "status-flags: ", BACnetStatusFlags);
+                break;
+            case 2:
+                /* alarm-value (CharacterString) */
+                offset  = fCharacterString(tvb, pinfo, subtree, offset, "alarm-value: ");
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 18: /* change-of-status-flags */
+        while (tvb_reported_length_remaining(tvb, offset) > 0) {
+            /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset = fApplicationTypesEnumerated(tvb, pinfo, subtree, offset,
+                    "present-value: ", BACnetStatusFlags);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "referenced-flags: ", BACnetStatusFlags);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+        /* todo: add new parameters here ... */
+    default:
+        offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
+        break;
+    }
+
+    /* Closing tag for parameter choice */
+    offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    return offset;
+}
+
+static guint
+fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = offset;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0,
+        ett_bacapp_value, NULL, "event parameters (%d) %s",
+        tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type"));
+
+    /* Opening tag for parameter choice */
+    offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+
+    switch (tag_no) {
+    case 0: /* change-of-bitstring */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+            if (tag_is_closing(tag_info)) {
+                break;
+            }
+            switch (tag_no) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: ");
+                break;
+            case 2: /* SEQUENCE OF BIT STRING */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+                    lastoffset = offset;
+                    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+                    if (tag_is_closing(tag_info)) {
+                        break;
+                    }
+                    offset = fBitStringTag(tvb, pinfo, subtree, offset,
+                                           "bitstring value: ");
+                }
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 1: /* change-of-state */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+            if (tag_is_closing(tag_info)) {
+                break;
+            }
+            switch (tag_no) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1: /* SEQUENCE OF BACnetPropertyStates */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+                    lastoffset = offset;
+                    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+                    if (tag_is_closing(tag_info)) {
+                        break;
+                    }
+                    offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset);
+                }
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 2: /* change-of-value */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1: /* don't loop it, it's a CHOICE */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                switch (fTagNo(tvb, offset)) {
+                case 0:
+                    offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: ");
+                    break;
+                case 1:
+                    offset = fRealTag(tvb, pinfo, subtree, offset,
+                                       "referenced Property Increment: ");
+                    break;
+                default:
+                    break;
+                }
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 3: /* command-failure */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            tag_no = fTagNo(tvb, offset);
+            switch (tag_no) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 4: /* floating-limit */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+            if (tag_is_closing(tag_info)) {
+                break;
+            }
+            switch (tag_no) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 2:
+                offset  = fRealTag(tvb, pinfo, subtree, offset, "low diff limit: ");
+                break;
+            case 3:
+                offset  = fRealTag(tvb, pinfo, subtree, offset, "high diff limit: ");
+                break;
+            case 4:
+                offset  = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 5: /* out-of-range */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "low limit: ");
+                break;
+            case 2:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "high limit: ");
+                break;
+            case 3:
+                offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+        /*  deprectated
+            case 6:
+            offset = fBACnetPropertyValue (tvb, pinfo, tree, offset);
+            break;
         */
 
-               case 7: /* buffer-ready */
-                       /* deprecated
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { 
-                               lastoffset = offset;
-                               switch (fTagNo(tvb, offset)) {
-                               case 0:
-                                       offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
-                                       break;
-                               case 1:
-                                       offset = fUnsignedTag (tvb,tree,offset,
-                                               "previous notification count: ");
-                                       break;
-                               default:
-                                       return offset;
-                               }
-                       }
-                       */
-                       break;
-               case 8: /* change-of-life-safety */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               switch (fTagNo(tvb, offset)) {
-                               case 0:
-                                       offset = fTimeSpan (tvb, subtree, offset, "Time Delay");
-                                       break;
-                               case 1:
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                                               lastoffset = offset;
-                                               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                                               if (tag_is_closing(tag_info)) {
-                                                       break;
-                                               }
-                                               offset = fEnumeratedTagSplit (tvb, subtree, offset,
-                                                       "life safety alarm value: ", BACnetLifeSafetyState, 256);
-                                       }
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       break;
-                               case 2:
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                                               lastoffset = offset;
-                                               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                                               if (tag_is_closing(tag_info)) {
-                                                       break;
-                                               }
-                                               offset = fEnumeratedTagSplit (tvb, subtree, offset,
-                                                       "alarm value: ", BACnetLifeSafetyState, 256);
-                                       }
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       break;
-                               case 3:
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       offset = fDeviceObjectPropertyReference (tvb, pinfo, subtree, offset);
-                                       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case 9: /* extended */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               switch (fTagNo(tvb, offset)) {
-                               case 0:
-                                       offset = fVendorIdentifier (tvb, pinfo, tree, offset);
-                                       break;
-                               case 1:
-                                       offset = fUnsignedTag (tvb, tree, offset,
-                                               "extended-event-type: ");
-                                       break;
-                               case 2: /* parameters */
-                                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                                       offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
-                                       offset = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
-                                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                               lastoffset = offset;
-                                       break;
-                               default:
-                                       break;
-                               }
-                               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-                       }
-                       break;
-               case 10: /* buffer-ready */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               switch (fTagNo(tvb, offset)) {
-                               case 0:
-                                       offset = fUnsignedTag (tvb, subtree, offset,
-                                               "notification-threshold: ");
-                                       break;
-                               case 1:
-                                       offset = fUnsignedTag (tvb, subtree, offset,
-                                               "previous-notification-count: ");
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case 11: /* unsigned-range */
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               switch (fTagNo(tvb, offset)) {
-                               case 0:
-                                       offset = fTimeSpan (tvb, tree, offset, "Time Delay");
-                                       break;
-                               case 1:
-                                       offset = fUnsignedTag (tvb, tree, offset,
-                                               "low-limit: ");
-                                       break;
-                               case 2:
-                                       offset = fUnsignedTag (tvb, tree, offset,
-                                               "high-limit: ");
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               default:
-                       break;
-               }
-       
-       /* Closing tag for parameter choice */
-       offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-       return offset;
-}
-
-static guint
-fLogRecord (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* timestamp */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fDate (tvb,tree,offset,"Date: ");
-                       offset = fTime (tvb,tree,offset,"Time: ");
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               case 1: /* logDatum: don't loop, it's a CHOICE */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       switch (fTagNo(tvb, offset)) {
-                       case 0: /* logStatus */    /* Changed this to BitString per BACnet Spec. */
-                           offset = fBitStringTagVS(tvb, tree, offset, "log status:", BACnetLogStatus);
-                               break;
-                       case 1:
-                               offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
-                               break;
-                       case 2:
-                               offset = fRealTag (tvb, tree, offset, "real value: ");
-                               break;
-                       case 3:
-                               offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
-                               break;
-                       case 4:
-                               offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
-                               break;
-                       case 5:
-                               offset = fSignedTag (tvb, tree, offset, "signed value: ");
-                               break;
-                       case 6:
-                               offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
-                               break;
-                       case 7:
-                               offset = fNullTag(tvb, tree, offset, "null value: ");
-                               break;
-                       case 8:
-                               offset = fError (tvb, pinfo, tree, offset);
-                               break;
-                       case 9:
-                               offset = fRealTag (tvb, tree, offset, "time change: ");
-                               break;
-                       case 10:        /* any Value */
-                               offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
-                               offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       default:
-                               return offset;
-                       }
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               case 2:
-                       /* Changed this to BitString per BACnet Spec. */
-                       offset = fBitStringTagVS(tvb, tree, offset, "Status Flags:", BACnetStatusFlags);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-
-static guint
-fConfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-
-               switch (fTagNo(tvb,offset)) {
-               case 0: /* ProcessId */
-                       offset = fProcessId (tvb,tree,offset);
-                       break;
-               case 1: /* initiating ObjectId */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 2: /* event ObjectId */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 3: /* time stamp */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fTimeStamp (tvb, tree, offset, NULL);
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               case 4: /* notificationClass */
-                       offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
-                       break;
-               case 5: /* Priority */
-                       offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
-                       break;
-               case 6: /* EventType */
-                       offset = fEnumeratedTagSplit (tvb, tree, offset,
-                               "Event Type: ", BACnetEventType, 64);
-                       break;
-               case 7: /* messageText */
-                       offset = fCharacterString (tvb, tree, offset, "message Text: ");
-                       break;
-               case 8: /* NotifyType */
-                       offset = fEnumeratedTag (tvb, tree, offset,
-                               "Notify Type: ", BACnetNotifyType);
-                       break;
-               case 9: /* ackRequired */
-                       offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
-                       break;
-               case 10: /* fromState */
-                       offset = fEnumeratedTagSplit (tvb, tree, offset,
-                               "from State: ", BACnetEventState, 64);
-                       break;
-               case 11: /* toState */
-                       offset = fEnumeratedTagSplit (tvb, tree, offset,
-                               "to State: ", BACnetEventState, 64);
-                       break;
-               case 12: /* NotificationParameters */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fNotificationParameters (tvb, pinfo, tree, offset);
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               default:
-                       break;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       return fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
-}
-
-static guint
-fConfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       offset += len;
-                       subtree = tree;
-                       continue;
-               }
-
-               switch (tag_no) {
-               case 0: /* ProcessId */
-                       offset = fProcessId (tvb,tree,offset);
-                       break;
-               case 1: /* initiating DeviceId */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 2: /* monitored ObjectId */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 3: /* time remaining */
-                       offset = fTimeSpan (tvb, tree, offset, "Time remaining");
-                       break;
-               case 4: /* List of Values */
-                       if (tag_is_opening(tag_info)) {
-                               tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       return fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
-}
-
-static guint
-fAcknowledgeAlarmRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no = 0, tag_info = 0;
-       guint32 lvt = 0;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* acknowledgingProcessId */
-                       offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
-                       break;
-               case 1: /* eventObjectId */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 2: /* eventStateAcknowledged */
-                       offset = fEnumeratedTagSplit (tvb, tree, offset,
-                               "event State Acknowledged: ", BACnetEventState, 64);
-                       break;
-               case 3: /* timeStamp */
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fTimeStamp(tvb, tree, offset, NULL);
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               case 4: /* acknowledgementSource */
-                       offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
-                       break;
-               case 5: /* timeOfAcknowledgement */
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fGetAlarmSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
-               offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
-                       "alarm State: ", BACnetEventState, 64);
-               offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
-                       "acknowledged Transitions: ", BACnetEventTransitionBits);
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return  offset;
-}
-
-static guint
-fGetEnrollmentSummaryRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* acknowledgmentFilter */
-                       offset = fEnumeratedTag (tvb, tree, offset,
-                               "acknowledgment Filter: ", BACnetAcknowledgementFilter);
-                       break;
-               case 1: /* eventObjectId - OPTIONAL */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fRecipientProcess (tvb, pinfo, tree, offset);
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               case 2: /* eventStateFilter */
-                       offset = fEnumeratedTag (tvb, tree, offset,
-                               "event State Filter: ", BACnetEventStateFilter);
-                       break;
-               case 3: /* eventTypeFilter - OPTIONAL */
-                       offset = fEnumeratedTag (tvb, tree, offset,
-                               "event Type Filter: ", BACnetEventType);
-                       break;
-               case 4: /* priorityFilter */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
-                       offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               case 5: /* notificationClassFilter - OPTIONAL */
-                       offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fGetEnrollmentSummaryAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
-               offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
-                       "event Type: ", BACnetEventType, 64);
-               offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
-                       "event State: ", BACnetEventState);
-               offset = fApplicationTypes (tvb, pinfo, tree, offset, "Priority: ");
-               offset = fApplicationTypes (tvb, pinfo, tree, offset, "Notification Class: ");
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-
-       return  offset;
-}
-
-static guint
-fGetEventInformationRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       if (tvb_reported_length_remaining(tvb, offset) > 0) {
-               if (fTagNo(tvb, offset) == 0) {
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-               }
-       }
-       return offset;
-}
-
-static guint
-flistOfEventSummaries (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree* subtree = tree;
-       proto_item* ti = 0;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               /* we are finished here if we spot a closing tag */
-               if (tag_is_closing(tag_info)) {
-                       break;
-               }
-               switch (tag_no) {
-               case 0: /* ObjectId */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* eventState */
-                       offset = fEnumeratedTag (tvb, tree, offset,
-                               "event State: ", BACnetEventState);
-                       break;
-               case 2: /* acknowledgedTransitions */
-                       offset = fBitStringTagVS (tvb, tree, offset,
-                               "acknowledged Transitions: ", BACnetEventTransitionBits);
-                       break;
-               case 3: /* eventTimeStamps */
-                       ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
-                       if (ti) {
-                               subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-                       }
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
-                       offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
-                       offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               case 4: /* notifyType */
-                       offset = fEnumeratedTag (tvb, tree, offset,
-                               "Notify Type: ", BACnetNotifyType);
-                       break;
-               case 5: /* eventEnable */
-                       offset = fBitStringTagVS (tvb, tree, offset,
-                               "event Enable: ", BACnetEventTransitionBits);
-                       break;
-               case 6: /* eventPriorities */
-                       ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
-                       if (ti) {
-                               subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
-                       }
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
-                       offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
-                       offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fLOPR (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               /* we are finished here if we spot a closing tag */
-               if (tag_is_closing(tag_info)) {
-                       break;
-               }
-               offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fGetEventInformationACK (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* listOfEventSummaries */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = flistOfEventSummaries (tvb, pinfo, tree, offset);
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               case 1: /* moreEvents */
-                       offset = fBooleanTag (tvb, tree, offset, "more Events: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    case 7: /* buffer-ready */
+#if 0
+        /* deprecated */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification threshold");
+                break;
+            case 1:
+                offset = fUnsignedTag(tvb, pinfo, tree, offset,
+                                       "previous notification count: ");
+                break;
+            default:
+                return offset;
+            }
+        }
+#endif
+        break;
+    case 8: /* change-of-life-safety */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+                    lastoffset = offset;
+                    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+                    if (tag_is_closing(tag_info)) {
+                        break;
+                    }
+                    offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
+                                                  "life safety alarm value: ", BACnetLifeSafetyState, 256);
+                }
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 2:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+                    lastoffset = offset;
+                    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+                    if (tag_is_closing(tag_info)) {
+                        break;
+                    }
+                    offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
+                                                  "alarm value: ", BACnetLifeSafetyState, 256);
+                }
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 3:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 9: /* extended */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fVendorIdentifier(tvb, pinfo, tree, offset);
+                break;
+            case 1:
+                offset = fUnsignedTag(tvb, pinfo, tree, offset,
+                                       "extended-event-type: ");
+                break;
+            case 2: /* parameters */
+                offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: ");
+                offset  = fDeviceObjectPropertyValue(tvb, pinfo, tree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                lastoffset = offset;
+                break;
+            default:
+                break;
+            }
+            if (offset == lastoffset) break;     /* nothing happened, exit loop */
+        }
+        break;
+    case 10: /* buffer-ready */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset,
+                                       "notification-threshold: ");
+                break;
+            case 1:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset,
+                                       "previous-notification-count: ");
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 11: /* unsigned-range */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, tree, offset, "Time Delay");
+                break;
+            case 1:
+                offset = fUnsignedTag(tvb, pinfo, tree, offset,
+                                       "low-limit: ");
+                break;
+            case 2:
+                offset = fUnsignedTag(tvb, pinfo, tree, offset,
+                                       "high-limit: ");
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 13: /* access-event */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                /* TODO: [0] SEQUENCE OF BACnetAccessEvent */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+                    lastoffset = offset;
+                    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+                    if (tag_is_closing(tag_info)) {
+                        break;
+                    }
+                    offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset,
+                                                  "access event: ", BACnetAccessEvent, 512);
+                }
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 1:
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 14: /* double-out-of-range */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset = fDoubleTag(tvb, pinfo, subtree, offset, "low limit: ");
+                break;
+            case 2:
+                offset = fDoubleTag(tvb, pinfo, subtree, offset, "high limit: ");
+                break;
+            case 3:
+                offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 15: /* signed-out-of-range */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset = fSignedTag(tvb, pinfo, subtree, offset, "low limit: ");
+                break;
+            case 2:
+                offset = fSignedTag(tvb, pinfo, subtree, offset, "high limit: ");
+                break;
+            case 3:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 16: /* unsigned-out-of-range */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset, "low limit: ");
+                break;
+            case 2:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset, "high limit: ");
+                break;
+            case 3:
+                offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: ");
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 17: /* change-of-characterstring */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1: /* SEQUENCE OF CharacterString */
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+                    lastoffset = offset;
+                    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+                    if (tag_is_closing(tag_info)) {
+                        break;
+                    }
+                    offset  = fCharacterString(tvb, pinfo, tree, offset, "alarm value: ");
+                }
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 18: /* change-of-status-flags */
+        while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+            lastoffset = offset;
+            switch (fTagNo(tvb, offset)) {
+            case 0:
+                offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay");
+                break;
+            case 1:
+                offset = fBitStringTagVS(tvb, pinfo, subtree, offset,
+                    "selected flags: ", BACnetStatusFlags);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+        /* todo: add new event-parameter cases here */
+    default:
+        break;
+    }
+
+    /* Closing tag for parameter choice */
+    offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+    return offset;
+}
+
+static guint
+fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* timestamp */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fDate(tvb, pinfo, tree, offset, "Date: ");
+            offset  = fTime(tvb, pinfo, tree, offset, "Time: ");
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 1: /* logDatum: don't loop, it's a CHOICE */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            switch (fTagNo(tvb, offset)) {
+            case 0: /* logStatus */    /* Changed this to BitString per BACnet Spec. */
+                offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
+                break;
+            case 1: /* todo: move this to new method fConfirmedEventNotificationRequestTag... */
+                subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "notification: ");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 2:
+                offset = fRealTag(tvb, pinfo, tree, offset, "time-change: ");
+                break;
+            default:
+                return offset;
+            }
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* timestamp */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fDate(tvb, pinfo, tree, offset, "Date: ");
+            offset  = fTime(tvb, pinfo, tree, offset, "Time: ");
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 1: /* logDatum: don't loop, it's a CHOICE */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            switch (fTagNo(tvb, offset)) {
+            case 0: /* logStatus */    /* Changed this to BitString per BACnet Spec. */
+                offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
+                break;
+            case 1:
+                offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: ");
+                break;
+            case 2:
+                offset = fRealTag(tvb, pinfo, tree, offset, "real value: ");
+                break;
+            case 3:
+                offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: ");
+                break;
+            case 4:
+                offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: ");
+                break;
+            case 5:
+                offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: ");
+                break;
+            case 6:
+                offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: ");
+                break;
+            case 7:
+                offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
+                break;
+            case 8:
+                offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fError(tvb, pinfo, tree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 9:
+                offset = fRealTag(tvb, pinfo, tree, offset, "time change: ");
+                break;
+            case 10:    /* any Value */
+                offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            default:
+                return offset;
+            }
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 2:
+            /* Changed this to BitString per BACnet Spec. */
+            offset = fBitStringTagVS(tvb, pinfo, tree, offset, "Status Flags:", BACnetStatusFlags);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* timestamp */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fDate(tvb, pinfo, tree, offset, "Date: ");
+            offset  = fTime(tvb, pinfo, tree, offset, "Time: ");
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 1: /* logData: don't loop, it's a CHOICE */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            switch (fTagNo(tvb, offset)) {
+            case 0: /* logStatus */    /* Changed this to BitString per BACnet Spec. */
+                offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus);
+                break;
+            case 1: /* log-data: SEQUENCE OF CHOICE */
+                offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset != lastoffset)) {  /* exit loop if nothing happens inside */
+                    lastoffset = offset;
+                    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+                    if (tag_is_closing(tag_info)) {
+                        lastoffset = offset;
+                        break;
+                    }
+                    switch (tag_no) {
+                    case 0:
+                        offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: ");
+                        break;
+                    case 1:
+                        offset = fRealTag(tvb, pinfo, tree, offset, "real value: ");
+                        break;
+                    case 2:
+                        offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: ");
+                        break;
+                    case 3:
+                        offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: ");
+                        break;
+                    case 4:
+                        offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: ");
+                        break;
+                    case 5:
+                        offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: ");
+                        break;
+                    case 6:
+                        offset = fNullTag(tvb, pinfo, tree, offset, "null value: ");
+                        break;
+                    case 7:
+                        offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                        offset  = fError(tvb, pinfo, tree, offset);
+                        offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                        break;
+                    case 8: /* any Value */
+                        offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                        offset  = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
+                        offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                        break;
+                    default:
+                        return offset;
+                    }
+                }
+                offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+                break;
+            case 2:
+                offset = fRealTag(tvb, pinfo, tree, offset, "time-change: ");
+                break;
+            default:
+                return offset;
+            }
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+
+static guint
+fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            break;
+        }
+
+        switch (tag_no) {
+        case 0: /* ProcessId */
+            offset  = fProcessId(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* initiating ObjectId */
+            offset  = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 2: /* event ObjectId */
+            offset  = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 3: /* time stamp */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fTimeStamp(tvb, pinfo, tree, offset, NULL);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 4: /* notificationClass */
+            offset  = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: ");
+            break;
+        case 5: /* Priority */
+            offset  = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: ");
+            break;
+        case 6: /* EventType */
+            offset  = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
+                "Event Type: ", BACnetEventType, 64);
+            break;
+        case 7: /* messageText */
+            offset  = fCharacterString(tvb, pinfo, tree, offset, "message Text: ");
+            break;
+        case 8: /* NotifyType */
+            offset  = fEnumeratedTag(tvb, pinfo, tree, offset,
+                "Notify Type: ", BACnetNotifyType);
+            break;
+        case 9: /* ackRequired */
+            offset  = fBooleanTag(tvb, pinfo, tree, offset, "ack Required: ");
+            break;
+        case 10: /* fromState */
+            offset  = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
+                "from State: ", BACnetEventState, 64);
+            break;
+        case 11: /* toState */
+            offset  = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
+                "to State: ", BACnetEventState, 64);
+            break;
+        case 12: /* NotificationParameters */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fNotificationParameters(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            break;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    return fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
+}
+
+static guint
+fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0, len;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree    = tree;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            offset += len;
+            subtree = tree;
+            continue;
+        }
+
+        switch (tag_no) {
+        case 0: /* ProcessId */
+            offset = fProcessId(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* initiating DeviceId */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 2: /* monitored ObjectId */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 3: /* time remaining */
+            offset = fTimeSpan(tvb, pinfo, tree, offset, "Time remaining");
+            break;
+        case 4: /* List of Values */
+            if (tag_is_opening(tag_info)) {
+                subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "list of Values");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    return fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
+}
+
+static guint
+fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no = 0, tag_info = 0;
+    guint32 lvt = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* acknowledgingProcessId */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "acknowledging Process Id: ");
+            break;
+        case 1: /* eventObjectId */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 2: /* eventStateAcknowledged */
+            offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset,
+                "event State Acknowledged: ", BACnetEventState, 64);
+            break;
+        case 3: /* timeStamp */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fTimeStamp(tvb, pinfo, tree, offset, NULL);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 4: /* acknowledgementSource */
+            offset  = fCharacterString(tvb, pinfo, tree, offset, "acknowledgement Source: ");
+            break;
+        case 5: /* timeOfAcknowledgement */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fTimeStamp(tvb, pinfo, tree, offset, "acknowledgement timestamp: ");
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
+        offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
+            "alarm State: ", BACnetEventState, 64);
+        offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
+            "acknowledged Transitions: ", BACnetEventTransitionBits);
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return  offset;
+}
+
+static guint
+fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* acknowledgmentFilter */
+            offset = fEnumeratedTag(tvb, pinfo, tree, offset,
+                "acknowledgment Filter: ", BACnetAcknowledgementFilter);
+            break;
+        case 1: /* eventObjectId - OPTIONAL */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fRecipientProcess(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 2: /* eventStateFilter */
+            offset  = fEnumeratedTag(tvb, pinfo, tree, offset,
+                "event State Filter: ", BACnetEventStateFilter);
+            break;
+        case 3: /* eventTypeFilter - OPTIONAL */
+            offset  = fEnumeratedTag(tvb, pinfo, tree, offset,
+                "event Type Filter: ", BACnetEventType);
+            break;
+        case 4: /* priorityFilter */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fUnsignedTag(tvb, pinfo, tree, offset, "min Priority: ");
+            offset  = fUnsignedTag(tvb, pinfo, tree, offset, "max Priority: ");
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 5: /* notificationClassFilter - OPTIONAL */
+            offset  = fUnsignedTag(tvb, pinfo, tree, offset, "notification Class Filter: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
+        offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
+            "event Type: ", BACnetEventType, 64);
+        offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
+            "event State: ", BACnetEventState);
+        offset = fApplicationTypes(tvb, pinfo, tree, offset, "Priority: ");
+        if (tvb_reported_length_remaining(tvb, offset) > 0 && fTagNo(tvb, offset) == 2)  /* Notification Class - OPTIONAL */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: ");
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+
+    return  offset;
+}
+
+static guint
+fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {
+        if (fTagNo(tvb, offset) == 0) {
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+        }
+    }
+    return offset;
+}
+
+static guint
+flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree* subtree = tree;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        /* we are finished here if we spot a closing tag */
+        if (tag_is_closing(tag_info)) {
+            break;
+        }
+        switch (tag_no) {
+        case 0: /* ObjectId */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* eventState */
+            offset = fEnumeratedTag(tvb, pinfo, tree, offset,
+                "event State: ", BACnetEventState);
+            break;
+        case 2: /* acknowledgedTransitions */
+            offset = fBitStringTagVS(tvb, pinfo, tree, offset,
+                "acknowledged Transitions: ", BACnetEventTransitionBits);
+            break;
+        case 3: /* eventTimeStamps */
+            subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventTimeStamps");
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: ");
+            offset  = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: ");
+            offset  = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: ");
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 4: /* notifyType */
+            offset  = fEnumeratedTag(tvb, pinfo, tree, offset,
+                "Notify Type: ", BACnetNotifyType);
+            break;
+        case 5: /* eventEnable */
+            offset  = fBitStringTagVS(tvb, pinfo, tree, offset,
+                "event Enable: ", BACnetEventTransitionBits);
+            break;
+        case 6: /* eventPriorities */
+            subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventPriorities");
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-OFFNORMAL Priority: ");
+            offset  = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-FAULT Priority: ");
+            offset  = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-NORMAL Priority: ");
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        /* we are finished here if we spot a closing tag */
+        if (tag_is_closing(tag_info)) {
+            break;
+        }
+        offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset);
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* listOfEventSummaries */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = flistOfEventSummaries(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        case 1: /* moreEvents */
+            offset  = fBooleanTag(tvb, pinfo, tree, offset, "more Events: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       offset += len;
-                       subtree = tree;
-                       continue;
-               }
-
-               switch (tag_no) {
-               case 0: /* ObjectId */
-                       offset = fBACnetObjectPropertyReference (tvb, pinfo, subtree, offset);
-                       break;
-               case 3: /* listOfElements */
-                       if (tag_is_opening(tag_info)) {
-                               tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    guint       lastoffset = 0, len;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree    = tree;
+
+    col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            offset += len;
+            subtree = tree;
+            continue;
+        }
+
+        switch (tag_no) {
+        case 0: /* ObjectId */
+            offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
+            break;
+        case 3: /* listOfElements */
+            if (tag_is_opening(tag_info)) {
+                subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfElements");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       return fObjectIdentifier (tvb, pinfo, tree, offset);
+    return fObjectIdentifier(tvb, pinfo, tree, offset);
 }
 
 static guint
-fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
+fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
+    guint lastoffset = 0;
 
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
 
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* timeDuration */
-                       offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
-                       break;
-               case 1: /* enable-disable */
-                       offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
-                               BACnetEnableDisable);
-                       break;
-               case 2: /* password - OPTIONAL */
-                       offset = fCharacterString (tvb, tree, offset, "Password: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* timeDuration */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "time Duration: ");
+            break;
+        case 1: /* enable-disable */
+            offset = fEnumeratedTag(tvb, pinfo, tree, offset, "enable-disable: ",
+                BACnetEnableDisable);
+            break;
+        case 2: /* password - OPTIONAL */
+            offset = fCharacterString(tvb, pinfo, tree, offset, "Password: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
-fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
+fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
+    guint lastoffset = 0;
 
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
 
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* reinitializedStateOfDevice */
-                       offset = fEnumeratedTag (tvb, tree, offset,
-                               "reinitialized State Of Device: ",
-                               BACnetReinitializedStateOfDevice);
-                       break;
-               case 1: /* password - OPTIONAL */
-                       offset = fCharacterString (tvb, tree, offset, "Password: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* reinitializedStateOfDevice */
+            offset = fEnumeratedTag(tvb, pinfo, tree, offset,
+                "reinitialized State Of Device: ",
+                BACnetReinitializedStateOfDevice);
+            break;
+        case 1: /* password - OPTIONAL */
+            offset = fCharacterString(tvb, pinfo, tree, offset, "Password: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
-               "vtClass: ", BACnetVTClass);
-       return fApplicationTypes (tvb, pinfo, tree,offset,"local VT Session ID: ");
+    offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
+                                          "vtClass: ", BACnetVTClass);
+    return fApplicationTypes(tvb, pinfo, tree, offset, "local VT Session ID: ");
 }
 
 static guint
-fVtOpenAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       return fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
+    return fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: ");
 }
 
 static guint
-fVtCloseRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
+    guint lastoffset = 0;
 
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               offset= fApplicationTypes (tvb, pinfo, tree,offset,"remote VT Session ID: ");
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        offset= fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: ");
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
-fVtDataRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       offset= fApplicationTypes (tvb, pinfo, tree,offset,"VT Session ID: ");
-       offset = fApplicationTypes (tvb, pinfo, tree, offset, "VT New Data: ");
-       return fApplicationTypes (tvb, pinfo, tree,offset,"VT Data Flag: ");;
+    offset= fApplicationTypes(tvb, pinfo, tree, offset, "VT Session ID: ");
+    offset = fApplicationTypes(tvb, pinfo, tree, offset, "VT New Data: ");
+    return fApplicationTypes(tvb, pinfo, tree, offset, "VT Data Flag: ");
 }
 
 static guint
-fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
+fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
+    guint lastoffset = 0;
 
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
 
-               switch (fTagNo(tvb,offset)) {
-               case 0: /* BOOLEAN */
-                       offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
-                       break;
-               case 1: /* Unsigned OPTIONAL */
-                       offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* BOOLEAN */
+            offset = fBooleanTag(tvb, pinfo, tree, offset, "all New Data Accepted: ");
+            break;
+        case 1: /* Unsigned OPTIONAL */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "accepted Octet Count: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
-fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
+fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
+    guint lastoffset = 0;
 
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
 
-               switch (fTagNo(tvb,offset)) {
-               case 0: /* Unsigned32 */
-                       offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
-                       break;
-               case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
-                       proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
-                       break;
-               case 2: /* Chararacter String OPTIONAL */
-                       offset = fCharacterString (tvb, tree, offset, "operator Name: ");
-                       break;
-               case 3: /* Chararacter String OPTIONAL */
-                       offset = fCharacterString (tvb, tree, offset, "operator Password: ");
-                       break;
-               case 4: /* Boolean OPTIONAL */
-                       offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* Unsigned32 */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "pseudo Random Number: ");
+            break;
+        case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
+            proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
+            break;
+        case 2: /* Chararacter String OPTIONAL */
+            offset = fCharacterString(tvb, pinfo, tree, offset, "operator Name: ");
+            break;
+        case 3: /* Chararacter String OPTIONAL */
+            offset = fCharacterString(tvb, pinfo, tree, offset, "operator Password: ");
+            break;
+        case 4: /* Boolean OPTIONAL */
+            offset = fBooleanTag(tvb, pinfo, tree, offset, "start Encyphered Session: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
-fAuthenticateAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       return fApplicationTypes (tvb, pinfo, tree, offset, "modified Random Number: ");
+    return fApplicationTypes(tvb, pinfo, tree, offset, "modified Random Number: ");
 }
 
 static guint
-fRequestKeyRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Requesting Device Identifier */
-       offset = fAddress (tvb, tree, offset);
-       offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* Remote Device Identifier */
-       return fAddress (tvb, tree, offset);
+    offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* Requesting Device Identifier */
+    offset = fAddress(tvb, pinfo, tree, offset);
+    offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* Remote Device Identifier */
+    return fAddress(tvb, pinfo, tree, offset);
 }
 
 static guint
 fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       /* Same as AddListElement request after service choice */
-       return fAddListElementRequest(tvb, pinfo, tree, offset);
+    /* Same as AddListElement request after service choice */
+    return fAddListElementRequest(tvb, pinfo, tree, offset);
 }
 
 static guint
 fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
-}
-
-static guint
-fReadPropertyAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-
-       /* set the optional global properties to indicate not-used */
-       propertyArrayIndex = -1;
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       offset += len;
-                       subtree = tree;
-                       continue;
-               }
-               switch (tag_no) {
-               case 0: /* objectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 1: /* propertyIdentifier */
-                       offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 2: /* propertyArrayIndex */
-                       offset = fPropertyArrayIndex (tvb, subtree, offset);
-                       break;
-               case 3: /* propertyValue */
-                       offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
-                       break;
-               default:
-                       break;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
+}
+
+static guint
+fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0, len;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    /* set the optional global properties to indicate not-used */
+    propertyArrayIndex = -1;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            offset += len;
+            subtree = tree;
+            continue;
+        }
+        switch (tag_no) {
+        case 0: /* objectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 1: /* propertyIdentifier */
+            offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 2: /* propertyArrayIndex */
+            offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
+            break;
+        case 3: /* propertyValue */
+            offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
+            break;
+        default:
+            break;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-
-       /* set the optional global properties to indicate not-used */
-       propertyArrayIndex = -1;
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               /* quit loop if we spot a closing tag */
-               if (tag_is_closing(tag_info)) {
-                       subtree = tree;
-                       break;
-               }
-
-               switch (tag_no) {
-               case 0: /* objectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 1: /* propertyIdentifier */
-                       offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 2: /* propertyArrayIndex */
-                       offset = fPropertyArrayIndex (tvb, subtree, offset);
-                       break;
-               case 3: /* propertyValue */
-                       offset = fPropertyValue (tvb, pinfo, subtree, offset, tag_info);
-                       break;
-               case 4: /* Priority (only used for write) */
-                       offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fWriteAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
-{
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
-               if (tag_is_closing(tag_info)) {
-                       offset += len;
-                       continue;
-               }
-
-               switch (tag_no) {
-               case 0: /* objectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 1: /* listOfPropertyValues */
-                       if (tag_is_opening(tag_info)) {
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    /* set the optional global properties to indicate not-used */
+    propertyArrayIndex = -1;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        /* quit loop if we spot a closing tag */
+        if (tag_is_closing(tag_info)) {
+            break;
+        }
+
+        switch (tag_no) {
+        case 0: /* objectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 1: /* propertyIdentifier */
+            offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 2: /* propertyArrayIndex */
+            offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset);
+            break;
+        case 3: /* propertyValue */
+            offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
+            break;
+        case 4: /* Priority (only used for write) */
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
+{
+    guint   lastoffset = 0, len;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */
+        if (tag_is_closing(tag_info)) {
+            offset += len;
+            continue;
+        }
+
+        switch (tag_no) {
+        case 0: /* objectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 1: /* listOfPropertyValues */
+            if (tag_is_opening(tag_info)) {
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       if (offset >= tvb_reported_length(tvb))
-               return offset;
+    if (offset >= tvb_reported_length(tvb))
+        return offset;
 
-       col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-       return fWriteAccessSpecification (tvb, pinfo, tree, offset);
+    col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+    return fWriteAccessSpecification(tvb, pinfo, tree, offset);
 }
 
 static guint
-fPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
+fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
 {
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
 
-       /* set the optional global properties to indicate not-used */
-       propertyArrayIndex = -1;
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
-                       return offset;
-               } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
-                       return offset;
-               }
-               switch (tag_no-tagoffset) {
-               case 0: /* PropertyIdentifier */
-                       offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* propertyArrayIndex */
-                       offset = fPropertyArrayIndex (tvb, tree, offset);
-                       if (list != 0) break; /* Continue decoding if this may be a list */
-               default:
-                       lastoffset = offset; /* Set loop end condition */
-                       break;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    /* set the optional global properties to indicate not-used */
+    propertyArrayIndex = -1;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
+            return offset;
+        } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
+            return offset;
+        }
+        switch (tag_no-tagoffset) {
+        case 0: /* PropertyIdentifier */
+            offset = fPropertyIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* propertyArrayIndex */
+            offset = fPropertyArrayIndex(tvb, pinfo, tree, offset);
+            if (list != 0) break; /* Continue decoding if this may be a list */
+        default:
+            lastoffset = offset; /* Set loop end condition */
+            break;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
-fBACnetPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
+fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 list)
 {
-       col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-       return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
+    col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+    return fPropertyReference(tvb, pinfo, tree, offset, 0, list);
 }
 
 static guint
-fBACnetObjectPropertyReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
+    guint lastoffset = 0;
 
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
 
-               switch (fTagNo(tvb,offset)) {
-               case 0: /* ObjectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* PropertyIdentifier and propertyArrayIndex */
-                       offset = fPropertyReference (tvb, pinfo, tree, offset, 1, 0);
-                       col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-               default:
-                       lastoffset = offset; /* Set loop end condition */
-                       break;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* ObjectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* PropertyIdentifier and propertyArrayIndex */
+            offset = fPropertyReference(tvb, pinfo, tree, offset, 1, 0);
+            col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+        default:
+            lastoffset = offset; /* Set loop end condition */
+            break;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 #if 0
 static guint
-fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree* subtree = tree;
-       proto_item* tt;
-
-       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_closing(tag_info)) {
-                       offset += fTagHeaderTree (tvb, subtree, offset,
-                               &tag_no, &tag_info, &lvt);
-                       continue;
-               }
-               switch (tag_no) {
-               case 0: /* ObjectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 1: /* PropertyIdentifier */
-                       offset = fPropertyIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 2: /* propertyArrayIndex */
-                       offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
-                       break;
-               case 3:  /* Value */
-                       offset = fPropertyValue (tvb, subtree, offset, tag_info);
-                       break;
-               case 4:  /* Priority */
-                       offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
-                       break;
-               default:
-                       break;
-               }
-       }
-       return offset;
+fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree* subtree = tree;
+    proto_item* tt;
+
+    while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_closing(tag_info)) {
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
+                &tag_no, &tag_info, &lvt);
+            continue;
+        }
+        switch (tag_no) {
+        case 0: /* ObjectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 1: /* PropertyIdentifier */
+            offset = fPropertyIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 2: /* propertyArrayIndex */
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "property Array Index: ");
+            break;
+        case 3:  /* Value */
+            offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info);
+            break;
+        case 4:  /* Priority */
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: ");
+            break;
+        default:
+            break;
+        }
+    }
+    return offset;
 }
 #endif
 
 static guint
-fPriorityArray (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       char i = 1, ar[256];
-       guint lastoffset = 0;
-
-       if (propertyArrayIndex > 0) {
-               /* BACnetARRAY index 0 refers to the length
-               of the array, not the elements of the array.
-               BACnetARRAY index -1 is our internal flag that
-               the optional index was not used.
-               BACnetARRAY refers to this as all elements of the array.
-               If the optional index is specified for a BACnetARRAY,
-               then that specific array element is referenced. */
-               i = propertyArrayIndex;
-       }
-       while (tvb_reported_length_remaining(tvb, offset)) {
-               /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               g_snprintf (ar, sizeof(ar), "%s[%d]: ",
-                       val_to_split_str(87 , 512,
-                               BACnetPropertyIdentifier,
-                               ASHRAE_Reserved_Fmt,
-                               Vendor_Proprietary_Fmt),
-                       i++);
-               /* DMR Should be fAbstractNSyntax, but that's where we came from! */
-               offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
-               /* there are only 16 priority array elements */
-               if (i > 16) {
-                       break;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-
-       return offset;
-}
-
-static guint
-fDeviceObjectReference (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-
-               switch (fTagNo(tvb,offset)) {
-               case 0: /* deviceIdentifier - OPTIONAL */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* ObjectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fSpecialEvent (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       guint lastoffset = 0, len;
-    gboolean closing_found = FALSE;  /* tracks when we are done decoding the fSpecialEvent entries */
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               /* maybe a SEQUENCE of SpecialEvents if we spot a closing tag */
-               if (tag_is_closing(tag_info)) {
-                       /* if we find 2 closing tags in succession we need to exit without incrementing the offset again */
-                       /* This handles the special case where we have a special event entry in an RPM-ACK msg           */
-                       if ( closing_found == TRUE )
-                               break;
-                       offset += len;
-                       closing_found = TRUE;
-                       continue;
-               }
-
-               switch (tag_no) {
-               case 0: /* calendarEntry */
-                       if (tag_is_opening(tag_info)) {
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fCalendarEntry (tvb, subtree, offset);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       }
-                       break;
-               case 1: /* calendarReference */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 2: /* list of BACnetTimeValue */
-                       if (tag_is_opening(tag_info)) {
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fTimeValue (tvb, pinfo, subtree, offset);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               case 3: /* eventPriority */
-                       offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
-                       break;
-               default:
-                       return offset;
-               }
-               closing_found = FALSE; /* reset our closing tag status, we processed another open tag */
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0, len;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               /* maybe a listOfSelectionCriteria if we spot a closing tag */
-               if (tag_is_closing(tag_info)) {
-                       offset += len;
-                       continue;
-               }
-
-               switch (fTagNo(tvb,offset)) {
-               case 0: /* propertyIdentifier */
-                       offset = fPropertyIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* propertyArrayIndex */
-                       offset = fPropertyArrayIndex (tvb, tree, offset);
-                       break;
-               case 2: /* relationSpecifier */
-                       offset = fEnumeratedTag (tvb, tree, offset,
-                               "relation Specifier: ", BACnetRelationSpecifier);
-                       break;
-               case 3: /* comparisonValue */
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fAbstractSyntaxNType (tvb, pinfo, tree, offset);
-                       offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fObjectSelectionCriteria (tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               /* quit loop if we spot a closing tag */
-               if (tag_is_closing(tag_info)) {
-                       break;
-               }
-
-               switch (tag_no) {
-               case 0: /* selectionLogic */
-                       offset = fEnumeratedTag (tvb, subtree, offset,
-                               "selection Logic: ", BACnetSelectionLogic);
-                       break;
-               case 1: /* listOfSelectionCriteria */
-                       if (tag_is_opening(tag_info)) {
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fSelectionCriteria (tvb, pinfo, subtree, offset);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    char  i = 1, ar[256];
+    guint lastoffset = 0;
+
+    if (propertyArrayIndex > 0) {
+        /* BACnetARRAY index 0 refers to the length
+        of the array, not the elements of the array.
+        BACnetARRAY index -1 is our internal flag that
+        the optional index was not used.
+        BACnetARRAY refers to this as all elements of the array.
+        If the optional index is specified for a BACnetARRAY,
+        then that specific array element is referenced. */
+        i = propertyArrayIndex;
+    }
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {
+        /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        g_snprintf(ar, sizeof(ar), "%s[%d]: ",
+            val_to_split_str(87 , 512,
+                BACnetPropertyIdentifier,
+                ASHRAE_Reserved_Fmt,
+                Vendor_Proprietary_Fmt),
+            i++);
+        /* DMR Should be fAbstractNSyntax, but that's where we came from! */
+        offset = fApplicationTypes(tvb, pinfo, tree, offset, ar);
+        /* there are only 16 priority array elements */
+        if (i > 16) {
+            break;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+
+    return offset;
+}
+
+static guint
+fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* deviceIdentifier - OPTIONAL */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* ObjectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
+{
+    guint8 tag_no, tag_info;
+    guint32 lvt;
+    guint lastoffset = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        /* quit loop if we spot an un-matched closing tag */
+        if (tag_is_closing(tag_info)) {
+            break;
+        }
+        switch (tag_no) {
+        case 0: /* calendarEntry */
+            if (tag_is_opening(tag_info)) {
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fCalendarEntry(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            }
+            break;
+        case 1: /* calendarReference */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 2: /* list of BACnetTimeValue */
+            if (tag_is_opening(tag_info)) {
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fTimeValue(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        case 3: /* eventPriority */
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "event priority: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0, len;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        /* maybe a listOfSelectionCriteria if we spot a closing tag */
+        if (tag_is_closing(tag_info)) {
+            offset += len;
+            continue;
+        }
+
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* propertyIdentifier */
+            offset  = fPropertyIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* propertyArrayIndex */
+            offset  = fPropertyArrayIndex(tvb, pinfo, tree, offset);
+            break;
+        case 2: /* relationSpecifier */
+            offset  = fEnumeratedTag(tvb, pinfo, tree, offset,
+                "relation Specifier: ", BACnetRelationSpecifier);
+            break;
+        case 3: /* comparisonValue */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        /* quit loop if we spot a closing tag */
+        if (tag_is_closing(tag_info)) {
+            break;
+        }
+
+        switch (tag_no) {
+        case 0: /* selectionLogic */
+            offset = fEnumeratedTag(tvb, pinfo, subtree, offset,
+                "selection Logic: ", BACnetSelectionLogic);
+            break;
+        case 1: /* listOfSelectionCriteria */
+            if (tag_is_opening(tag_info)) {
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fSelectionCriteria(tvb, pinfo, subtree, offset);
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 
 static guint
 fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, guint offset)
 {
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-
-               if (tag_is_opening(tag_info) && tag_no < 2) {
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       switch (tag_no) {
-                       case 0: /* objectSelectionCriteria */
-                               offset = fObjectSelectionCriteria (tvb, pinfo, subtree, offset);
-                               break;
-                       case 1: /* listOfPropertyReferences */
-                               offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
-                               break;
-                       default:
-                               return offset;
-                       }
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fReadAccessSpecification (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_item *tt;
-       proto_tree *subtree = tree;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               switch (tag_no) {
-               case 0: /* objectIdentifier */
-                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 1: /* listOfPropertyReferences */
-                       if (tag_is_opening(tag_info)) {
-                               tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fBACnetPropertyReference (tvb, pinfo, subtree, offset, 1);
-                       } else if (tag_is_closing(tag_info)) {
-                               offset += fTagHeaderTree (tvb, subtree, offset,
-                                       &tag_no, &tag_info, &lvt);
-                               subtree = tree;
-                       } else {
-                               /* error condition: let caller handle */
-                               return offset;
-                       }
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fReadAccessResult (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0, len;
-       guint8 tag_no;
-       guint8 tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               /* maybe a listOfReadAccessResults if we spot a closing tag here */
-               if (tag_is_closing(tag_info)) {
-                       offset += len;
-                       if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
-                       continue;
-               }
-
-               switch (tag_no) {
-               case 0: /* objectSpecifier */
-                       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* list of Results */
-                       if (tag_is_opening(tag_info)) {
-                               tt = proto_tree_add_text(tree, tvb, offset, 1, "listOfResults");
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               case 2: /* propertyIdentifier */
-                       offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
-                       break;
-               case 5: /* propertyAccessError */
-                       if (tag_is_opening(tag_info)) {
-                               tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               /* Error Code follows */
-                               offset = fError(tvb, pinfo, subtree, offset);
-                               break;
-                       }
-                       FAULT;
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-
-static guint
-fReadPropertyConditionalAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       /* listOfReadAccessResults */
-       return fReadAccessResult (tvb, pinfo, tree, offset);
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+
+        if (tag_is_opening(tag_info) && tag_no < 2) {
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            switch (tag_no) {
+            case 0: /* objectSelectionCriteria */
+                offset = fObjectSelectionCriteria(tvb, pinfo, subtree, offset);
+                break;
+            case 1: /* listOfPropertyReferences */
+                offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
+                break;
+            default:
+                return offset;
+            }
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        switch (tag_no) {
+        case 0: /* objectIdentifier */
+            offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 1: /* listOfPropertyReferences */
+            if (tag_is_opening(tag_info)) {
+                subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfPropertyReferences");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1);
+            } else if (tag_is_closing(tag_info)) {
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
+                    &tag_no, &tag_info, &lvt);
+                subtree = tree;
+            } else {
+                /* error condition: let caller handle */
+                return offset;
+            }
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint       lastoffset = 0, len;
+    guint8      tag_no;
+    guint8      tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        /* maybe a listOfReadAccessResults if we spot a closing tag here */
+        if (tag_is_closing(tag_info)) {
+            offset += len;
+            if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
+            continue;
+        }
+
+        switch (tag_no) {
+        case 0: /* objectSpecifier */
+            offset = fObjectIdentifier(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* list of Results */
+            if (tag_is_opening(tag_info)) {
+                subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfResults");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        case 2: /* propertyIdentifier */
+            offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
+            break;
+        case 5: /* propertyAccessError */
+            if (tag_is_opening(tag_info)) {
+                subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "propertyAccessError");
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                /* Error Code follows */
+                offset  = fError(tvb, pinfo, subtree, offset);
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+            }
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+
+static guint
+fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    /* listOfReadAccessResults */
+    return fReadAccessResult(tvb, pinfo, tree, offset);
 }
 
 
 static guint
 fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
 {
-       guint lastoffset = 0;
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-
-               if (tag_no < 2) {
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       switch (tag_no) {
-                       case 0: /* objectSpecifier */
-                               switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
-                               case 0: /* objectType */
-                                       offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
-                                       break;
-                               case 1: /* objectIdentifier */
-                                       offset = fObjectIdentifier (tvb, pinfo, subtree, offset);
-                                       break;
-                               default:
-                                       break;
-                               }
-                               break;
-                       case 1: /* propertyValue */
-                               if (tag_is_opening(tag_info)) {
-                                       offset = fBACnetPropertyValue (tvb, pinfo, subtree, offset);
-                                       break;
-                               }
-                               FAULT;
-                               break;
-                       default:
-                               break;
-                       }
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-               }
-               if (offset == lastoffset) break;    /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fCreateObjectAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       return fObjectIdentifier (tvb, pinfo, tree, offset);
-}
-
-static guint
-fReadRangeRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
-
-       if (tvb_reported_length_remaining(tvb, offset) > 0) {
-               /* optional range choice */
-               fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               if (tag_is_opening(tag_info)) {
-                       tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
-                       subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       switch (tag_no) {
-                       case 3: /* range byPosition */
-                       case 6: /* range bySequenceNumber, 2004 spec */
-                               offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Index: ");
-                               offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
-                               break;
-                       case 4: /* range byTime - deprecated in 2004 */
-                       case 7: /* 2004 spec */
-                               offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
-                               offset = fApplicationTypes (tvb, pinfo, subtree, offset, "reference Count: ");
-                               break;
-                       case 5: /* range timeRange - deprecated in 2004 */
-                               offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
-                               offset = fDateTime(tvb, subtree, offset, "ending Time: ");
-                               break;
-                       default:
-                               break;
-                       }
-                       offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-               }
-       }
-       return offset;
-}
-
-static guint
-fReadRangeAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       /* set the optional global properties to indicate not-used */
-       propertyArrayIndex = -1;
-       /* objectIdentifier, propertyIdentifier, and
-          OPTIONAL propertyArrayIndex */
-       offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
-       /* resultFlags => BACnetResultFlags ::= BIT STRING */
-       offset = fBitStringTagVS (tvb, tree, offset,
-               "resultFlags: ",
-               BACnetResultFlags);
-       /* itemCount */
-       offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
-       /* itemData */
-       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-       if (tag_is_opening(tag_info)) {
-               col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-               tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
-               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-               offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
-               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-       }
-       /* firstSequenceNumber - OPTIONAL */
-       if (tvb_reported_length_remaining(tvb, offset) > 0) {
-               offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
-       }
-
-       return offset;
+    guint   lastoffset = 0;
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+
+        if (tag_no < 2) {
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            switch (tag_no) {
+            case 0: /* objectSpecifier */
+                switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
+                case 0: /* objectType */
+                    offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, "Object Type: ", BACnetObjectType, 128);
+                    break;
+                case 1: /* objectIdentifier */
+                    offset = fObjectIdentifier(tvb, pinfo, subtree, offset);
+                    break;
+                default:
+                    break;
+                }
+                break;
+            case 1: /* propertyValue */
+                if (tag_is_opening(tag_info)) {
+                    offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
+                } else {
+                    expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
+                }
+                break;
+            default:
+                break;
+            }
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+        }
+        if (offset == lastoffset) break;    /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    return fObjectIdentifier(tvb, pinfo, tree, offset);
+}
+
+static guint
+fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
+
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {
+        /* optional range choice */
+        fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        if (tag_is_opening(tag_info)) {
+            subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL,
+                val_to_str_const(tag_no, BACnetReadRangeOptions, "unknown range option"));
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            switch (tag_no) {
+            case 3: /* range byPosition */
+            case 6: /* range bySequenceNumber, 2004 spec */
+                offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Index: ");
+                offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: ");
+                break;
+            case 4: /* range byTime - deprecated in 2004 */
+            case 7: /* 2004 spec */
+                offset = fDateTime(tvb, pinfo, subtree, offset, "reference Date/Time: ");
+                offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: ");
+                break;
+            case 5: /* range timeRange - deprecated in 2004 */
+                offset = fDateTime(tvb, pinfo, subtree, offset, "beginning Time: ");
+                offset = fDateTime(tvb, pinfo, subtree, offset, "ending Time: ");
+                break;
+            default:
+                break;
+            }
+            offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+        }
+    }
+    return offset;
+}
+
+static guint
+fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
+
+    /* set the optional global properties to indicate not-used */
+    propertyArrayIndex = -1;
+    /* objectIdentifier, propertyIdentifier, and
+       OPTIONAL propertyArrayIndex */
+    offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset);
+    /* resultFlags => BACnetResultFlags ::= BIT STRING */
+    offset = fBitStringTagVS(tvb, pinfo, tree, offset,
+        "resultFlags: ",
+        BACnetResultFlags);
+    /* itemCount */
+    offset = fUnsignedTag(tvb, pinfo, subtree, offset, "item Count: ");
+    /* itemData */
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+    if (tag_is_opening(tag_info)) {
+        col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+        subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "itemData");
+        offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+        offset  = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
+        offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+    }
+    /* firstSequenceNumber - OPTIONAL */
+    if (tvb_reported_length_remaining(tvb, offset) > 0) {
+        offset  = fUnsignedTag(tvb, pinfo, subtree, offset, "first Sequence Number: ");
+    }
+
+    return offset;
 }
 
 static guint
 fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
-       guint32 lvt;
-       guint8 tag_no, tag_info;
-       proto_item* tt;
-       proto_tree* subtree = NULL;
-
-       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-
-       if (tag_is_opening(tag_info)) {
-               tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
-               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-               offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
-               offset = fApplicationTypes (tvb, pinfo, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
-
-               if (tag_no == 1) {
-                       while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
-                               /* exit loop if nothing happens inside */
-                               lastoffset = offset;
-                               offset = fApplicationTypes (tvb, pinfo, subtree, offset, "Record Data: ");
-                       }
-               }
-
-               if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
-                       /* More Flag is not set, so we can look for closing tag in this segment */
-                       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-                       if (tag_is_closing(tag_info)) {
-                               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                       }
-               }
-       }
-       return offset;
+    guint       lastoffset = 0;
+    guint32     lvt;
+    guint8      tag_no, tag_info;
+    proto_tree* subtree = NULL;
+
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+
+    if (tag_is_opening(tag_info)) {
+        subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL,
+            val_to_str_const(tag_no, BACnetFileAccessOption, "invalid access method"));
+        offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+        offset  = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "invalid option"));
+        offset  = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileWriteInfo, "unknown option"));
+
+        if (tag_no == 1) {
+            while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
+                /* exit loop if nothing happens inside */
+                lastoffset = offset;
+                offset = fApplicationTypes(tvb, pinfo, subtree, offset, "Record Data: ");
+            }
+        }
+
+        if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) {
+            /* More Flag is not set, so we can look for closing tag in this segment */
+            fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+            if (tag_is_closing(tag_info)) {
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+            }
+        }
+    }
+    return offset;
 }
 
 static guint
 fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-       proto_tree *subtree = tree;
-       proto_item *tt;
+    guint8      tag_no, tag_info;
+    guint32     lvt;
+    proto_tree *subtree = tree;
 
-       offset = fObjectIdentifier (tvb, pinfo, tree, offset);
+    offset = fObjectIdentifier(tvb, pinfo, tree, offset);
 
-       fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
+    fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
 
-       if (tag_is_opening(tag_info)) {
-               tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
-               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-               offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
-               offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
-               offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-       }
-       return offset;
+    if (tag_is_opening(tag_info)) {
+        subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL,
+                        val_to_str_const(tag_no, BACnetFileAccessOption, "unknown access method"));
+        offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+        offset  = fSignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
+        offset  = fUnsignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileRequestCount, "unknown option"));
+        offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+    }
+    return offset;
 }
 
 static guint
 fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
 
-       offset = fObjectIdentifier (tvb, pinfo, tree, offset); /* file Identifier */
-       offset = fAccessMethod(tvb, pinfo, tree, offset);
+    offset = fObjectIdentifier(tvb, pinfo, tree, offset); /* file Identifier */
+    offset = fAccessMethod(tvb, pinfo, tree, offset);
 
-       return offset;
+    return offset;
 }
 
 static guint
-fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
+fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint tag_no = fTagNo(tvb, offset);
-       return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
+    guint tag_no = fTagNo(tvb, offset);
+    return fSignedTag(tvb, pinfo, tree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option"));
 }
 
 static guint
-fAtomicReadFileAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       offset = fApplicationTypes (tvb, pinfo, tree, offset, "End Of File: ");
-       offset = fAccessMethod(tvb,pinfo, tree, offset);
+    offset = fApplicationTypes(tvb, pinfo, tree, offset, "End Of File: ");
+    offset = fAccessMethod(tvb, pinfo, tree, offset);
 
-       return offset;
+    return offset;
 }
 
 static guint
 fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offset)
 {
-       col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-       return fReadAccessSpecification (tvb,pinfo,subtree,offset);
-}
-
-static guint
-fReadPropertyMultipleAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-       return fReadAccessResult (tvb,pinfo,tree,offset);
-}
-
-static guint
-fConfirmedServiceRequest (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
-{
-       if (tvb_reported_length_remaining(tvb,offset) <= 0)
-               return offset;
-
-       switch (service_choice) {
-       case 0: /* acknowledgeAlarm */
-               offset = fAcknowledgeAlarmRequest (tvb, pinfo, tree, offset);
-               break;
-       case 1: /* confirmedCOVNotification */
-               offset = fConfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
-               break;
-       case 2: /* confirmedEventNotification */
-               offset = fConfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
-               break;
-       case 3: /* confirmedGetAlarmSummary conveys no parameters */
-               break;
-       case 4: /* getEnrollmentSummaryRequest */
-               offset = fGetEnrollmentSummaryRequest (tvb, pinfo, tree, offset);
-               break;
-       case 5: /* subscribeCOVRequest */
-               offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
-               break;
-       case 6: /* atomicReadFile-Request */
-               offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
-               break;
-       case 7: /* atomicWriteFile-Request */
-               offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
-               break;
-       case 8: /* AddListElement-Request */
-               offset = fAddListElementRequest(tvb, pinfo, tree, offset);
-               break;
-       case 9: /* removeListElement-Request */
-               offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
-               break;
-       case 10: /* createObjectRequest */
-               offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
-               break;
-       case 11: /* deleteObject */
-               offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
-               break;
-       case 12:
-               offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
-               break;
-       case 13:
-               offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
-               break;
-       case 14:
-               offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
-               break;
-       case 15:
-               offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
-               break;
-       case 16:
-               offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
-               break;
-       case 17:
-               offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
-               break;
-       case 18:
-               offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
-               break;
-       case 19:
-               offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
-               break;
-       case 20:
-               offset = fReinitializeDeviceRequest(tvb, tree, offset);
-               break;
-       case 21:
-               offset = fVtOpenRequest(tvb, pinfo, tree, offset);
-               break;
-       case 22:
-               offset = fVtCloseRequest (tvb, pinfo, tree, offset);
-               break;
-       case 23:
-               offset = fVtDataRequest (tvb, pinfo, tree, offset);
-               break;
-       case 24:
-               offset = fAuthenticateRequest (tvb, tree, offset);
-               break;
-       case 25:
-               offset = fRequestKeyRequest (tvb, pinfo, tree, offset);
-               break;
-       case 26:
-               offset = fReadRangeRequest (tvb, pinfo, tree, offset);
-               break;
-       case 27:
-               offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
-               break;
-       case 28:
-               offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
-               break;
-       case 29:
-               offset = fGetEventInformationRequest (tvb, pinfo, tree, offset);
-               break;
-       default:
-               return offset;
-       }
-       return offset;
-}
-
-static guint
-fConfirmedServiceAck (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
-{
-       if (tvb_reported_length_remaining(tvb,offset) <= 0)
-               return offset;
-
-       switch (service_choice) {
-       case 3: /* confirmedEventNotificationAck */
-               offset = fGetAlarmSummaryAck (tvb, pinfo, tree, offset);
-               break;
-       case 4: /* getEnrollmentSummaryAck */
-               offset = fGetEnrollmentSummaryAck (tvb, pinfo, tree, offset);
-               break;
-       case 6: /* atomicReadFile */
-               offset = fAtomicReadFileAck (tvb, pinfo, tree, offset);
-               break;
-       case 7: /* atomicReadFileAck */
-               offset = fAtomicWriteFileAck (tvb, tree, offset);
-               break;
-       case 10: /* createObject */
-               offset = fCreateObjectAck (tvb, pinfo, tree, offset);
-               break;
-       case 12:
-               offset = fReadPropertyAck (tvb, pinfo, tree, offset);
-               break;
-       case 13:
-               offset = fReadPropertyConditionalAck (tvb, pinfo, tree, offset);
-               break;
-       case 14:
-               offset = fReadPropertyMultipleAck (tvb, pinfo, tree, offset);
-               break;
-       case 18:
-               offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
-               break;
-       case 21:
-               offset = fVtOpenAck (tvb, pinfo, tree, offset);
-               break;
-       case 23:
-               offset = fVtDataAck (tvb, tree, offset);
-               break;
-       case 24:
-               offset = fAuthenticateAck (tvb, pinfo, tree, offset);
-               break;
-       case 26:
-               offset = fReadRangeAck (tvb, pinfo, tree, offset);
-               break;
-       case 29:
-               offset = fGetEventInformationACK (tvb, pinfo, tree, offset);
-               break;
-       default:
-               return offset;
-       }
-       return offset;
-}
-
-static guint
-fIAmRequest  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       /* BACnetObjectIdentifier */
-       offset = fApplicationTypes (tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
-
-       /* MaxAPDULengthAccepted */
-       offset = fApplicationTypes (tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
-
-       /* segmentationSupported */
-       offset = fApplicationTypesEnumerated (tvb, pinfo, tree, offset,
-               "Segmentation Supported: ", BACnetSegmentation);
-
-       /* vendor ID */
-       return fVendorIdentifier (tvb, pinfo, tree, offset);
-}
-
-static guint
-fIHaveRequest  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       /* BACnetDeviceIdentifier */
-       offset = fApplicationTypes (tvb, pinfo, tree, offset, "Device Identifier: ");
-
-       /* BACnetObjectIdentifier */
-       offset = fApplicationTypes (tvb, pinfo, tree, offset, "Object Identifier: ");
-
-       /* ObjectName */
-       return fApplicationTypes (tvb, pinfo, tree, offset, "Object Name: ");
-
-}
-
-static guint
-fWhoIsRequest  (tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
-{
-       guint lastoffset = 0;
-       guint val;
-       guint8 tag_len;
-
-       guint8 tag_no, tag_info;
-       guint32 lvt;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-
-               tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-
-               switch (tag_no) {
-               case 0:
-                       /* DeviceInstanceRangeLowLimit Optional */
-                       fUnsigned32(tvb, offset+tag_len, lvt, &val);
-                       if (col_get_writable(pinfo->cinfo))
-                               col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
-                       offset = fDevice_Instance (tvb, tree, offset,
-                               hf_Device_Instance_Range_Low_Limit);
-                       break;
-               case 1:
-                       /* DeviceInstanceRangeHighLimit Optional but
-                               required if DeviceInstanceRangeLowLimit is there */
-                       fUnsigned32(tvb, offset+tag_len, lvt, &val);
-                       if (col_get_writable(pinfo->cinfo))
-                               col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
-                       offset = fDevice_Instance (tvb, tree, offset,
-                               hf_Device_Instance_Range_High_Limit);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fUnconfirmedServiceRequest  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
-{
-       if (tvb_reported_length_remaining(tvb,offset) <= 0)
-               return offset;
-
-       switch (service_choice) {
-       case 0: /* I-Am-Request */
-               offset = fIAmRequest  (tvb, pinfo, tree, offset);
-               break;
-       case 1: /* i-Have Request */
-               offset = fIHaveRequest  (tvb, pinfo, tree, offset);
-       break;
-       case 2: /* unconfirmedCOVNotification */
-               offset = fUnconfirmedCOVNotificationRequest (tvb, pinfo, tree, offset);
-               break;
-       case 3: /* unconfirmedEventNotification */
-               offset = fUnconfirmedEventNotificationRequest (tvb, pinfo, tree, offset);
-               break;
-       case 4: /* unconfirmedPrivateTransfer */
-               offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
-               break;
-       case 5: /* unconfirmedTextMessage */
-               offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
-               break;
-       case 6: /* timeSynchronization */
-               offset = fTimeSynchronizationRequest  (tvb, tree, offset);
-               break;
-       case 7: /* who-Has */
-               offset = fWhoHas (tvb, pinfo, tree, offset);
-               break;
-       case 8: /* who-Is */
-               offset = fWhoIsRequest  (tvb, pinfo, tree, offset);
-               break;
-       case 9: /* utcTimeSynchronization */
-               offset = fUTCTimeSynchronizationRequest  (tvb, tree, offset);
-               break;
-       default:
-               break;
-       }
-       return offset;
+    col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+    return fReadAccessSpecification(tvb, pinfo, subtree, offset);
+}
+
+static guint
+fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+    return fReadAccessResult(tvb, pinfo, tree, offset);
+}
+
+static guint
+fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
+{
+    if (tvb_reported_length_remaining(tvb, offset) <= 0)
+        return offset;
+
+    switch (service_choice) {
+    case 0: /* acknowledgeAlarm */
+        offset = fAcknowledgeAlarmRequest(tvb, pinfo, tree, offset);
+        break;
+    case 1: /* confirmedCOVNotification */
+        offset = fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
+        break;
+    case 2: /* confirmedEventNotification */
+        offset = fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
+        break;
+    case 3: /* confirmedGetAlarmSummary conveys no parameters */
+        break;
+    case 4: /* getEnrollmentSummaryRequest */
+        offset = fGetEnrollmentSummaryRequest(tvb, pinfo, tree, offset);
+        break;
+    case 5: /* subscribeCOVRequest */
+        offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset);
+        break;
+    case 6: /* atomicReadFile-Request */
+        offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset);
+        break;
+    case 7: /* atomicWriteFile-Request */
+        offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset);
+        break;
+    case 8: /* AddListElement-Request */
+        offset = fAddListElementRequest(tvb, pinfo, tree, offset);
+        break;
+    case 9: /* removeListElement-Request */
+        offset = fRemoveListElementRequest(tvb, pinfo, tree, offset);
+        break;
+    case 10: /* createObjectRequest */
+        offset = fCreateObjectRequest(tvb, pinfo, tree, offset);
+        break;
+    case 11: /* deleteObject */
+        offset = fDeleteObjectRequest(tvb, pinfo, tree, offset);
+        break;
+    case 12:
+        offset = fReadPropertyRequest(tvb, pinfo, tree, offset);
+        break;
+    case 13:
+        offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset);
+        break;
+    case 14:
+        offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset);
+        break;
+    case 15:
+        offset = fWritePropertyRequest(tvb, pinfo, tree, offset);
+        break;
+    case 16:
+        offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset);
+        break;
+    case 17:
+        offset = fDeviceCommunicationControlRequest(tvb, pinfo, tree, offset);
+        break;
+    case 18:
+        offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
+        break;
+    case 19:
+        offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset);
+        break;
+    case 20:
+        offset = fReinitializeDeviceRequest(tvb, pinfo, tree, offset);
+        break;
+    case 21:
+        offset = fVtOpenRequest(tvb, pinfo, tree, offset);
+        break;
+    case 22:
+        offset = fVtCloseRequest(tvb, pinfo, tree, offset);
+        break;
+    case 23:
+        offset = fVtDataRequest(tvb, pinfo, tree, offset);
+        break;
+    case 24:
+        offset = fAuthenticateRequest(tvb, pinfo, tree, offset);
+        break;
+    case 25:
+        offset = fRequestKeyRequest(tvb, pinfo, tree, offset);
+        break;
+    case 26:
+        offset = fReadRangeRequest(tvb, pinfo, tree, offset);
+        break;
+    case 27:
+        offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL);
+        break;
+    case 28:
+        offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset);
+        break;
+    case 29:
+        offset = fGetEventInformationRequest(tvb, pinfo, tree, offset);
+        break;
+    default:
+        return offset;
+    }
+    return offset;
+}
+
+static guint
+fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
+{
+    if (tvb_reported_length_remaining(tvb, offset) <= 0)
+        return offset;
+
+    switch (service_choice) {
+    case 3: /* confirmedEventNotificationAck */
+        offset = fGetAlarmSummaryAck(tvb, pinfo, tree, offset);
+        break;
+    case 4: /* getEnrollmentSummaryAck */
+        offset = fGetEnrollmentSummaryAck(tvb, pinfo, tree, offset);
+        break;
+    case 6: /* atomicReadFile */
+        offset = fAtomicReadFileAck(tvb, pinfo, tree, offset);
+        break;
+    case 7: /* atomicReadFileAck */
+        offset = fAtomicWriteFileAck(tvb, pinfo, tree, offset);
+        break;
+    case 10: /* createObject */
+        offset = fCreateObjectAck(tvb, pinfo, tree, offset);
+        break;
+    case 12:
+        offset = fReadPropertyAck(tvb, pinfo, tree, offset);
+        break;
+    case 13:
+        offset = fReadPropertyConditionalAck(tvb, pinfo, tree, offset);
+        break;
+    case 14:
+        offset = fReadPropertyMultipleAck(tvb, pinfo, tree, offset);
+        break;
+    case 18:
+        offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset);
+        break;
+    case 21:
+        offset = fVtOpenAck(tvb, pinfo, tree, offset);
+        break;
+    case 23:
+        offset = fVtDataAck(tvb, pinfo, tree, offset);
+        break;
+    case 24:
+        offset = fAuthenticateAck(tvb, pinfo, tree, offset);
+        break;
+    case 26:
+        offset = fReadRangeAck(tvb, pinfo, tree, offset);
+        break;
+    case 29:
+        offset = fGetEventInformationACK(tvb, pinfo, tree, offset);
+        break;
+    default:
+        return offset;
+    }
+    return offset;
+}
+
+static guint
+fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    /* BACnetObjectIdentifier */
+    offset = fApplicationTypes(tvb, pinfo, tree, offset, "BACnet Object Identifier: ");
+
+    /* MaxAPDULengthAccepted */
+    offset = fApplicationTypes(tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: ");
+
+    /* segmentationSupported */
+    offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset,
+        "Segmentation Supported: ", BACnetSegmentation);
+
+    /* vendor ID */
+    return fVendorIdentifier(tvb, pinfo, tree, offset);
+}
+
+static guint
+fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    /* BACnetDeviceIdentifier */
+    offset = fApplicationTypes(tvb, pinfo, tree, offset, "Device Identifier: ");
+
+    /* BACnetObjectIdentifier */
+    offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: ");
+
+    /* ObjectName */
+    return fApplicationTypes(tvb, pinfo, tree, offset, "Object Name: ");
+
+}
+
+static guint
+fWhoIsRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, guint offset)
+{
+    guint   lastoffset = 0;
+    guint   val;
+    guint8  tag_len;
+
+    guint8  tag_no, tag_info;
+    guint32 lvt;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+
+        tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+
+        switch (tag_no) {
+        case 0:
+            /* DeviceInstanceRangeLowLimit Optional */
+            if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
+                col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
+            offset = fDevice_Instance(tvb, pinfo, tree, offset,
+                hf_Device_Instance_Range_Low_Limit);
+            break;
+        case 1:
+            /* DeviceInstanceRangeHighLimit Optional but
+                required if DeviceInstanceRangeLowLimit is there */
+            if (col_get_writable(pinfo->cinfo) && fUnsigned32(tvb, offset+tag_len, lvt, &val))
+                col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val);
+            offset = fDevice_Instance(tvb, pinfo, tree, offset,
+                hf_Device_Instance_Range_High_Limit);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, gint service_choice)
+{
+    if (tvb_reported_length_remaining(tvb, offset) <= 0)
+        return offset;
+
+    switch (service_choice) {
+    case 0: /* I-Am-Request */
+        offset = fIAmRequest(tvb, pinfo, tree, offset);
+        break;
+    case 1: /* i-Have Request */
+        offset = fIHaveRequest(tvb, pinfo, tree, offset);
+    break;
+    case 2: /* unconfirmedCOVNotification */
+        offset = fUnconfirmedCOVNotificationRequest(tvb, pinfo, tree, offset);
+        break;
+    case 3: /* unconfirmedEventNotification */
+        offset = fUnconfirmedEventNotificationRequest(tvb, pinfo, tree, offset);
+        break;
+    case 4: /* unconfirmedPrivateTransfer */
+        offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset);
+        break;
+    case 5: /* unconfirmedTextMessage */
+        offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset);
+        break;
+    case 206: /* utc-time-synchronization-recipients */
+    case 6: /* timeSynchronization */
+        offset = fTimeSynchronizationRequest(tvb, pinfo, tree, offset);
+        break;
+    case 7: /* who-Has */
+        offset = fWhoHas(tvb, pinfo, tree, offset);
+        break;
+    case 8: /* who-Is */
+        offset = fWhoIsRequest(tvb, pinfo, tree, offset);
+        break;
+    case 9: /* utcTimeSynchronization */
+        offset = fUTCTimeSynchronizationRequest(tvb, pinfo, tree, offset);
+        break;
+    default:
+        break;
+    }
+    return offset;
 }
 
 static guint
 fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset, guint8 ack,
-               gint *svc, proto_item **tt)
-{
-       proto_item *tc;
-       proto_tree *bacapp_tree_control;
-       gint tmp;
-       guint extra = 2;
-
-       bacapp_seq = 0;
-       tmp = (gint) tvb_get_guint8(tvb, offset);
-       bacapp_flags = tmp & 0x0f;
-
-       if (ack == 0) {
-               extra = 3;
-       }
-       *svc = (gint) tvb_get_guint8(tvb, offset+extra);
-       if (bacapp_flags & 0x08)
-               *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
-
-       proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
-       tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
-       bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
-
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
-       if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
-           proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
-           proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
-                                                       offset, 1, ENC_BIG_ENDIAN);
-           proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
-                                                       offset, 1, ENC_BIG_ENDIAN);
-       }
-       offset++;
-       proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
-       if (bacapp_flags & 0x08) {
-               bacapp_seq = tvb_get_guint8(tvb, offset);
-               proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
-                   offset++, 1, ENC_BIG_ENDIAN);
-               proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
-                   offset++, 1, ENC_BIG_ENDIAN);
-       }
-       *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
-                                 offset++, 1, ENC_BIG_ENDIAN);
-       return offset;
+        gint *svc, proto_item **tt)
+{
+    proto_item *tc;
+    proto_tree *bacapp_tree_control;
+    gint        tmp;
+    guint       extra = 2;
+
+    bacapp_seq = 0;
+    tmp = (gint) tvb_get_guint8(tvb, offset);
+    bacapp_flags = tmp & 0x0f;
+
+    if (ack == 0) {
+        extra = 3;
+    }
+    *svc = (gint) tvb_get_guint8(tvb, offset+extra);
+    if (bacapp_flags & 0x08)
+        *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
+
+    proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+    tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN);
+    bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
+
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN);
+    if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */
+        proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN);
+        proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
+                            offset, 1, ENC_BIG_ENDIAN);
+        proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
+                            offset, 1, ENC_BIG_ENDIAN);
+    }
+    offset++;
+    proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN);
+    if (bacapp_flags & 0x08) {
+        bacapp_seq = tvb_get_guint8(tvb, offset);
+        proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
+            offset++, 1, ENC_BIG_ENDIAN);
+        proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
+            offset++, 1, ENC_BIG_ENDIAN);
+    }
+    *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
+                  offset++, 1, ENC_BIG_ENDIAN);
+    return offset;
 }
 
 static guint
 fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
-{      /* BACnet-Confirmed-Request */
-       /* ASHRAE 135-2001 20.1.2 */
+{   /* BACnet-Confirmed-Request */
+    /* ASHRAE 135-2001 20.1.2 */
 
-       return fConfirmedServiceRequest (tvb, pinfo, bacapp_tree, offset, svc);
+    return fConfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, svc);
 }
 
 static guint
 fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
-{      /* BACnet-Confirmed-Request */
-       /* ASHRAE 135-2001 20.1.2 */
-       gint svc;
-       proto_item *tt = 0;
+{   /* BACnet-Confirmed-Request */
+    /* ASHRAE 135-2001 20.1.2 */
+    gint        svc;
+    proto_item *tt = 0;
 
-       offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
-       return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
+    offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt);
+    return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc);
 }
 
 static guint
 fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
-{      /* BACnet-Unconfirmed-Request-PDU */
-       /* ASHRAE 135-2001 20.1.3 */
+{   /* BACnet-Unconfirmed-Request-PDU */
+    /* ASHRAE 135-2001 20.1.3 */
 
-       gint tmp;
+    gint tmp;
 
-       proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
 
-       tmp = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
-           offset++, 1, ENC_BIG_ENDIAN);
-       /* Service Request follows... Variable Encoding 20.2ff */
-       return fUnconfirmedServiceRequest  (tvb, pinfo, bacapp_tree, offset, tmp);
+    tmp = tvb_get_guint8(tvb, offset);
+    proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
+        offset++, 1, ENC_BIG_ENDIAN);
+    /* Service Request follows... Variable Encoding 20.2ff */
+    return fUnconfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, tmp);
 }
 
 static guint
 fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
-{      /* BACnet-Simple-Ack-PDU */
-       /* ASHRAE 135-2001 20.1.4 */
+{   /* BACnet-Simple-Ack-PDU */
+    /* ASHRAE 135-2001 20.1.4 */
 
-       proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
 
-       proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
 
-       return offset;
+    return offset;
 }
 
 static guint
 fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset, gint svc)
-{      /* BACnet-Complex-Ack-PDU */
-       /* ASHRAE 135-2001 20.1.5 */
+{   /* BACnet-Complex-Ack-PDU */
+    /* ASHRAE 135-2001 20.1.5 */
 
-       /* Service ACK follows... */
-       return fConfirmedServiceAck (tvb, pinfo, bacapp_tree, offset, svc);
+    /* Service ACK follows... */
+    return fConfirmedServiceAck(tvb, pinfo, bacapp_tree, offset, svc);
 }
 
 static guint
 fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
-{      /* BACnet-Complex-Ack-PDU */
-       /* ASHRAE 135-2001 20.1.5 */
-       gint svc;
-       proto_item *tt = 0;
+{   /* BACnet-Complex-Ack-PDU */
+    /* ASHRAE 135-2001 20.1.5 */
+    gint        svc;
+    proto_item *tt = 0;
 
-       offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
-       return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
+    offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt);
+    return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc);
 }
 
 static guint
 fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
-{      /* BACnet-SegmentAck-PDU */
-       /* ASHRAE 135-2001 20.1.6 */
+{   /* BACnet-SegmentAck-PDU */
+    /* ASHRAE 135-2001 20.1.6 */
 
-       proto_item *tc;
-       proto_tree *bacapp_tree_control;
+    proto_item *tc;
+    proto_tree *bacapp_tree_control;
 
-       tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
-       bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
+    tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+    bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
 
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       return offset;
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    return offset;
 }
 
 static guint
 fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint8 tag_info = 0;
-       guint8 parsed_tag = 0;
-       guint32 lvt = 0;
-       offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
-       offset = fError(tvb, pinfo, tree, offset);
-       return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
+    guint8  tag_info   = 0;
+    guint8  parsed_tag = 0;
+    guint32 lvt        = 0;
+
+    offset += fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
+    offset  = fError(tvb, pinfo, tree, offset);
+    return offset + fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt);
 }
 
 static guint
 fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
-       guint8 tag_no = 0, tag_info = 0;
-       guint32 lvt = 0;
-       proto_tree *subtree = tree;
-       proto_item *tt;
-
-       guint vendor_identifier = 0;
-       guint service_number = 0;
-       guint8 tag_len = 0;
-
-       while (tvb_reported_length_remaining(tvb, offset)) {
-               /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
-               switch (tag_no) {
-               case 0: /* errorType */
-                       offset = fContextTaggedError(tvb, pinfo, subtree, offset);
-                       break;
-               case 1: /* vendorID */
-                       fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
-                       if (col_get_writable(pinfo->cinfo))
-                               col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ",        vendor_identifier);
-                       offset = fVendorIdentifier (tvb, pinfo, subtree, offset);
-                       break;
-               case 2: /* serviceNumber */
-                       fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
-                       if (col_get_writable(pinfo->cinfo))
-                               col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ",       service_number);
-                       offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
-                       break;
-               case 3: /* errorParameters */
-                       if (tag_is_opening(tag_info)) {
-                               tt = proto_tree_add_text(subtree, tvb, offset, 1,
-                                       "error Parameters");
-                               subtree = proto_item_add_subtree(tt, ett_bacapp_value);
-                               propertyIdentifier = -1;
-                               offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
-                               offset = fAbstractSyntaxNType (tvb, pinfo, subtree, offset);
-                       } else if (tag_is_closing(tag_info)) {
-                               offset += fTagHeaderTree (tvb, subtree, offset,
-                                       &tag_no, &tag_info, &lvt);
-                               subtree = tree;
-                       } else {
-                               /* error condition: let caller handle */
-                               return offset;
-                       }
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    guint       lastoffset        = 0;
+    guint8      tag_no            = 0, tag_info = 0;
+    guint32     lvt               = 0;
+    proto_tree *subtree           = tree;
+
+    guint       vendor_identifier = 0;
+    guint       service_number    = 0;
+    guint8      tag_len           = 0;
+
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {
+        /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
+        switch (tag_no) {
+        case 0: /* errorType */
+            offset = fContextTaggedError(tvb, pinfo, subtree, offset);
+            break;
+        case 1: /* vendorID */
+            fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier);
+            if (col_get_writable(pinfo->cinfo))
+                col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ",    vendor_identifier);
+            offset = fVendorIdentifier(tvb, pinfo, subtree, offset);
+            break;
+        case 2: /* serviceNumber */
+            fUnsigned32(tvb, offset+tag_len, lvt, &service_number);
+            if (col_get_writable(pinfo->cinfo))
+                col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ",   service_number);
+            offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: ");
+            break;
+        case 3: /* errorParameters */
+            if (tag_is_opening(tag_info)) {
+                subtree = proto_tree_add_subtree(subtree, tvb, offset, 1,
+                    ett_bacapp_value, NULL, "error Parameters");
+                propertyIdentifier = -1;
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
+                offset  = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
+            } else if (tag_is_closing(tag_info)) {
+                offset += fTagHeaderTree(tvb, pinfo, subtree, offset,
+                    &tag_no, &tag_info, &lvt);
+                subtree = tree;
+            } else {
+                /* error condition: let caller handle */
+                return offset;
+            }
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
+    guint lastoffset = 0;
 
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* errorType */
-                       offset = fContextTaggedError(tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* firstFailedElementNumber */
-                       offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* errorType */
+            offset = fContextTaggedError(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* firstFailedElementNumber */
+            offset = fUnsignedTag(tvb, pinfo, tree, offset, "first failed element number: ");
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
 }
 
 static guint
 fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       /* Identical to CreateObjectError */
-       return fCreateObjectError(tvb, pinfo, tree, offset);
+    /* Identical to CreateObjectError */
+    return fCreateObjectError(tvb, pinfo, tree, offset);
 }
 
 static guint
 fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint8 tag_no = 0, tag_info = 0;
-       guint32 lvt = 0;
+    guint8  tag_no = 0, tag_info = 0;
+    guint32 lvt = 0;
 
-       if (fTagNo(tvb, offset) == 0) {
-               /* errorType */
-               offset = fContextTaggedError(tvb, pinfo, tree,offset);
-               if (fTagNo(tvb, offset) == 1) {
-                       /* listOfVTSessionIdentifiers [OPTIONAL] */
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fVtCloseRequest (tvb, pinfo, tree, offset);
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-               }
-       }
-       /* should report bad packet if initial tag wasn't 0 */
-       return offset;
+    if (fTagNo(tvb, offset) == 0) {
+        /* errorType */
+        offset = fContextTaggedError(tvb, pinfo, tree, offset);
+        if (fTagNo(tvb, offset) == 1) {
+            /* listOfVTSessionIdentifiers [OPTIONAL] */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fVtCloseRequest(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+        }
+    }
+    /* should report bad packet if initial tag wasn't 0 */
+    return offset;
 }
 
 static guint
 fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
 {
-       guint lastoffset = 0;
-       guint8 tag_no = 0, tag_info = 0;
-       guint32 lvt = 0;
-
-       col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
-       while (tvb_reported_length_remaining(tvb, offset)) {  /* exit loop if nothing happens inside */
-               lastoffset = offset;
-               switch (fTagNo(tvb, offset)) {
-               case 0: /* errorType */
-                       offset = fContextTaggedError(tvb, pinfo, tree, offset);
-                       break;
-               case 1: /* firstFailedWriteAttempt */
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
-                       offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
-                       break;
-               default:
-                       return offset;
-               }
-               if (offset == lastoffset) break;     /* nothing happened, exit loop */
-       }
-       return offset;
-}
-
-static guint
-fError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
-{
-       offset = fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
-                                                  "error Class: ", BACnetErrorClass, 64);
-       return fApplicationTypesEnumeratedSplit (tvb, pinfo, tree, offset,
-                                                "error Code: ", BACnetErrorCode, 256);
-}
-
-static guint
-fBACnetError (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
-{
-       switch (service) {
-       case 8:  /* no break here !!!! */
-       case 9:
-               offset = fChangeListError (tvb, pinfo, tree, offset);
-               break;
-       case 10:
-               offset = fCreateObjectError (tvb, pinfo, tree, offset);
-               break;
-       case 16:
-               offset = fWritePropertyMultipleError (tvb, pinfo, tree, offset);
-               break;
-       case 18:
-               offset = fConfirmedPrivateTransferError (tvb,pinfo,tree,offset);
-               break;
-       case 22:
-               offset = fVTCloseError (tvb, pinfo, tree, offset);
-               break;
-       default:
-               return fError (tvb, pinfo, tree, offset);
-       }
-       return offset;
+    guint   lastoffset = 0;
+    guint8  tag_no     = 0, tag_info = 0;
+    guint32 lvt        = 0;
+
+    col_set_writable(pinfo->cinfo, FALSE); /* don't set all infos into INFO column */
+    while (tvb_reported_length_remaining(tvb, offset) > 0) {  /* exit loop if nothing happens inside */
+        lastoffset = offset;
+        switch (fTagNo(tvb, offset)) {
+        case 0: /* errorType */
+            offset = fContextTaggedError(tvb, pinfo, tree, offset);
+            break;
+        case 1: /* firstFailedWriteAttempt */
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            offset  = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset);
+            offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt);
+            break;
+        default:
+            return offset;
+        }
+        if (offset == lastoffset) break;     /* nothing happened, exit loop */
+    }
+    return offset;
+}
+
+static guint
+fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
+{
+    offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
+                           "error Class: ", BACnetErrorClass, 64);
+    return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset,
+                         "error Code: ", BACnetErrorCode, 256);
+}
+
+static guint
+fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint service)
+{
+    switch (service) {
+    case 8:  /* no break here !!!! */
+    case 9:
+        offset = fChangeListError(tvb, pinfo, tree, offset);
+        break;
+    case 10:
+        offset = fCreateObjectError(tvb, pinfo, tree, offset);
+        break;
+    case 16:
+        offset = fWritePropertyMultipleError(tvb, pinfo, tree, offset);
+        break;
+    case 18:
+        offset = fConfirmedPrivateTransferError(tvb, pinfo, tree, offset);
+        break;
+    case 22:
+        offset = fVTCloseError(tvb, pinfo, tree, offset);
+        break;
+    default:
+        return fError(tvb, pinfo, tree, offset);
+    }
+    return offset;
 }
 
 static guint
 fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, guint offset)
-{      /* BACnet-Error-PDU */
-       /* ASHRAE 135-2001 20.1.7 */
+{   /* BACnet-Error-PDU */
+    /* ASHRAE 135-2001 20.1.7 */
 
-       proto_item *tc;
-       proto_tree *bacapp_tree_control;
-       guint8 tmp;
+    proto_item *tc;
+    proto_tree *bacapp_tree_control;
+    guint8      tmp;
 
-       tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
-       bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
+    tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
+    bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
 
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       tmp = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
-                                offset++, 1, ENC_BIG_ENDIAN);
-       /* Error Handling follows... */
-       return fBACnetError (tvb, pinfo, bacapp_tree, offset, tmp);
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    tmp = tvb_get_guint8(tvb, offset);
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb,
+                 offset++, 1, ENC_BIG_ENDIAN);
+    /* Error Handling follows... */
+    return fBACnetError(tvb, pinfo, bacapp_tree, offset, tmp);
 }
 
 static guint
 fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
-{      /* BACnet-Reject-PDU */
-       /* ASHRAE 135-2001 20.1.8 */
+{   /* BACnet-Reject-PDU */
+    /* ASHRAE 135-2001 20.1.8 */
 
-       proto_item *tc;
-       proto_tree *bacapp_tree_control;
+    proto_item *tc;
+    proto_tree *bacapp_tree_control;
 
-       tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
-       bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
+    tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
+    bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
 
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       return offset;
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    return offset;
 }
 
 static guint
 fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, guint offset)
-{      /* BACnet-Abort-PDU */
-       /* ASHRAE 135-2001 20.1.9 */
+{   /* BACnet-Abort-PDU */
+    /* ASHRAE 135-2001 20.1.9 */
 
-       proto_item *tc;
-       proto_tree *bacapp_tree_control;
+    proto_item *tc;
+    proto_tree *bacapp_tree_control;
 
-       tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
-       bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
+    tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+    bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
 
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
-                           offset++, 1, ENC_BIG_ENDIAN);
-       return offset;
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb,
+                offset++, 1, ENC_BIG_ENDIAN);
+    return offset;
 }
 
 static guint
 do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
-       guint8 flag, bacapp_type;
-       guint offset = 0;
-
-       flag = (gint) tvb_get_guint8(tvb, 0);
-       bacapp_type = (flag >> 4) & 0x0f;
-
-       if (tvb == NULL) {
-               return 0;
-       }
-
-       /* ASHRAE 135-2001 20.1.1 */
-       switch (bacapp_type) {
-       case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:     /* BACnet-Confirmed-Service-Request */
-               offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
-               break;
-       case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:   /* BACnet-Unconfirmed-Request-PDU */
-               offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
-               break;
-       case BACAPP_TYPE_SIMPLE_ACK:    /* BACnet-Simple-Ack-PDU */
-               offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
-               break;
-       case BACAPP_TYPE_COMPLEX_ACK:   /* BACnet-Complex-Ack-PDU */
-               offset = fComplexAckPDU(tvb, pinfo, tree, offset);
-               break;
-       case BACAPP_TYPE_SEGMENT_ACK:   /* BACnet-SegmentAck-PDU */
-               offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
-               break;
-       case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
-               offset = fErrorPDU(tvb, pinfo, tree, offset);
-               break;
-       case BACAPP_TYPE_REJECT:        /* BACnet-Reject-PDU */
-               offset = fRejectPDU(tvb, pinfo, tree, offset);
-               break;
-       case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
-               offset = fAbortPDU(tvb, pinfo, tree, offset);
-               break;
-       }
-       return offset;
+    guint8 flag, bacapp_type;
+    guint  offset = 0;
+
+    flag = (gint) tvb_get_guint8(tvb, 0);
+    bacapp_type = (flag >> 4) & 0x0f;
+
+    if (tvb == NULL) {
+        return 0;
+    }
+
+    /* ASHRAE 135-2001 20.1.1 */
+    switch (bacapp_type) {
+    case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
+        offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset);
+        break;
+    case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:   /* BACnet-Unconfirmed-Request-PDU */
+        offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset);
+        break;
+    case BACAPP_TYPE_SIMPLE_ACK:    /* BACnet-Simple-Ack-PDU */
+        offset = fSimpleAckPDU(tvb, pinfo, tree, offset);
+        break;
+    case BACAPP_TYPE_COMPLEX_ACK:   /* BACnet-Complex-Ack-PDU */
+        offset = fComplexAckPDU(tvb, pinfo, tree, offset);
+        break;
+    case BACAPP_TYPE_SEGMENT_ACK:   /* BACnet-SegmentAck-PDU */
+        offset = fSegmentAckPDU(tvb, pinfo, tree, offset);
+        break;
+    case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
+        offset = fErrorPDU(tvb, pinfo, tree, offset);
+        break;
+    case BACAPP_TYPE_REJECT:    /* BACnet-Reject-PDU */
+        offset = fRejectPDU(tvb, pinfo, tree, offset);
+        break;
+    case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
+        offset = fAbortPDU(tvb, pinfo, tree, offset);
+        break;
+    }
+    return offset;
 }
 
 static void
 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
-       guint8 flag, bacapp_type;
-       guint save_fragmented = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
-       tvbuff_t* new_tvb = NULL;
-       guint offset = 0;
-       guint8 bacapp_seqno = 0;
-       guint8 bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
-       guint8 bacapp_invoke_id = 0;
-       proto_item *ti;
-       proto_tree *bacapp_tree = NULL;
-
-       gint svc = 0;
-       proto_item *tt = 0;
-       gint8 ack = 0;
-
-       /* Strings for BACnet Statistics */
-       const gchar errstr[]="ERROR: ";
-       const gchar rejstr[]="REJECTED: ";
-       const gchar abortstr[]="ABORTED: ";
-       const gchar sackstr[]=" (SimpleAck)";
-       const gchar cackstr[]=" (ComplexAck)";
-       const gchar uconfsreqstr[]=" (Unconfirmed Service Request)";
-       const gchar confsreqstr[]=" (Confirmed Service Request)";
-
-       col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
-       col_clear (pinfo->cinfo, COL_INFO);
-
-       flag = tvb_get_guint8(tvb, 0);
-       bacapp_type = (flag >> 4) & 0x0f;
-
-       /* show some descriptive text in the INFO column */
-       col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
-               val_to_str(bacapp_type, BACnetTypeName, "# unknown APDU #"));
-
-       bacinfo.service_type = NULL;
-       bacinfo.invoke_id = NULL;
-       bacinfo.instance_ident = NULL;
-       bacinfo.object_ident = NULL;
-
-       switch (bacapp_type)
-       {
-               case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
-                       /* segmented messages have 2 additional bytes */
-                       if (flag & BACAPP_SEGMENTED_REQUEST) {
-                               fragment = TRUE;
-                               ack = 0;
-                               /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
-                               bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
-                               bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
-                               /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
-                               bacapp_service = tvb_get_guint8(tvb, offset + 5);
-                               data_offset = 6;
-                       } else {
-                               bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
-                               bacapp_service = tvb_get_guint8(tvb, offset + 3);
-                       }
-                       col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
-                               val_to_str(bacapp_service,
-                                       BACnetConfirmedServiceChoice,
-                                       bacapp_unknown_service_str),bacapp_invoke_id);
-
-                       updateBacnetInfoValue(BACINFO_INVOKEID,
-                                             ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
-
-                       updateBacnetInfoValue(BACINFO_SERVICE,
-                           ep_strconcat(val_to_str(bacapp_service,
-                                                   BACnetConfirmedServiceChoice,
-                                                   bacapp_unknown_service_str),
-                                        confsreqstr, NULL));
-                       break;
-               case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
-                       bacapp_service = tvb_get_guint8(tvb, offset + 1);
-                       col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
-                               val_to_str(bacapp_service,
-                                       BACnetUnconfirmedServiceChoice,
-                                       bacapp_unknown_service_str));
-
-                       updateBacnetInfoValue(BACINFO_SERVICE,
-                           ep_strconcat(val_to_str(bacapp_service,
-                                                   BACnetUnconfirmedServiceChoice,
-                                                   bacapp_unknown_service_str),
-                                        uconfsreqstr, NULL));
-                       break;
-               case BACAPP_TYPE_SIMPLE_ACK:
-                       bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
-                       bacapp_service = tvb_get_guint8(tvb, offset + 2);
-                       col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
-                               val_to_str(bacapp_service,
-                                       BACnetConfirmedServiceChoice,
-                                       bacapp_unknown_service_str), bacapp_invoke_id);
-
-                       updateBacnetInfoValue(BACINFO_INVOKEID,
-                                             ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
-
-                       updateBacnetInfoValue(BACINFO_SERVICE,
-                           ep_strconcat(val_to_str(bacapp_service,
-                                                   BACnetConfirmedServiceChoice,
-                                                   bacapp_unknown_service_str),
-                                        sackstr, NULL));
-                       break;
-               case BACAPP_TYPE_COMPLEX_ACK:
-                       /* segmented messages have 2 additional bytes */
-                       if (flag & BACAPP_SEGMENTED_REQUEST) {
-                               fragment = TRUE;
-                               ack = 1;
-                               /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
-                               bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
-                               bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
-                               /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
-                               bacapp_service = tvb_get_guint8(tvb, offset + 4);
-                               data_offset = 5;
-                       } else {
-                               bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
-                               bacapp_service = tvb_get_guint8(tvb, offset + 2);
-                       }
-                       col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
-                               val_to_str(bacapp_service,
-                                       BACnetConfirmedServiceChoice,
-                                       bacapp_unknown_service_str), bacapp_invoke_id);
-
-                       updateBacnetInfoValue(BACINFO_INVOKEID,
-                                             ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
-
-                       updateBacnetInfoValue(BACINFO_SERVICE,
-                           ep_strconcat(val_to_str(bacapp_service,
-                                                   BACnetConfirmedServiceChoice,
-                                                   bacapp_unknown_service_str),
-                                        cackstr, NULL));
-                       break;
-               case BACAPP_TYPE_SEGMENT_ACK:
-                       /* nothing more to add */
-                       break;
-               case BACAPP_TYPE_ERROR:
-                       bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
-                       bacapp_service = tvb_get_guint8(tvb, offset + 2);
-                       col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
-                               val_to_str(bacapp_service,
-                                       BACnetConfirmedServiceChoice,
-                                       bacapp_unknown_service_str), bacapp_invoke_id);
-
-                       updateBacnetInfoValue(BACINFO_INVOKEID,
-                                             ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
-
-                       updateBacnetInfoValue(BACINFO_SERVICE,
-                           ep_strconcat(errstr,
-                                        val_to_str(bacapp_service,
-                                                   BACnetConfirmedServiceChoice,
-                                                   bacapp_unknown_service_str),
-                                        NULL));
-                       break;
-               case BACAPP_TYPE_REJECT:
-                       bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
-                       bacapp_reason = tvb_get_guint8(tvb, offset + 2);
-                       col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
-                               val_to_split_str(bacapp_reason,
-                                       64,
-                                       BACnetRejectReason,
-                                       ASHRAE_Reserved_Fmt,
-                                       Vendor_Proprietary_Fmt), bacapp_invoke_id);
-
-                       updateBacnetInfoValue(BACINFO_INVOKEID,
-                                             ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
-
-                       updateBacnetInfoValue(BACINFO_SERVICE,
-                               ep_strconcat(rejstr,
-                                            val_to_split_str(bacapp_reason, 64,
-                                            BACnetRejectReason,
-                                            ASHRAE_Reserved_Fmt,
-                                            Vendor_Proprietary_Fmt),
-                                            NULL));
-                       break;
-               case BACAPP_TYPE_ABORT:
-                       bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
-                       bacapp_reason = tvb_get_guint8(tvb, offset + 2);
-                       col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
-                               val_to_split_str(bacapp_reason,
-                                       64,
-                                       BACnetAbortReason,
-                                       ASHRAE_Reserved_Fmt,
-                                       Vendor_Proprietary_Fmt), bacapp_invoke_id);
-
-                       updateBacnetInfoValue(BACINFO_INVOKEID,
-                                             ep_strdup_printf("Invoke ID: %d", bacapp_invoke_id));
-
-                       updateBacnetInfoValue(BACINFO_SERVICE,
-                               ep_strconcat(abortstr,
-                                            val_to_split_str(bacapp_reason,
-                                                             64,
-                                                             BACnetAbortReason,
-                                                             ASHRAE_Reserved_Fmt,
-                                                             Vendor_Proprietary_Fmt),
-                                            NULL));
-                       break;
-               /* UNKNOWN */
-               default:
-                       /* nothing more to add */
-                       break;
-       }
-
-       save_fragmented = pinfo->fragmented;
-
-       ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, FALSE);
-       bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
-
-       if (!fragment)
-               offset = do_the_dissection(tvb,pinfo,bacapp_tree);
-       else
-               fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
-                       /* not resetting the offset so the remaining can be done */
-
-       if (fragment) { /* fragmented */
-               fragment_data *frag_msg = NULL;
-
-               new_tvb = NULL;
-               pinfo->fragmented = TRUE;
-
-               frag_msg = fragment_add_seq_check(tvb, data_offset, pinfo,
-                       bacapp_invoke_id, /* ID for fragments belonging together */
-                       msg_fragment_table, /* list of message fragments */
-                       msg_reassembled_table, /* list of reassembled messages */
-                       bacapp_seqno, /* fragment sequence number */
-                       tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
-                       flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
-               new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
-                               "Reassembled BACapp", frag_msg, &msg_frag_items,
-                               NULL, tree);
-
-               if (new_tvb) { /* Reassembled */
-                       col_append_str(pinfo->cinfo, COL_INFO,
-                               " (Message Reassembled)");
-               } else { /* Not last packet of reassembled Short Message */
-                       col_append_fstr(pinfo->cinfo, COL_INFO,
-                       " (Message fragment %u)", bacapp_seqno);
-               }
-               if (new_tvb) { /* take it all */
-                       switch (bacapp_type)
-                       {
-                               case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
-                                       fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
-                               break;
-                               case BACAPP_TYPE_COMPLEX_ACK:
-                                       fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
-                               break;
-                               default:
-                                       /* do nothing */
-                               break;
-                       }
-                       /* } */
-               }
-       }
-
-       pinfo->fragmented = save_fragmented;
-
-       /* tapping */
-       tap_queue_packet(bacapp_tap,pinfo,&bacinfo);
+    guint8      flag, bacapp_type;
+    guint       save_fragmented  = FALSE, data_offset = 0, /*bacapp_apdu_size,*/ fragment = FALSE;
+    tvbuff_t   *new_tvb          = NULL;
+    guint       offset           = 0;
+    guint8      bacapp_seqno     = 0;
+    guint8      bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/;
+    guint8      bacapp_invoke_id = 0;
+    proto_item *ti;
+    proto_tree *bacapp_tree      = NULL;
+
+    gint        svc = 0;
+    proto_item *tt  = 0;
+    gint8       ack = 0;
+
+    /* Strings for BACnet Statistics */
+    const gchar errstr[]       = "ERROR: ";
+    const gchar rejstr[]       = "REJECTED: ";
+    const gchar abortstr[]     = "ABORTED: ";
+    const gchar sackstr[]      = " (SimpleAck)";
+    const gchar cackstr[]      = " (ComplexAck)";
+    const gchar uconfsreqstr[] = " (Unconfirmed Service Request)";
+    const gchar confsreqstr[]  = " (Confirmed Service Request)";
+
+    col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
+    col_clear(pinfo->cinfo, COL_INFO);
+
+    flag = tvb_get_guint8(tvb, 0);
+    bacapp_type = (flag >> 4) & 0x0f;
+
+    /* show some descriptive text in the INFO column */
+    col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s",
+        val_to_str_const(bacapp_type, BACnetTypeName, "# unknown APDU #"));
+
+    bacinfo.service_type = NULL;
+    bacinfo.invoke_id = NULL;
+    bacinfo.instance_ident = NULL;
+    bacinfo.object_ident = NULL;
+
+    switch (bacapp_type) {
+    case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
+        /* segmented messages have 2 additional bytes */
+        if (flag & BACAPP_SEGMENTED_REQUEST) {
+            fragment = TRUE;
+            ack = 0;
+            /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_guint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */
+            bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
+            bacapp_seqno = tvb_get_guint8(tvb, offset + 3);
+            /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 4); */
+            bacapp_service = tvb_get_guint8(tvb, offset + 5);
+            data_offset = 6;
+        } else {
+            bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
+            bacapp_service = tvb_get_guint8(tvb, offset + 3);
+        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ",
+                        val_to_str_const(bacapp_service,
+                                         BACnetConfirmedServiceChoice,
+                                         bacapp_unknown_service_str),
+                        bacapp_invoke_id);
+
+        updateBacnetInfoValue(BACINFO_INVOKEID,
+                              wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
+
+        updateBacnetInfoValue(BACINFO_SERVICE,
+                              wmem_strconcat(wmem_packet_scope(),
+                                             val_to_str_const(bacapp_service,
+                                                              BACnetConfirmedServiceChoice,
+                                                              bacapp_unknown_service_str),
+                                             confsreqstr, NULL));
+        break;
+    case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
+        bacapp_service = tvb_get_guint8(tvb, offset + 1);
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
+                        val_to_str_const(bacapp_service,
+                                         BACnetUnconfirmedServiceChoice,
+                                         bacapp_unknown_service_str));
+
+        updateBacnetInfoValue(BACINFO_SERVICE,
+                              wmem_strconcat(wmem_packet_scope(),
+                                             val_to_str_const(bacapp_service,
+                                                              BACnetUnconfirmedServiceChoice,
+                                                              bacapp_unknown_service_str),
+                                             uconfsreqstr, NULL));
+        break;
+    case BACAPP_TYPE_SIMPLE_ACK:
+        bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
+        bacapp_service = tvb_get_guint8(tvb, offset + 2);
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
+                        val_to_str_const(bacapp_service,
+                                         BACnetConfirmedServiceChoice,
+                                         bacapp_unknown_service_str),
+                        bacapp_invoke_id);
+
+        updateBacnetInfoValue(BACINFO_INVOKEID,
+                              wmem_strdup_printf(wmem_packet_scope(),
+                                                 "Invoke ID: %d", bacapp_invoke_id));
+
+        updateBacnetInfoValue(BACINFO_SERVICE,
+                              wmem_strconcat(wmem_packet_scope(),
+                                             val_to_str_const(bacapp_service,
+                                                              BACnetConfirmedServiceChoice,
+                                                              bacapp_unknown_service_str),
+                                             sackstr, NULL));
+        break;
+    case BACAPP_TYPE_COMPLEX_ACK:
+        /* segmented messages have 2 additional bytes */
+        if (flag & BACAPP_SEGMENTED_REQUEST) {
+            fragment = TRUE;
+            ack = 1;
+            /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */
+            bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
+            bacapp_seqno = tvb_get_guint8(tvb, offset + 2);
+            /* bacapp_prop_win_size = tvb_get_guint8(tvb, offset + 3); */
+            bacapp_service = tvb_get_guint8(tvb, offset + 4);
+            data_offset = 5;
+        } else {
+            bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
+            bacapp_service = tvb_get_guint8(tvb, offset + 2);
+        }
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
+                        val_to_str_const(bacapp_service,
+                                         BACnetConfirmedServiceChoice,
+                                         bacapp_unknown_service_str),
+                        bacapp_invoke_id);
+
+        updateBacnetInfoValue(BACINFO_INVOKEID,
+                              wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
+
+        updateBacnetInfoValue(BACINFO_SERVICE,
+                              wmem_strconcat(wmem_packet_scope(),
+                                             val_to_str_const(bacapp_service,
+                                                              BACnetConfirmedServiceChoice,
+                                                              bacapp_unknown_service_str),
+                                             cackstr, NULL));
+        break;
+    case BACAPP_TYPE_SEGMENT_ACK:
+        /* nothing more to add */
+        break;
+    case BACAPP_TYPE_ERROR:
+        bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
+        bacapp_service = tvb_get_guint8(tvb, offset + 2);
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
+                        val_to_str_const(bacapp_service,
+                                         BACnetConfirmedServiceChoice,
+                                         bacapp_unknown_service_str),
+                        bacapp_invoke_id);
+
+        updateBacnetInfoValue(BACINFO_INVOKEID,
+                              wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
+
+        updateBacnetInfoValue(BACINFO_SERVICE,
+                              wmem_strconcat(wmem_packet_scope(),
+                                             errstr,
+                                             val_to_str_const(bacapp_service,
+                                                              BACnetConfirmedServiceChoice,
+                                                              bacapp_unknown_service_str),
+                                             NULL));
+        break;
+    case BACAPP_TYPE_REJECT:
+        bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
+        bacapp_reason = tvb_get_guint8(tvb, offset + 2);
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
+                        val_to_split_str(bacapp_reason,
+                                         64,
+                                         BACnetRejectReason,
+                                         ASHRAE_Reserved_Fmt,
+                                         Vendor_Proprietary_Fmt), bacapp_invoke_id);
+
+        updateBacnetInfoValue(BACINFO_INVOKEID,
+                              wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
+
+        updateBacnetInfoValue(BACINFO_SERVICE,
+                              wmem_strconcat(wmem_packet_scope(), rejstr,
+                                             val_to_split_str(bacapp_reason, 64,
+                                                              BACnetRejectReason,
+                                                              ASHRAE_Reserved_Fmt,
+                                                              Vendor_Proprietary_Fmt),
+                                             NULL));
+        break;
+    case BACAPP_TYPE_ABORT:
+        bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
+        bacapp_reason = tvb_get_guint8(tvb, offset + 2);
+        col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */
+                        val_to_split_str(bacapp_reason,
+                                         64,
+                                         BACnetAbortReason,
+                                         ASHRAE_Reserved_Fmt,
+                                         Vendor_Proprietary_Fmt), bacapp_invoke_id);
+
+        updateBacnetInfoValue(BACINFO_INVOKEID,
+                              wmem_strdup_printf(wmem_packet_scope(), "Invoke ID: %d", bacapp_invoke_id));
+
+        updateBacnetInfoValue(BACINFO_SERVICE,
+                              wmem_strconcat(wmem_packet_scope(), abortstr,
+                                             val_to_split_str(bacapp_reason,
+                                                              64,
+                                                              BACnetAbortReason,
+                                                              ASHRAE_Reserved_Fmt,
+                                                              Vendor_Proprietary_Fmt),
+                                             NULL));
+        break;
+        /* UNKNOWN */
+    default:
+        /* nothing more to add */
+        break;
+    }
+
+    save_fragmented = pinfo->fragmented;
+
+    ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA);
+    bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
+
+    if (!fragment)
+        do_the_dissection(tvb, pinfo, bacapp_tree);
+    else
+        fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt);
+            /* not resetting the offset so the remaining can be done */
+
+    if (fragment) { /* fragmented */
+        fragment_head *frag_msg;
+
+        pinfo->fragmented = TRUE;
+
+        frag_msg = fragment_add_seq_check(&msg_reassembly_table,
+            tvb, data_offset,
+            pinfo,
+            bacapp_invoke_id,      /* ID for fragments belonging together */
+            NULL,
+            bacapp_seqno,          /* fragment sequence number */
+            tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */
+            flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */
+        new_tvb = process_reassembled_data(tvb, data_offset, pinfo,
+                "Reassembled BACapp", frag_msg, &msg_frag_items,
+                NULL, tree);
+
+        if (new_tvb) { /* Reassembled */
+            col_append_str(pinfo->cinfo, COL_INFO,
+                           " (Message Reassembled)");
+        } else { /* Not last packet of reassembled Short Message */
+            col_append_fstr(pinfo->cinfo, COL_INFO,
+                            " (Message fragment %u)", bacapp_seqno);
+        }
+        if (new_tvb) { /* take it all */
+            switch (bacapp_type) {
+            case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
+                fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
+                break;
+            case BACAPP_TYPE_COMPLEX_ACK:
+                fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc);
+                break;
+            default:
+                /* do nothing */
+                break;
+            }
+        }
+    }
+
+    pinfo->fragmented = save_fragmented;
+
+    /* tapping */
+    tap_queue_packet(bacapp_tap, pinfo, &bacinfo);
 }
 
 static void
 bacapp_init_routine(void)
 {
-       fragment_table_init(&msg_fragment_table);
-       reassembled_table_init(&msg_reassembled_table);
-}
-
-static guint32
-fConvertXXXtoUTF8 (gchar *in, gsize *inbytesleft, gchar *out, gsize *outbytesleft, const gchar *fromcoding)
-{
-       guint32 i;
-       GIConv icd;
-
-       if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
-               i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
-               /* g_iconv incremented 'out'; now ensure it's NULL terminated */
-               out[0] = '\0';
-
-               g_iconv_close (icd);
-               return i;
-       }
-
-       uni_to_string(in,*inbytesleft,out);
-       out[*inbytesleft] = '\0';
-       *outbytesleft -= *inbytesleft;
-       *inbytesleft = 0;
-
-       return 0;
+    reassembly_table_init(&msg_reassembly_table,
+                          &addresses_reassembly_table_functions);
 }
 
 static void
-uni_to_string(char * data, gsize str_length, char *dest_buf)
-{
-       gint i;
-       guint16 c_char;
-       gsize length_remaining = 0;
-
-       length_remaining = str_length;
-       dest_buf[0] = '\0';
-       if(str_length == 0) {
-               return;
-       }
-       for ( i = 0; i < (gint) str_length; i++ ) {
-               c_char = data[i];
-               if (c_char<0x20 || c_char>0x7e) {
-                       if (c_char != 0x00) {
-                               c_char = '.';
-                               dest_buf[i] = c_char & 0xff;
-                       } else {
-                               i--;
-                               str_length--;
-                       }
-               } else {
-                       dest_buf[i] = c_char & 0xff;
-               }
-               length_remaining--;
-
-               if(length_remaining==0) {
-                       dest_buf[i+1] = '\0';
-                       return;
-               }
-       }
-       if (i < 0) {
-               i = 0;
-       }
-       dest_buf[i] = '\0';
-       return;
+bacapp_cleanup_routine(void)
+{
+    reassembly_table_destroy(&msg_reassembly_table);
 }
 
 void
 proto_register_bacapp(void)
 {
-       static hf_register_info hf[] = {
-               { &hf_bacapp_type,
-                       { "APDU Type",           "bacapp.type",
-                       FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
-               },
-               { &hf_bacapp_pduflags,
-                       { "PDU Flags",                  "bacapp.pduflags",
-                       FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
-               },
-               { &hf_bacapp_SEG,
-                       { "Segmented Request",           "bacapp.segmented_request",
-                       FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
-               },
-               { &hf_bacapp_MOR,
-                       { "More Segments",           "bacapp.more_segments",
-                       FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
-               },
-               { &hf_bacapp_SA,
-                       { "SA",           "bacapp.SA",
-                       FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
-               },
-               { &hf_bacapp_max_adpu_size,
-                       { "Size of Maximum ADPU accepted",           "bacapp.max_adpu_size",
-                       FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
-               },
-               { &hf_bacapp_response_segments,
-                       { "Max Response Segments accepted",           "bacapp.response_segments",
-                       FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
-               },
-               { &hf_bacapp_objectType,
-                       { "Object Type",           "bacapp.objectType",
-                       FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
-               },
-               { &hf_bacapp_instanceNumber,
-                       { "Instance Number",           "bacapp.instance_number",
-                       FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
-               },
-               { &hf_BACnetPropertyIdentifier,
-                       { "Property Identifier", "bacapp.property_identifier",
-                       FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
-               },
-               { &hf_BACnetVendorIdentifier,
-                       { "Vendor Identifier", "bacapp.vendor_identifier",
-                       FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
-               },
-               { &hf_BACnetRestartReason,
-                       { "Restart Reason", "bacapp.restart_reason",
-                       FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
-               },
-               { &hf_bacapp_invoke_id,
-                       { "Invoke ID",           "bacapp.invoke_id",
-                       FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
-               },
-               { &hf_bacapp_sequence_number,
-                       { "Sequence Number",           "bacapp.sequence_number",
-                       FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
-               },
-               { &hf_bacapp_window_size,
-                       { "Proposed Window Size",           "bacapp.window_size",
-                       FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
-               },
-               { &hf_bacapp_service,
-                       { "Service Choice",           "bacapp.confirmed_service",
-                       FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
-               },
-               { &hf_bacapp_uservice,
-                       { "Unconfirmed Service Choice",           "bacapp.unconfirmed_service",
-                       FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
-               },
-               { &hf_bacapp_NAK,
-                       { "NAK",           "bacapp.NAK",
-                       FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
-               },
-               { &hf_bacapp_SRV,
-                       { "SRV",           "bacapp.SRV",
-                       FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
-               },
-               { &hf_Device_Instance_Range_Low_Limit,
-                       { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
-                       FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
-               },
-               { &hf_Device_Instance_Range_High_Limit,
-                       { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
-                       FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
-               },
-               { &hf_BACnetRejectReason,
-                       { "Reject Reason",           "bacapp.reject_reason",
-                       FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
-               },
-               { &hf_BACnetAbortReason,
-                       { "Abort Reason",           "bacapp.abort_reason",
-                       FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
-               },
-               { &hf_BACnetApplicationTagNumber,
-                       { "Application Tag Number",
-                       "bacapp.application_tag_number",
-                       FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
-                       NULL, HFILL }
-               },
-               { &hf_BACnetContextTagNumber,
-                       { "Context Tag Number",
-                       "bacapp.context_tag_number",
-                       FT_UINT8, BASE_DEC, NULL, 0xF0,
-                       NULL, HFILL }
-               },
-               { &hf_BACnetExtendedTagNumber,
-                       { "Extended Tag Number",
-                       "bacapp.extended_tag_number",
-                       FT_UINT8, BASE_DEC, NULL, 0,
-                       NULL, HFILL }
-               },
-               { &hf_BACnetNamedTag,
-                       { "Named Tag",
-                       "bacapp.named_tag",
-                       FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
-                       NULL, HFILL }
-               },
-               { &hf_BACnetCharacterSet,
-                       { "String Character Set",
-                       "bacapp.string_character_set",
-                       FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet),0,
-                       NULL, HFILL }
-               },
-               { &hf_BACnetTagClass,
-                       { "Tag Class",           "bacapp.tag_class",
-                       FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
-               },
-               { &hf_bacapp_tag_lvt,
-                       { "Length Value Type",
-                       "bacapp.LVT",
-                       FT_UINT8, BASE_DEC, NULL, 0,
-                       NULL, HFILL }
-               },
-               { &hf_bacapp_tag_ProcessId,
-                       { "ProcessIdentifier",           "bacapp.processId",
-                       FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
-               },
-               { &hf_bacapp_tag_IPV4,
-                       { "IPV4",           "bacapp.IPV4",
-                       FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
-               },
-               { &hf_bacapp_tag_IPV6,
-               { "IPV6",           "bacapp.IPV6",
-                       FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
-               },
-               { &hf_bacapp_tag_PORT,
-                       { "Port",           "bacapp.Port",
-                       FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
-               },
-               {&hf_msg_fragments,
-                       {"Message fragments", "bacapp.fragments",
-                       FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_fragment,
-                       {"Message fragment", "bacapp.fragment",
-                       FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_fragment_overlap,
-                       {"Message fragment overlap", "bacapp.fragment.overlap",
-                       FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_fragment_overlap_conflicts,
-                       {"Message fragment overlapping with conflicting data",
-                       "bacapp.fragment.overlap.conflicts",
-                       FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_fragment_multiple_tails,
-                       {"Message has multiple tail fragments",
-                       "bacapp.fragment.multiple_tails",
-                       FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_fragment_too_long_fragment,
-                       {"Message fragment too long", "bacapp.fragment.too_long_fragment",
-                       FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_fragment_error,
-                       {"Message defragmentation error", "bacapp.fragment.error",
-                       FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_fragment_count,
-                       {"Message fragment count", "bacapp.fragment.count",
-                       FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_reassembled_in,
-                       {"Reassembled in", "bacapp.reassembled.in",
-                       FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
-               {&hf_msg_reassembled_length,
-                       {"Reassembled BACapp length", "bacapp.reassembled.length",
-                       FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
-       };
-       static gint *ett[] = {
-               &ett_bacapp,
-               &ett_bacapp_control,
-               &ett_bacapp_tag,
-               &ett_bacapp_list,
-               &ett_bacapp_value,
-               &ett_msg_fragment,
-               &ett_msg_fragments
-
-       };
-
-       proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
-                                              "BACapp", "bacapp");
-
-       proto_register_field_array(proto_bacapp, hf, array_length(hf));
-       proto_register_subtree_array(ett, array_length(ett));
-       register_dissector("bacapp", dissect_bacapp, proto_bacapp);
-       register_init_routine (&bacapp_init_routine);
-
-       bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
-                                                         "BACapp Vendor Identifier",
-                                                         FT_UINT8, BASE_HEX);
-
-       /* Register BACnet Statistic trees */
-       register_bacapp_stat_trees();
-       bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
+    static hf_register_info hf[] = {
+        { &hf_bacapp_type,
+          { "APDU Type",           "bacapp.type",
+            FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
+        },
+        { &hf_bacapp_pduflags,
+          { "PDU Flags",          "bacapp.pduflags",
+            FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
+        },
+        { &hf_bacapp_SEG,
+          { "Segmented Request",           "bacapp.segmented_request",
+            FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
+        },
+        { &hf_bacapp_MOR,
+          { "More Segments",           "bacapp.more_segments",
+            FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
+        },
+        { &hf_bacapp_SA,
+          { "SA",           "bacapp.SA",
+            FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
+        },
+        { &hf_bacapp_max_adpu_size,
+          { "Size of Maximum ADPU accepted",           "bacapp.max_adpu_size",
+            FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
+        },
+        { &hf_bacapp_response_segments,
+          { "Max Response Segments accepted",           "bacapp.response_segments",
+            FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
+        },
+        { &hf_bacapp_objectType,
+          { "Object Type",           "bacapp.objectType",
+            FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
+        },
+        { &hf_bacapp_instanceNumber,
+          { "Instance Number",           "bacapp.instance_number",
+            FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
+        },
+        { &hf_BACnetPropertyIdentifier,
+          { "Property Identifier", "bacapp.property_identifier",
+            FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
+        },
+        { &hf_BACnetVendorIdentifier,
+          { "Vendor Identifier", "bacapp.vendor_identifier",
+            FT_UINT16, BASE_DEC|BASE_EXT_STRING, &BACnetVendorIdentifiers_ext, 0, NULL, HFILL }
+        },
+        { &hf_BACnetRestartReason,
+          { "Restart Reason", "bacapp.restart_reason",
+            FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL }
+        },
+        { &hf_bacapp_invoke_id,
+          { "Invoke ID",           "bacapp.invoke_id",
+            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
+        },
+        { &hf_bacapp_sequence_number,
+          { "Sequence Number",           "bacapp.sequence_number",
+            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
+        },
+        { &hf_bacapp_window_size,
+          { "Proposed Window Size",           "bacapp.window_size",
+            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
+        },
+        { &hf_bacapp_service,
+          { "Service Choice",           "bacapp.confirmed_service",
+            FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
+        },
+        { &hf_bacapp_uservice,
+          { "Unconfirmed Service Choice",           "bacapp.unconfirmed_service",
+            FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
+        },
+        { &hf_bacapp_NAK,
+          { "NAK",           "bacapp.NAK",
+            FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
+        },
+        { &hf_bacapp_SRV,
+          { "SRV",           "bacapp.SRV",
+            FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
+        },
+        { &hf_Device_Instance_Range_Low_Limit,
+          { "Device Instance Range Low Limit", "bacapp.who_is.low_limit",
+            FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
+        },
+        { &hf_Device_Instance_Range_High_Limit,
+          { "Device Instance Range High Limit", "bacapp.who_is.high_limit",
+            FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
+        },
+        { &hf_BACnetRejectReason,
+          { "Reject Reason",           "bacapp.reject_reason",
+            FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
+        },
+        { &hf_BACnetAbortReason,
+          { "Abort Reason",           "bacapp.abort_reason",
+            FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
+        },
+        { &hf_BACnetApplicationTagNumber,
+          { "Application Tag Number",
+            "bacapp.application_tag_number",
+            FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0,
+            NULL, HFILL }
+        },
+        { &hf_BACnetContextTagNumber,
+          { "Context Tag Number",
+            "bacapp.context_tag_number",
+            FT_UINT8, BASE_DEC, NULL, 0xF0,
+            NULL, HFILL }
+        },
+        { &hf_BACnetExtendedTagNumber,
+          { "Extended Tag Number",
+            "bacapp.extended_tag_number",
+            FT_UINT8, BASE_DEC, NULL, 0,
+            NULL, HFILL }
+        },
+        { &hf_BACnetNamedTag,
+          { "Named Tag",
+            "bacapp.named_tag",
+            FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07,
+            NULL, HFILL }
+        },
+        { &hf_BACnetCharacterSet,
+          { "String Character Set",
+            "bacapp.string_character_set",
+            FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet), 0,
+            NULL, HFILL }
+        },
+        { &hf_BACnetCodePage,
+          { "Code Page",
+            "bacapp.code_page",
+            FT_UINT16, BASE_DEC, NULL, 0,
+            NULL, HFILL }
+        },
+        { &hf_BACnetTagClass,
+          { "Tag Class",           "bacapp.tag_class",
+            FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
+        },
+        { &hf_bacapp_tag_lvt,
+          { "Length Value Type",
+            "bacapp.LVT",
+            FT_UINT8, BASE_DEC, NULL, 0,
+            NULL, HFILL }
+        },
+        { &hf_bacapp_tag_ProcessId,
+          { "ProcessIdentifier",           "bacapp.processId",
+            FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
+        },
+        { &hf_bacapp_tag_IPV4,
+          { "IPV4",           "bacapp.IPV4",
+            FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL }
+        },
+        { &hf_bacapp_tag_IPV6,
+          { "IPV6",           "bacapp.IPV6",
+            FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL }
+        },
+        { &hf_bacapp_tag_PORT,
+          { "Port",           "bacapp.Port",
+            FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
+        },
+        {&hf_msg_fragments,
+         {"Message fragments", "bacapp.fragments",
+          FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_fragment,
+         {"Message fragment", "bacapp.fragment",
+          FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_fragment_overlap,
+         {"Message fragment overlap", "bacapp.fragment.overlap",
+          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_fragment_overlap_conflicts,
+         {"Message fragment overlapping with conflicting data",
+          "bacapp.fragment.overlap.conflicts",
+          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_fragment_multiple_tails,
+         {"Message has multiple tail fragments",
+          "bacapp.fragment.multiple_tails",
+          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_fragment_too_long_fragment,
+         {"Message fragment too long", "bacapp.fragment.too_long_fragment",
+          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_fragment_error,
+         {"Message defragmentation error", "bacapp.fragment.error",
+          FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_fragment_count,
+         {"Message fragment count", "bacapp.fragment.count",
+          FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_reassembled_in,
+         {"Reassembled in", "bacapp.reassembled.in",
+          FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+        {&hf_msg_reassembled_length,
+         {"Reassembled BACapp length", "bacapp.reassembled.length",
+          FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
+    };
+    static gint *ett[] = {
+        &ett_bacapp,
+        &ett_bacapp_control,
+        &ett_bacapp_tag,
+        &ett_bacapp_list,
+        &ett_bacapp_value,
+        &ett_msg_fragment,
+        &ett_msg_fragments
+
+    };
+
+    static ei_register_info ei[] = {
+        { &ei_bacapp_bad_length, { "bacapp.bad_length", PI_MALFORMED, PI_ERROR, "Wrong length indicated", EXPFILL }},
+        { &ei_bacapp_bad_tag, { "bacapp.bad_tag", PI_MALFORMED, PI_ERROR, "Wrong tag found", EXPFILL }},
+    };
+
+    expert_module_t* expert_bacapp;
+
+    proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
+                                           "BACapp", "bacapp");
+
+    proto_register_field_array(proto_bacapp, hf, array_length(hf));
+    proto_register_subtree_array(ett, array_length(ett));
+    expert_bacapp = expert_register_protocol(proto_bacapp);
+    expert_register_field_array(expert_bacapp, ei, array_length(ei));
+    register_dissector("bacapp", dissect_bacapp, proto_bacapp);
+    register_init_routine(&bacapp_init_routine);
+    register_cleanup_routine(&bacapp_cleanup_routine);
+
+    bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier",
+                                                      "BACapp Vendor Identifier",
+                                                      FT_UINT8, BASE_HEX);
+
+    /* Register BACnet Statistic trees */
+    register_bacapp_stat_trees();
+    bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */
 }
 
-void
-proto_reg_handoff_bacapp(void)
-{
-       data_handle = find_dissector("data");
-}
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */