μHAL (v2.7.9)
Part of the IPbus software repository
ClientFactory.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/ClientFactory.hpp"
34 
35 #include <algorithm>
36 
37 #include <boost/spirit/include/qi.hpp>
38 
40 #include "uhal/ProtocolUDP.hpp"
41 #include "uhal/ProtocolTCP.hpp"
42 #include "uhal/ProtocolIPbus.hpp"
44 #include "uhal/ProtocolMmap.hpp"
45 #include "uhal/ProtocolPCIe.hpp"
46 
47 
48 
49 namespace uhal
50 {
51 
53 
54 
56  {
57  }
58 
59 
61  {
62  }
63 
64 
66  {
67  if ( ! mInstance )
68  {
69  mInstance.reset(new ClientFactory());
70  // ---------------------------------------------------------------------
71  mInstance->add< UDP< IPbus< 1 , 3 > > > ( "ipbusudp-1.3" , "Direct access to hardware via UDP, using IPbus version 1.3", false );
72  mInstance->add< UDP< IPbus< 2 , 0 > > > ( "ipbusudp-2.0" , "Direct access to hardware via UDP, using IPbus version 2.0", false );
73  // ---------------------------------------------------------------------
74  mInstance->add< TCP< IPbus< 1 , 3 > , 1 > > ( "ipbustcp-1.3" , "Direct access to hardware via TCP, using IPbus version 1.3", false );
75  mInstance->add< TCP< IPbus< 2 , 0 > , 1 > > ( "ipbustcp-2.0" , "Direct access to hardware via TCP, using IPbus version 2.0", false );
76  // ---------------------------------------------------------------------
77  mInstance->add< TCP< ControlHub < IPbus< 1 , 3 > > , 3 > > ( "chtcp-1.3", "Hardware access via the Control Hub, using IPbus version 1.3", false );
78  mInstance->add< TCP< ControlHub < IPbus< 2 , 0 > > , 3 > > ( "chtcp-2.0", "Hardware access via the Control Hub, using IPbus version 2.0", false );
79  // ---------------------------------------------------------------------
80  mInstance->add< PCIe > ( "ipbuspcie-2.0" , "Direct access to hardware via PCIe, using IPbus version 2.0", false );
81  mInstance->add< Mmap > ( "ipbusmmap-2.0" , "Direct access to hardware via mmap, using IPbus version 2.0", false );
82  // ---------------------------------------------------------------------
83 
84  }
85 
86  return *mInstance;
87  }
88 
89 
90  boost::shared_ptr<ClientInterface> ClientFactory::getClient ( const std::string& aId , const std::string& aUri )
91  {
92  return getClient(aId, aUri, std::vector<std::string>());
93  }
94 
95 
96  boost::shared_ptr<ClientInterface> ClientFactory::getClient ( const std::string& aId , const std::string& aUri, const std::vector<std::string>& aUserClientActivationList )
97  {
98  URI lUri;
99 
100  try
101  {
102  grammars::URIGrammar lGrammar;
103  std::string::const_iterator lBegin ( aUri.begin() );
104  std::string::const_iterator lEnd ( aUri.end() );
105  boost::spirit::qi::phrase_parse ( lBegin , lEnd , lGrammar , boost::spirit::ascii::space , lUri );
106  }
107  catch ( const std::exception& aExc )
108  {
109  exception::FailedToParseURI lExc;
110  log ( lExc , "Failed to parse device URI " , Quote ( aUri ) );
111  throw lExc;
112  }
113 
114  log ( Info() , "URI " , Quote ( aUri ) , " parsed as:\n" , lUri );
115  boost::unordered_map< std::string , ClientInfo >::const_iterator lIt = mClientMap.find ( lUri.mProtocol );
116 
117  if ( lIt == mClientMap.end() )
118  {
119  std::stringstream lStr;
120 
121  for (lIt = mClientMap.begin() ; lIt != mClientMap.end() ; ++lIt )
122  {
123  lStr << "\n > " << lIt->first << "\t: " << lIt->second.description;
124  }
125 
126  exception::ProtocolDoesNotExist lExc;
127  log ( lExc , "Protocol " , Quote ( lUri.mProtocol ) , " does not exists in map of creators. Options are:" , lStr.str() );
128  throw lExc;
129  }
130  else if (lIt->second.userDefined)
131  {
132  std::vector<std::string>::const_iterator lIt2 = std::find(aUserClientActivationList.begin(), aUserClientActivationList.end(), lUri.mProtocol);
133 
134  if (lIt2 == aUserClientActivationList.end()) {
135  exception::ProtocolNotEnabled lExc;
136  log ( lExc , "Protocol " , Quote ( lUri.mProtocol ) , " with user-defined client is not activated");
137  throw lExc;
138  }
139  }
140 
141  return lIt->second.creator->create ( aId , lUri );
142  }
143 
144 }
145 
uhal::ClientFactory::mInstance
static boost::shared_ptr< ClientFactory > mInstance
The single instance of the class.
Definition: ClientFactory.hpp:196
ProtocolPCIe.hpp
boost::shared_ptr
Definition: DerivedNodeFactory.hpp:52
uhal::ClientFactory::getInstance
static ClientFactory & getInstance()
Static method to retrieve the single instance of the class.
Definition: ClientFactory.cpp:65
uhal::ClientFactory::getClient
boost::shared_ptr< ClientInterface > getClient(const std::string &aId, const std::string &aUri)
Construct an IPbus client based on the protocol identifier specified.
Definition: ClientFactory.cpp:90
uhal::ClientFactory
A class to construct an IPbus client based on the protocol identifier specified NOTE!...
Definition: ClientFactory.hpp:75
ProtocolTCP.hpp
uhal::ClientFactory::mClientMap
boost::unordered_map< std::string, ClientInfo > mClientMap
Hash map associating a creator for a particular protocol with a file name.
Definition: ClientFactory.hpp:198
uhal::TCP
Transport protocol to transfer an IPbus buffer via TCP.
Definition: ProtocolTCP.hpp:85
uhal
Definition: HttpResponseGrammar.hpp:49
ProtocolControlHub.hpp
uhal::Info
InfoLevel Info
Definition: LogLevels.cpp:115
uhal::log
void log(FatalLevel &aFatal, const T0 &aArg0)
Function to add a log entry at Fatal level.
Definition: log.hxx:20
uhal::ClientFactory::~ClientFactory
virtual ~ClientFactory()
Destructor.
Definition: ClientFactory.cpp:60
uhal::UDP
Transport protocol to transfer an IPbus buffer via UDP.
Definition: ProtocolUDP.hpp:85
ProtocolMmap.hpp
ProtocolIPbus.hpp
uhal::Quote
_Quote< T > Quote(const T &aT)
Definition: log_inserters.quote.hxx:49
uhal::ClientFactory::ClientFactory
ClientFactory()
Default constructor This is private since only a single instance is to be created,...
Definition: ClientFactory.cpp:55
URIGrammar.hpp
uhal::URI::mProtocol
std::string mProtocol
The "protocol" part of a URI of the form "protocol://host:port/patha/pathb/blah.ext?...
Definition: URI.hpp:52
uhal::Mmap
Transport protocol to transfer an IPbus buffer via device file, using mmap.
Definition: ProtocolMmap.hpp:84
uhal::URI
Struct to store a URI when parsed by boost spirit.
Definition: URI.hpp:50
uhal::PCIe
Transport protocol to transfer an IPbus buffer via PCIe.
Definition: ProtocolPCIe.hpp:89
ProtocolUDP.hpp
ClientFactory.hpp