CIP Motion: Connection Configuration Data
1. Dissect the Motion Configuration Block from the Forward Open 2. Add Motion Attributes related to #1 3. Save the first/last segment for certain segment types in an EPATH. Behavior changes based on the values in first segments for a given type, vs later segments. Change-Id: Id0552a585d158041c13adfa50f4bb164cada79b7 Reviewed-on: https://code.wireshark.org/review/37168 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
256cc1a85c
commit
da8c28dc67
|
@ -535,7 +535,6 @@ static gint ett_path_seg = -1;
|
|||
static gint ett_mcsc = -1;
|
||||
static gint ett_cia_path = -1;
|
||||
static gint ett_data_seg = -1;
|
||||
static gint ett_data_seg_data = -1;
|
||||
static gint ett_port_path = -1;
|
||||
static gint ett_network_seg = -1;
|
||||
static gint ett_network_seg_safety = -1;
|
||||
|
@ -3886,7 +3885,7 @@ attribute_info_t* cip_get_attribute(guint class_id, guint instance, guint attrib
|
|||
{
|
||||
pattr = &att_array->attrs[j];
|
||||
if ((pattr->class_id == class_id) &&
|
||||
(instance != (guint)-1) &&
|
||||
(instance != SEGMENT_VALUE_NOT_SET) &&
|
||||
(((instance == 0) && (pattr->class_instance == TRUE)) || ((instance != 0) && (pattr->class_instance == FALSE))) &&
|
||||
(pattr->attribute == attribute))
|
||||
{
|
||||
|
@ -4701,15 +4700,15 @@ static int dissect_segment_safety(packet_info* pinfo, tvbuff_t* tvb, int offset,
|
|||
return segment_len;
|
||||
}
|
||||
|
||||
static int dissect_segment_data_simple(tvbuff_t* tvb, int offset, gboolean generate,
|
||||
proto_tree* path_seg_tree, proto_item* path_seg_item)
|
||||
static int dissect_segment_data_simple(packet_info* pinfo, tvbuff_t* tvb, int offset, gboolean generate,
|
||||
proto_tree* path_seg_tree, proto_item* path_seg_item, cip_simple_request_info_t* req_data)
|
||||
{
|
||||
/* Segment size */
|
||||
guint16 seg_size = tvb_get_guint8(tvb, offset + 1) * 2;
|
||||
int segment_len = seg_size + 2;
|
||||
|
||||
if (generate)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(path_seg_tree, hf_cip_data_seg_size_simple, tvb, 0, 0, seg_size);
|
||||
proto_item* it = proto_tree_add_uint(path_seg_tree, hf_cip_data_seg_size_simple, tvb, 0, 0, seg_size / 2);
|
||||
proto_item_set_generated(it);
|
||||
}
|
||||
else
|
||||
|
@ -4717,24 +4716,32 @@ static int dissect_segment_data_simple(tvbuff_t* tvb, int offset, gboolean gener
|
|||
proto_tree_add_item(path_seg_tree, hf_cip_data_seg_size_simple, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
if (generate)
|
||||
{
|
||||
return segment_len;
|
||||
}
|
||||
|
||||
/* Segment data */
|
||||
if (seg_size != 0 && generate == FALSE)
|
||||
if (seg_size != 0)
|
||||
{
|
||||
proto_item* ds_data_item;
|
||||
proto_tree* ds_data_tree = proto_tree_add_subtree(path_seg_tree, tvb, offset + 2, 0, ett_data_seg_data, &ds_data_item, "Data");
|
||||
int parsed_data_len = 0;
|
||||
if (req_data && req_data->iClass == CI_CLS_MOTION
|
||||
&& req_data->iConnPointA != SEGMENT_VALUE_NOT_SET
|
||||
&& req_data->iConnPoint != SEGMENT_VALUE_NOT_SET)
|
||||
{
|
||||
parsed_data_len += dissect_motion_configuration_block(tvb, pinfo, path_seg_tree, path_seg_item, offset + 2);
|
||||
}
|
||||
|
||||
for (int i = 0; i < seg_size / 2; i++)
|
||||
proto_tree_add_item(ds_data_tree, hf_cip_data_seg_item, tvb, offset + 2 + (i * 2), 2, ENC_LITTLE_ENDIAN);
|
||||
|
||||
proto_item_set_len(ds_data_item, seg_size);
|
||||
int remaining_data_len = seg_size - parsed_data_len;
|
||||
if (remaining_data_len > 0)
|
||||
{
|
||||
proto_tree_add_item(path_seg_tree, hf_cip_data_seg_item, tvb, offset + 2 + parsed_data_len, remaining_data_len, ENC_NA);
|
||||
}
|
||||
}
|
||||
|
||||
if (generate == FALSE)
|
||||
{
|
||||
proto_item_set_len(path_seg_item, 2 + seg_size);
|
||||
}
|
||||
proto_item_set_len(path_seg_item, segment_len);
|
||||
|
||||
return 2 + seg_size;
|
||||
return segment_len;
|
||||
}
|
||||
|
||||
static int dissect_segment_ansi_extended_symbol(packet_info* pinfo, tvbuff_t* tvb, int offset,
|
||||
|
@ -5077,15 +5084,28 @@ int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, pr
|
|||
switch (logical_seg_type)
|
||||
{
|
||||
case CI_LOGICAL_SEG_CLASS_ID:
|
||||
{
|
||||
guint32 ClassID;
|
||||
segment_len = dissect_cia(tvb, offset, segment_type, generate, packed, pinfo,
|
||||
epath_item, path_seg_tree, path_seg_item, &cia_ret_item,
|
||||
"Class", cip_class_names_vals, (req_data == NULL) ? NULL : &req_data->iClass,
|
||||
"Class", cip_class_names_vals, &ClassID,
|
||||
hf_cip_class8, hf_cip_class16, hf_cip_class32);
|
||||
if (segment_len == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req_data)
|
||||
{
|
||||
req_data->iClass = ClassID;
|
||||
|
||||
// Save the first ClassID separately.
|
||||
if (req_data->iClassA == SEGMENT_VALUE_NOT_SET)
|
||||
{
|
||||
req_data->iClassA = ClassID;
|
||||
}
|
||||
}
|
||||
|
||||
if (req_data != NULL)
|
||||
{
|
||||
if (cip_enhanced_info_column == TRUE && is_msp_item == FALSE)
|
||||
|
@ -5100,13 +5120,33 @@ int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, pr
|
|||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CI_LOGICAL_SEG_INST_ID:
|
||||
{
|
||||
guint32 InstanceID;
|
||||
segment_len = dissect_cia(tvb, offset, segment_type, generate, packed, pinfo,
|
||||
epath_item, path_seg_tree, path_seg_item, &cia_ret_item,
|
||||
"Instance", NULL, (req_data == NULL) ? NULL : &req_data->iInstance,
|
||||
"Instance", NULL, &InstanceID,
|
||||
hf_cip_instance8, hf_cip_instance16, hf_cip_instance32);
|
||||
if (segment_len == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req_data)
|
||||
{
|
||||
req_data->iInstance = InstanceID;
|
||||
|
||||
// Save the first InstanceID separately.
|
||||
if (req_data->iInstanceA == SEGMENT_VALUE_NOT_SET)
|
||||
{
|
||||
req_data->iInstanceA = InstanceID;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CI_LOGICAL_SEG_MBR_ID:
|
||||
segment_len = dissect_cia(tvb, offset, segment_type, generate, packed, pinfo,
|
||||
|
@ -5138,11 +5178,30 @@ int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, pr
|
|||
break;
|
||||
|
||||
case CI_LOGICAL_SEG_CON_POINT:
|
||||
{
|
||||
guint32 ConnPoint;
|
||||
segment_len = dissect_cia(tvb, offset, segment_type, generate, packed, pinfo,
|
||||
epath_item, path_seg_tree, path_seg_item, &cia_ret_item,
|
||||
"Connection Point", NULL, (req_data == NULL) ? NULL : &req_data->iConnPoint,
|
||||
hf_cip_conpoint8, hf_cip_conpoint16, hf_cip_conpoint32);
|
||||
epath_item, path_seg_tree, path_seg_item, &cia_ret_item,
|
||||
"Connection Point", NULL, &ConnPoint,
|
||||
hf_cip_conpoint8, hf_cip_conpoint16, hf_cip_conpoint32);
|
||||
if (segment_len == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req_data)
|
||||
{
|
||||
req_data->iConnPoint = ConnPoint;
|
||||
|
||||
// Save the first ConnPoint separately.
|
||||
if (req_data->iConnPointA == SEGMENT_VALUE_NOT_SET)
|
||||
{
|
||||
req_data->iConnPointA = ConnPoint;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CI_LOGICAL_SEG_SPECIAL:
|
||||
segment_len = dissect_segment_logical_special(pinfo, tvb, offset, generate,
|
||||
|
@ -5187,7 +5246,7 @@ int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, pr
|
|||
switch( segment_type & CI_DATA_SEG_TYPE_MASK)
|
||||
{
|
||||
case CI_DATA_SEG_SIMPLE:
|
||||
segment_len = dissect_segment_data_simple(tvb, offset, generate, path_seg_tree, path_seg_item);
|
||||
segment_len = dissect_segment_data_simple(pinfo, tvb, offset, generate, path_seg_tree, path_seg_item, req_data);
|
||||
proto_item_append_text(epath_item, "[Data]" );
|
||||
break;
|
||||
|
||||
|
@ -5241,12 +5300,17 @@ int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, pr
|
|||
|
||||
void reset_cip_request_info(cip_simple_request_info_t* req_data)
|
||||
{
|
||||
// All code relies on the fact that if something is (-1), then it's not defined yet.
|
||||
req_data->iClass = (guint32)-1;
|
||||
req_data->iInstance = (guint32)-1;
|
||||
req_data->iAttribute = (guint32)-1;
|
||||
req_data->iMember = (guint32)-1;
|
||||
req_data->iConnPoint = (guint32)-1;
|
||||
req_data->iClass = SEGMENT_VALUE_NOT_SET;
|
||||
req_data->iClassA = SEGMENT_VALUE_NOT_SET;
|
||||
|
||||
req_data->iInstance = SEGMENT_VALUE_NOT_SET;
|
||||
req_data->iInstanceA = SEGMENT_VALUE_NOT_SET;
|
||||
|
||||
req_data->iAttribute = SEGMENT_VALUE_NOT_SET;
|
||||
req_data->iMember = SEGMENT_VALUE_NOT_SET;
|
||||
|
||||
req_data->iConnPoint = SEGMENT_VALUE_NOT_SET;
|
||||
req_data->iConnPointA = SEGMENT_VALUE_NOT_SET;
|
||||
}
|
||||
|
||||
void dissect_epath(tvbuff_t *tvb, packet_info *pinfo, proto_tree *path_tree, proto_item *epath_item, int offset, int path_length,
|
||||
|
@ -6455,6 +6519,7 @@ dissect_cip_cm_fwd_open_req(cip_req_info_t *preq_info, proto_tree *cmd_tree, tvb
|
|||
preq_info->connInfo->O2T.type = O2TType;
|
||||
preq_info->connInfo->safety = safety_fwdopen;
|
||||
preq_info->connInfo->ClassID = connection_path.iClass;
|
||||
// The 2nd Connection Point defines the Motion I/O Format.
|
||||
preq_info->connInfo->ConnPoint = connection_path.iConnPoint;
|
||||
|
||||
preq_info->connInfo->FwdOpenPathLenBytes = conn_path_size;
|
||||
|
@ -7737,7 +7802,7 @@ dissect_cip_cco_data( proto_tree *item_tree, proto_item *ti, tvbuff_t *tvb, int
|
|||
{
|
||||
/* Success responses */
|
||||
if (((service & CIP_SC_MASK) == SC_GET_ATT_ALL) &&
|
||||
(req_data.iInstance != (guint32)-1))
|
||||
(req_data.iInstance != SEGMENT_VALUE_NOT_SET))
|
||||
{
|
||||
if (req_data.iInstance == 0)
|
||||
{
|
||||
|
@ -7801,7 +7866,7 @@ dissect_cip_cco_data( proto_tree *item_tree, proto_item *ti, tvbuff_t *tvb, int
|
|||
break;
|
||||
case SC_SET_ATT_ALL:
|
||||
if ((req_data.iInstance == 0) ||
|
||||
(req_data.iInstance == (guint32)-1))
|
||||
(req_data.iInstance == SEGMENT_VALUE_NOT_SET))
|
||||
{
|
||||
/* Just add raw data */
|
||||
proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+2+req_path_size, item_length-req_path_size-2, ENC_NA);
|
||||
|
@ -8248,7 +8313,7 @@ proto_register_cip(void)
|
|||
{ &hf_cip_data_seg_type, { "Data Segment Type", "cip.data_segment.type", FT_UINT8, BASE_DEC, VALS(cip_data_segment_type_vals), CI_DATA_SEG_TYPE_MASK, NULL, HFILL }},
|
||||
{ &hf_cip_data_seg_size_simple, { "Data Size", "cip.data_segment.size", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, &units_word_words, 0, NULL, HFILL }},
|
||||
{ &hf_cip_data_seg_size_extended, { "Data Size", "cip.data_segment.size", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, &units_byte_bytes, 0, NULL, HFILL } },
|
||||
{ &hf_cip_data_seg_item, { "Data", "cip.data_segment.data", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
|
||||
{ &hf_cip_data_seg_item, { "Data", "cip.data_segment.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
|
||||
{ &hf_cip_symbol, { "ANSI Symbol", "cip.symbol", FT_STRING, BASE_NONE, NULL, 0, "ANSI Extended Symbol Segment", HFILL }},
|
||||
{ &hf_cip_symbol_size, { "Symbolic Symbol Size", "cip.symbol.size", FT_UINT8, BASE_DEC, NULL, 0x1F, NULL, HFILL } },
|
||||
{ &hf_cip_symbol_ascii, { "ASCII Symbol", "cip.ascii_symbol", FT_STRING, BASE_NONE, NULL, 0, "ASCII Symbol Segment", HFILL } },
|
||||
|
@ -8660,7 +8725,6 @@ proto_register_cip(void)
|
|||
&ett_mcsc,
|
||||
&ett_cia_path,
|
||||
&ett_data_seg,
|
||||
&ett_data_seg_data,
|
||||
&ett_cmd_data,
|
||||
&ett_port_path,
|
||||
&ett_network_seg,
|
||||
|
|
|
@ -397,11 +397,24 @@
|
|||
{ SC_REMOVE_MEMBER, "Remove Member" }, \
|
||||
{ SC_GROUP_SYNC, "Group Sync" }, \
|
||||
|
||||
#define SEGMENT_VALUE_NOT_SET ((guint32)-1)
|
||||
typedef struct cip_simple_request_info {
|
||||
// First Class ID
|
||||
guint32 iClassA;
|
||||
// Last Class ID
|
||||
guint32 iClass;
|
||||
|
||||
// First Instance ID
|
||||
guint32 iInstanceA;
|
||||
// Last Instance ID
|
||||
guint32 iInstance;
|
||||
|
||||
guint32 iAttribute;
|
||||
guint32 iMember;
|
||||
|
||||
// First Connection Point
|
||||
guint32 iConnPointA;
|
||||
// Last Connection Point
|
||||
guint32 iConnPoint;
|
||||
} cip_simple_request_info_t;
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ static int proto_cipmotion3 = -1;
|
|||
static int hf_cip_format = -1;
|
||||
static int hf_cip_revision = -1;
|
||||
static int hf_cip_class1_seqnum = -1;
|
||||
static int hf_configuration_block_format_rev = -1;
|
||||
static int hf_configuration_block_drive_power_struct_id = -1;
|
||||
static int hf_cip_updateid = -1;
|
||||
static int hf_cip_instance_cnt = -1;
|
||||
static int hf_cip_last_update = -1;
|
||||
|
@ -67,6 +69,12 @@ static int hf_cip_motor_cntrl = -1;
|
|||
static int hf_cip_feedback = -1;
|
||||
static int hf_cip_feedback_mode = -1;
|
||||
static int hf_cip_feedback_data_type = -1;
|
||||
|
||||
static int hf_connection_configuration_bits = -1;
|
||||
static int hf_connection_configuration_bits_power = -1;
|
||||
static int hf_connection_configuration_bits_safety_bit_valid = -1;
|
||||
static int hf_connection_configuration_bits_allow_network_safety = -1;
|
||||
|
||||
static int hf_cip_axis_control = -1;
|
||||
static int hf_cip_control_status = -1;
|
||||
static int hf_cip_control_status_complete = -1;
|
||||
|
@ -271,6 +279,7 @@ static gint ett_time_data_set = -1;
|
|||
static gint ett_inst_data_header = -1;
|
||||
static gint ett_cyclic_data_block = -1;
|
||||
static gint ett_feedback_mode = -1;
|
||||
static gint ett_connection_configuration_bits = -1;
|
||||
static gint ett_control_mode = -1;
|
||||
static gint ett_feedback_config = -1;
|
||||
static gint ett_command_data_set = -1;
|
||||
|
@ -290,6 +299,7 @@ static gint ett_set_cyclic_list = -1;
|
|||
static gint ett_group_sync = -1;
|
||||
static gint ett_axis_status_set = -1;
|
||||
static gint ett_command_control = -1;
|
||||
static gint ett_configuration_block = -1;
|
||||
|
||||
static expert_field ei_format_rev_conn_pt = EI_INIT;
|
||||
|
||||
|
@ -768,10 +778,27 @@ static int dissect_feedback_mode(packet_info *pinfo _U_, proto_tree *tree, proto
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int dissect_connection_configuration_bits(packet_info* pinfo _U_, proto_tree* tree, proto_item* item _U_, tvbuff_t* tvb,
|
||||
int offset, int total_len _U_)
|
||||
{
|
||||
static const int* bits[] = {
|
||||
&hf_connection_configuration_bits_power,
|
||||
&hf_connection_configuration_bits_safety_bit_valid,
|
||||
&hf_connection_configuration_bits_allow_network_safety,
|
||||
NULL
|
||||
};
|
||||
|
||||
proto_tree_add_bitmask(tree, tvb, offset, hf_connection_configuration_bits, ett_connection_configuration_bits, bits, ENC_LITTLE_ENDIAN);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
attribute_info_t cip_motion_attribute_vals[] = {
|
||||
{ CI_CLS_MOTION, CIP_ATTR_CLASS, 14, -1, "Node Control", cip_dissector_func, NULL, dissect_node_control },
|
||||
{ CI_CLS_MOTION, CIP_ATTR_CLASS, 15, -1, "Node Status", cip_dissector_func, NULL, dissect_node_status },
|
||||
{ CI_CLS_MOTION, CIP_ATTR_CLASS, 31, -1, "Time Data Set", cip_dissector_func, NULL, dissect_time_data_set },
|
||||
{ CI_CLS_MOTION, CIP_ATTR_CLASS, 34, -1, "Drive Power Structure Class ID", cip_udint, &hf_configuration_block_drive_power_struct_id, NULL },
|
||||
{ CI_CLS_MOTION, CIP_ATTR_CLASS, 36, -1, "Connection Configuration Bits", cip_dissector_func, NULL, dissect_connection_configuration_bits },
|
||||
{ CI_CLS_MOTION, CIP_ATTR_INSTANCE, 40, -1, "Control Mode", cip_usint, &hf_cip_motor_cntrl, NULL },
|
||||
{ CI_CLS_MOTION, CIP_ATTR_INSTANCE, 42, -1, "Feedback Mode", cip_dissector_func, NULL, dissect_feedback_mode },
|
||||
{ CI_CLS_MOTION, CIP_ATTR_INSTANCE, 60, -1, "Event Checking Control", cip_dissector_func, NULL, dissect_event_checking_control },
|
||||
|
@ -2152,6 +2179,27 @@ static int dissect_cipmotion3(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tre
|
|||
return dissect_cipmotion(tvb, pinfo, tree, &io_data_input);
|
||||
}
|
||||
|
||||
int dissect_motion_configuration_block(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, proto_item* item, int offset)
|
||||
{
|
||||
proto_item* config_item;
|
||||
proto_tree* config_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_configuration_block, &config_item, "Motion Configuration Block");
|
||||
|
||||
proto_tree_add_item(config_tree, hf_configuration_block_format_rev, tvb, offset, 1, ENC_LITTLE_ENDIAN);
|
||||
int parsed_len = 1;
|
||||
|
||||
parsed_len += dissect_connection_configuration_bits(pinfo, config_tree, item, tvb, offset + parsed_len, 1);
|
||||
|
||||
// 2 reserved bytes
|
||||
parsed_len += 2;
|
||||
|
||||
proto_tree_add_item(config_tree, hf_configuration_block_drive_power_struct_id, tvb, offset + parsed_len, 4, ENC_LITTLE_ENDIAN);
|
||||
parsed_len += 4;
|
||||
|
||||
proto_item_set_len(config_item, parsed_len);
|
||||
|
||||
return parsed_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function name: proto_register_cipmotion
|
||||
*
|
||||
|
@ -2189,6 +2237,19 @@ proto_register_cipmotion(void)
|
|||
FT_UINT16, BASE_DEC, NULL, 0,
|
||||
NULL, HFILL }
|
||||
},
|
||||
|
||||
{ &hf_configuration_block_format_rev,
|
||||
{ "Format Revision", "cipm.config.format_rev",
|
||||
FT_UINT8, BASE_DEC, NULL, 0,
|
||||
NULL, HFILL }
|
||||
},
|
||||
|
||||
{ &hf_configuration_block_drive_power_struct_id,
|
||||
{ "Drive Power Structure Class ID", "cipm.config.drive_class_id",
|
||||
FT_UINT32, BASE_DEC, NULL, 0,
|
||||
NULL, HFILL }
|
||||
},
|
||||
|
||||
{ &hf_cip_updateid,
|
||||
{ "Update Id", "cipm.updateid",
|
||||
FT_UINT8, BASE_DEC, NULL, 0,
|
||||
|
@ -2316,6 +2377,7 @@ proto_register_cipmotion(void)
|
|||
FT_UINT8, BASE_DEC, VALS(cip_motor_control_vals), 0,
|
||||
"Cyclic Data Block: Motor Control Mode", HFILL }
|
||||
},
|
||||
|
||||
{ &hf_cip_feedback,
|
||||
{ "Feedback Information", "cipm.feedback",
|
||||
FT_UINT8, BASE_HEX, NULL, 0,
|
||||
|
@ -2331,6 +2393,25 @@ proto_register_cipmotion(void)
|
|||
FT_UINT8, BASE_DEC, VALS(cip_feedback_type_vals), FEEDBACK_DATA_TYPE_BITS,
|
||||
NULL, HFILL }
|
||||
},
|
||||
|
||||
{ &hf_connection_configuration_bits,
|
||||
{ "Connection Configuration Bits", "cipm.ccb",
|
||||
FT_UINT8, BASE_DEC, NULL, 0,
|
||||
NULL, HFILL }
|
||||
},
|
||||
{ &hf_connection_configuration_bits_power,
|
||||
{ "Verify Power Ratings", "cipm.ccb.verify_power_ratings",
|
||||
FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x01,
|
||||
NULL, HFILL } },
|
||||
{ &hf_connection_configuration_bits_safety_bit_valid,
|
||||
{ "Networked Safety Bit Valid", "cipm.ccb.networked_safety_bit_valid",
|
||||
FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x02,
|
||||
NULL, HFILL } },
|
||||
{ &hf_connection_configuration_bits_allow_network_safety,
|
||||
{ "Allow Networked Safety", "cipm.ccb.allow_networked_safety",
|
||||
FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x04,
|
||||
NULL, HFILL } },
|
||||
|
||||
{ &hf_cip_axis_control,
|
||||
{ "Axis Control", "cipm.axisctrl",
|
||||
FT_UINT8, BASE_DEC, VALS(cip_axis_control_vals), 0,
|
||||
|
@ -3303,6 +3384,7 @@ proto_register_cipmotion(void)
|
|||
&ett_inst_data_header,
|
||||
&ett_cyclic_data_block,
|
||||
&ett_feedback_mode,
|
||||
&ett_connection_configuration_bits,
|
||||
&ett_control_mode,
|
||||
&ett_feedback_config,
|
||||
&ett_command_data_set,
|
||||
|
@ -3321,7 +3403,8 @@ proto_register_cipmotion(void)
|
|||
&ett_set_cyclic_list,
|
||||
&ett_group_sync,
|
||||
&ett_axis_status_set,
|
||||
&ett_command_control
|
||||
&ett_command_control,
|
||||
&ett_configuration_block
|
||||
};
|
||||
|
||||
static ei_register_info ei[] = {
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "packet-cip.h" // For attribute_info_t
|
||||
|
||||
extern attribute_info_t cip_motion_attribute_vals[18];
|
||||
extern int dissect_motion_configuration_block(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, proto_item* item, int offset);
|
||||
|
||||
extern attribute_info_t cip_motion_attribute_vals[20];
|
||||
|
||||
#endif /* PACKET_CIPMOTION_H */
|
||||
|
|
|
@ -1131,7 +1131,7 @@ dissect_cip_s_validator_data( proto_tree *item_tree,
|
|||
{
|
||||
/* Success responses */
|
||||
if (((service & CIP_SC_MASK) == SC_GET_ATT_ALL) &&
|
||||
(req_data.iInstance != (guint32)-1) &&
|
||||
(req_data.iInstance != SEGMENT_VALUE_NOT_SET) &&
|
||||
(req_data.iInstance != 0))
|
||||
{
|
||||
dissect_cip_get_attribute_all_rsp(tvb, pinfo, cmd_data_tree, offset + 4 + add_stat_size, &req_data);
|
||||
|
|
Loading…
Reference in New Issue