source: trunk/Cosy/candrv/ethernet.cc

Last change on this file 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.