openSAFETY: CRC Maintenance, new CRC, new expert interface implemented. Bug 8847...
authormmann <mmann@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 26 Jun 2013 12:11:08 +0000 (12:11 +0000)
committermmann <mmann@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 26 Jun 2013 12:11:08 +0000 (12:11 +0000)
From Roland Knall

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@50166 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-opensafety.c
wsutil/crc16.c
wsutil/crc16.h

index 803cfc6684e6cad70cecf0b37e1ac7cf4370f302..8a434600264a9f292567b1eb7e0b20b7da8d9e19 100644 (file)
@@ -440,6 +440,18 @@ static gint ett_opensafety_sod_mapping = -1;
 static gint ett_opensafety_sender = -1;
 static gint ett_opensafety_receiver = -1;
 
+static expert_field ei_payload_length_not_positive = EI_INIT;
+static expert_field ei_payload_unknown_format = EI_INIT;
+static expert_field ei_crc_slimssdo_instead_of_spdo = EI_INIT;
+static expert_field ei_crc_frame_1_invalid = EI_INIT;
+static expert_field ei_crc_frame_1_valid_frame2_invalid = EI_INIT;
+static expert_field ei_message_unknown_type = EI_INIT;
+static expert_field ei_message_reassembly_size_differs_from_header = EI_INIT;
+static expert_field ei_message_spdo_address_invalid = EI_INIT;
+static expert_field ei_scmudid_autodetected = EI_INIT;
+static expert_field ei_scmudid_invalid_preference = EI_INIT;
+static expert_field ei_scmudid_unknown = EI_INIT;
+
 static int hf_oss_msg = -1;
 static int hf_oss_msg_direction = -1;
 static int hf_oss_msg_category = -1;
@@ -590,21 +602,6 @@ setup_dissector(void)
 void proto_register_opensafety(void);
 void proto_reg_handoff_opensafety(void);
 
-void opensafety_add_expert_note(packet_info *pinfo, proto_item *pi, int group, int severity, const char *format, ...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    expert_add_info_format(pinfo, pi, group, severity, format, ap);
-    va_end(ap);
-}
-
-#define opensafety_add_warning(pinf, pi, fmt) opensafety_add_expert_note (pinf, pi, PI_PROTOCOL, PI_WARN, fmt)
-#define opensafety_add_warning1(pinf, pi, fmt, arg1) opensafety_add_expert_note (pinf, pi, PI_PROTOCOL, PI_WARN, fmt, arg1)
-#define opensafety_add_error(pinf, pi, fmt) opensafety_add_expert_note (pinf, pi, PI_MALFORMED, PI_ERROR, fmt)
-#define opensafety_add_error1(pinf, pi, fmt, arg1, arg2, arg3) opensafety_add_expert_note (pinf, pi, PI_MALFORMED, PI_ERROR, fmt, arg1)
-#define opensafety_add_note(pinf, pi, fmt) opensafety_add_expert_note (pinf, pi, PI_UNDECODED, PI_NOTE, fmt)
-
 /* Conversation functions */
 
 /* This is defined by the specification. The Address field is 10 bits long, and the node with the number
@@ -623,10 +620,10 @@ void opensafety_add_expert_note(packet_info *pinfo, proto_item *pi, int group, i
         PROTO_ITEM_SET_GENERATED(psf_item); \
         if ( sdn > 0 ) \
         { \
-               psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn, "0x%04X", sdn); \
+            psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn, "0x%04X", sdn); \
         } else if ( sdn <= 0 ) { \
             psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn * -1, "0x%04X", sdn * -1); \
-            opensafety_add_note(pinfo, psf_item, "SCM UDID unknown, assuming 00 as first UDID octet" ); \
+            expert_add_info(pinfo, psf_item, &ei_scmudid_unknown ); \
         } \
         PROTO_ITEM_SET_GENERATED(psf_item); \
         }
@@ -642,10 +639,10 @@ void opensafety_add_expert_note(packet_info *pinfo, proto_item *pi, int group, i
         PROTO_ITEM_SET_GENERATED(psf_item); \
         if ( sdn > 0 ) \
         { \
-               psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn, "0x%04X", sdn); \
+            psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn, "0x%04X", sdn); \
         } else if ( sdn <= 0 ) { \
             psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn * -1, "0x%04X", sdn * -1); \
-            opensafety_add_note(pinfo, psf_item, "SCM UDID unknown, assuming 00 as first UDID octet" ); \
+            expert_add_info(pinfo, psf_item, &ei_scmudid_unknown ); \
         } \
         PROTO_ITEM_SET_GENERATED(psf_item); \
         }
@@ -778,7 +775,7 @@ static guint8 findSafetyFrame ( tvbuff_t * message_tvb, guint u_Offset, gboolean
                                     crcOffset = 1;
 
                                     if ( crc != 0x00 )
-                                        calcCrc = crc16_0x5935( bytes, b_Length + 4, 0 );
+                                        calcCrc = crc16_0x755B( bytes, b_Length + 4, 0 );
                                 } else {
                                     if ( crc != 0x00 )
                                         calcCrc = crc8_0x2F ( bytes, b_Length + 4, 0 );
@@ -953,7 +950,7 @@ static void dissect_ssdo_payload ( packet_info *pinfo, tvbuff_t *new_tvb, proto_
             item = proto_tree_add_item(ext_tree, hf_oss_ssdo_extpar_data, new_tvb, 16, dataLength - 16, ENC_NA );
 
             if ( ( dataLength - sodLength ) != 16 )
-                opensafety_add_error ( pinfo, item, "Reassembled message size differs from size in header!");
+                expert_add_info ( pinfo, item, &ei_message_reassembly_size_differs_from_header );
         }
     }
     else
@@ -1011,7 +1008,7 @@ static void dissect_ssdo_payload ( packet_info *pinfo, tvbuff_t *new_tvb, proto_
                                                                           sod_idx_names, "Unknown") );
 
                 if ( ssdoIndex < 0x1000 || ssdoIndex > 0xE7FF )
-                    opensafety_add_error ( pinfo, item, "Unknown payload format detected!" );
+                    expert_add_info ( pinfo, item, &ei_payload_unknown_format );
 
                 sod_tree = proto_item_add_subtree(item, ett_opensafety_ssdo_sodentry);
 
@@ -1295,7 +1292,8 @@ dissect_opensafety_ssdo_message(tvbuff_t *message_tvb , packet_info *pinfo, prot
                 {
                     proto_tree_add_item(ssdo_tree, hf_oss_ssdo_payload, message_tvb, payloadOffset, calcDataLength, ENC_NA );
                 } else {
-                    opensafety_add_warning1(pinfo, item, "Calculation for payload length yielded non-positive result [%d]", (guint) calcDataLength );
+                    expert_add_info_format_text(pinfo, item, &ei_payload_length_not_positive, 
+                                                "Calculation for payload length yielded non-positive result [%d]", (guint) calcDataLength );
                 }
             }
             else
@@ -1453,7 +1451,7 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
                 {
                     local_scm_udid = (char *)se_alloc0(18 * sizeof(char));
                     g_snprintf(local_scm_udid, 18, "%s", tempString );
-                    expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_NOTE, "Auto detected payload as SCM UDID [%s].", tempString);
+                    expert_add_info_format_text(pinfo, item, &ei_scmudid_autodetected, "Auto detected payload as SCM UDID [%s].", tempString);
                 }
             }
 
@@ -1536,7 +1534,7 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
 }
 
 static gboolean
-dissect_opensafety_checksum(tvbuff_t *message_tvb, proto_tree *opensafety_tree,
+dissect_opensafety_checksum(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *opensafety_tree,
                             guint16 frameStart1, guint16 frameStart2 )
 {
     guint16     frame1_crc, frame2_crc;
@@ -1565,7 +1563,15 @@ dissect_opensafety_checksum(tvbuff_t *message_tvb, proto_tree *opensafety_tree,
 
     bytes = (guint8*)ep_tvb_memdup(message_tvb, frameStart1, dataLength + 4);
     if ( dataLength > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 )
-        calc1_crc = crc16_0x5935(&bytes[frameStart1], dataLength + 4, 0);
+    {
+        calc1_crc = crc16_0x755B(&bytes[frameStart1], dataLength + 4, 0);
+        if ( frame1_crc != calc1_crc )
+        {
+            calc1_crc = crc16_0x5935(&bytes[frameStart1], dataLength + 4, 0);
+            if ( frame1_crc == calc1_crc )
+                expert_add_info(pinfo, item, &ei_crc_slimssdo_instead_of_spdo );
+        }
+    }
     else
         calc1_crc = crc8_0x2F(&bytes[frameStart1], dataLength + 4, 0);
 
@@ -1652,7 +1658,7 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
 
             item = proto_tree_add_boolean(opensafety_tree, hf_oss_scm_udid_valid, message_tvb, 0, 0, validSCMUDID);
             if ( scmUDID->len != 6 )
-                opensafety_add_warning(pinfo, item, "openSAFETY protocol settings are invalid! SCM UDID first octet will be assumed to be 00" );
+                expert_add_info(pinfo, item, &ei_scmudid_invalid_preference );
             PROTO_ITEM_SET_GENERATED(item);
 
             g_byte_array_free( scmUDID, TRUE);
@@ -1676,16 +1682,16 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
                                    message_tvb, OSS_FRAME_POS_LEN + frameStart1, 1, OSS_FRAME_LENGTH_T(message_tvb, frameStart1));
         if ( messageTypeUnknown )
         {
-            opensafety_add_error(pinfo, item, "Unknown openSAFETY message type" );
+            expert_add_info(pinfo, item, &ei_message_unknown_type );
         }
         else
         {
-            crcValid = dissect_opensafety_checksum ( message_tvb, opensafety_tree, frameStart1, frameStart2 );
+            crcValid = dissect_opensafety_checksum ( message_tvb, pinfo, opensafety_tree, frameStart1, frameStart2 );
         }
 
         if ( ! crcValid )
         {
-            opensafety_add_error(pinfo, opensafety_item, "Frame 1 CRC invalid => possible error in package" );
+            expert_add_info(pinfo, opensafety_item, &ei_crc_frame_1_invalid );
         }
 
         /* with SNMT's we can check if the ID's for the frames match. Rare randomized packages do have
@@ -1694,7 +1700,7 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
         if ( crcValid && type == OPENSAFETY_SNMT_MESSAGE_TYPE )
         {
             if ( OSS_FRAME_ID_T(message_tvb, frameStart1) != OSS_FRAME_ID_T(message_tvb, frameStart2) )
-                opensafety_add_error(pinfo, opensafety_item, "Frame 1 is valid, frame 2 id is invalid => error in openSAFETY frame" );
+                expert_add_info(pinfo, opensafety_item, &ei_crc_frame_1_valid_frame2_invalid );
         }
     }
 
@@ -1943,7 +1949,7 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
             if ( tree && markAsMalformed )
             {
                 if ( OSS_FRAME_ADDR_T(message_tvb, byte_offset + frameStart1) > 1024 )
-                    opensafety_add_error(pinfo, opensafety_item, "SPDO address is invalid" );
+                    expert_add_info(pinfo, opensafety_item, &ei_message_spdo_address_invalid );
             }
             handled = TRUE;
         }
@@ -2141,10 +2147,10 @@ proto_register_opensafety(void)
             { "SCM UDID Configured",    "opensafety.scm_udid",
             FT_STRING,   BASE_NONE, NULL,   0x0, NULL, HFILL } },
         { &hf_oss_scm_udid_auto,
-            { "SCM UDID Auto Detect",    "opensafety.scm_udid_auto",
+            { "SCM UDID Auto Detect",    "opensafety.scm_udid.auto",
             FT_STRING,   BASE_NONE, NULL,   0x0, NULL, HFILL } },
         { &hf_oss_scm_udid_valid,
-            { "SCM UDID Valid",    "opensafety.scm_udid_valid",
+            { "SCM UDID Valid",    "opensafety.scm_udid.valid",
             FT_BOOLEAN,   BASE_NONE, NULL,   0x0, NULL, HFILL } },
 
         { &hf_oss_msg,
@@ -2396,7 +2402,47 @@ proto_register_opensafety(void)
         &ett_opensafety_spdo,
     };
 
+    static ei_register_info ei[] = {
+        { &ei_crc_frame_1_invalid, 
+            { "opensafety.crc.error.frame1_invalid", PI_MALFORMED, PI_ERROR, 
+              "Frame 1 CRC invalid, Possible error in package", EXPFILL } },
+        { &ei_crc_frame_1_valid_frame2_invalid, 
+            { "opensafety.crc.error.frame1_valid_frame2_invalid", PI_MALFORMED, PI_ERROR, 
+              "Frame 1 is valid, frame 2 id is invalid", EXPFILL } },
+        { &ei_crc_slimssdo_instead_of_spdo, 
+            { "opensafety.crc.warning.wrong_crc_for_spdo", PI_PROTOCOL, PI_WARN, 
+              "Frame 1 SPDO CRC is Slim SSDO CRC16 0x5935", EXPFILL } },
+              
+        { &ei_message_reassembly_size_differs_from_header, 
+            { "opensafety.msg.warning.reassembly_size_fail", PI_PROTOCOL, PI_WARN, 
+              "Reassembled message size differs from size in header", EXPFILL } },
+        { &ei_message_unknown_type, 
+            { "opensafety.msg.error.unknown_type", PI_MALFORMED, PI_ERROR, 
+              "Unknown openSAFETY message type", EXPFILL } },
+        { &ei_message_spdo_address_invalid, 
+            { "opensafety.msg.error.spdo_address_invalid", PI_MALFORMED, PI_ERROR, 
+              "SPDO address is invalid", EXPFILL } },
+              
+        { &ei_scmudid_autodetected, 
+            { "opensafety.scm_udid.note.autodetected", PI_PROTOCOL, PI_NOTE, 
+              "Auto detected payload as SCM UDID", EXPFILL } },
+        { &ei_scmudid_invalid_preference, 
+            { "opensafety.scm_udid.note.invalid_preference", PI_PROTOCOL, PI_WARN, 
+              "openSAFETY protocol settings are invalid! SCM UDID first octet will be assumed to be 00", EXPFILL } },
+        { &ei_scmudid_unknown, 
+            { "opensafety.scm_udid.warning.assuming_first_octet", PI_PROTOCOL, PI_WARN, 
+              "SCM UDID unknown, assuming 00 as first UDID octet", EXPFILL } },
+              
+        { &ei_payload_unknown_format, 
+            { "opensafety.msg.warning.unknown_format", PI_PROTOCOL, PI_WARN, 
+              "Unknown payload format detected", EXPFILL } },
+        { &ei_payload_length_not_positive, 
+            { "opensafety.msg.warning.reassembly_length_not_positive", PI_PROTOCOL, PI_NOTE, 
+              "Calculation for payload length yielded non-positive result", EXPFILL } },
+    };
+    
     module_t *opensafety_module;
+    expert_module_t *expert_opensafety;
 
     /* Register the protocol name and description */
     proto_opensafety = proto_register_protocol("openSAFETY", "openSAFETY",  "opensafety");
@@ -2406,6 +2452,9 @@ proto_register_opensafety(void)
     proto_register_field_array(proto_opensafety, hf, array_length(hf));
     proto_register_subtree_array(ett, array_length(ett));
 
+    expert_opensafety = expert_register_protocol ( proto_opensafety );
+    expert_register_field_array ( expert_opensafety, ei, array_length (ei ) );
+    
     /* register user preferences */
     prefs_register_string_preference(opensafety_module, "scm_udid",
                  "SCM UDID (xx:xx:xx:xx:xx:xx)",
index f7a7a92b6644c1c39106f94a74445b2776107673..ea7a0c891d0e7e42b8caa8a59ecbc339e64dcaf0 100644 (file)
@@ -185,6 +185,42 @@ static const guint crc16_precompiled_5935[256] =
        0x65AA, 0x3C9F, 0xD7C0, 0x8EF5, 0x584B, 0x017E, 0xEA21, 0xB314
 };
 
+/* This table was compiled using the polynom 0x755B */
+static const guint crc16_precompiled_755B[] =
+{
+    0x0000, 0x755b, 0xeab6, 0x9fed, 0xa037, 0xd56c, 0x4a81, 0x3fda,     /* 0x00 */
+    0x3535, 0x406e, 0xdf83, 0xaad8, 0x9502, 0xe059, 0x7fb4, 0x0aef,     /* 0x08 */
+    0x6a6a, 0x1f31, 0x80dc, 0xf587, 0xca5d, 0xbf06, 0x20eb, 0x55b0,     /* 0x10 */
+    0x5f5f, 0x2a04, 0xb5e9, 0xc0b2, 0xff68, 0x8a33, 0x15de, 0x6085,     /* 0x18 */
+    0xd4d4, 0xa18f, 0x3e62, 0x4b39, 0x74e3, 0x01b8, 0x9e55, 0xeb0e,     /* 0x20 */
+    0xe1e1, 0x94ba, 0x0b57, 0x7e0c, 0x41d6, 0x348d, 0xab60, 0xde3b,     /* 0x28 */
+    0xbebe, 0xcbe5, 0x5408, 0x2153, 0x1e89, 0x6bd2, 0xf43f, 0x8164,     /* 0x30 */
+    0x8b8b, 0xfed0, 0x613d, 0x1466, 0x2bbc, 0x5ee7, 0xc10a, 0xb451,     /* 0x38 */
+    0xdcf3, 0xa9a8, 0x3645, 0x431e, 0x7cc4, 0x099f, 0x9672, 0xe329,     /* 0x40 */
+    0xe9c6, 0x9c9d, 0x0370, 0x762b, 0x49f1, 0x3caa, 0xa347, 0xd61c,     /* 0x48 */
+    0xb699, 0xc3c2, 0x5c2f, 0x2974, 0x16ae, 0x63f5, 0xfc18, 0x8943,     /* 0x50 */
+    0x83ac, 0xf6f7, 0x691a, 0x1c41, 0x239b, 0x56c0, 0xc92d, 0xbc76,     /* 0x58 */
+    0x0827, 0x7d7c, 0xe291, 0x97ca, 0xa810, 0xdd4b, 0x42a6, 0x37fd,     /* 0x60 */
+    0x3d12, 0x4849, 0xd7a4, 0xa2ff, 0x9d25, 0xe87e, 0x7793, 0x02c8,     /* 0x68 */
+    0x624d, 0x1716, 0x88fb, 0xfda0, 0xc27a, 0xb721, 0x28cc, 0x5d97,     /* 0x70 */
+    0x5778, 0x2223, 0xbdce, 0xc895, 0xf74f, 0x8214, 0x1df9, 0x68a2,     /* 0x78 */
+    0xccbd, 0xb9e6, 0x260b, 0x5350, 0x6c8a, 0x19d1, 0x863c, 0xf367,     /* 0x80 */
+    0xf988, 0x8cd3, 0x133e, 0x6665, 0x59bf, 0x2ce4, 0xb309, 0xc652,     /* 0x88 */
+    0xa6d7, 0xd38c, 0x4c61, 0x393a, 0x06e0, 0x73bb, 0xec56, 0x990d,     /* 0x90 */
+    0x93e2, 0xe6b9, 0x7954, 0x0c0f, 0x33d5, 0x468e, 0xd963, 0xac38,     /* 0x98 */
+    0x1869, 0x6d32, 0xf2df, 0x8784, 0xb85e, 0xcd05, 0x52e8, 0x27b3,     /* 0xA0 */
+    0x2d5c, 0x5807, 0xc7ea, 0xb2b1, 0x8d6b, 0xf830, 0x67dd, 0x1286,     /* 0xA8 */
+    0x7203, 0x0758, 0x98b5, 0xedee, 0xd234, 0xa76f, 0x3882, 0x4dd9,     /* 0xB0 */
+    0x4736, 0x326d, 0xad80, 0xd8db, 0xe701, 0x925a, 0x0db7, 0x78ec,     /* 0xB8 */
+    0x104e, 0x6515, 0xfaf8, 0x8fa3, 0xb079, 0xc522, 0x5acf, 0x2f94,     /* 0xC0 */
+    0x257b, 0x5020, 0xcfcd, 0xba96, 0x854c, 0xf017, 0x6ffa, 0x1aa1,     /* 0xC8 */
+    0x7a24, 0x0f7f, 0x9092, 0xe5c9, 0xda13, 0xaf48, 0x30a5, 0x45fe,     /* 0xD0 */
+    0x4f11, 0x3a4a, 0xa5a7, 0xd0fc, 0xef26, 0x9a7d, 0x0590, 0x70cb,     /* 0xD8 */
+    0xc49a, 0xb1c1, 0x2e2c, 0x5b77, 0x64ad, 0x11f6, 0x8e1b, 0xfb40,     /* 0xE0 */
+    0xf1af, 0x84f4, 0x1b19, 0x6e42, 0x5198, 0x24c3, 0xbb2e, 0xce75,     /* 0xE8 */
+    0xaef0, 0xdbab, 0x4446, 0x311d, 0x0ec7, 0x7b9c, 0xe471, 0x912a,     /* 0xF0 */
+    0x9bc5, 0xee9e, 0x7173, 0x0428, 0x3bf2, 0x4ea9, 0xd144, 0xa41f      /* 0xF8 */
+};
 
 static const guint16 crc16_ccitt_start = 0xFFFF;
 static const guint16 crc16_ccitt_xorout = 0xFFFF;
@@ -244,3 +280,8 @@ guint16 crc16_0x5935(const guint8 *buf, guint32 len, guint16 seed)
     return crc16_unreflected(buf, len, seed, crc16_precompiled_5935);
 }
 
+guint16 crc16_0x755B(const guint8 *buf, guint32 len, guint16 seed)
+{
+    return crc16_unreflected(buf, len, seed, crc16_precompiled_755B);
+}
+
index 3529a1af6c3347844197d67ae502c13b53944aca..351b049e9f84a815b967d78364b96be67a5bcd4b 100644 (file)
@@ -72,6 +72,15 @@ WS_DLL_PUBLIC guint16 crc16_ccitt_seed(const guint8 *buf, guint len, guint16 see
  */
 WS_DLL_PUBLIC guint16 crc16_0x5935(const guint8 *buf, guint32 len, guint16 seed);
 
+/** Calculates a CRC16 checksum for the given buffer with the polynom
+ *  0x755B using a precompiled CRC table
+ * @param pBuffer a pointer to a buffer of the given length
+ * @param len the length of the given buffer
+ * @param seed The seed to use.
+ * @return the CRC16 checksum for the buffer
+ */
+WS_DLL_PUBLIC guint16 crc16_0x755B(const guint8 *buf, guint32 len, guint16 seed);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */