14#include "keyple/core/service/SmartCardServiceAdapter.hpp"
21#include "keyple/core/common/CommonApiProperties.hpp"
22#include "keyple/core/plugin/PluginApiProperties.hpp"
23#include "keyple/core/plugin/PluginIOException.hpp"
24#include "keyple/core/plugin/spi/AutonomousObservablePluginSpi.hpp"
25#include "keyple/core/plugin/spi/ObservablePluginSpi.hpp"
26#include "keyple/core/plugin/spi/PluginSpi.hpp"
27#include "keyple/core/plugin/spi/PoolPluginSpi.hpp"
28#include "keyple/core/service/AutonomousObservableLocalPluginAdapter.hpp"
29#include "keyple/core/service/KeyplePluginException.hpp"
30#include "keyple/core/service/LocalPoolPluginAdapter.hpp"
31#include "keyple/core/service/ObservableLocalPluginAdapter.hpp"
32#include "keyple/core/service/ReaderApiFactoryAdapter.hpp"
33#include "keyple/core/util/KeypleAssert.hpp"
34#include "keyple/core/util/cpp/KeypleStd.hpp"
35#include "keyple/core/util/cpp/StringUtils.hpp"
36#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp"
37#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
38#include "keyple/core/util/cpp/exception/PatternSyntaxException.hpp"
39#include "keypop/card/CardApiProperties.hpp"
40#include "keypop/reader/ReaderApiProperties.hpp"
46using keyple::core::common::CommonApiProperties_VERSION;
47using keyple::core::plugin::PluginApiProperties_VERSION;
48using keyple::core::plugin::PluginIOException;
49using keyple::core::plugin::spi::AutonomousObservablePluginSpi;
50using keyple::core::plugin::spi::ObservablePluginSpi;
51using keyple::core::plugin::spi::PluginSpi;
52using keyple::core::plugin::spi::PoolPluginSpi;
53using keyple::core::service::AutonomousObservableLocalPluginAdapter;
54using keyple::core::service::KeyplePluginException;
55using keyple::core::service::LocalPoolPluginAdapter;
56using keyple::core::service::ReaderApiFactoryAdapter;
57using keyple::core::util::Assert;
58using keyple::core::util::cpp::StringUtils;
59using keyple::core::util::cpp::exception::IllegalArgumentException;
60using keyple::core::util::cpp::exception::IllegalStateException;
61using keyple::core::util::cpp::exception::PatternSyntaxException;
62using keypop::card::CardApiProperties_VERSION;
63using keypop::reader::ReaderApiProperties_VERSION;
65const std::string SmartCardServiceAdapter::MSG_VERSION_MISMATCH_DETECTED
66 =
"Version mismatch detected: % [%] uses '%' version '%' (expected '%'). "
67 "Compatibility issues "
70std::shared_ptr<SmartCardServiceAdapter> SmartCardServiceAdapter::mInstance;
72std::shared_ptr<SmartCardServiceAdapter>
73SmartCardServiceAdapter::getInstance()
75 if (mInstance ==
nullptr) {
76 mInstance = std::shared_ptr<SmartCardServiceAdapter>(
77 new SmartCardServiceAdapter());
84SmartCardServiceAdapter::compareVersions(
85 const std::string& providedVersion,
const std::string& localVersion)
const
87 const std::regex re(
"[.]");
89 std::vector<std::string> providedVersions;
90 std::split(providedVersion, re, std::back_inserter(providedVersions));
92 std::vector<std::string> localVersions;
93 std::split(localVersion, re, std::back_inserter(localVersions));
95 if (providedVersions.size() != localVersions.size()) {
96 throw IllegalStateException(
97 "Inconsistent version numbers: provided = " + providedVersion
98 +
", local = " + localVersion);
105 for (
const auto& v : providedVersions) {
106 provided += std::stoi(v);
109 for (
const auto& v : localVersions) {
110 local += std::stoi(v);
115 }
catch (
const std::invalid_argument&) {
116 throw IllegalStateException(
117 std::string(
"Bad version numbers: provided = ") + providedVersion
118 +
", local = " + localVersion);
122 return provided != local;
126SmartCardServiceAdapter::checkPluginVersion(
127 const std::shared_ptr<PluginFactorySpi> pluginFactorySpi)
130 pluginFactorySpi->getCommonApiVersion(),
131 CommonApiProperties_VERSION)
134 MSG_VERSION_MISMATCH_DETECTED,
135 std::string(
"plugin"),
136 pluginFactorySpi->getPluginName(),
137 std::string(
"Common API"),
138 pluginFactorySpi->getCommonApiVersion(),
139 CommonApiProperties_VERSION);
143 pluginFactorySpi->getPluginApiVersion(),
144 PluginApiProperties_VERSION)
147 MSG_VERSION_MISMATCH_DETECTED,
148 std::string(
"plugin"),
149 pluginFactorySpi->getPluginName(),
150 std::string(
"Plugin API"),
151 pluginFactorySpi->getPluginApiVersion(),
152 PluginApiProperties_VERSION);
156std::shared_ptr<Plugin>
157SmartCardServiceAdapter::registerPlugin(
158 const std::shared_ptr<KeyplePluginExtensionFactory> pluginFactory)
160 Assert::getInstance().notNull(pluginFactory,
"pluginFactory");
162 std::shared_ptr<AbstractPluginAdapter> plugin =
nullptr;
164 const std::lock_guard<std::mutex> lock(mMutex);
167 const auto factorySpi
168 = std::dynamic_pointer_cast<PluginFactorySpi>(pluginFactory);
170 = std::dynamic_pointer_cast<PoolPluginFactorySpi>(pluginFactory);
172 plugin = createLocalPlugin(factorySpi);
173 }
else if (poolSpi) {
174 plugin = createLocalPoolPlugin(poolSpi);
179 throw IllegalArgumentException(
180 "The factory doesn't implement the right SPI");
183 mPlugins.insert({plugin->getName(), plugin});
184 plugin->doRegister();
186 }
catch (
const IllegalArgumentException& e) {
187 throw IllegalArgumentException(
188 "The provided plugin factory doesn't implement the plugin"
192 }
catch (
const PluginIOException& e) {
193 throw KeyplePluginException(
194 std::string(
"Unable to register the plugin [") + plugin->getName()
195 +
"]: " + e.getMessage(),
203SmartCardServiceAdapter::unregisterPlugin(
const std::string& pluginName)
205 mLogger->info(
"Unregister plugin [%]\n", pluginName);
207 const std::lock_guard<std::mutex> lock(mMutex);
209 auto i = mPlugins.find(pluginName);
210 if (i != mPlugins.end()) {
211 std::shared_ptr<Plugin> removedPlugin = std::move(i->second);
212 std::dynamic_pointer_cast<AbstractPluginAdapter>(removedPlugin)
217 mLogger->warn(
"Plugin [%] not registered\n", pluginName);
221const std::vector<std::string>
222SmartCardServiceAdapter::getPluginNames()
const
224 std::vector<std::string> pluginNames;
225 for (
const auto& pair : mPlugins) {
226 pluginNames.push_back(pair.first);
232const std::vector<std::shared_ptr<Plugin>>
233SmartCardServiceAdapter::getPlugins()
const
235 std::vector<std::shared_ptr<Plugin>> plugins;
236 for (
const auto& pair : mPlugins) {
237 plugins.push_back(pair.second);
243std::shared_ptr<Plugin>
244SmartCardServiceAdapter::getPlugin(
const std::string& pluginName)
const
246 auto it = mPlugins.find(pluginName);
247 if (it != mPlugins.end()) {
254std::shared_ptr<Plugin>
255SmartCardServiceAdapter::getPlugin(
256 const std::shared_ptr<CardReader> cardReader)
const
258 for (
const auto& plugin : mPlugins) {
259 const auto& readers = plugin.second->getReaders();
263 [cardReader](
const std::shared_ptr<CardReader>& reader) {
264 return reader == cardReader;
266 return plugin.second;
273std::shared_ptr<CardReader>
274SmartCardServiceAdapter::getReader(
const std::string& readerName)
const
276 for (
const auto& plugin : mPlugins) {
277 const auto& readers = plugin.second->getReaders();
278 auto it = std::find_if(
281 [readerName](
const std::shared_ptr<CardReader>& reader) {
282 return reader->getName() == readerName;
284 if (it != readers.end()) {
292std::shared_ptr<CardReader>
293SmartCardServiceAdapter::findReader(
const std::string& readerNameRegex)
const
295 for (
const auto& plugin : mPlugins) {
296 std::shared_ptr<CardReader> reader(
297 plugin.second->findReader(readerNameRegex));
298 if (reader !=
nullptr) {
307SmartCardServiceAdapter::checkCardExtension(
308 const std::shared_ptr<KeypleCardExtension> cardExtension)
const
310 checkCardExtensionVersion(cardExtension);
313std::unique_ptr<ReaderApiFactory>
314SmartCardServiceAdapter::getReaderApiFactory()
316 return std::unique_ptr<ReaderApiFactoryAdapter>(
317 new ReaderApiFactoryAdapter());
321SmartCardServiceAdapter::checkPoolPluginVersion(
322 const std::shared_ptr<PoolPluginFactorySpi> poolPluginFactorySpi)
325 poolPluginFactorySpi->getCommonApiVersion(),
326 CommonApiProperties_VERSION)
329 MSG_VERSION_MISMATCH_DETECTED,
330 std::string(
"pool plugin"),
331 poolPluginFactorySpi->getPoolPluginName(),
332 std::string(
"Common API"),
333 poolPluginFactorySpi->getCommonApiVersion(),
334 CommonApiProperties_VERSION);
338 poolPluginFactorySpi->getPluginApiVersion(),
339 PluginApiProperties_VERSION)
342 MSG_VERSION_MISMATCH_DETECTED,
343 std::string(
"pool plugin"),
344 poolPluginFactorySpi->getPoolPluginName(),
345 std::string(
"Plugin API"),
346 poolPluginFactorySpi->getPluginApiVersion(),
347 PluginApiProperties_VERSION);
352SmartCardServiceAdapter::checkCardExtensionVersion(
353 const std::shared_ptr<KeypleCardExtension> cardExtension)
const
356 cardExtension->getCommonApiVersion(), CommonApiProperties_VERSION)
358 const auto& c = *cardExtension.get();
360 MSG_VERSION_MISMATCH_DETECTED,
361 std::string(
"card extension"),
362 std::string(
typeid(c).name()),
363 std::string(
"Common API"),
364 cardExtension->getCommonApiVersion(),
365 CommonApiProperties_VERSION);
369 cardExtension->getCardApiVersion(), CardApiProperties_VERSION)
371 const auto& c = *cardExtension.get();
373 MSG_VERSION_MISMATCH_DETECTED,
374 std::string(
"card extension"),
375 std::string(
typeid(c).name()),
376 std::string(
"Card API"),
377 cardExtension->getCardApiVersion(),
378 CardApiProperties_VERSION);
382 cardExtension->getReaderApiVersion(), ReaderApiProperties_VERSION)
384 const auto& c = *cardExtension.get();
386 MSG_VERSION_MISMATCH_DETECTED,
387 std::string(
"card extension"),
388 std::string(
typeid(c).name()),
389 std::string(
"Reader API"),
390 cardExtension->getReaderApiVersion(),
391 ReaderApiProperties_VERSION);
396SmartCardServiceAdapter::checkPluginRegistration(
const std::string& pluginName)
398 mLogger->info(
"Registering a new Plugin to the service : %\n", pluginName);
400 const auto it = mPlugins.find(pluginName);
401 if (it != mPlugins.end()) {
402 throw IllegalStateException(
403 "Plugin [" + pluginName
404 +
"] has already been registered to the service.");
408std::shared_ptr<AbstractPluginAdapter>
409SmartCardServiceAdapter::createLocalPlugin(
410 std::shared_ptr<PluginFactorySpi> pluginFactorySpi)
412 checkPluginRegistration(pluginFactorySpi->getPluginName());
413 checkPluginVersion(pluginFactorySpi);
415 std::shared_ptr<PluginSpi> pluginSpi = pluginFactorySpi->getPlugin();
417 if (pluginSpi->getName() != pluginFactorySpi->getPluginName()) {
418 throw IllegalArgumentException(
419 std::string(
"Plugin name [") + pluginSpi->getName()
420 + std::string(
"] mismatches the expected name [")
421 + pluginFactorySpi->getPluginName()
422 + std::string(
"] provided by the factory"));
425 std::shared_ptr<AbstractPluginAdapter> plugin =
nullptr;
427 auto observable = std::dynamic_pointer_cast<ObservablePluginSpi>(pluginSpi);
429 plugin = std::make_shared<ObservableLocalPluginAdapter>(observable);
432 = std::dynamic_pointer_cast<AutonomousObservablePluginSpi>(
435 plugin = std::make_shared<AutonomousObservableLocalPluginAdapter>(
438 plugin = std::make_shared<LocalPluginAdapter>(pluginSpi);
445std::shared_ptr<AbstractPluginAdapter>
446SmartCardServiceAdapter::createLocalPoolPlugin(
447 std::shared_ptr<PoolPluginFactorySpi> poolPluginFactorySpi)
449 checkPluginRegistration(poolPluginFactorySpi->getPoolPluginName());
450 checkPoolPluginVersion(poolPluginFactorySpi);
452 std::shared_ptr<PoolPluginSpi> poolPluginSpi
453 = poolPluginFactorySpi->getPoolPlugin();
455 if (poolPluginSpi->getName() != poolPluginFactorySpi->getPoolPluginName()) {
456 throw IllegalArgumentException(
457 std::string(
"Pool plugin name [") + poolPluginSpi->getName()
458 +
"] mismatches the expected name ["
459 + poolPluginFactorySpi->getPoolPluginName()
460 +
"] provided by the factory");
463 return std::make_shared<LocalPoolPluginAdapter>(poolPluginSpi);