1 /* packet-sercosiii_1v1_at.c
2 * Routines for SERCOS III dissection
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
33 #include "packet-sercosiii.h"
35 static gint ett_siii_at = -1;
36 static gint ett_siii_at_svc = -1;
37 static gint ett_siii_at_devstats = -1;
39 static gint ett_siii_at_svc_channel[MAX_SERCOS_DEVICES];
40 static gint ett_siii_at_dev_status[MAX_SERCOS_DEVICES];
42 static void dissect_siii_at_cp0(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
44 guint16 seqcnt; /* sequence counter */
45 guint16 tfield; /* topology field for sercos addresses */
47 char devices[]="Recognized Devices"; /* fixme: it would be nice to have this as subtree */
48 static char outbuf[200];
50 proto_tree_add_text(tree, tvb, 0, 1024, "%s", devices);
52 /* check sequence count field */
53 seqcnt = tvb_get_letohs(tvb, 0);
54 g_snprintf(outbuf, sizeof(outbuf), "Number of Devices: %u", (0x1FF & seqcnt)-1);
55 proto_tree_add_text(tree, tvb, 0, 2, "%s", outbuf);
57 /* check SERCOS address of each topology field */
58 for(i=1;i < MAX_SERCOS_DEVICES; ++i)
60 tfield = tvb_get_letohs(tvb, i*2);
64 g_snprintf(outbuf, sizeof(outbuf), "Device Address %u: No SERCOS Address", i);
66 else if(tfield == 0xFFFF)
68 g_snprintf(outbuf, sizeof(outbuf), "Device Address %u: No Device", i);
72 g_snprintf(outbuf, sizeof(outbuf), "Device Address %u: %u", i, tfield);
74 proto_tree_add_text(tree, tvb, i*2, 2, "%s", outbuf);
78 static void dissect_siii_at_cp1_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint telno)
80 guint devstart = telno * 128; /* AT0: slaves 0-127; AT1: slaves 128-255; ... */
85 proto_item* ti; /* temporary item */
87 proto_tree* subtree_svc;
88 proto_tree* subtree_devstat;
90 ti = proto_tree_add_text(tree, tvb, 0, 128 * 6, "Service Channel");
91 subtree_svc = proto_item_add_subtree(ti, ett_siii_at_svc);
93 ti = proto_tree_add_text(tree, tvb, 128 * 6, 512, "Device Status");
94 subtree_devstat = proto_item_add_subtree(ti, ett_siii_at_devstats);
96 for(idx = 0; idx < 128; ++idx) /* each AT of CP1/2 has data of 128 different slaves */
98 tvb_n = tvb_new_subset(tvb, 6 * idx, 6, 6); /* subset for service channel data */
100 ti = proto_tree_add_text(subtree_svc, tvb_n, 0, 6, "Device %u", idx + devstart);
101 subtree = proto_item_add_subtree(ti, ett_siii_at_svc_channel[idx]);
102 dissect_siii_at_svc(tvb_n, pinfo, subtree, idx + devstart);
104 tvb_n = tvb_new_subset(tvb, 128 * 6 + 4 * idx, 2, 2); /* subset for device status information */
106 ti = proto_tree_add_text(subtree_devstat, tvb_n, 0, 2, "Device %u", idx + devstart);
107 subtree = proto_item_add_subtree(ti, ett_siii_at_dev_status[idx]);
108 dissect_siii_at_devstat(tvb_n, pinfo, subtree);
112 static void dissect_siii_at_cp3_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint telno)
115 proto_tree* subtree_svc;
116 proto_tree* subtree_devstat;
118 if(0 == telno) /* dissect hotplug field in AT0 only */
119 dissect_siii_at_hp(tvb, pinfo, tree);
121 /* offsets of service channel, device status and connections are unknown
122 * this data could be extracted from svc communication during CP2
124 ti = proto_tree_add_text(tree, tvb, 0, 0, "Service Channels");
125 subtree_svc = proto_item_add_subtree(ti, ett_siii_at_svc);
127 ti = proto_tree_add_text(tree, tvb, 0, 0, "Device Status");
128 subtree_devstat = proto_item_add_subtree(ti, ett_siii_at_devstats);
132 void dissect_siii_at(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
134 proto_item* ti; /* temporary item */
141 phase = (tvb_get_guint8(tvb, 1)&0x8F); /* read communication phase out of SERCOS III header*/
142 telno = (tvb_get_guint8(tvb, 0) & 0xF); /* read number of AT out of SERCOS III header */
144 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIII AT");
146 if(check_col(pinfo->cinfo, COL_INFO))
148 if(phase & 0x80) /* communication phase switching in progress */
150 col_append_fstr(pinfo->cinfo, COL_INFO, " Phase=CP?s -> CP%u",
153 else /* communication as usual */
155 col_append_fstr(pinfo->cinfo, COL_INFO, " Phase=CP%u",
160 ti = proto_tree_add_text(tree, tvb, 0, -1, "AT%u", telno);
161 subtree = proto_item_add_subtree(ti, ett_siii_at);
163 dissect_siii_mst(tvb, pinfo, subtree); /* dissect SERCOS III header */
165 switch(phase) /* call the AT dissector depending on the current communication phase */
167 case COMMUNICATION_PHASE_0: /* CP0 */
168 tvb_n = tvb_new_subset(tvb, 6, 1024, 1024);
169 dissect_siii_at_cp0(tvb_n, pinfo, subtree);
172 case COMMUNICATION_PHASE_1: /* CP1 */
173 case COMMUNICATION_PHASE_2: /* CP2 */
174 tvb_n = tvb_new_subset(tvb, 6, 1280, 1280);
175 dissect_siii_at_cp1_2(tvb_n, pinfo, subtree, telno);
178 case COMMUNICATION_PHASE_3: /* CP3 */
179 case COMMUNICATION_PHASE_4: /* CP4 */
180 tvb_n = tvb_new_subset_remaining(tvb, 6);
181 dissect_siii_at_cp3_4(tvb_n, pinfo, subtree, telno);
185 proto_tree_add_text(tree, tvb, 6, -1, "CP is unknown");
190 void dissect_siii_at_init(gint proto_siii _U_)
194 /* Setup protocol subtree array */
195 static gint *ett[] = {
198 &ett_siii_at_devstats
201 static gint* etts[MAX_SERCOS_DEVICES];
203 for(idx = 0; idx < MAX_SERCOS_DEVICES; ++idx)
205 ett_siii_at_svc_channel[idx] = -1;
206 etts[idx] = &ett_siii_at_svc_channel[idx];
208 proto_register_subtree_array(etts, array_length(etts));
210 for(idx = 0; idx < MAX_SERCOS_DEVICES; ++idx)
212 ett_siii_at_dev_status[idx] = -1;
213 etts[idx] = &ett_siii_at_dev_status[idx];
215 proto_register_subtree_array(etts, array_length(etts));
217 /* Required function calls to register the header fields and subtrees used */
218 proto_register_subtree_array(ett, array_length(ett));