14#include "keyple/core/service/ObservableLocalReaderAdapter.hpp"
20#include "keyple/core/plugin/CardIOException.hpp"
21#include "keyple/core/plugin/ReaderIOException.hpp"
22#include "keyple/core/service/ObservableReaderStateServiceAdapter.hpp"
23#include "keyple/core/service/ReaderEventAdapter.hpp"
24#include "keyple/core/service/ScheduledCardSelectionsResponseAdapter.hpp"
25#include "keyple/core/util/cpp/Arrays.hpp"
26#include "keyple/core/util/cpp/exception/Exception.hpp"
27#include "keypop/card/CardBrokenCommunicationException.hpp"
28#include "keypop/card/ReaderBrokenCommunicationException.hpp"
29#include "keypop/reader/ReaderCommunicationException.hpp"
35using keyple::core::plugin::CardIOException;
36using keyple::core::plugin::ReaderIOException;
37using keyple::core::util::cpp::Arrays;
38using keyple::core::util::cpp::exception::Exception;
39using keypop::card::CardBrokenCommunicationException;
40using keypop::card::ReaderBrokenCommunicationException;
41using keypop::reader::ReaderCommunicationException;
46ObservableLocalReaderAdapter::ObservableLocalReaderAdapterJob::
47 ObservableLocalReaderAdapterJob(
48 std::shared_ptr<CardReaderObserverSpi> observer,
49 const std::shared_ptr<CardReaderEvent> event,
50 ObservableLocalReaderAdapter* parent)
51: Job(
"ObservableLocalReaderAdapter")
59ObservableLocalReaderAdapter::ObservableLocalReaderAdapterJob::execute()
61 mParent->notifyObserver(mObserver, mEvent);
67const std::vector<uint8_t> ObservableLocalReaderAdapter::APDU_PING_CARD_PRESENCE
68 = {0x00, 0xC0, 0x00, 0x00, 0x00};
69const std::string ObservableLocalReaderAdapter::READER_MONITORING_ERROR
70 =
"An error occurred while monitoring the reader.";
72ObservableLocalReaderAdapter::ObservableLocalReaderAdapter(
73 std::shared_ptr<ObservableReaderSpi> observableReaderSpi,
74 const std::string& pluginName)
75: LocalReaderAdapter(observableReaderSpi, pluginName)
76, mObservableReaderSpi(observableReaderSpi)
77, mStateService(std::make_shared<ObservableReaderStateServiceAdapter>(this))
79 std::make_shared<ObservationManagerAdapter<
80 CardReaderObserverSpi,
81 CardReaderObservationExceptionHandlerSpi>>(pluginName, getName()))
83 auto asynchronousInsertion
84 = std::dynamic_pointer_cast<CardInsertionWaiterAsynchronousSpi>(
86 auto autonomousInsertion
87 = std::dynamic_pointer_cast<WaitForCardInsertionAutonomousSpi>(
89 if (asynchronousInsertion) {
90 asynchronousInsertion->setCallback(
this);
91 }
else if (autonomousInsertion) {
92 autonomousInsertion->connect(
this);
95 auto asynchronousRemoval
96 = std::dynamic_pointer_cast<CardRemovalWaiterAsynchronousSpi>(
98 auto autonomousRemoval
99 = std::dynamic_pointer_cast<WaitForCardRemovalAutonomousSpi>(
100 observableReaderSpi);
101 if (asynchronousRemoval) {
102 asynchronousRemoval->setCallback(
this);
103 }
else if (autonomousRemoval) {
104 autonomousRemoval->connect(
this);
108std::shared_ptr<ObservableReaderSpi>
109ObservableLocalReaderAdapter::getObservableReaderSpi()
const
111 return mObservableReaderSpi;
114std::shared_ptr<CardReaderObservationExceptionHandlerSpi>
115ObservableLocalReaderAdapter::getObservationExceptionHandler()
const
117 return mObservationManager->getObservationExceptionHandler();
121ObservableLocalReaderAdapter::getDetectionMode()
const
123 return mDetectionMode;
127ObservableLocalReaderAdapter::getCurrentMonitoringState()
const
129 return mStateService->getCurrentMonitoringState();
133ObservableLocalReaderAdapter::isCardPresentPing()
137 mObservableReaderSpi->transmitApdu(APDU_PING_CARD_PRESENCE);
138 }
catch (
const ReaderIOException& e) {
140 const auto rce = std::make_shared<ReaderCommunicationException>(
141 READER_MONITORING_ERROR, e);
142 getObservationExceptionHandler()->onReaderObservationError(
143 getPluginName(), getName(), rce);
146 }
catch (
const CardIOException&) {
153std::shared_ptr<CardReaderEvent>
154ObservableLocalReaderAdapter::processCardInserted()
157 mLogger->trace(
"Process inserted card\n");
159 mIsCardRemovedEventNotificationEnabled =
true;
161 if (mCardSelectionScenario ==
nullptr) {
163 "No card selection scenario defined. Notify "
164 "[CARD_INSERTED] event\n");
167 return std::make_shared<ReaderEventAdapter>(
170 CardReaderEvent::Type::CARD_INSERTED,
179 const std::vector<std::shared_ptr<CardSelectionResponseApi>>
180 cardSelectionResponses = transmitCardSelectionRequests(
181 mCardSelectionScenario->getCardSelectors(),
182 mCardSelectionScenario->getCardSelectionRequests(),
183 mCardSelectionScenario->getMultiSelectionProcessing(),
184 mCardSelectionScenario->getChannelControl());
186 if (hasACardMatched(cardSelectionResponses)) {
187 return std::make_shared<ReaderEventAdapter>(
190 CardReaderEvent::Type::CARD_MATCHED,
191 std::make_shared<ScheduledCardSelectionsResponseAdapter>(
192 cardSelectionResponses));
195 if (mNotificationMode == NotificationMode::MATCHED_ONLY) {
199 "Selection hasn't matched. Do not throw any event because of "
200 "[MATCHED_ONLY] flag\n");
208 "[%] none of % default selection matched\n",
210 cardSelectionResponses.size());
212 return std::make_shared<ReaderEventAdapter>(
215 CardReaderEvent::Type::CARD_INSERTED,
216 std::make_shared<ScheduledCardSelectionsResponseAdapter>(
217 cardSelectionResponses));
219 }
catch (
const ReaderBrokenCommunicationException& e) {
221 const auto rce = std::make_shared<ReaderCommunicationException>(
222 READER_MONITORING_ERROR, e);
223 getObservationExceptionHandler()->onReaderObservationError(
224 getPluginName(), getName(), rce);
226 }
catch (
const CardBrokenCommunicationException&) {
229 closeLogicalAndPhysicalChannelsSilently();
236 "Error while processing card selection scenario: %\n",
245 mObservableReaderSpi->closePhysicalChannel();
247 }
catch (
const ReaderIOException& e) {
249 const auto rce = std::make_shared<ReaderCommunicationException>(
250 READER_MONITORING_ERROR, e);
251 getObservationExceptionHandler()->onReaderObservationError(
252 getPluginName(), getName(), rce);
260ObservableLocalReaderAdapter::hasACardMatched(
261 const std::vector<std::shared_ptr<CardSelectionResponseApi>>&
262 cardSelectionResponses)
265 cardSelectionResponses.begin(),
266 cardSelectionResponses.end(),
267 [](
const std::shared_ptr<CardSelectionResponseApi>&
268 cardSelectionResponse) {
269 return cardSelectionResponse != nullptr
270 && cardSelectionResponse->hasMatched();
272 mLogger->trace(
"A default selection case matched\n");
280ObservableLocalReaderAdapter::processCardRemoved()
283 closeLogicalAndPhysicalChannelsSilently();
284 if (mIsCardRemovedEventNotificationEnabled) {
286 std::make_shared<ReaderEventAdapter>(
289 CardReaderEvent::Type::CARD_REMOVED,
295ObservableLocalReaderAdapter::switchState(
const MonitoringState stateId)
297 mStateService->switchState(stateId);
301ObservableLocalReaderAdapter::notifyObservers(
302 const std::shared_ptr<CardReaderEvent> event)
305 "Reader [%] notifies event [%] to % observer(s)\n",
310 for (
const auto& observer : mObservationManager->getObservers()) {
311 notifyObserver(observer, event);
316ObservableLocalReaderAdapter::notifyObserver(
317 std::shared_ptr<CardReaderObserverSpi> observer,
318 const std::shared_ptr<CardReaderEvent> event)
321 observer->onReaderEvent(event);
322 }
catch (
const Exception& e) {
324 mObservationManager->getObservationExceptionHandler()
325 ->onReaderObservationError(
326 getPluginName(), getName(), std::make_shared<Exception>(e));
327 }
catch (
const Exception& e2) {
329 "Event notification error: % - %\n", e2.getMessage(), e2);
330 mLogger->error(
"Original cause: % - %\n", e.getMessage(), e);
332 }
catch (
const std::exception& e) {
334 mObservationManager->getObservationExceptionHandler()
335 ->onReaderObservationError(
338 std::make_shared<std::runtime_error>(e.what()));
339 }
catch (
const std::exception& e2) {
340 mLogger->error(
"Event notification error: %\n", e2.what());
341 mLogger->error(
"Original cause: %\n", e.what());
347ObservableLocalReaderAdapter::scheduleCardSelectionScenario(
348 std::shared_ptr<CardSelectionScenarioAdapter> cardSelectionScenario,
349 const NotificationMode notificationMode)
351 mCardSelectionScenario = cardSelectionScenario;
352 mNotificationMode = notificationMode;
356ObservableLocalReaderAdapter::doUnregister()
360 }
catch (
const Exception& e) {
362 "Error stopping card detection on reader [%] - %\n", getName(), e);
366 mStateService->shutdown();
369 std::make_shared<ReaderEventAdapter>(
372 CardReaderEvent::Type::UNAVAILABLE,
375 LocalReaderAdapter::doUnregister();
379ObservableLocalReaderAdapter::isCardPresent()
383 if (LocalReaderAdapter::isCardPresent()) {
390 if (isLogicalChannelOpen()
391 || mObservableReaderSpi->isPhysicalChannelOpen()) {
392 processCardRemoved();
400ObservableLocalReaderAdapter::addObserver(
401 std::shared_ptr<CardReaderObserverSpi> observer)
404 mObservationManager->addObserver(observer);
408ObservableLocalReaderAdapter::removeObserver(
409 std::shared_ptr<CardReaderObserverSpi> observer)
411 Assert::getInstance().notNull(observer,
"observer");
413 if (Arrays::contains(mObservationManager->getObservers(), observer)) {
414 mObservationManager->removeObserver(observer);
419ObservableLocalReaderAdapter::countObservers()
const
421 return mObservationManager->countObservers();
425ObservableLocalReaderAdapter::clearObservers()
427 mObservationManager->clearObservers();
431ObservableLocalReaderAdapter::startCardDetection(
438 "Reader [%] starts card detection with polling mode [%]\n",
442 mDetectionMode = detectionMode;
443 mStateService->onEvent(InternalEvent::START_DETECT);
447ObservableLocalReaderAdapter::stopCardDetection()
450 mLogger->info(
"Reader [%] stops card detection\n", getName());
452 mStateService->onEvent(InternalEvent::STOP_DETECT);
456ObservableLocalReaderAdapter::finalizeCardProcessing()
458 mLogger->info(
"Reader [%] starts card removal sequence\n", getName());
460 mStateService->onEvent(InternalEvent::CARD_PROCESSED);
464ObservableLocalReaderAdapter::setReaderObservationExceptionHandler(
465 std::shared_ptr<CardReaderObservationExceptionHandlerSpi> exceptionHandler)
468 mObservationManager->setObservationExceptionHandler(exceptionHandler);
472ObservableLocalReaderAdapter::onCardInserted()
474 mStateService->onEvent(InternalEvent::CARD_INSERTED);
478ObservableLocalReaderAdapter::onCardRemoved()
480 mStateService->onEvent(InternalEvent::CARD_REMOVED);
ObservableCardReader::DetectionMode DetectionMode