source: trunk/Cosy/candrv/ethernet.cc@ 9969

Last change on this file since 9969 was 9439, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 7.6 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 1/2008 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2008
21!
22!
23\* ======================================================================== */
24
25///////////////////////////////////////////////////////////////////////
26//
27// Ethernet
28//
29// Class describing the interface to the Janz card in RawCan mode.
30//
31///////////////////////////////////////////////////////////////////////
32#include "ethernet.h"
33
34#include "MLog.h"
35#include "MLogManip.h"
36
37#include <TSocket.h>
38
39//ClassImp(Ethernet);
40
41#undef DEBUG
42
43using namespace std;
44
45// --------------------------------------------------------------------------
46//
47// Constructor. Sets logging.
48// Set the receiving thread to priority -10 and detached.
49//
50// Open the device.
51// reset the device
52// Enable the fifo buffers
53// Set the baud rate to the given rate
54// Disable passthrough of all cobids (all canbus messages)
55// and switch the can bus communication on
56//
57Ethernet::Ethernet(const char *addr, const int tx, const int rx, CanOpen *receiver)
58 : MTcpIpI(rx), /*MTcpIpO(addr, tx),*/ Interface(receiver), fTxAddress(addr), fTxPort(tx)
59{
60 gLog << inf2 << "- Ethernet initialized." << endl;
61}
62
63// --------------------------------------------------------------------------
64//
65// Destructor. Stopt the receiver, disables the bus connection and
66// close the device
67//
68Ethernet::~Ethernet()
69{
70 MTcpIpI::CancelThread();
71 gLog << inf2 << "- Ethernet stopped." << endl;
72}
73
74// --------------------------------------------------------------------------
75//
76Bool_t Ethernet::ReadSocket(TSocket &rx)
77{
78 Int_t pos = -1;
79
80 Message msg;
81 msg.cmd = M_BCAN_RX_ind;
82 msg.data[0] = 0;
83 msg.data[1] = 0;
84
85 const TString address = MTcpIpO::GetSocketAddress(rx);
86
87 while (!MTcpIpI::IsThreadCanceled())
88 {
89 unsigned char c;
90 const Int_t len = rx.RecvRaw(&c, 1);
91
92 // For details see TSocket::RecvRaw
93 // -1: // ERROR
94 // EINVAL, EWOULDBLOCK
95 // -5: // EPIPE || ECONNRESET = Pipe broken or connection reset by peer
96 // 0: Data received with zero length! (Connection lost/call interrupted)
97 if (len<=0)
98 return kFALSE;
99
100 // Data received
101 if (len>1)
102 {
103 gLog << err << "Data received from " << address << " is more than one byte!" << endl;
104 continue;
105 }
106
107 if (pos<0)
108 {
109 if (c>=MSGLEN)
110 {
111 gLog << err << "Data received from " << address << " too long (> " << MSGLEN << ")" << endl;
112 continue;
113 }
114
115 msg.len = c;
116 pos = 2;
117 continue;
118 }
119
120 // if (pos==2 && c==0x0a)
121 // continue;
122
123 msg.data[pos++] = c;
124 if (pos-2<msg.len)
125 continue;
126
127#ifdef DEBUG
128 cout << "*** RcvdCanFrame len=" << dec << msg.len << ": ";
129 for (int i=0; i<msg.len; i++)
130 cout << "0x" << setfill('0') << setw(2) << hex << (int)((msg.data+2)[i]) << " ";
131 cout << dec << endl;
132#endif
133
134 pos = -1;
135
136 // String completed
137 HandleMessage(msg);
138
139 return kTRUE;
140 }
141
142 return kTRUE;
143}
144
145/*
146void Ethernet::ReadSocket(TSocket &rx)
147{
148 Int_t pos = -1;
149
150 Message msg;
151 msg.cmd = M_BCAN_RX_ind;
152 msg.data[0] = 0;
153 msg.data[1] = 0;
154
155 const TString address = MTcpIpO::GetSocketAddress(rx);
156
157 while (!IsThreadCanceled())
158 {
159 //TThread::CancelPoint();
160
161 unsigned char c;
162 const Int_t len = rx.RecvRaw(&c, 1);
163
164 //TThread::CancelPoint();
165
166 // No data received (non-blocking mode)
167 if (len<0)
168 {
169 usleep(1);
170 continue;
171 }
172
173 // Data received with zero length!
174 if (len==0)
175 {
176 gLog << warn << "WARNING - Connection lost (received 0bytes) to " << address << endl;
177 //break; // This break is for TEST PURPOSE FIXME!!!
178 return;
179 }
180
181 // Data received
182 if (len>1)
183 {
184 gLog << err << "Data received from " << address << " is more than one byte!" << endl;
185 continue;
186 }
187
188 if (pos<0)
189 {
190 if (c>=MSGLEN)
191 {
192 cout << "Data received from " << address << " too long (> " << MSGLEN << ")" << endl;
193 continue;
194 }
195
196 msg.len = c;
197 pos = 2;
198 continue;
199 }
200
201 // if (pos==2 && c==0x0a)
202 // continue;
203
204 msg.data[pos++] = c;
205 if (pos-2<msg.len)
206 continue;
207
208#ifdef DEBUG
209 cout << "*** RcvdCanFrame len=" << dec << msg.len << ": ";
210 for (int i=0; i<msg.len; i++)
211 cout << "0x" << setfill('0') << setw(2) << hex << (int)((msg.data+2)[i]) << " ";
212 cout << dec << endl;
213#endif
214
215 pos = -1;
216
217 // String completed
218 HandleMessage(msg);
219 }
220}
221*/
222
223// --------------------------------------------------------------------------
224//
225// This is IcSendReqBCAN from the Janz software
226//
227// /*
228// * IcSendReqBCAN - Send a CANbus message
229// *
230// * Issue request to send a CAN message. <Spec> controls whether to send with
231// * or without spec/confirmation.
232// * .CS
233// * spec action
234// * 0 send only
235// * 1 send with confirmation to the host.
236// * 2 send and echo message to the host.
237// * 3 send and generate both echo and confirmation.
238// * .CE
239// *
240// * SERVICE: CTXreq, CTXCreq, CTXEreq, CTXCEreq
241// *
242// * NOTE:
243// * Raw ICANOS version of the firmware only.
244// */
245//
246#ifdef DEBUG
247#include <TStopwatch.h>
248#endif
249void Ethernet::SendCanFrame(WORD_t cobid, BYTE_t m[8], BYTE_t rtr)
250{
251 const WORD_t desc = MsgDescr(cobid, 8, rtr);
252
253 Message msg;
254
255// msg.cmd = M_BCAN_TX_req;
256
257 msg.len = 12;
258// msg.data[0] = 0;
259 msg.data[1] = msg.len-2;
260 msg.data[2] = word_to_msb(desc);
261 msg.data[3] = word_to_lsb(desc);
262
263 memcpy(&msg.data[4], m, 8);
264
265 /*
266 cout << "*** SendCanFrame len=" << dec << msg.len-2 << ": ";
267 for (int i=0; i<msg.len-2; i++)
268 cout << "0x" << setfill('0') << setw(2) << hex << (int)((msg.data+2)[i]) << " ";
269 cout << endl;
270 */
271
272#ifdef DEBUG
273 // FIXME: MUST BECOME NON-BLOCKING!!!!!
274 cout << "*** Send CanFrame over IP " << endl;
275 // FIXME: MUST BECOME NON-BLOCKING!!!!!
276#endif
277
278#ifdef DEBUG
279 TStopwatch st;
280 st.Start();
281#endif
282 MTcpIpO::SendFrame(fTxAddress, fTxPort, (char*)(msg.data+1), msg.len-1);
283// Send((char*)(msg.data+1), msg.len-1);
284#ifdef DEBUG
285 st.Print();
286#endif
287 //Send((char*)(msg.data+1), msg.len-1);
288
289 /*
290 const WORD_t desc = MsgDescr(cobid, 8, rtr);
291
292 Message msg;
293
294 msg.cmd = M_BCAN_TX_req;
295
296 msg.len = 12;
297 msg.data[0] = 0;
298 msg.data[1] = 0;
299 msg.data[2] = word_to_msb(desc);
300 msg.data[3] = word_to_lsb(desc);
301
302 memcpy(&msg.data[4], m, 8);
303
304 while (!Send(&msg));*/
305}
Note: See TracBrowser for help on using the repository browser.