14#include "keyple/core/service/CardSelectionManagerAdapter.hpp"
21#include "keyple/core/service/AbstractReaderAdapter.hpp"
22#include "keyple/core/service/CardSelectionResultAdapter.hpp"
23#include "keyple/core/service/CardSelectionScenarioAdapter.hpp"
24#include "keyple/core/service/ObservableLocalReaderAdapter.hpp"
25#include "keyple/core/service/ScheduledCardSelectionsResponseAdapter.hpp"
26#include "keyple/core/util/KeypleAssert.hpp"
27#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp"
28#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
29#include "keyple/core/util/cpp/exception/UnsupportedOperationException.hpp"
30#include "keypop/card/CardBrokenCommunicationException.hpp"
31#include "keypop/card/CardSelectionResponseApi.hpp"
32#include "keypop/card/ParseException.hpp"
33#include "keypop/card/ReaderBrokenCommunicationException.hpp"
34#include "keypop/card/spi/CardSelectionExtensionSpi.hpp"
35#include "keypop/reader/CardCommunicationException.hpp"
36#include "keypop/reader/ReaderCommunicationException.hpp"
37#include "keypop/reader/cpp/CardSelectorBase.hpp"
38#include "keypop/reader/selection/InvalidCardResponseException.hpp"
39#include "keypop/reader/selection/spi/SmartCard.hpp"
45using keyple::core::util::Assert;
46using keyple::core::util::cpp::exception::IllegalArgumentException;
47using keyple::core::util::cpp::exception::IllegalStateException;
48using keyple::core::util::cpp::exception::UnsupportedOperationException;
49using keypop::card::CardBrokenCommunicationException;
50using keypop::card::CardSelectionResponseApi;
51using keypop::card::ParseException;
52using keypop::card::ReaderBrokenCommunicationException;
53using keypop::card::spi::CardSelectionExtensionSpi;
54using keypop::reader::CardCommunicationException;
55using keypop::reader::ReaderCommunicationException;
56using keypop::reader::cpp::CardSelectorBase;
57using keypop::reader::selection::InvalidCardResponseException;
58using keypop::reader::selection::spi::SmartCard;
60const std::string CardSelectionManagerAdapter::MULTI_SELECTION_PROCESSING
61 =
"multiSelectionProcessing";
62const std::string CardSelectionManagerAdapter::CHANNEL_CONTROL
64const std::string CardSelectionManagerAdapter::CARD_SELECTORS_TYPES
65 =
"cardSelectorsTypes";
66const std::string CardSelectionManagerAdapter::CARD_SELECTORS =
"cardSelectors";
67const std::string CardSelectionManagerAdapter::CARD_SELECTIONS_TYPES
68 =
"cardSelectionsTypes";
69const std::string CardSelectionManagerAdapter::CARD_SELECTIONS
71const std::string CardSelectionManagerAdapter::DEFAULT_CARD_SELECTIONS
72 =
"defaultCardSelections";
74CardSelectionManagerAdapter::CardSelectionManagerAdapter()
75: mMultiSelectionProcessing(MultiSelectionProcessing::FIRST_MATCH)
76, mChannelControl(ChannelControl::KEEP_OPEN)
81CardSelectionManagerAdapter::setMultipleSelectionMode()
83 mMultiSelectionProcessing = MultiSelectionProcessing::PROCESS_ALL;
87CardSelectionManagerAdapter::prepareSelection(
88 const std::shared_ptr<CardSelectorBase> cardSelector,
89 const std::shared_ptr<CardSelectionExtension> cardSelectionExtension)
92 .notNull(cardSelector,
"cardSelector")
93 .notNull(cardSelectionExtension,
"cardSelectionExtension");
95 auto cardSelectionExtensionSpi
96 = std::dynamic_pointer_cast<CardSelectionExtensionSpi>(
97 cardSelectionExtension);
98 if (!cardSelectionExtensionSpi) {
99 throw IllegalArgumentException(
101 "Cannot cast 'cardSelectionExtension' to "
102 "CardSelectionExtensionSpi. Actual type: ")
103 +
typeid(cardSelectionExtension).name());
107 mCardSelectors.push_back(cardSelector);
108 mCardSelections.push_back(
109 std::dynamic_pointer_cast<CardSelectionExtensionSpi>(
110 cardSelectionExtension));
111 mCardSelectionRequests.push_back(
112 std::dynamic_pointer_cast<CardSelectionExtensionSpi>(
113 cardSelectionExtension)
114 ->getCardSelectionRequest());
117 return static_cast<int>(mCardSelections.size()) - 1;
121CardSelectionManagerAdapter::prepareReleaseChannel()
123 mChannelControl = ChannelControl::CLOSE_AFTER;
126const std::shared_ptr<CardSelectionResult>
127CardSelectionManagerAdapter::processCardSelectionScenario(
128 std::shared_ptr<CardReader> reader)
130 Assert::getInstance().notNull(reader,
"reader");
133 std::vector<std::shared_ptr<CardSelectionResponseApi>>
134 cardSelectionResponses;
137 cardSelectionResponses
138 = std::dynamic_pointer_cast<AbstractReaderAdapter>(reader)
139 ->transmitCardSelectionRequests(
141 mCardSelectionRequests,
142 mMultiSelectionProcessing,
145 }
catch (
const ReaderBrokenCommunicationException& e) {
146 throw ReaderCommunicationException(e.getMessage(), e);
148 }
catch (
const CardBrokenCommunicationException& e) {
149 throw CardCommunicationException(e.getMessage(), e);
153 return processCardSelectionResponses(cardSelectionResponses);
157CardSelectionManagerAdapter::scheduleCardSelectionScenario(
158 std::shared_ptr<ObservableCardReader> observableCardReader,
159 const NotificationMode notificationMode)
161 Assert::getInstance().notNull(observableCardReader,
"observableCardReader");
163 auto cardSelectionScenario = std::make_shared<CardSelectionScenarioAdapter>(
165 mCardSelectionRequests,
166 mMultiSelectionProcessing,
169 auto local = std::dynamic_pointer_cast<ObservableLocalReaderAdapter>(
170 observableCardReader);
174 local->scheduleCardSelectionScenario(
175 cardSelectionScenario, notificationMode);
180 throw IllegalArgumentException(
"Not a Keyple reader implementation");
184const std::shared_ptr<CardSelectionResult>
185CardSelectionManagerAdapter::parseScheduledCardSelectionsResponse(
186 const std::shared_ptr<ScheduledCardSelectionsResponse>
187 scheduledCardSelectionsResponse)
189 Assert::getInstance().notNull(
190 scheduledCardSelectionsResponse,
"scheduledCardSelectionsResponse");
192 return processCardSelectionResponses(
193 std::static_pointer_cast<ScheduledCardSelectionsResponseAdapter>(
194 scheduledCardSelectionsResponse)
195 ->getCardSelectionResponses());
199CardSelectionManagerAdapter::exportProcessedCardSelectionScenario()
const
203 throw IllegalStateException(
"not implemented");
206const std::shared_ptr<CardSelectionResult>
207CardSelectionManagerAdapter::importProcessedCardSelectionScenario(
208 const std::string& )
const
212 throw IllegalStateException(
"not implemented");
215const std::shared_ptr<CardSelectionResult>
216CardSelectionManagerAdapter::processCardSelectionResponses(
217 const std::vector<std::shared_ptr<CardSelectionResponseApi>>&
218 cardSelectionResponses)
220 Assert::getInstance().isInRange(
221 cardSelectionResponses.size(),
223 mCardSelections.size(),
224 "cardSelectionResponses");
226 auto cardSelectionsResult = std::make_shared<CardSelectionResultAdapter>();
229 for (
const auto& cardSelectionResponse : cardSelectionResponses) {
230 if (cardSelectionResponse->hasMatched()) {
233 std::shared_ptr<SmartCard> smartCard =
nullptr;
235 smartCard = std::dynamic_pointer_cast<SmartCard>(
236 mCardSelections[index]->parse(cardSelectionResponse));
238 }
catch (
const ParseException& e) {
239 std::stringstream ss;
240 ss << cardSelectionResponse;
241 throw InvalidCardResponseException(
242 std::string(
"Failed to parse the card response: ")
246 }
catch (
const UnsupportedOperationException&) {
248 "Unable to parse card selection responses due to "
250 "extensions in runtime environment");
252 = std::make_shared<CardSelectionResultAdapter>();
257 cardSelectionsResult->addSmartCard(index, smartCard);
263 mCardSelectionResponses = cardSelectionResponses;
265 return cardSelectionsResult;
269CardSelectionManagerAdapter::exportCardSelectionScenario()
const
277CardSelectionManagerAdapter::importCardSelectionScenario(
278 const std::string& cardSelectionScenario)
282 (void)cardSelectionScenario;