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

Last change on this file since 10090 was 10031, checked in by tbretz, 14 years ago
Changed connection from SPS to a client-only connection.
File size: 7.1 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, CanOpen *receiver)
58 : MTcpIpOI(addr, tx), Interface(receiver)
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 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.len = 0;
82 msg.cmd = M_BCAN_RX_ind;
83 msg.data[0] = 0;
84 msg.data[1] = 0;
85
86 const TString address = GetSocketAddress(rx);
87
88 while (!IsThreadCanceled())
89 {
90 unsigned char c;
91 const Int_t len = rx.RecvRaw(&c, 1);
92
93 // For details see TSocket::RecvRaw
94 // -1: // ERROR
95 // EINVAL, EWOULDBLOCK
96 // -5: // EPIPE || ECONNRESET = Pipe broken or connection reset by peer
97 // 0: Data received with zero length! (Connection lost/call interrupted)
98 if (len<=0)
99 return kFALSE;
100
101 // Data received
102 if (len>1)
103 {
104 gLog << err << "Data received from " << address << " is more than one byte!" << endl;
105 continue;
106 }
107
108 if (pos<0)
109 {
110 if (c>=MSGLEN)
111 {
112 gLog << err << "Data received from " << address << " too long (> " << MSGLEN << ")" << endl;
113 continue;
114 }
115
116 msg.len = c;
117 pos = 2;
118 continue;
119 }
120
121 // if (pos==2 && c==0x0a)
122 // continue;
123
124 msg.data[pos++] = c;
125 if (pos-2<msg.len)
126 continue;
127
128#ifdef DEBUG
129 cout << "*** RcvdCanFrame len=" << dec << msg.len << ": ";
130 for (int i=0; i<msg.len; i++)
131 cout << "0x" << setfill('0') << setw(2) << hex << (int)((msg.data+2)[i]) << " ";
132 cout << dec << endl;
133#endif
134
135 pos = -1;
136
137 // String completed
138 HandleMessage(msg);
139
140 return kTRUE;
141 }
142
143 return kTRUE;
144}
145
146/*
147void Ethernet::ReadSocket(TSocket &rx)
148{
149 Int_t pos = -1;
150
151 Message msg;
152 msg.cmd = M_BCAN_RX_ind;
153 msg.data[0] = 0;
154 msg.data[1] = 0;
155
156 const TString address = MTcpIpO::GetSocketAddress(rx);
157
158 while (!IsThreadCanceled())
159 {
160 //TThread::CancelPoint();
161
162 unsigned char c;
163 const Int_t len = rx.RecvRaw(&c, 1);
164
165 //TThread::CancelPoint();
166
167 // No data received (non-blocking mode)
168 if (len<0)
169 {
170 usleep(1);
171 continue;
172 }
173
174 // Data received with zero length!
175 if (len==0)
176 {
177 gLog << warn << "WARNING - Connection lost (received 0bytes) to " << address << endl;
178 //break; // This break is for TEST PURPOSE FIXME!!!
179 return;
180 }
181
182 // Data received
183 if (len>1)
184 {
185 gLog << err << "Data received from " << address << " is more than one byte!" << endl;
186 continue;
187 }
188
189 if (pos<0)
190 {
191 if (c>=MSGLEN)
192 {
193 cout << "Data received from " << address << " too long (> " << MSGLEN << ")" << endl;
194 continue;
195 }
196
197 msg.len = c;
198 pos = 2;
199 continue;
200 }
201
202 // if (pos==2 && c==0x0a)
203 // continue;
204
205 msg.data[pos++] = c;
206 if (pos-2<msg.len)
207 continue;
208
209#ifdef DEBUG
210 cout << "*** RcvdCanFrame len=" << dec << msg.len << ": ";
211 for (int i=0; i<msg.len; i++)
212 cout << "0x" << setfill('0') << setw(2) << hex << (int)((msg.data+2)[i]) << " ";
213 cout << dec << endl;
214#endif
215
216 pos = -1;
217
218 // String completed
219 HandleMessage(msg);
220 }
221}
222*/
223
224// --------------------------------------------------------------------------
225//
226// This is IcSendReqBCAN from the Janz software
227//
228// /*
229// * IcSendReqBCAN - Send a CANbus message
230// *
231// * Issue request to send a CAN message. <Spec> controls whether to send with
232// * or without spec/confirmation.
233// * .CS
234// * spec action
235// * 0 send only
236// * 1 send with confirmation to the host.
237// * 2 send and echo message to the host.
238// * 3 send and generate both echo and confirmation.
239// * .CE
240// *
241// * SERVICE: CTXreq, CTXCreq, CTXEreq, CTXCEreq
242// *
243// * NOTE:
244// * Raw ICANOS version of the firmware only.
245// */
246//
247#ifdef DEBUG
248#include <TStopwatch.h>
249#endif
250void Ethernet::SendCanFrame(WORD_t cobid, BYTE_t m[8], BYTE_t rtr)
251{
252 const WORD_t desc = MsgDescr(cobid, 8, rtr);
253
254 Message msg;
255
256// msg.cmd = M_BCAN_TX_req;
257
258 msg.len = 12;
259// msg.data[0] = 0;
260 msg.data[1] = msg.len-2;
261 msg.data[2] = word_to_msb(desc);
262 msg.data[3] = word_to_lsb(desc);
263
264 memcpy(&msg.data[4], m, 8);
265
266 /*
267 cout << "*** SendCanFrame len=" << dec << msg.len-2 << ": ";
268 for (int i=0; i<msg.len-2; i++)
269 cout << "0x" << setfill('0') << setw(2) << hex << (int)((msg.data+2)[i]) << " ";
270 cout << endl;
271 */
272
273#ifdef DEBUG
274 // FIXME: MUST BECOME NON-BLOCKING!!!!!
275 cout << "*** Send CanFrame over IP " << endl;
276 // FIXME: MUST BECOME NON-BLOCKING!!!!!
277#endif
278
279#ifdef DEBUG
280 TStopwatch st;
281 st.Start();
282#endif
283
284 Send((char*)(msg.data+1), msg.len-1);
285
286#ifdef DEBUG
287 st.Print();
288#endif
289}
Note: See TracBrowser for help on using the repository browser.