14#include "keyple/core/service/CardSelectionManagerAdapter.hpp"
20#include "keyple/core/service/AbstractReaderAdapter.hpp"
21#include "keyple/core/service/CardSelectionResultAdapter.hpp"
22#include "keyple/core/service/CardSelectionScenarioAdapter.hpp"
23#include "keyple/core/service/ObservableLocalReaderAdapter.hpp"
24#include "keyple/core/service/ScheduledCardSelectionsResponseAdapter.hpp"
25#include "keyple/core/util/KeypleAssert.hpp"
26#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp"
27#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
28#include "keyple/core/util/cpp/exception/UnsupportedOperationException.hpp"
29#include "keypop/card/CardBrokenCommunicationException.hpp"
30#include "keypop/card/CardSelectionResponseApi.hpp"
31#include "keypop/card/ParseException.hpp"
32#include "keypop/card/ReaderBrokenCommunicationException.hpp"
33#include "keypop/card/spi/CardSelectionExtensionSpi.hpp"
34#include "keypop/reader/CardCommunicationException.hpp"
35#include "keypop/reader/ReaderCommunicationException.hpp"
36#include "keypop/reader/cpp/CardSelectorBase.hpp"
37#include "keypop/reader/selection/InvalidCardResponseException.hpp"
38#include "keypop/reader/selection/spi/SmartCard.hpp"
44using keyple::core::util::Assert;
45using keyple::core::util::cpp::exception::IllegalArgumentException;
46using keyple::core::util::cpp::exception::IllegalStateException;
47using keyple::core::util::cpp::exception::UnsupportedOperationException;
48using keypop::card::CardBrokenCommunicationException;
49using keypop::card::CardSelectionResponseApi;
50using keypop::card::ParseException;
51using keypop::card::ReaderBrokenCommunicationException;
52using keypop::card::spi::CardSelectionExtensionSpi;
53using keypop::reader::CardCommunicationException;
54using keypop::reader::ReaderCommunicationException;
55using keypop::reader::cpp::CardSelectorBase;
56using keypop::reader::selection::InvalidCardResponseException;
57using keypop::reader::selection::spi::SmartCard;
59const std::string CardSelectionManagerAdapter::MULTI_SELECTION_PROCESSING
60 =
"multiSelectionProcessing";
61const std::string CardSelectionManagerAdapter::CHANNEL_CONTROL
63const std::string CardSelectionManagerAdapter::CARD_SELECTORS_TYPES
64 =
"cardSelectorsTypes";
65const std::string CardSelectionManagerAdapter::CARD_SELECTORS =
"cardSelectors";
66const std::string CardSelectionManagerAdapter::CARD_SELECTIONS_TYPES
67 =
"cardSelectionsTypes";
68const std::string CardSelectionManagerAdapter::CARD_SELECTIONS
70const std::string CardSelectionManagerAdapter::DEFAULT_CARD_SELECTIONS
71 =
"defaultCardSelections";
73CardSelectionManagerAdapter::CardSelectionManagerAdapter()
74: mMultiSelectionProcessing(MultiSelectionProcessing::FIRST_MATCH)
75, mChannelControl(ChannelControl::KEEP_OPEN)
80CardSelectionManagerAdapter::setMultipleSelectionMode()
82 mMultiSelectionProcessing = MultiSelectionProcessing::PROCESS_ALL;
86CardSelectionManagerAdapter::prepareSelection(
87 const std::shared_ptr<CardSelectorBase> cardSelector,
88 const std::shared_ptr<CardSelectionExtension> cardSelectionExtension)
91 .notNull(cardSelector,
"cardSelector")
92 .notNull(cardSelectionExtension,
"cardSelectionExtension");
94 auto cardSelectionExtensionSpi
95 = std::dynamic_pointer_cast<CardSelectionExtensionSpi>(
96 cardSelectionExtension);
97 if (!cardSelectionExtensionSpi) {
98 throw IllegalArgumentException(
99 "The provided 'cardSelectionExtension' must be an instance"
100 " of 'CardSelectionExtensionSpi");
104 mCardSelectors.push_back(cardSelector);
105 mCardSelections.push_back(
106 std::dynamic_pointer_cast<CardSelectionExtensionSpi>(
107 cardSelectionExtension));
108 mCardSelectionRequests.push_back(
109 std::dynamic_pointer_cast<CardSelectionExtensionSpi>(
110 cardSelectionExtension)
111 ->getCardSelectionRequest());
114 return static_cast<int>(mCardSelections.size()) - 1;
118CardSelectionManagerAdapter::prepareReleaseChannel()
120 mChannelControl = ChannelControl::CLOSE_AFTER;
123const std::shared_ptr<CardSelectionResult>
124CardSelectionManagerAdapter::processCardSelectionScenario(
125 std::shared_ptr<CardReader> reader)
127 Assert::getInstance().notNull(reader,
"reader");
130 std::vector<std::shared_ptr<CardSelectionResponseApi>>
131 cardSelectionResponses;
134 cardSelectionResponses
135 = std::dynamic_pointer_cast<AbstractReaderAdapter>(reader)
136 ->transmitCardSelectionRequests(
138 mCardSelectionRequests,
139 mMultiSelectionProcessing,
142 }
catch (
const ReaderBrokenCommunicationException& e) {
143 throw ReaderCommunicationException(e.getMessage(), e);
145 }
catch (
const CardBrokenCommunicationException& e) {
146 throw CardCommunicationException(e.getMessage(), e);
150 return processCardSelectionResponses(cardSelectionResponses);
154CardSelectionManagerAdapter::scheduleCardSelectionScenario(
155 std::shared_ptr<ObservableCardReader> observableCardReader,
156 const NotificationMode notificationMode)
158 Assert::getInstance().notNull(observableCardReader,
"observableCardReader");
160 auto cardSelectionScenario = std::make_shared<CardSelectionScenarioAdapter>(
162 mCardSelectionRequests,
163 mMultiSelectionProcessing,
166 auto local = std::dynamic_pointer_cast<ObservableLocalReaderAdapter>(
167 observableCardReader);
171 local->scheduleCardSelectionScenario(
172 cardSelectionScenario, notificationMode);
177 throw IllegalArgumentException(
"Not a Keyple reader implementation");
181const std::shared_ptr<CardSelectionResult>
182CardSelectionManagerAdapter::parseScheduledCardSelectionsResponse(
183 const std::shared_ptr<ScheduledCardSelectionsResponse>
184 scheduledCardSelectionsResponse)
186 Assert::getInstance().notNull(
187 scheduledCardSelectionsResponse,
"scheduledCardSelectionsResponse");
189 return processCardSelectionResponses(
190 std::static_pointer_cast<ScheduledCardSelectionsResponseAdapter>(
191 scheduledCardSelectionsResponse)
192 ->getCardSelectionResponses());
196CardSelectionManagerAdapter::exportProcessedCardSelectionScenario()
const
200 throw IllegalStateException(
"not implemented");
203const std::shared_ptr<CardSelectionResult>
204CardSelectionManagerAdapter::importProcessedCardSelectionScenario(
205 const std::string& )
const
209 throw IllegalStateException(
"not implemented");
212const std::shared_ptr<CardSelectionResult>
213CardSelectionManagerAdapter::processCardSelectionResponses(
214 const std::vector<std::shared_ptr<CardSelectionResponseApi>>&
215 cardSelectionResponses)
217 Assert::getInstance().isInRange(
218 cardSelectionResponses.size(),
220 mCardSelections.size(),
221 "cardSelectionResponses");
223 auto cardSelectionsResult = std::make_shared<CardSelectionResultAdapter>();
226 for (
const auto& cardSelectionResponse : cardSelectionResponses) {
227 if (cardSelectionResponse->hasMatched()) {
230 std::shared_ptr<SmartCard> smartCard =
nullptr;
232 smartCard = std::dynamic_pointer_cast<SmartCard>(
233 mCardSelections[index]->parse(cardSelectionResponse));
235 }
catch (
const ParseException& e) {
236 throw InvalidCardResponseException(
237 "Error occurred while parsing the card response: "
241 }
catch (
const UnsupportedOperationException&) {
243 "Unable to parse card selection responses due to "
245 "extensions in runtime environment");
247 = std::make_shared<CardSelectionResultAdapter>();
252 cardSelectionsResult->addSmartCard(index, smartCard);
258 mCardSelectionResponses = cardSelectionResponses;
260 return cardSelectionsResult;
264CardSelectionManagerAdapter::exportCardSelectionScenario()
const
272CardSelectionManagerAdapter::importCardSelectionScenario(
273 const std::string& cardSelectionScenario)
277 (void)cardSelectionScenario;