14#include "keyple/core/service/resource/ReaderManagerAdapter.hpp"
16#include "keyple/core/service/SmartCardServiceProvider.hpp"
17#include "keyple/core/service/resource/CardResourceAdapter.hpp"
18#include "keyple/core/util/cpp/Arrays.hpp"
19#include "keyple/core/util/cpp/System.hpp"
20#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
21#include "keypop/reader/selection/spi/IsoSmartCard.hpp"
28using keyple::core::service::SmartCardServiceProvider;
29using keyple::core::service::resource::CardResourceAdapter;
30using keyple::core::util::cpp::Arrays;
31using keyple::core::util::cpp::System;
32using keyple::core::util::cpp::exception::IllegalStateException;
33using keypop::reader::selection::spi::IsoSmartCard;
35ReaderManagerAdapter::ReaderManagerAdapter(
36 std::shared_ptr<CardReader> reader,
37 std::shared_ptr<Plugin> plugin,
38 std::shared_ptr<ReaderConfiguratorSpi> readerConfiguratorSpi,
39 const int usageTimeoutMillis)
41, mReaderExtension(plugin->getReaderExtension(
42 typeid(KeypleReaderExtension), reader->getName()))
44, mReaderConfiguratorSpi(readerConfiguratorSpi)
45, mUsageTimeoutMillis(usageTimeoutMillis)
46, mSelectedCardResource(nullptr)
52std::shared_ptr<CardReader>
53ReaderManagerAdapter::getReader()
const
58std::shared_ptr<Plugin>
59ReaderManagerAdapter::getPlugin()
const
64const std::vector<std::shared_ptr<CardResourceAdapter>>&
65ReaderManagerAdapter::getCardResources()
const
67 return mCardResources;
71ReaderManagerAdapter::isActive()
const
77ReaderManagerAdapter::activate()
80 mReaderConfiguratorSpi->setupReader(mReader);
86std::shared_ptr<CardResourceAdapter>
87ReaderManagerAdapter::matches(
88 std::shared_ptr<CardResourceProfileExtension> extension)
90 std::shared_ptr<CardResourceAdapter> cardResource =
nullptr;
91 std::shared_ptr<SmartCard> smartCard = extension->matches(
92 mReader, SmartCardServiceProvider::getService()->getReaderApiFactory());
94 if (smartCard !=
nullptr) {
95 cardResource = getOrCreateCardResource(smartCard);
96 mSelectedCardResource = cardResource;
105ReaderManagerAdapter::lock(
106 std::shared_ptr<CardResource> cardResource,
107 std::shared_ptr<CardResourceProfileExtension> extension)
110 if (mUsageTimeoutMillis == 0
111 ||
static_cast<uint64_t
>(System::currentTimeMillis())
112 < mLockMaxTimeMillis) {
117 "Reader automatically unlocked due to a usage timeout exceeded " \
118 "[reader=%, usageTimeoutMs=%]\n",
120 mUsageTimeoutMillis);
123 if (mSelectedCardResource != cardResource) {
124 std::shared_ptr<SmartCard> smartCard = extension->matches(
126 SmartCardServiceProvider::getService()->getReaderApiFactory());
128 if (!areEquals(cardResource->getSmartCard(), smartCard)) {
129 mSelectedCardResource =
nullptr;
130 throw IllegalStateException(
131 "No card is inserted or its profile does not match the "
135 mSelectedCardResource = cardResource;
138 mLockMaxTimeMillis = System::currentTimeMillis() + mUsageTimeoutMillis;
145ReaderManagerAdapter::unlock()
151ReaderManagerAdapter::removeCardResource(
152 std::shared_ptr<CardResource> cardResource)
156 std::dynamic_pointer_cast<CardResourceAdapter>(cardResource));
158 if (mSelectedCardResource == cardResource) {
159 mSelectedCardResource =
nullptr;
163std::shared_ptr<CardResourceAdapter>
164ReaderManagerAdapter::getOrCreateCardResource(
165 std::shared_ptr<SmartCard> smartCard)
168 for (
const auto& cardResource : mCardResources) {
169 if (areEquals(cardResource->getSmartCard(), smartCard)) {
175 auto cardResource = std::make_shared<CardResourceAdapter>(
176 mReader, mReaderExtension, smartCard);
177 mCardResources.push_back(cardResource);
183ReaderManagerAdapter::areEquals(
184 const std::shared_ptr<SmartCard> s1,
const std::shared_ptr<SmartCard> s2)
190 if (s1 ==
nullptr || s2 ==
nullptr) {
194 bool hasSamePowerOnData
195 = (s1->getPowerOnData() ==
"" && s2->getPowerOnData() ==
"")
196 || (s1->getPowerOnData() !=
""
197 && s1->getPowerOnData() == s2->getPowerOnData());
200 const auto _s1 = std::dynamic_pointer_cast<IsoSmartCard>(s1);
201 const auto _s2 = std::dynamic_pointer_cast<IsoSmartCard>(s2);
203 hasSameFci = Arrays::equals(
204 _s1->getSelectApplicationResponse(),
205 _s2->getSelectApplicationResponse());
210 return hasSamePowerOnData && hasSameFci;