μHAL (v2.6.5)
Part of the IPbus software repository
ClientInterface.cpp
Go to the documentation of this file.
1 /*
2 ---------------------------------------------------------------------------
3 
4  This file is part of uHAL.
5 
6  uHAL is a hardware access library and programming framework
7  originally developed for upgrades of the Level-1 trigger of the CMS
8  experiment at CERN.
9 
10  uHAL is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  uHAL is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with uHAL. If not, see <http://www.gnu.org/licenses/>.
22 
23 
24  Andrew Rose, Imperial College, London
25  email: awr01 <AT> imperial.ac.uk
26 
27  Marc Magrans de Abril, CERN
28  email: marc.magrans.de.abril <AT> cern.ch
29 
30 ---------------------------------------------------------------------------
31 */
32 
33 #include "uhal/ClientInterface.hpp"
34 
35 
36 #include <sstream>
37 
38 #include <boost/shared_ptr.hpp>
39 #include <boost/thread/lock_guard.hpp>
40 
41 #include "uhal/Buffers.hpp"
42 #include "uhal/log/LogLevels.hpp" // for BaseLo...
43 #include "uhal/log/log_inserters.integer.hpp" // for Integer
44 #include "uhal/log/log.hpp"
45 #include "uhal/utilities/bits.hpp"
46 
47 
48 namespace uhal
49 {
50 
51  ClientInterface::ClientInterface ( const std::string& aId, const URI& aUri, const boost::posix_time::time_duration& aTimeoutPeriod ) :
52  mBuffers(),
53 #ifdef NO_PREEMPTIVE_DISPATCH
54  mNoPreemptiveDispatchBuffers(),
55 #endif
56  // mCurrentBuffers ( NULL ),
57  mId ( aId ),
58  mTimeoutPeriod ( aTimeoutPeriod ),
59  mUri ( aUri )
60  {
61  // log ( Warning() , ThisLocation() );
62  }
63 
64 
65 
67  mBuffers(),
68 #ifdef NO_PREEMPTIVE_DISPATCH
69  mNoPreemptiveDispatchBuffers(),
70 #endif
71  // mCurrentBuffers ( NULL ),
72  mId ( ),
73  mTimeoutPeriod ( boost::posix_time::pos_infin ),
74  mUri ( )
75  {
76  // log ( Warning() , ThisLocation() );
77  }
78 
79 
80 
81  ClientInterface::ClientInterface ( const ClientInterface& aClientInterface ) :
82  mBuffers(),
83 #ifdef NO_PREEMPTIVE_DISPATCH
84  mNoPreemptiveDispatchBuffers(),
85 #endif
86  // mCurrentBuffers ( NULL ),
87  mId ( aClientInterface.mId ),
88  mTimeoutPeriod ( aClientInterface.mTimeoutPeriod ),
89  mUri ( aClientInterface.mUri )
90  {
91  // log ( Warning() , ThisLocation() );
92  }
93 
94 
96  {
97  deleteBuffers();
98  mId = aClientInterface.mId;
99  mUri = aClientInterface.mUri;
100  mTimeoutPeriod = aClientInterface.mTimeoutPeriod;
101  return *this;
102  }
103 
104 
106  {
107  deleteBuffers();
108  }
109 
110  const std::string& ClientInterface::id() const
111  {
112  return mId;
113  }
114 
115 
116  // void ClientInterface::ping()
117  // {
118  // try
119  // {
120  // std::string lInstruction ( "ping -q -c 1 " + mUri.mHostname + " &> /dev/null" );
121  // log ( Info() , "Pinging " , Quote ( mId ) , " with instruction : " , lInstruction );
122  // //Cant use ICMP here because it requires raw socket (and hence superuser) access, so use system PING instead
123  // int lPingStatus = system ( lInstruction.c_str() );
124 
125  // if ( WEXITSTATUS ( lPingStatus ) )
126  // {
127  // log ( Error() , "Pinging " , Quote ( mId ) , " at address " , Quote( mUri.mHostname ) , " returned exit status ", Integer ( WEXITSTATUS ( lPingStatus ) ) );
128  // throw exception::// PingFailed();
129  // }
130  // }
131  // catch ( uhal::exception& aExc )
132  // {
133  // aExc.throw r;
134  // }
135  // catch ( const std::exception& aExc )
136  // {
137  // throw // StdException ( aExc );
138  // }
139  // }
140 
141 
142  std::string ClientInterface::uri() const
143  {
144  std::stringstream lReturn;
145  // url is always of the form "protocol://hostname:port"
146  lReturn << mUri.mProtocol << "://" << mUri.mHostname;
147  if ( !mUri.mPort.empty() )
148  lReturn << ":" << mUri.mPort;
149 
150  // there is sometimes a path
151  if ( mUri.mPath != "" )
152  {
153  lReturn << "/" << mUri.mPath;
154  }
155 
156  // there is sometimes a filename extension
157  if ( mUri.mExtension != "" )
158  {
159  lReturn << "." << mUri.mExtension;
160  }
161 
162  // there are sometimes arguments
163  if ( mUri.mArguments.size() )
164  {
165  lReturn << "?";
166  uhal::NameValuePairVectorType::const_iterator lIt = mUri.mArguments.begin();
167 
168  while ( true )
169  {
170  lReturn << lIt->first << "=" << lIt->second;
171 
172  if ( ++lIt == mUri.mArguments.end() )
173  {
174  break;
175  }
176 
177  lReturn << "&";
178  }
179  }
180 
181  return lReturn.str();
182  }
183 
184 
185 
187  {
188  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
189 
190  try
191  {
192 #ifdef NO_PREEMPTIVE_DISPATCH
193  log ( Info() , "mNoPreemptiveDispatchBuffers.size() = " , Integer ( mNoPreemptiveDispatchBuffers.size() ) );
194 
195  for ( std::deque < boost::shared_ptr< Buffers > >::iterator lIt = mNoPreemptiveDispatchBuffers.begin(); lIt != mNoPreemptiveDispatchBuffers.end(); ++lIt )
196  {
197  this->predispatch ( *lIt );
198  this->implementDispatch ( *lIt ); //responsibility for *lIt passed to the implementDispatch function
199  lIt->reset();
200  }
201 
202  {
203  boost::lock_guard<boost::mutex> lLock ( mBufferMutex );
204  mNoPreemptiveDispatchBuffers.clear();
205  }
206 
207  this->Flush();
208 #endif
209 
210  if ( mCurrentBuffers )
211  {
212  this->predispatch ( mCurrentBuffers );
213  this->implementDispatch ( mCurrentBuffers ); //responsibility for mCurrentBuffers passed to the implementDispatch function
214  mCurrentBuffers.reset();
215  this->Flush();
216  }
217  }
218  catch ( ... )
219  {
220  this->dispatchExceptionHandler();
221  throw;
222  }
223  }
224 
225 
226 
228  {}
229 
230 
232  {
233  // std::cout << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
234  // log ( Debug() , ThisLocation() );
235  //check that the results are valid
236  // log ( Warning() , "mDispatchSideMutex SET AT " , ThisLocation() );
237  //std::cout << mDispatchedBuffers.size() << std::endl;
238  exception::exception* lRet = this->validate ( aBuffers->getSendBuffer() ,
239  aBuffers->getSendBuffer() + aBuffers->sendCounter() ,
240  aBuffers->getReplyBuffer().begin() ,
241  aBuffers->getReplyBuffer().end() );
242 
243  //results are valid, so mark returned data as valid
244  if ( !lRet )
245  {
246  aBuffers->validate ();
247  }
248 
249  returnBufferToPool ( aBuffers );
250  return lRet;
251  }
252 
253 
255  {
256  return 0;
257  }
258 
259 
261  {}
262 
264  {}
265 
266 
267 
269  {
270  // std::cout << "LOCKED @ " << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
271  boost::lock_guard<boost::mutex> lLock ( mBufferMutex );
272 
273  if ( aBuffers )
274  {
275  mBuffers.push_back ( aBuffers );
276  aBuffers.reset();
277  }
278 
279  // std::cout << "UNLOCKED @ " << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
280  }
281 
282 
284  {
285  boost::lock_guard<boost::mutex> lLock ( mBufferMutex );
286 
287  for ( std::deque < boost::shared_ptr< Buffers > >::iterator lIt = aBuffers.begin(); lIt != aBuffers.end(); ++lIt )
288  {
289  if ( *lIt )
290  {
291  mBuffers.push_back ( *lIt );
292  }
293  }
294 
295  aBuffers.clear();
296  }
297 
298 
300  {
301  boost::lock_guard<boost::mutex> lLock ( mBufferMutex );
302 
303  for ( std::vector < boost::shared_ptr< Buffers > >::iterator lIt = aBuffers.begin(); lIt != aBuffers.end(); ++lIt )
304  {
305  if ( *lIt )
306  {
307  mBuffers.push_back ( *lIt );
308  }
309  }
310 
311  aBuffers.clear();
312  }
313 
314 
315  void ClientInterface::returnBufferToPool ( std::deque< std::vector< boost::shared_ptr<Buffers> > >& aBuffers )
316  {
317  boost::lock_guard<boost::mutex> lLock ( mBufferMutex );
318 
319  for ( std::deque < std::vector < boost::shared_ptr< Buffers > > >::iterator lIt1 = aBuffers.begin(); lIt1 != aBuffers.end(); ++lIt1 )
320  {
321  for ( std::vector< boost::shared_ptr<Buffers> >::iterator lIt2 = lIt1->begin(); lIt2 != lIt1->end(); ++lIt2 )
322  {
323  if ( *lIt2 )
324  {
325  mBuffers.push_back ( *lIt2 );
326  }
327  }
328  }
329 
330  aBuffers.clear();
331  }
332 
333 
334  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
335  boost::shared_ptr< Buffers > ClientInterface::checkBufferSpace ( const uint32_t& aRequestedSendSize , const uint32_t& aRequestedReplySize , uint32_t& aAvailableSendSize , uint32_t& aAvailableReplySize )
336  {
337  log ( Debug() , "Checking buffer space" );
338  //if there are no existing buffers in the pool, create them
340  uint32_t lSendBufferFreeSpace ( this->getMaxSendSize() - mCurrentBuffers->sendCounter() );
341  uint32_t lReplyBufferFreeSpace ( this->getMaxReplySize() - mCurrentBuffers->replyCounter() );
342  // log ( Debug() , "Current buffer:\n" ,
343  // " aRequestedSendSize " , Integer( aRequestedSendSize ) ,
344  // " | aRequestedReplySize " , Integer( aRequestedReplySize ) ,
345  // "\n" ,
346  // " mMaxSendSize " , Integer( mMaxSendSize ) ,
347  // " | mMaxReplySize " , Integer( mMaxReplySize ) ,
348  // "\n" ,
349  // " lBuffers->sendCounter() " , Integer( lBuffers->sendCounter() ) ,
350  // " | lBuffers->replyCounter() " , Integer( lBuffers->replyCounter() ) ,
351  // "\n" ,
352  // " lSendBufferFreeSpace " , Integer(lSendBufferFreeSpace) ,
353  // " | lReplyBufferFreeSpace " , Integer(lReplyBufferFreeSpace)
354  // );
355 
356  if ( ( aRequestedSendSize <= lSendBufferFreeSpace ) && ( aRequestedReplySize <= lReplyBufferFreeSpace ) )
357  {
358  aAvailableSendSize = aRequestedSendSize;
359  aAvailableReplySize = aRequestedReplySize;
360  return mCurrentBuffers;
361  }
362 
363  if ( ( lSendBufferFreeSpace > 16 ) && ( lReplyBufferFreeSpace > 16 ) )
364  {
365  aAvailableSendSize = lSendBufferFreeSpace;
366  aAvailableReplySize = lReplyBufferFreeSpace;
367  return mCurrentBuffers;
368  }
369 
370 #ifdef NO_PREEMPTIVE_DISPATCH
371  // if ( !mCurrentBuffers )
372  // {
373  // std::cout << "Buffer is NULL" << std::endl;
374  // }
375  mNoPreemptiveDispatchBuffers.push_back ( mCurrentBuffers );
376  mCurrentBuffers.reset();
377 #else
378  log ( Debug() , "Triggering automated dispatch" );
379 
380  try
381  {
382  this->predispatch ( mCurrentBuffers );
384  mCurrentBuffers.reset();
385  }
386  catch ( ... )
387  {
388  this->dispatchExceptionHandler();
389  throw;
390  }
391 
392 #endif
394  lSendBufferFreeSpace = this->getMaxSendSize() - mCurrentBuffers->sendCounter();
395  lReplyBufferFreeSpace = this->getMaxReplySize() - mCurrentBuffers->replyCounter();
396  // log ( Debug() , "Newly created buffer:\n" ,
397  // " aRequestedSendSize " , Integer( aRequestedSendSize ) ,
398  // " | aRequestedReplySize " , Integer( aRequestedReplySize ) ,
399  // "\n" ,
400  // " mMaxSendSize " , Integer( mMaxSendSize ) ,
401  // " | mMaxReplySize " , Integer( mMaxReplySize ) ,
402  // "\n" ,
403  // " lBuffers->sendCounter() " , Integer( lBuffers->sendCounter() ) ,
404  // " | lBuffers->replyCounter() " , Integer( lBuffers->replyCounter() ) ,
405  // "\n" ,
406  // " lSendBufferFreeSpace " , Integer(lSendBufferFreeSpace) ,
407  // " | lReplyBufferFreeSpace " , Integer(lReplyBufferFreeSpace)
408  // );
409 
410  if ( ( aRequestedSendSize <= lSendBufferFreeSpace ) && ( aRequestedReplySize <= lReplyBufferFreeSpace ) )
411  {
412  aAvailableSendSize = aRequestedSendSize;
413  aAvailableReplySize = aRequestedReplySize;
414  return mCurrentBuffers;
415  }
416 
417  aAvailableSendSize = lSendBufferFreeSpace;
418  aAvailableReplySize = lReplyBufferFreeSpace;
419  return mCurrentBuffers;
420  }
421  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
422 
424  {
425  if ( ! mCurrentBuffers )
426  {
427  {
428  // std::cout << "LOCKED @ " << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
429  boost::lock_guard<boost::mutex> lLock ( mBufferMutex );
430 
431  if ( mBuffers.size() == 0 )
432  {
433  for ( uint32_t i=0; i!=10; ++i )
434  {
435  mBuffers.push_back ( boost::shared_ptr< Buffers > ( new Buffers ( this->getMaxSendSize() ) ) );
436  }
437  }
438 
439  mCurrentBuffers = mBuffers.front();
440  mBuffers.pop_front();
441  mCurrentBuffers->clear();
442  // std::cout << "UNLOCKED @ " << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
443  }
444  this->preamble ( mCurrentBuffers );
445  }
446  }
447 
448 
449 
450 
452  {
453  // std::cout << "LOCKED @ " << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
454  boost::lock_guard<boost::mutex> lLock ( mBufferMutex );
455  /* for ( std::deque < boost::shared_ptr< Buffers > >::iterator lIt = mBuffers.begin(); lIt != mBuffers.end(); ++lIt )
456  {
457  if ( *lIt )
458  {
459  delete *lIt;
460  *lIt = NULL;
461  }
462  }*/
463  mBuffers.clear();
464  //
465 #ifdef NO_PREEMPTIVE_DISPATCH
466  /* for ( std::deque < boost::shared_ptr< Buffers > >::iterator lIt = mNoPreemptiveDispatchBuffers.begin(); lIt != mNoPreemptiveDispatchBuffers.end(); ++lIt )
467  {
468  if ( *lIt )
469  {
470  delete *lIt;
471  *lIt = NULL;
472  }
473  }*/
474  mNoPreemptiveDispatchBuffers.clear();
475 #endif
476 
477  if ( mCurrentBuffers )
478  {
479  // delete mCurrentBuffers;
480  mCurrentBuffers.reset();
481  }
482 
483  // std::cout << "UNLOCKED @ " << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
484  }
485 
486 
487 
488 
489 
491  {
492  deleteBuffers();
493  }
494 
495 
496 
497  std::pair < ValHeader , _ValHeader_* > ClientInterface::CreateValHeader()
498  {
499  ValHeader lReply;
500  return std::make_pair ( lReply , & ( * ( lReply.mMembers ) ) );
501  }
502 
503  std::pair < ValWord<uint32_t> , _ValWord_<uint32_t>* > ClientInterface::CreateValWord ( const uint32_t& aValue , const uint32_t& aMask )
504  {
505  ValWord<uint32_t> lReply ( aValue , aMask );
506  return std::make_pair ( lReply , & ( * ( lReply.mMembers ) ) );
507  }
508 
509  std::pair < ValVector<uint32_t> , _ValVector_<uint32_t>* > ClientInterface::CreateValVector ( const uint32_t& aSize )
510  {
511  ValVector<uint32_t> lReply ( aSize );
512  return std::make_pair ( lReply , & ( * ( lReply.mMembers ) ) );
513  }
514 
515  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
516  ValHeader ClientInterface::write ( const uint32_t& aAddr, const uint32_t& aSource )
517  {
518  // log ( Warning() , "mUserSideMutex SET AT " , ThisLocation() );
519  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
520  return implementWrite ( aAddr , aSource );
521  }
522 
523  ValHeader ClientInterface::write ( const uint32_t& aAddr, const uint32_t& aSource, const uint32_t& aMask )
524  {
525  // log ( Warning() , "mUserSideMutex SET AT " , ThisLocation() );
526  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
527  uint32_t lShiftSize ( utilities::TrailingRightBits ( aMask ) );
528  uint32_t lBitShiftedSource ( aSource << lShiftSize );
529 
530  if ( ( lBitShiftedSource >> lShiftSize ) != aSource )
531  {
532  exception::BitsSetWhichAreForbiddenByBitMask lExc;
533  log ( lExc , "Source data (" , Integer ( aSource , IntFmt<hex,fixed>() ) , ") has bits which would be shifted outside the register " );
534  throw lExc;
535  }
536 
537  uint32_t lOverlap ( lBitShiftedSource & ~aMask );
538 
539  if ( lOverlap )
540  {
541  exception::BitsSetWhichAreForbiddenByBitMask lExc;
542  log ( lExc , "Source data (" , Integer ( aSource , IntFmt<hex,fixed>() ) , ")"
543  " has the following bits set outside the bounds allowed by the bit-mask ( ", Integer ( aSource , IntFmt<hex,fixed>() ) , ") : " ,
544  Integer ( lOverlap , IntFmt<hex,fixed>() )
545  );
546  throw lExc;
547  }
548 
549  return ( ValHeader ) ( implementRMWbits ( aAddr , ~aMask , lBitShiftedSource & aMask ) );
550  }
551 
552  ValHeader ClientInterface::writeBlock ( const uint32_t& aAddr, const std::vector< uint32_t >& aSource, const defs::BlockReadWriteMode& aMode )
553  {
554  // log ( Warning() , "mUserSideMutex SET AT " , ThisLocation() );
555  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
556  return implementWriteBlock ( aAddr, aSource, aMode );
557  }
558  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
559 
560 
561 
562  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
563  ValWord< uint32_t > ClientInterface::read ( const uint32_t& aAddr )
564  {
565  // log ( Warning() , "mUserSideMutex SET AT " , ThisLocation() );
566  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
567  return implementRead ( aAddr );
568  }
569 
570  ValWord< uint32_t > ClientInterface::read ( const uint32_t& aAddr, const uint32_t& aMask )
571  {
572  // log ( Warning() , "mUserSideMutex SET AT " , ThisLocation() );
573  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
574  return implementRead ( aAddr, aMask );
575  }
576 
577  ValVector< uint32_t > ClientInterface::readBlock ( const uint32_t& aAddr, const uint32_t& aSize, const defs::BlockReadWriteMode& aMode )
578  {
579  // log ( Warning() , "mUserSideMutex SET AT " , ThisLocation() );
580  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
581  return implementReadBlock ( aAddr, aSize, aMode );
582  }
583  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
584 
585  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
586  ValWord< uint32_t > ClientInterface::rmw_bits ( const uint32_t& aAddr , const uint32_t& aANDterm , const uint32_t& aORterm )
587  {
588  // log ( Warning() , "mUserSideMutex SET AT " , ThisLocation() );
589  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
590  return implementRMWbits ( aAddr , aANDterm , aORterm );
591  }
592  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
593 
594 
595  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
596  ValWord< uint32_t > ClientInterface::rmw_sum ( const uint32_t& aAddr , const int32_t& aAddend )
597  {
598  // log ( Warning() , "mUserSideMutex SET AT " , ThisLocation() );
599  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
600  return implementRMWsum ( aAddr , aAddend );
601  }
602  //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
603 
604 
605  void ClientInterface::setTimeoutPeriod ( const uint32_t& aTimeoutPeriod )
606  {
607  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
608 
609  if ( aTimeoutPeriod == 0 )
610  {
611  mTimeoutPeriod = boost::posix_time::pos_infin;
612  }
613  else
614  {
615  mTimeoutPeriod = boost::posix_time::milliseconds ( aTimeoutPeriod );
616  }
617  }
618 
620  {
621  boost::lock_guard<boost::mutex> lLock ( mUserSideMutex );
622  return mTimeoutPeriod.total_milliseconds();
623  }
624 
625 
626  const boost::posix_time::time_duration& ClientInterface::getBoostTimeoutPeriod()
627  {
628  return mTimeoutPeriod;
629  }
630 
631 }
virtual ValHeader implementWrite(const uint32_t &aAddr, const uint32_t &aValue)=0
Write a single, unmasked word to a register.
boost::shared_ptr< _ValHeader_ > mMembers
Return a std::deque containing all the IPbus headers returned during the transaction.
Definition: ValMem.hpp:202
void returnBufferToPool(boost::shared_ptr< Buffers > &aBuffers)
Function to return a buffer to the buffer pool.
std::deque< boost::shared_ptr< Buffers > > mBuffers
A memory pool of buffers which will be dispatched.
virtual uint32_t getPreambleSize()
Return the size of the preamble.
ValWord< uint32_t > read(const uint32_t &aAddr)
Read a single, unmasked, unsigned word.
virtual ~ClientInterface()
Destructor.
void dispatch()
Method to dispatch all IPbus packets which are in the queue of IPbusPacketInfo&#39;s and wait until all q...
boost::shared_ptr< Buffers > mCurrentBuffers
A pointer to a buffer-wrapper object.
boost::mutex mBufferMutex
A MutEx lock used to make sure the access to the buffers is thread safe.
void setTimeoutPeriod(const uint32_t &aTimeoutPeriod=0)
A method to modify the timeout period for any pending or future transactions.
std::string mHostname
The "host" part of a URI of the form "protocol://host:port/patha/pathb/blah.ext?key1=val1&key2=val2&k...
Definition: URI.hpp:54
virtual void preamble(boost::shared_ptr< Buffers > aBuffers)
Add a preamble to an IPbus buffer.
A class wrapping the send and recieve buffers that are to be filled and transported and the validated...
Definition: Buffers.hpp:55
virtual ClientInterface & operator=(const ClientInterface &aClientInterface)
Assignment operator.
boost::shared_ptr< _ValWord_< T > > mMembers
Return a std::deque containing all the IPbus headers returned during the transaction.
Definition: ValMem.hpp:286
A Template helper struct wrapping an IPbus header, a register for storing a single word of data...
Definition: ValMem.hpp:103
virtual ValWord< uint32_t > implementRead(const uint32_t &aAddr, const uint32_t &aMask=defs::NOMASK)=0
Read a single, masked, unsigned word.
ValWord< uint32_t > rmw_sum(const uint32_t &aAddr, const int32_t &aAddend)
Read the value of a register, add the addend, set the register to this new value and return a copy of...
An abstract base exception class providing an interface to a throw/ThrowAsDerivedType mechanism which...
Definition: exception.hpp:89
ValHeader write(const uint32_t &aAddr, const uint32_t &aValue)
Write a single, unmasked word to a register.
ClientInterface()
Default Constructor.
boost::mutex mUserSideMutex
A MutEx lock used to make sure the access functions are thread safe.
boost::posix_time::time_duration mTimeoutPeriod
Timeout period for transactions.
virtual void dispatchExceptionHandler()
Function which is called when an exception is thrown.
virtual void implementDispatch(boost::shared_ptr< Buffers > aBuffers)=0
Pure virtual function which actually performs the dispatch operation.
std::string uri() const
Ping the target for this client.
virtual void predispatch(boost::shared_ptr< Buffers > aBuffers)
Finalize the buffer before it is transmitted.
std::string mPort
The "port" part of a URI of the form "protocol://host:port/patha/pathb/blah.ext?key1=val1&key2=val2&k...
Definition: URI.hpp:56
if(hw.uri().find("ipbusudp-1.3://") !=std::string::npos||hw.uri().find("ipbustcp-1.3://") !=std::string::npos||hw.uri().find("chtcp-1.3://") !=std::string::npos)
std::pair< ValVector< uint32_t >, _ValVector_< uint32_t > *> CreateValVector(const uint32_t &aSize)
Helper function to create a ValVector object.
std::pair< ValWord< uint32_t >, _ValWord_< uint32_t > *> CreateValWord(const uint32_t &aValue, const uint32_t &aMask=defs::NOMASK)
Helper function to create a ValWord object.
NameValuePairVectorType mArguments
The "key1=val1&key2=val2&key3=val3" part of a URI of the form "protocol://host:port/patha/pathb/blah...
Definition: URI.hpp:62
virtual void Flush()
Virtual function to dispatch all buffers and block until all replies are received.
std::string mId
the identifier of the target for this client
Empty struct which acts as a dummy variable for passing the formatting information around...
std::pair< ValHeader, _ValHeader_ *> CreateValHeader()
Helper function to create a ValHeader object.
boost::shared_ptr< _ValVector_< T > > mMembers
Return a std::deque containing all the IPbus headers returned during the transaction.
Definition: ValMem.hpp:436
uint64_t getTimeoutPeriod()
A method to retrieve the timeout period currently being used.
ValVector< uint32_t > readBlock(const uint32_t &aAddr, const uint32_t &aSize, const defs::BlockReadWriteMode &aMode=defs::INCREMENTAL)
Read a block of unsigned data from a block of registers or a block-read port.
virtual ValWord< uint32_t > implementRMWsum(const uint32_t &aAddr, const int32_t &aAddend)=0
Read the value of a register, add the addend, set the register to this new value and return a copy of...
virtual ValVector< uint32_t > implementReadBlock(const uint32_t &aAddr, const uint32_t &aSize, const defs::BlockReadWriteMode &aMode=defs::INCREMENTAL)=0
Read a block of unsigned data from a block of registers or a block-read port.
ValHeader writeBlock(const uint32_t &aAddr, const std::vector< uint32_t > &aValues, const defs::BlockReadWriteMode &aMode=defs::INCREMENTAL)
Write a block of data to a block of registers or a block-write port.
An abstract base class for defining the interface to the various IPbus clients as well as providing t...
std::string mExtension
The "ext" part of a URI of the form "protocol://host:port/patha/pathb/blah.ext?key1=val1&key2=val2&ke...
Definition: URI.hpp:60
virtual ValWord< uint32_t > implementRMWbits(const uint32_t &aAddr, const uint32_t &aANDterm, const uint32_t &aORterm)=0
Read the value of a register, apply the AND-term, apply the OR-term, set the register to this new val...
virtual boost::shared_ptr< Buffers > checkBufferSpace(const uint32_t &aSendSize, const uint32_t &aReplySize, uint32_t &aAvailableSendSize, uint32_t &aAvailableReplySize)
Function which checks the available space in the currently filling buffer against requested send and ...
std::string mProtocol
The "protocol" part of a URI of the form "protocol://host:port/patha/pathb/blah.ext?key1=val1&key2=val2&key3=val3".
Definition: URI.hpp:52
DebugLevel Debug
Definition: LogLevels.cpp:133
std::string mPath
The "patha/pathb/blah" part of a URI of the form "protocol://host:port/patha/pathb/blah.ext?key1=val1&key2=val2&key3=val3".
Definition: URI.hpp:58
BlockReadWriteMode
define whether transactions target a single register, a block of registers, a block-read/write port o...
Definition: definitions.hpp:53
A class which wraps a single word of data and marks whether or not it is valid.
Definition: ValMem.hpp:156
virtual exception::exception * validate(boost::shared_ptr< Buffers > aBuffers)
Function which dispatch calls when the reply is received to check that the headers are as expected...
void updateCurrentBuffers()
If the current buffer is null, allocate a buffer from the buffer pool for it If the buffer pool is em...
ValWord< uint32_t > rmw_bits(const uint32_t &aAddr, const uint32_t &aANDterm, const uint32_t &aORterm)
Read the value of a register, apply the AND-term, apply the OR-term, set the register to this new val...
unsigned int TrailingRightBits(uint32_t aValue)
Helper function to calculate the number of zero-bits at the righthand end of a 32-bit number...
Definition: bits.cpp:44
virtual uint32_t getMaxReplySize()=0
Return the maximum size of reply packet based on the buffer size in the target.
InfoLevel Info
Definition: LogLevels.cpp:114
const std::string & id() const
Return the identifier of the target for this client.
URI mUri
a struct containing the full URI of the target for this client
virtual ValHeader implementWriteBlock(const uint32_t &aAddr, const std::vector< uint32_t > &aValues, const defs::BlockReadWriteMode &aMode=defs::INCREMENTAL)=0
Write a block of data to a block of registers or a block-write port.
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...
Struct to store a URI when parsed by boost spirit.
Definition: URI.hpp:49
A Template helper struct wrapping a block of IPbus header, a register for storing a block of data and...
Definition: ValMem.hpp:131
const boost::posix_time::time_duration & getBoostTimeoutPeriod()
A method to retrieve the timeout period currently being used.
virtual uint32_t getMaxSendSize()=0
Return the maximum size to be sent based on the buffer size in the target.