39 #include <arpa/inet.h> 41 #include <boost/chrono/chrono_io.hpp> 42 #include <boost/thread/thread.hpp> 46 #include "uhal/log/log.hpp" 56 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
61 mConfigurationSpace(),
65 mLastPacketHeader ( 0x200000f0 ),
66 mTrafficHistory ( 16, 0x00 ),
67 mReceivedControlPacketHeaderHistory ( 4 , 0x00000000 ),
68 mSentControlPacketHeaderHistory ( 4 , 0x00000000 ),
69 mBigEndianHack ( aBigEndianHack )
71 for (
size_t i = 0; i < 10; i++)
72 mConfigurationSpace.push_back( (uint16_t(getpid()) << 16) | i );
75 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
81 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
85 if ( IPbus_major == 2 )
87 bool is_status_request = ( *mReceive.begin() == 0xF1000020 );
88 bool is_resend_request = ( ( *mReceive.begin() & 0xFF0000FF ) == 0xF2000020 );
90 if ( mBigEndianHack || is_status_request || is_resend_request )
92 for ( std::vector<uint32_t>::iterator lIt ( mReceive.begin() ) ; lIt != mReceive.begin() + ( aByteCount>>2 ) ; ++lIt )
94 *lIt = ntohl ( *lIt );
99 std::vector<uint32_t>::const_iterator lBegin, lEnd;
103 if ( LoggingIncludes (
Debug() ) )
105 log (
Debug() ,
"\n=============================================== RECEIVED ===============================================" );
107 lBegin = mReceive.begin();
108 lEnd = mReceive.begin() + ( aByteCount>>2 );
109 lHostToTargetDebugger.
analyze ( lBegin , lEnd );
114 lBegin = mReceive.begin();
115 lEnd = mReceive.begin() + ( aByteCount>>2 );
117 if ( ! base_type::analyze ( lBegin , lEnd ) )
119 log (
Error() ,
"Found a bad header" );
123 if ( ( base_type::mPacketType == 0 ) && ( mReply.size() != 0 ) )
125 mReplyHistory.push_back ( std::make_pair ( base_type::mPacketCounter , mReply ) );
126 mReplyHistory.pop_front();
129 if ( mReplyDelay > boost::chrono::microseconds(0) )
131 log (
Info() ,
"Sleeping for " , mReplyDelay );
132 boost::this_thread::sleep_for( mReplyDelay );
133 mReplyDelay = boost::chrono::microseconds(0);
134 log (
Info() ,
"Now replying " );
139 if ( LoggingIncludes (
Debug() ) && ! mReply.empty() )
141 log (
Debug() ,
"\n=============================================== SENDING ===============================================" );
143 lBegin = mReply.begin();
145 lTargetToHostDebugger.
analyze ( lBegin , lEnd );
151 if ( IPbus_major == 2 )
153 if ( mBigEndianHack || base_type::mPacketType == 1 )
155 for ( std::vector<uint32_t>::iterator lIt ( mReply.begin() ) ; lIt != mReply.end() ; ++lIt )
157 *lIt = htonl ( *lIt );
164 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
167 if( ! mMemory.size() )
173 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
176 if( ! mMemory.size() )
182 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
185 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
186 mReceivedControlPacketHeaderHistory.pop_front();
188 mReply.push_back ( lExpected );
189 mSentControlPacketHeaderHistory.push_back ( lExpected );
190 mSentControlPacketHeaderHistory.pop_front();
194 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
197 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
198 mReceivedControlPacketHeaderHistory.pop_front();
199 uint32_t lAddress ( aAddress );
201 mReply.push_back ( lExpected );
202 mSentControlPacketHeaderHistory.push_back ( lExpected );
203 mSentControlPacketHeaderHistory.pop_front();
205 for ( ; base_type::mWordCounter!=0 ; --base_type::mWordCounter )
207 mReply.push_back ( GetEndpoint( lAddress ) );
212 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
215 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
216 mReceivedControlPacketHeaderHistory.pop_front();
217 uint32_t lAddress ( aAddress );
219 mReply.push_back ( lExpected );
220 mSentControlPacketHeaderHistory.push_back ( lExpected );
221 mSentControlPacketHeaderHistory.pop_front();
223 for ( ; base_type::mWordCounter!=0 ; --base_type::mWordCounter )
225 mReply.push_back ( GetEndpoint( lAddress++ ) );
230 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
233 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
234 mReceivedControlPacketHeaderHistory.pop_front();
235 uint32_t lAddress ( aAddress );
237 mReply.push_back ( lExpected );
238 mSentControlPacketHeaderHistory.push_back ( lExpected );
239 mSentControlPacketHeaderHistory.pop_front();
241 for ( ; base_type::mWordCounter!=0 ; --base_type::mWordCounter )
243 mReply.push_back ( mConfigurationSpace.at( lAddress++ ) );
248 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
251 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
252 mReceivedControlPacketHeaderHistory.pop_front();
253 uint32_t lAddress ( aAddress );
255 while ( aIt != aEnd )
257 SetEndpoint ( lAddress , *aIt++ );
262 if ( IPbus_major == 1 )
271 mReply.push_back ( lExpected );
272 mSentControlPacketHeaderHistory.push_back ( lExpected );
273 mSentControlPacketHeaderHistory.pop_front();
277 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
280 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
281 mReceivedControlPacketHeaderHistory.pop_front();
282 uint32_t lAddress ( aAddress );
284 while ( aIt != aEnd )
286 SetEndpoint ( lAddress++ , *aIt++ );
291 if ( IPbus_major == 1 )
300 mReply.push_back ( lExpected );
301 mSentControlPacketHeaderHistory.push_back ( lExpected );
302 mSentControlPacketHeaderHistory.pop_front();
306 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
309 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
310 mReceivedControlPacketHeaderHistory.pop_front();
311 uint32_t lAddress ( aAddress );
313 mReply.push_back ( lExpected );
314 mSentControlPacketHeaderHistory.push_back ( lExpected );
315 mSentControlPacketHeaderHistory.pop_front();
317 if ( IPbus_major == 1 )
320 uint32_t lValue( GetEndpoint( lAddress ) );
322 SetEndpoint( lAddress , lValue );
323 mReply.push_back ( lValue );
328 uint32_t lValue( GetEndpoint( lAddress ) );
329 mReply.push_back ( lValue );
331 SetEndpoint( lAddress , lValue );
336 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
339 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
340 mReceivedControlPacketHeaderHistory.pop_front();
341 uint32_t lAddress ( aAddress );
343 mReply.push_back ( lExpected );
344 mSentControlPacketHeaderHistory.push_back ( lExpected );
345 mSentControlPacketHeaderHistory.pop_front();
347 if ( IPbus_major == 1 )
350 uint32_t lValue( GetEndpoint( lAddress ) );
353 SetEndpoint( lAddress , lValue );
354 mReply.push_back ( lValue );
359 uint32_t lValue( GetEndpoint( lAddress ) );
360 mReply.push_back ( lValue );
363 SetEndpoint( lAddress , lValue );
368 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
372 mReceivedControlPacketHeaderHistory.push_back ( base_type::mPacketHeader );
373 mReceivedControlPacketHeaderHistory.pop_front();
375 mReply.push_back ( lExpected );
376 mSentControlPacketHeaderHistory.push_back ( lExpected );
377 mSentControlPacketHeaderHistory.pop_front();
381 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
388 if ( base_type::mPacketCounter != 0 )
390 uint16_t lTemp ( ( ( mLastPacketHeader>>8 ) &0x0000FFFF ) + 1 );
397 if ( base_type::mPacketCounter != lTemp )
399 mTrafficHistory.push_back ( 5 );
400 mTrafficHistory.pop_front();
401 log(
Notice(),
"Dummy hardware received control packet with ID ",
Integer(base_type::mPacketCounter),
", but expected ID ",
Integer(lTemp));
405 mLastPacketHeader = base_type::mPacketHeader;
408 mReply.push_back ( base_type::mPacketHeader );
409 mTrafficHistory.push_back ( 2 );
410 mTrafficHistory.pop_front();
415 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
422 mReply.push_back ( base_type::mPacketHeader );
423 mReply.push_back (
BUFFER_SIZE *
sizeof ( uint32_t ) );
425 uint16_t lTemp ( ( ( mLastPacketHeader>>8 ) &0x0000FFFF ) + 1 );
432 mReply.push_back ( ( mLastPacketHeader & 0xFF0000FF ) | ( ( lTemp <<8 ) & 0x00FFFF00 ) );
433 std::deque< uint8_t >::const_iterator lIt ( mTrafficHistory.begin() );
435 for ( uint32_t i = 0; i != 4 ; ++i )
437 uint32_t lTemp ( 0x00000000 );
439 for ( uint32_t
j = 0;
j != 4 ; ++
j )
442 lTemp |= ( uint32_t ) ( *lIt );
446 mReply.push_back ( lTemp );;
449 for ( std::deque< uint32_t >::const_iterator i = mReceivedControlPacketHeaderHistory.begin(); i != mReceivedControlPacketHeaderHistory.end() ; ++i )
451 mReply.push_back ( *i );
454 for ( std::deque< uint32_t >::const_iterator i = mSentControlPacketHeaderHistory.begin(); i != mSentControlPacketHeaderHistory.end() ; ++i )
456 mReply.push_back ( *i );
459 mTrafficHistory.push_back ( 3 );
460 mTrafficHistory.pop_front();
464 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
471 std::deque< std::pair< uint32_t , std::vector< uint32_t > > >::reverse_iterator lIt = mReplyHistory.rbegin();
473 for ( ; lIt!=mReplyHistory.rend() ; ++lIt )
475 if ( lIt->first == base_type::mPacketCounter )
477 mReply = lIt->second;
482 mTrafficHistory.push_back ( 4 );
483 mTrafficHistory.pop_front();
487 template< u
int8_t IPbus_major , u
int8_t IPbus_minor >
490 mTrafficHistory.push_back ( 5 );
491 mTrafficHistory.pop_front();
bool analyze(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd, const bool &aContinueOnError=true)
Analyse an IPbus packet held as a vector of uint32_t's.
A class which provides the version-specific functionality for IPbus.
Helper class to decode IPbus packets as passed from the Client to the Target.
static const uint32_t BUFFER_SIZE
Size of the receive and reply buffers.
std::vector< uint32_t >::const_iterator j
Common abstract base class for IPbus 1.3 and 2.0 dummy hardware.
Helper class to decode IPbus packets as passed from the Target to the Client.
Empty struct which acts as a dummy variable for passing the formatting information around...
static const uint32_t REPLY_HISTORY_DEPTH
The size of the reply history for IPbus 2.0.
bool analyze(std::vector< uint32_t >::const_iterator &aIt, const std::vector< uint32_t >::const_iterator &aEnd, const bool &aContinueOnError=true)
Analyse an IPbus packet held as a vector of uint32_t's.
Abstract base class to emulate IPbus hardware.
static const uint32_t ADDRESSMASK
The mask for the address space (size of the address space in one larger than this) ...
DummyHardware(const uint32_t &aReplyDelay, const bool &aBigEndianHack)
Constructor.
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...