source: trunk/Cosy/candrv/network.cc@ 13831

Last change on this file since 13831 was 12586, checked in by tbretz, 13 years ago
Added a missing output in case there are zombies in the network.
File size: 11.0 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of Stesy, the MAGIC Steering System
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 2001 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2008
21!
22!
23\* ======================================================================== */
24
25///////////////////////////////////////////////////////////////////////
26//
27// Network
28//
29// is a collection of nodes which coordinates the network
30//
31///////////////////////////////////////////////////////////////////////
32#include "network.h"
33
34#include "MLog.h"
35#include "MLogManip.h"
36
37ClassImp(Network);
38
39using namespace std;
40
41// --------------------------------------------------------------------------
42//
43// Start the canopen module
44// Initialize all nodes (calling NodeDrv::Init()
45//
46void Network::Start()
47{
48 gLog << inf << "- Starting network." << endl;
49
50 CanOpen::Start();
51 InitNodes();
52
53 gLog << inf << "- Network started." << endl;
54}
55
56// --------------------------------------------------------------------------
57//
58// Stop all nodes, stop the can module
59//
60void Network::Stop()
61{
62 gLog << inf << "- Stopping network." << endl;
63
64 StopNodes();
65 CanOpen::Stop();
66
67 gLog << inf << "- Network stopped." << endl;
68}
69
70// --------------------------------------------------------------------------
71//
72// Initialize the network, set all nodes to NULL (n/a)
73//
74Network::Network() : CanOpen()
75{
76 memset(fNodes, 0, 32*sizeof(*fNodes));
77 memset(fNodeInitialized, 0, 32*sizeof(*fNodeInitialized));
78
79 gLog << inf << "- Network initialized." << endl;
80}
81
82// --------------------------------------------------------------------------
83//
84// Distributes the received SDO messages to the addressed nodes.
85// Depending on the received command either HandleSDO, HandleSDOOK or
86// HandleSDOError called.
87// HandleSDO: Handles a received value
88// HandleSDOOK: Handles the acknoledgment of a trasmitted SDO
89// HandleSDOError: Handles error occursion (see CanOpen standard)
90//
91void Network::HandleSDO(BYTE_t node, BYTE_t cmd, WORD_t idx, BYTE_t subidx, LWORD_t data, const timeval_t &tv)
92{
93 if (fNodes[node])
94 switch (cmd)
95 {
96 case kSDO_TX4: // answer to 0x40 with 4 bytes of data
97 fNodes[node]->HandleSDO(idx, subidx, data, tv);
98 return;
99
100 case kSDO_TX3: // answer to 0x40 with 2 bytes of data
101 fNodes[node]->HandleSDO(idx, subidx, data&0xffff, tv);
102 return;
103
104 case kSDO_TX1: // answer to 0x40 with 1 byte of data
105 fNodes[node]->HandleSDO(idx, subidx, data&0xff, tv);
106 return;
107
108 case kSDO_TX_OK: // answer to a SDO_TX message
109 fNodes[node]->HandleSDOOK(idx, subidx, data, tv);
110 return;
111
112 case kSDO_TX_ERROR: // error message (instead of 0x60)
113 fNodes[node]->HandleSDOError(idx, subidx);
114 return;
115 }
116
117 gLog << warn << dec << setfill('0');
118 gLog << "Network::HandleSDO: Node=" << (int)node << " Cmd=0x" << hex << (int)cmd << ": ";
119 gLog << "Sdo=" << idx << "/" << (int)subidx << ": 0x" << setw(8) << data;
120 gLog << endl;
121}
122
123// --------------------------------------------------------------------------
124//
125// Distributes PDO1 messages to the correspoding node calling HandlePDO1
126//
127void Network::HandlePDO1(BYTE_t node, const BYTE_t *data, const timeval_t &tv)
128{
129 if (!fNodes[node])
130 {
131 gLog << err << "ERROR - Network::HandlePDO1: Node #" << dec << (int)node << " not found - PDO1: " << hex;
132 for (int i=0; i<8; i++)
133 gLog << " 0x" << (int)data[i];
134 gLog << dec << endl;
135 return;
136 }
137
138 fNodes[node]->HandlePDO1(data, tv);
139}
140
141// --------------------------------------------------------------------------
142//
143// Distributes PDO2 messages to the correspoding node calling HandlePDO2
144//
145void Network::HandlePDO2(BYTE_t node, const BYTE_t *data, const timeval_t &tv)
146{
147 if (!fNodes[node])
148 {
149 gLog << err << "ERROR - Network::HandlePDO2: Node #" << dec << (int)node << " not found - PDO2: " << hex;
150 for (int i=0; i<8; i++)
151 gLog << " 0x" << (int)data[i];
152 gLog << dec << endl;
153 return;
154 }
155
156 fNodes[node]->HandlePDO2(data, tv);
157}
158
159// --------------------------------------------------------------------------
160//
161// Distributes PDO3 messages to the correspoding node calling HandlePDO3
162//
163void Network::HandlePDO3(BYTE_t node, const BYTE_t *data, const timeval_t &tv)
164{
165 if (!fNodes[node])
166 {
167 gLog << err << "ERROR - Network::HandlePDO3: Node #" << dec << (int)node << " not found - PDO3: " << hex;
168 for (int i=0; i<8; i++)
169 gLog << " 0x" << (int)data[i];
170 gLog << dec << endl;
171 return;
172 }
173
174 fNodes[node]->HandlePDO3(data, tv);
175}
176
177// --------------------------------------------------------------------------
178//
179// Distributes PDO4 messages to the correspoding node calling HandlePDO4
180//
181void Network::HandlePDO4(BYTE_t node, const BYTE_t *data, const timeval_t &tv)
182{
183 if (!fNodes[node])
184 {
185 gLog << err << "ERROR - Network::HandlePDO4: Node #" << dec << (int)node << " not found - PDO4: " << hex;
186 for (int i=0; i<8; i++)
187 gLog << " 0x" << (int)data[i];
188 gLog << dec << endl;
189 return;
190 }
191
192 fNodes[node]->HandlePDO4(data, tv);
193}
194
195// --------------------------------------------------------------------------
196//
197// Distributes Nodeguard messages to the correspoding node calling
198// HandleNodeguard
199//
200void Network::HandleNodeguard(BYTE_t node, const timeval_t &tv)
201{
202 if (!fNodes[node])
203 {
204 gLog << err << "ERROR - Network::HandleNodeguard: Node #" << dec << (int)node << " not found: Nodeguard." << endl;
205 return;
206 }
207
208 fNodes[node]->HandleNodeguard(tv);
209}
210
211// --------------------------------------------------------------------------
212//
213// Distributes Emergency messages to the correspoding node calling
214// HandleEmergency
215//
216void Network::HandleEmergency(BYTE_t node, const timeval_t &tv)
217{
218 if (!fNodes[node])
219 {
220 gLog << err << "ERROR - Network::HandleEmergency: Node #" << dec << (int)node << " not found: Emergency." << endl;
221 return;
222 }
223
224 fNodes[node]->HandleEmergency(tv);
225}
226
227
228// --------------------------------------------------------------------------
229//
230// Sets a node to a given nodedrv. The id is requested from the drv object.
231//
232void Network::SetNode(NodeDrv *drv)
233{
234 const BYTE_t nodeid = drv->GetId();
235
236 if (nodeid>31)
237 {
238 gLog << err << "ERROR - Network::SetNode: Only node Numbers < 32 are allowed"<< endl;
239 return;
240 }
241
242 fNodes[nodeid] = drv;
243}
244
245// --------------------------------------------------------------------------
246//
247// Initializes all nodes calling InitDevice
248//
249void Network::InitNodes()
250{
251 for (int i=0; i<32; i++)
252 if (fNodes[i])
253 {
254 gLog << inf2 << "- Setting up Node #" << dec << i << " (";
255 gLog << fNodes[i]->GetNodeName() << ")" << endl;
256 if (fNodes[i]->InitDevice(this))
257 fNodeInitialized[i] = TRUE;
258 else
259 gLog << err << "- " << fNodes[i]->GetNodeName() << ": InitDevice failed." << endl;
260 }
261 gLog << inf << "- All Nodes setup." << endl;
262}
263
264// --------------------------------------------------------------------------
265//
266// Stop all nodes calling StopDevice
267//
268void Network::StopNodes()
269{
270 for (int i=0; i<32; i++)
271 if (fNodes[i] && fNodeInitialized[i])
272 {
273 gLog << inf2 << "- Stopping Node #" << dec << i;
274 gLog << " (" << fNodes[i]->GetNodeName() << ")" << endl;
275 fNodes[i]->StopDevice();
276 }
277 gLog << inf << "- All Nodes stopped." << endl;
278}
279
280// --------------------------------------------------------------------------
281//
282// Print all errors which are currently set
283//
284void Network::PrintError() const
285{
286 for (int i=0; i<32; i++)
287 {
288 if (!fNodes[i])
289 continue;
290
291 if (!fNodes[i]->HasError())
292 continue;
293
294 gLog << err << "- Node #" << dec << i << " '" << fNodes[i]->GetNodeName() << "' ";
295
296 if (fNodes[i]->GetError() <= 0)
297 gLog << "Error occured." << endl;
298 else
299 gLog << "has error #" << fNodes[i]->GetError() << endl;
300 }
301}
302
303// --------------------------------------------------------------------------
304//
305// returns true if one of the nodes has the error-flag set (HasError).
306//
307bool Network::HasError() const
308{
309 bool rc = false;
310
311 for (int i=0; i<32; i++)
312 {
313 if (!fNodes[i])
314 continue;
315
316 if (CanOpen::HasError())
317 fNodes[i]->SetZombie();
318
319 if (!fNodes[i]->HasError())
320 continue;
321
322 rc = true;
323
324 if (fNodes[i]->GetError() <= 0)
325 continue;
326
327 //gLog << "- Node #" << dec << i << " '" << fNodes[i]->GetNodeName();
328 //gLog << "' has error #" << fNodes[i]->GetError() << endl;
329 }
330
331 if (CanOpen::HasError())
332 return true;
333
334 return rc;
335}
336
337// --------------------------------------------------------------------------
338//
339// returns true if one of the nodes is a zombie node
340//
341bool Network::HasZombie() const
342{
343 for (int i=0; i<32; i++)
344 if (fNodes[i])
345 if (fNodes[i]->IsZombieNode())
346 {
347 gLog << err << "- Zombie " << i << endl;
348 return true;
349 }
350
351 return false;
352}
353
354// --------------------------------------------------------------------------
355//
356// try to reboot all zombie nodes to get them working again. all other
357// nodes are left untouched.
358//
359bool Network::RebootZombies()
360{
361 if (!HasConnection())
362 {
363 gLog << warn << "- No connection to network." << endl;
364 return false;
365 }
366
367 bool rc = true;
368
369 gLog << inf2 << "- Trying to reboot all Zombies..." << endl;
370 for (int i=0; i<32; i++)
371 if (fNodes[i])
372 if (fNodes[i]->IsZombieNode())
373 if (!fNodes[i]->Reboot())
374 {
375 gLog << err << "- Failed to reboot " << fNodes[i]->GetNodeName() << "." << endl;
376 rc = false;
377 }
378
379// if (rc)
380// gLog << inf << "- All Zombies rebooted." << endl;
381
382 return rc;
383}
384
385// --------------------------------------------------------------------------
386//
387// Check the connections to all nodes. (This can also mean: Validate
388// the correct setup, etc)
389//
390void Network::CheckConnections()
391{
392 for (int i=0; i<32; i++)
393 if (fNodes[i])
394 fNodes[i]->CheckConnection();
395}
Note: See TracBrowser for help on using the repository browser.