aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorHannes Mezger <hannes.mezger@ascolab.com>2014-06-12 10:11:06 +0200
committerEvan Huus <eapache@gmail.com>2014-06-16 15:47:01 +0000
commit0bb0b62ec8580ab48c1e8c3eaa82b9fa255d7a4e (patch)
treece4d936e822589ae4b08fe83db3f5623383354b1 /plugins
parenta9b18eff0fe904c87c38262148b39718f6e3cea5 (diff)
Display status code info bits if set
Checks if a StatusCode has any of the additional info bits set and displays them accordingly. Change-Id: Ic584233083174d3fd30c6ec6684f308e0e5ae22e Reviewed-on: https://code.wireshark.org/review/2127 Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/opcua/opcua_simpletypes.c94
1 files changed, 92 insertions, 2 deletions
diff --git a/plugins/opcua/opcua_simpletypes.c b/plugins/opcua/opcua_simpletypes.c
index 0f105de774..a55a52cb32 100644
--- a/plugins/opcua/opcua_simpletypes.c
+++ b/plugins/opcua/opcua_simpletypes.c
@@ -49,6 +49,13 @@
#define DATAVALUE_ENCODINGBYTE_SERVERPICOSECONDS 0x20
#define EXTOBJ_ENCODINGMASK_BINBODY_FLAG 0x01
#define EXTOBJ_ENCODINGMASK_XMLBODY_FLAG 0x02
+#define STATUSCODE_STRUCTURECHANGED 0x8000
+#define STATUSCODE_SEMANTICSCHANGED 0x4000
+#define STATUSCODE_INFOTYPE_DATAVALUE 0x00000400
+#define STATUSCODE_INFOBIT_OVERFLOW 0x0080
+#define STATUSCODE_INFOBIT_HISTORIAN_PARTIAL 0x0004
+#define STATUSCODE_INFOBIT_HISTORIAN_EXTRADATA 0x0008
+#define STATUSCODE_INFOBIT_HISTORIAN_MULTIVALUE 0x0010
/* Chosen arbitrarily */
#define MAX_ARRAY_LEN 10000
@@ -93,6 +100,15 @@ static int hf_opcua_extobj_mask_binbodyflag = -1;
static int hf_opcua_extobj_mask_xmlbodyflag = -1;
static int hf_opcua_ArraySize = -1;
static int hf_opcua_ServerIndex = -1;
+static int hf_opcua_status_StructureChanged = -1;
+static int hf_opcua_status_SemanticsChanged = -1;
+static int hf_opcua_status_InfoBit_Limit_Overflow = -1;
+static int hf_opcua_status_InfoBit_Historian_Partial = -1;
+static int hf_opcua_status_InfoBit_Historian_ExtraData = -1;
+static int hf_opcua_status_InfoBit_Historian_MultiValue = -1;
+static int hf_opcua_status_InfoType = -1;
+static int hf_opcua_status_Limit = -1;
+static int hf_opcua_status_Historian = -1;
/** NodeId encoding mask table */
static const value_string g_nodeidmasks[] = {
@@ -105,6 +121,33 @@ static const value_string g_nodeidmasks[] = {
{ 0, NULL }
};
+/** StatusCode info types */
+static const value_string g_infotype[] = {
+ { 0x00, "Not used" },
+ { 0x01, "DataValue" },
+ { 0x02, "Reserved" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
+/** StatusCode Limit types */
+static const value_string g_limit[] = {
+ { 0x00, "None" },
+ { 0x01, "Low" },
+ { 0x02, "High" },
+ { 0x03, "Constant" },
+ { 0, NULL }
+};
+
+/** StatusCode Historian types */
+static const value_string g_historian[] = {
+ { 0x00, "Raw" },
+ { 0x01, "Calculated" },
+ { 0x02, "Interpolated" },
+ { 0x03, "Reserved" },
+ { 0, NULL }
+};
+
/** UA Variant Type enum */
typedef enum _OpcUa_BuiltInType
{
@@ -233,6 +276,8 @@ static gint ett_opcua_datavalue = -1;
static gint ett_opcua_variant = -1;
static gint ett_opcua_extensionobject = -1;
static gint ett_opcua_extobj_encodingmask = -1;
+static gint ett_opcua_statuscode = -1;
+static gint ett_opcua_statuscode_info = -1;
static gint *ett[] =
{
&ett_opcua_array,
@@ -244,7 +289,9 @@ static gint *ett[] =
&ett_opcua_datavalue,
&ett_opcua_variant,
&ett_opcua_extensionobject,
- &ett_opcua_extobj_encodingmask
+ &ett_opcua_extobj_encodingmask,
+ &ett_opcua_statuscode,
+ &ett_opcua_statuscode_info
};
void registerSimpleTypes(int proto)
@@ -311,7 +358,16 @@ void registerSimpleTypes(int proto)
{ &hf_opcua_extobj_mask_binbodyflag, { "has binary body", "opcua.has_binary_body", FT_BOOLEAN, 8, NULL, EXTOBJ_ENCODINGMASK_BINBODY_FLAG, NULL, HFILL } },
{ &hf_opcua_extobj_mask_xmlbodyflag, { "has xml body", "opcua.has_xml_body", FT_BOOLEAN, 8, NULL, EXTOBJ_ENCODINGMASK_XMLBODY_FLAG, NULL, HFILL } },
{ &hf_opcua_ArraySize, { "ArraySize", "opcua.ArraySize", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
- { &hf_opcua_ServerIndex, { "ServerIndex", "opcua.ServerIndex", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }
+ { &hf_opcua_ServerIndex, { "ServerIndex", "opcua.ServerIndex", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_opcua_status_StructureChanged, { "StructureChanged", "opcua.statuscode.structureChanged", FT_BOOLEAN, 16, NULL, STATUSCODE_STRUCTURECHANGED, NULL, HFILL } },
+ { &hf_opcua_status_SemanticsChanged, { "SemanticsChanged", "opcua.statuscode.semanticsChanged", FT_BOOLEAN, 16, NULL, STATUSCODE_SEMANTICSCHANGED, NULL, HFILL } },
+ { &hf_opcua_status_InfoBit_Limit_Overflow, { "Overflow", "opcua.statuscode.overflow", FT_BOOLEAN, 16, NULL, STATUSCODE_INFOBIT_OVERFLOW, NULL, HFILL } },
+ { &hf_opcua_status_InfoBit_Historian_Partial, { "HistorianBit: Partial", "opcua.statuscode.historian.partial", FT_BOOLEAN, 16, NULL, STATUSCODE_INFOBIT_HISTORIAN_PARTIAL, NULL, HFILL } },
+ { &hf_opcua_status_InfoBit_Historian_ExtraData, { "HistorianBit: ExtraData", "opcua.statuscode.historian.extraData", FT_BOOLEAN, 16, NULL, STATUSCODE_INFOBIT_HISTORIAN_EXTRADATA, NULL, HFILL } },
+ { &hf_opcua_status_InfoBit_Historian_MultiValue, { "HistorianBit: MultiValue", "opcua.statuscode.historian.multiValue", FT_BOOLEAN, 16, NULL, STATUSCODE_INFOBIT_HISTORIAN_MULTIVALUE, NULL, HFILL } },
+ { &hf_opcua_status_InfoType, { "InfoType", "opcua.statuscode.infoType", FT_UINT16, BASE_HEX, VALS(g_infotype), 0x0C00, NULL, HFILL } },
+ { &hf_opcua_status_Limit, { "Limit", "opcua.statuscode.limit", FT_UINT16, BASE_HEX, VALS(g_limit), 0x0300, NULL, HFILL } },
+ { &hf_opcua_status_Historian, { "Historian", "opcua.statuscode.historian", FT_UINT16, BASE_HEX, VALS(g_historian), 0x0003, NULL, HFILL } },
};
proto_register_field_array(proto, hf, array_length(hf));
@@ -410,6 +466,40 @@ void parseStatusCode(proto_tree *tree, tvbuff_t *tvb, gint *pOffset, int hfIndex
szStatusCode = val_to_str_const(uStatusCode & 0xFFFF0000, g_statusCodes, "Unknown Status Code");
proto_item_append_text(item, " [%s]", szStatusCode);
+ /* check for status code info flags */
+ if (uStatusCode & 0x0000FFFF)
+ {
+ gint iOffset = *pOffset;
+ proto_tree *flags_tree;
+ proto_item *ti_inner;
+
+ flags_tree = proto_item_add_subtree(item, ett_opcua_statuscode);
+
+ proto_tree_add_item(flags_tree, hf_opcua_status_StructureChanged, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_opcua_status_SemanticsChanged, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+ ti_inner = proto_tree_add_item(flags_tree, hf_opcua_status_InfoType, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+
+ switch (uStatusCode & 0x00000C00)
+ {
+ case STATUSCODE_INFOTYPE_DATAVALUE:
+ {
+ /* InfoType == DataValue */
+ proto_tree *tree_inner;
+
+ tree_inner = proto_item_add_subtree(ti_inner, ett_opcua_statuscode_info);
+
+ proto_tree_add_item(tree_inner, hf_opcua_status_Limit, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree_inner, hf_opcua_status_InfoBit_Limit_Overflow, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree_inner, hf_opcua_status_InfoBit_Historian_MultiValue, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree_inner, hf_opcua_status_InfoBit_Historian_ExtraData, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree_inner, hf_opcua_status_InfoBit_Historian_Partial, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree_inner, hf_opcua_status_Historian, tvb, iOffset, 2, ENC_LITTLE_ENDIAN);
+ }
+ default:
+ break;
+ }
+ }
+
*pOffset += 4;
}