μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
34
35#include <algorithm>
36
37#include <boost/spirit/include/qi.hpp>
38
40#include "uhal/ProtocolUDP.hpp"
41#include "uhal/ProtocolTCP.hpp"
44#include "uhal/ProtocolMmap.hpp"
45#include "uhal/ProtocolPCIe.hpp"
46
47
48
49namespace uhal
50{
51
52 std::shared_ptr<ClientFactory> ClientFactory::mInstance;
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 std::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 std::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 const auto lIt = mClientMap.find ( lUri.mProtocol );
116
117 if ( lIt == mClientMap.end() )
118 {
119 std::stringstream lStr;
120
121 for (const auto& c: mClientMap)
122 lStr << "\n > " << c.first << "\t: " << c.second.description;
123
124 exception::ProtocolDoesNotExist lExc;
125 log ( lExc , "Protocol " , Quote ( lUri.mProtocol ) , " does not exists in map of creators. Options are:" , lStr.str() );
126 throw lExc;
127 }
128 else if (lIt->second.userDefined)
129 {
130 std::vector<std::string>::const_iterator lIt2 = std::find(aUserClientActivationList.begin(), aUserClientActivationList.end(), lUri.mProtocol);
131
132 if (lIt2 == aUserClientActivationList.end()) {
133 exception::ProtocolNotEnabled lExc;
134 log ( lExc , "Protocol " , Quote ( lUri.mProtocol ) , " with user-defined client is not activated");
135 throw lExc;
136 }
137 }
138
139 return lIt->second.creator->create ( aId , lUri );
140 }
141
142}
143
A class to construct an IPbus client based on the protocol identifier specified NOTE!...
ClientFactory()
Default constructor This is private since only a single instance is to be created,...
static ClientFactory & getInstance()
Static method to retrieve the single instance of the class.
std::unordered_map< std::string, ClientInfo > mClientMap
Hash map associating a creator for a particular protocol with a file name.
static std::shared_ptr< ClientFactory > mInstance
The single instance of the class.
virtual ~ClientFactory()
Destructor.
std::shared_ptr< ClientInterface > getClient(const std::string &aId, const std::string &aUri)
Construct an IPbus client based on the protocol identifier specified.
Transport protocol to transfer an IPbus buffer via device file, using mmap.
Transport protocol to transfer an IPbus buffer via PCIe.
Transport protocol to transfer an IPbus buffer via TCP.
Definition: ProtocolTCP.hpp:84
Transport protocol to transfer an IPbus buffer via UDP.
Definition: ProtocolUDP.hpp:83
_Quote< T > Quote(const T &aT)
void log(FatalLevel &aFatal, const T0 &aArg0)
Function to add a log entry at Fatal level.
Definition: log.hxx:18
InfoLevel Info
Definition: LogLevels.cpp:115
Struct to store a URI when parsed by boost spirit.
Definition: URI.hpp:50
std::string mProtocol
The "protocol" part of a URI of the form "protocol://host:port/patha/pathb/blah.ext?...
Definition: URI.hpp:52