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(
"[reader=%] Processing inserted card\n", getName());
159 mIsCardRemovedEventNotificationEnabled =
true;
161 if (mCardSelectionScenario ==
nullptr) {
163 "[reader=%] No card selection scenario defined. Notifying card "
164 "reader event [eventType=CARD_INSERTED]\n",
168 return std::make_shared<ReaderEventAdapter>(
171 CardReaderEvent::Type::CARD_INSERTED,
180 const std::vector<std::shared_ptr<CardSelectionResponseApi>>
181 cardSelectionResponses = transmitCardSelectionRequests(
182 mCardSelectionScenario->getCardSelectors(),
183 mCardSelectionScenario->getCardSelectionRequests(),
184 mCardSelectionScenario->getMultiSelectionProcessing(),
185 mCardSelectionScenario->getChannelControl());
187 if (hasACardMatched(cardSelectionResponses)) {
188 return std::make_shared<ReaderEventAdapter>(
191 CardReaderEvent::Type::CARD_MATCHED,
192 std::make_shared<ScheduledCardSelectionsResponseAdapter>(
193 cardSelectionResponses));
196 if (mNotificationMode == NotificationMode::MATCHED_ONLY) {
201 "[reader=%] Selection hasn't matched. Event not notified "
202 "because the notification mode is MATCHED_ONLY\n",
213 "[reader=%] No selection cases matched [selectionCaseCount=%]\n",
215 cardSelectionResponses.size());
217 return std::make_shared<ReaderEventAdapter>(
220 CardReaderEvent::Type::CARD_INSERTED,
221 std::make_shared<ScheduledCardSelectionsResponseAdapter>(
222 cardSelectionResponses));
224 }
catch (
const ReaderBrokenCommunicationException& e) {
226 const auto rce = std::make_shared<ReaderCommunicationException>(
227 READER_MONITORING_ERROR, e);
228 getObservationExceptionHandler()->onReaderObservationError(
229 getPluginName(), getName(), rce);
231 }
catch (
const CardBrokenCommunicationException& e) {
235 closeLogicalAndPhysicalChannelsSilently();
242 "[reader=%] Failed to process card selection scenario [reason=%]\n",
252 mObservableReaderSpi->closePhysicalChannel();
254 }
catch (
const ReaderIOException& e) {
256 const auto rce = std::make_shared<ReaderCommunicationException>(
257 READER_MONITORING_ERROR, e);
258 getObservationExceptionHandler()->onReaderObservationError(
259 getPluginName(), getName(), rce);
267ObservableLocalReaderAdapter::hasACardMatched(
268 const std::vector<std::shared_ptr<CardSelectionResponseApi>>&
269 cardSelectionResponses)
272 cardSelectionResponses.begin(),
273 cardSelectionResponses.end(),
274 [](
const std::shared_ptr<CardSelectionResponseApi>&
275 cardSelectionResponse) {
276 return cardSelectionResponse != nullptr
277 && cardSelectionResponse->hasMatched();
280 "[reader=%] A default selection case matched\n", getName());
288ObservableLocalReaderAdapter::processCardRemoved()
291 closeLogicalAndPhysicalChannelsSilently();
292 if (mIsCardRemovedEventNotificationEnabled) {
294 std::make_shared<ReaderEventAdapter>(
297 CardReaderEvent::Type::CARD_REMOVED,
303ObservableLocalReaderAdapter::switchState(
const MonitoringState stateId)
305 mStateService->switchState(stateId);
309ObservableLocalReaderAdapter::notifyObservers(
310 const std::shared_ptr<CardReaderEvent> event)
313 "[reader=%] Notifying observers [eventType=%, observerCount=%]\n",
318 for (
const auto& observer : mObservationManager->getObservers()) {
319 notifyObserver(observer, event);
322 mLogger->debug(
"[reader=%] Observers notified\n", getName());
326ObservableLocalReaderAdapter::notifyObserver(
327 std::shared_ptr<CardReaderObserverSpi> observer,
328 const std::shared_ptr<CardReaderEvent> event)
331 observer->onReaderEvent(event);
333 }
catch (
const Exception& e) {
335 mObservationManager->getObservationExceptionHandler()
336 ->onReaderObservationError(
337 getPluginName(), getName(), std::make_shared<Exception>(e));
339 }
catch (
const Exception& e2) {
341 "[reader=%] Failed to notify observer [reason=%]\n",
345 "[reader=%] Failed to notify observation exception handler "
351 }
catch (
const std::exception& e) {
353 mObservationManager->getObservationExceptionHandler()
354 ->onReaderObservationError(
357 std::make_shared<std::runtime_error>(e.what()));
358 }
catch (
const std::exception& e2) {
360 "Reader [%] failed to notify observer: %\n",
364 "Reader [%] failed to notify observation exception handler: "
373ObservableLocalReaderAdapter::scheduleCardSelectionScenario(
374 std::shared_ptr<CardSelectionScenarioAdapter> cardSelectionScenario,
375 const NotificationMode notificationMode)
377 mCardSelectionScenario = cardSelectionScenario;
378 mNotificationMode = notificationMode;
382ObservableLocalReaderAdapter::doUnregister()
386 }
catch (
const Exception& e) {
388 "[reader=%] Failed to stop card monitoring [reason=%]\n",
394 mStateService->shutdown();
397 std::make_shared<ReaderEventAdapter>(
400 CardReaderEvent::Type::UNAVAILABLE,
403 LocalReaderAdapter::doUnregister();
407ObservableLocalReaderAdapter::isCardPresent()
411 if (LocalReaderAdapter::isCardPresent()) {
418 if (isLogicalChannelOpen()
419 || mObservableReaderSpi->isPhysicalChannelOpen()) {
420 processCardRemoved();
428ObservableLocalReaderAdapter::addObserver(
429 std::shared_ptr<CardReaderObserverSpi> observer)
432 mObservationManager->addObserver(observer);
436ObservableLocalReaderAdapter::removeObserver(
437 std::shared_ptr<CardReaderObserverSpi> observer)
439 Assert::getInstance().notNull(observer,
"observer");
441 if (Arrays::contains(mObservationManager->getObservers(), observer)) {
442 mObservationManager->removeObserver(observer);
447ObservableLocalReaderAdapter::countObservers()
const
449 return mObservationManager->countObservers();
453ObservableLocalReaderAdapter::clearObservers()
455 mObservationManager->clearObservers();
459ObservableLocalReaderAdapter::startCardDetection(
466 "[reader=%] Starting card monitoring [detectionMode=%]\n",
470 mDetectionMode = detectionMode;
471 mStateService->onEvent(InternalEvent::START_DETECT);
475ObservableLocalReaderAdapter::stopCardDetection()
478 mLogger->info(
"[reader=%] Stopping card monitoring\n", getName());
480 mStateService->onEvent(InternalEvent::STOP_DETECT);
484ObservableLocalReaderAdapter::finalizeCardProcessing()
486 mLogger->info(
"[reader=%] Starting card removal sequence\n", getName());
488 mStateService->onEvent(InternalEvent::CARD_PROCESSED);
492ObservableLocalReaderAdapter::setReaderObservationExceptionHandler(
493 std::shared_ptr<CardReaderObservationExceptionHandlerSpi> exceptionHandler)
496 mObservationManager->setObservationExceptionHandler(exceptionHandler);
500ObservableLocalReaderAdapter::onCardInserted()
502 mStateService->onEvent(InternalEvent::CARD_INSERTED);
506ObservableLocalReaderAdapter::onCardRemoved()
508 mStateService->onEvent(InternalEvent::CARD_REMOVED);
ObservableCardReader::DetectionMode DetectionMode