μHAL (v2.6.5)
Part of the IPbus software repository
ProtocolIPbus.hpp
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 
39 #ifndef _uhal_ProtocolIPbus_hpp_
40 #define _uhal_ProtocolIPbus_hpp_
41 
42 
43 #include <deque>
44 #include <iosfwd>
45 #include <stdint.h>
46 #include <string>
47 #include <utility>
48 
49 #include <boost/function.hpp> // for function
50 #include <boost/thread/mutex.hpp> // for mutex
51 
52 #include "uhal/log/exception.hpp"
53 #include "uhal/ClientInterface.hpp" // for PacketLevelError
55 
56 
57 // Forward declarations
58 namespace boost { template <class Y> class shared_ptr; }
59 
60 
61 namespace uhal
62 {
63  class Buffers;
64  struct URI;
65 
66 
68  template< uint8_t IPbus_major , uint8_t IPbus_minor >
69  class IPbus;
70 
71 
73  template< uint8_t IPbus_minor >
74  class IPbus < 1 , IPbus_minor > : public IPbusCore
75  {
76 
77  public:
83  IPbus ( const std::string& aId, const URI& aUri );
84 
88  virtual ~IPbus();
89 
90  protected:
94  virtual void preamble ( boost::shared_ptr< Buffers > aBuffers );
95 
99  virtual uint32_t getPreambleSize();
100 
104  virtual void predispatch ( boost::shared_ptr< Buffers > aBuffers );
105 
106  public:
115  static uint32_t CalculateHeader ( const eIPbusTransactionType& aType , const uint32_t& aWordCount , const uint32_t& aTransactionId , const uint8_t& aInfoCode = 0 );
116 
125  static uint32_t ExpectedHeader ( const eIPbusTransactionType& aType , const uint32_t& aWordCount , const uint32_t& aTransactionId , const uint8_t& aInfoCode = 0 );
126 
136  static bool ExtractHeader ( const uint32_t& aHeader , eIPbusTransactionType& aType , uint32_t& aWordCount , uint32_t& aTransactionId , uint8_t& aInfoCode );
137 
138 
139  protected:
140 
149  uint32_t implementCalculateHeader ( const eIPbusTransactionType& aType , const uint32_t& aWordCount , const uint32_t& aTransactionId , const uint8_t& aInfoCode );
150 
160  bool implementExtractHeader ( const uint32_t& aHeader , eIPbusTransactionType& aType , uint32_t& aWordCount , uint32_t& aTransactionId , uint8_t& aInfoCode );
161 
163  uint8_t requestTransactionInfoCode () const
164  {
165  return 0;
166  }
167 
169  uint32_t getMaxTransactionWordCount() const
170  {
171  return 0x1ff;
172  }
173 
174  virtual uint32_t getMaxNumberOfBuffers()
175  {
176  return 1;
177  }
178 
179  virtual void dispatchExceptionHandler();
180 
181  private:
182  boost::function<void (std::ostream&, const uint8_t&)> getInfoCodeTranslator() { return translateInfoCode; }
183 
184  static void translateInfoCode(std::ostream& aStream, const uint8_t& aErrorCode);
185  // std::vector< uint32_t > mSendPadding;
186  // std::vector< uint32_t > mReplyPadding;
187 
188  };
189 
190 
191 
192  namespace exception
193  {
195  UHAL_DEFINE_DERIVED_EXCEPTION_CLASS ( IPbus2PacketHeaderMismatch, PacketLevelError, "Exception class to handle the case where the IPbus 2.0 packet header does not match that sent." )
196  }
197 
198 
200  template< uint8_t IPbus_minor >
201  class IPbus < 2 , IPbus_minor > : public IPbusCore
202  {
203 
204  public:
210  IPbus ( const std::string& aId, const URI& aUri );
211 
215  virtual ~IPbus();
216 
217  protected:
221  virtual void preamble ( boost::shared_ptr< Buffers > aBuffers );
222 
226  virtual uint32_t getPreambleSize();
227 
231  virtual void predispatch ( boost::shared_ptr< Buffers > aBuffers );
232 
233  public:
242  static uint32_t CalculateHeader ( const eIPbusTransactionType& aType , const uint32_t& aWordCount , const uint32_t& aTransactionId , const uint8_t& aInfoCode = 0 );
243 
252  static uint32_t ExpectedHeader ( const eIPbusTransactionType& aType , const uint32_t& aWordCount , const uint32_t& aTransactionId , const uint8_t& aInfoCode = 0 );
253 
263  static bool ExtractHeader ( const uint32_t& aHeader , eIPbusTransactionType& aType , uint32_t& aWordCount , uint32_t& aTransactionId , uint8_t& aInfoCode );
264 
265 
266 
267  protected:
268 
277  virtual exception::exception* validate ( uint8_t* aSendBufferStart ,
278  uint8_t* aSendBufferEnd ,
279  std::deque< std::pair< uint8_t* , uint32_t > >::iterator aReplyStartIt ,
280  std::deque< std::pair< uint8_t* , uint32_t > >::iterator aReplyEndIt );
281 
290  uint32_t implementCalculateHeader ( const eIPbusTransactionType& aType , const uint32_t& aWordCount , const uint32_t& aTransactionId , const uint8_t& aInfoCode );
291 
301  bool implementExtractHeader ( const uint32_t& aHeader , eIPbusTransactionType& aType , uint32_t& aWordCount , uint32_t& aTransactionId , uint8_t& aInfoCode );
302 
304  uint8_t requestTransactionInfoCode () const
305  {
306  return 0xF;
307  }
308 
310  uint32_t getMaxTransactionWordCount() const
311  {
312  return 0xff;
313  }
314 
315  virtual uint32_t getMaxNumberOfBuffers()
316  {
317  return 16;
318  }
319 
320  virtual void dispatchExceptionHandler();
321 
322  private:
323  boost::function<void (std::ostream&, const uint8_t&)> getInfoCodeTranslator() { return translateInfoCode; }
324 
325  static void translateInfoCode(std::ostream& aStream, const uint8_t& aErrorCode);
326 
328  uint16_t mPacketCounter;
329 
330  boost::mutex mReceivePacketMutex;
331  std::deque< uint32_t > mReceivePacketHeader;
332 
333  };
334 
335 
336 }
337 
338 
339 #endif
virtual uint32_t getMaxNumberOfBuffers()
Return the maximum number of packets in flight.
A class which provides the version-specific functionality for IPbus.
uint8_t requestTransactionInfoCode() const
Returns the InfoCode for request transactions in this IPbus version.
boost::function< void(std::ostream &, const uint8_t &)> getInfoCodeTranslator()
eIPbusTransactionType
Enumerated type to define the IPbus transaction type.
uint32_t getMaxTransactionWordCount() const
Returns the maximum value of the word count in the transaction header, for each IPbus version...
uint32_t getMaxTransactionWordCount() const
Returns the maximum value of the word count in the transaction header, for each IPbus version...
#define UHAL_DEFINE_DERIVED_EXCEPTION_CLASS(ClassName, BaseClassName, ClassDescription)
Macro for simplifying the declaration and definition of derived exception types.
Definition: exception.hpp:54
An abstract base exception class providing an interface to a throw/ThrowAsDerivedType mechanism which...
Definition: exception.hpp:89
A class providing the core IPbus packing functionality.
virtual uint32_t getMaxNumberOfBuffers()
Return the maximum number of packets in flight.
std::deque< uint32_t > mReceivePacketHeader
uint8_t requestTransactionInfoCode() const
Returns the InfoCode for request transactions in this IPbus version.
boost::function< void(std::ostream &, const uint8_t &)> getInfoCodeTranslator()
uint16_t mPacketCounter
The transaction counter which will be incremented in the sent IPbus headers.
Struct to store a URI when parsed by boost spirit.
Definition: URI.hpp:49