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

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