Use MAC address documentation range in filter examples
[metze/wireshark/wip.git] / epan / dissectors / packet-bacapp.c
index 398e02e9d38febdc665bc95ea8b7cbc242c729e0..1abf510e8c781d4d57b56af36923bd004779b393 100644 (file)
 
 #include "config.h"
 
-#include <glib.h>
-
 #include <epan/packet.h>
 #include <epan/to_str.h>
-#include <epan/wmem/wmem.h>
 #include <epan/reassemble.h>
 #include <epan/expert.h>
 #include <epan/stats_tree.h>
@@ -41,11 +38,6 @@ 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
@@ -756,7 +748,7 @@ fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subt
  *  listOfReadAccessResults SEQUENCE OF ReadAccessResult
  * }
  * @param tvb the tv buffer of the current data
- * @parma pinfo
+ * @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
@@ -4841,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;
@@ -4872,6 +4865,7 @@ static gint ett_bacapp_list = -1;
 static gint ett_bacapp_value = -1;
 
 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;
@@ -5096,7 +5090,7 @@ register_bacapp_stat_trees(void)
         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, const gchar *data)
 {
@@ -5350,24 +5344,26 @@ fTagHeaderTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
     if (tree) {
         proto_tree *subtree;
-        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);
+        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 */
-        subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
         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,
@@ -5402,10 +5398,10 @@ fTagHeaderTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                 tvb, lvt_offset, lvt_len, *lvt);
     } /* if (tree) */
 
-    if (*lvt > tvb_length(tvb)) {
+    if (*lvt > tvb_reported_length(tvb)) {
         expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
                                "LVT length too long: %d > %d", *lvt,
-                               tvb_length(tvb));
+                               tvb_reported_length(tvb));
         *lvt = 1;
     }
 
@@ -5900,7 +5896,7 @@ fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset,
     offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
 
     if (lvt > 0) {
-        tmp = tvb_bytes_to_ep_str(tvb, offset, lvt);
+        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;
@@ -5920,27 +5916,20 @@ fMacAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, c
 
     offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt);
 
-    subtree = proto_tree_add_subtree(tree, tvb, offset, 6, ett_bacapp_tag, NULL, label); /* just add the label, with the tagHeader information in its subtree */
-
-    if (lvt > 0) {
-        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_ep_str(tvb, offset, lvt));
-            }
-        }
-        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 (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, pinfo, subtree, start, &tag_no, &tag_info, &lvt);
 
@@ -6300,7 +6289,7 @@ fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offs
 {
     guint8      tag_no, tag_info, character_set;
     guint32     lvt, l;
-    guint       offs, extra = 1;
+    guint       offs;
     const char *coding;
     guint8     *out;
     proto_tree *subtree;
@@ -6309,14 +6298,17 @@ fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offs
     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--;
 
-        character_set = tvb_get_guint8(tvb, offset+offs);
         /* Account for code page if DBCS */
-        if (character_set == 1) {
-            extra = 3;
+        if (character_set == IBM_MS_DBCS) {
+            offset += 2;
+            lvt -= 2;
         }
-        offset += (offs+extra);
-        lvt -= (extra);
 
         do {
             l = MIN(lvt, 256);
@@ -6377,8 +6369,8 @@ fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offs
         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 == 1) {
-            proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
+        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 */
     }
@@ -7042,14 +7034,14 @@ fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset
         offset += fTagHeaderTree(tvb, pinfo, tree, offset,
                                  &tag_no, &tag_info, &lvt);
         offset  = fAbstractSyntaxNType(tvb, pinfo, tree, offset);
-        if (tvb_length_remaining(tvb, offset) > 0) {
+        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_length(tvb) - offset,
+        proto_tree_add_text(tree, tvb, offset, tvb_reported_length(tvb) - offset,
                             "expected Opening Tag!");
-        offset = tvb_length(tvb);
+        offset = tvb_reported_length(tvb);
     }
 
     return offset;
@@ -7130,9 +7122,9 @@ fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                 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);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         case 5: /* covIncrement */
             offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: ");
@@ -7284,19 +7276,18 @@ fVendorIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
 
     tag_len = fTagHeader(tvb, pinfo, 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)",
+        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
-        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);
+        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_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
+        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;
     }
@@ -7320,17 +7311,16 @@ fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset
 
     tag_len = fTagHeader(tvb, pinfo, 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,
+        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
-        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);
+        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_tree_add_expert_format(tree, pinfo, &ei_bacapp_bad_length, tvb, 0, lvt,
+        expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length,
                                 "Wrong length indicated. Expected 1, got %u", lvt);
         return offset+tag_len+lvt;
     }
@@ -7405,7 +7395,7 @@ fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
     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);
+        offset += tvb_reported_length(next_tvb);
         return offset;
     }
 
@@ -7439,9 +7429,9 @@ fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
                         ett_bacapp_value, NULL, "service Parameters");
                 propertyIdentifier = -1;
                 offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         default:
             return offset;
@@ -8090,6 +8080,26 @@ fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gui
         }
         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:
@@ -8861,9 +8871,9 @@ fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
                 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);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         default:
             return offset;
@@ -9147,9 +9157,9 @@ fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin
                 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);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         default:
             return offset;
@@ -9440,9 +9450,9 @@ fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree
             if (tag_is_opening(tag_info)) {
                 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
                 offset  = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         default:
             return offset;
@@ -9633,23 +9643,15 @@ fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offs
 {
     guint8 tag_no, tag_info;
     guint32 lvt;
-    guint lastoffset = 0, len;
-    gboolean closing_found = FALSE;  /* tracks when we are done decoding the fSpecialEvent entries */
+    guint lastoffset = 0;
 
     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 SEQUENCE of SpecialEvents if we spot a closing tag */
+        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)) {
-            /* 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;
+            break;
         }
-
         switch (tag_no) {
         case 0: /* calendarEntry */
             if (tag_is_opening(tag_info)) {
@@ -9666,9 +9668,9 @@ fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offs
                 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);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         case 3: /* eventPriority */
             offset = fUnsignedTag(tvb, pinfo, subtree, offset, "event priority: ");
@@ -9676,7 +9678,6 @@ fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, guint offs
         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;
@@ -9747,9 +9748,9 @@ fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree,
                 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);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         default:
             return offset;
@@ -9854,9 +9855,9 @@ fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
             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);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         case 2: /* propertyIdentifier */
             offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2);
@@ -9867,9 +9868,9 @@ fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
                 offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt);
                 /* Error Code follows */
                 offset  = fError(tvb, pinfo, subtree, offset);
-                break;
+            } else {
+                expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
             }
-            FAULT;
             break;
         default:
             return offset;
@@ -9917,9 +9918,9 @@ fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, gui
             case 1: /* propertyValue */
                 if (tag_is_opening(tag_info)) {
                     offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset);
-                    break;
+                } else {
+                    expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag);
                 }
-                FAULT;
                 break;
             default:
                 break;
@@ -11073,6 +11074,12 @@ bacapp_init_routine(void)
                           &addresses_reassembly_table_functions);
 }
 
+static void
+bacapp_cleanup_routine(void)
+{
+    reassembly_table_destroy(&msg_reassembly_table);
+}
+
 void
 proto_register_bacapp(void)
 {
@@ -11199,6 +11206,12 @@ proto_register_bacapp(void)
             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 }
@@ -11271,6 +11284,7 @@ proto_register_bacapp(void)
 
     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;
@@ -11284,6 +11298,7 @@ proto_register_bacapp(void)
     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",