Keyple Service C++ Library - 3.4.1
Component of the Keyple C++ middleware
AbstractReaderAdapter.cpp
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * See the NOTICE file(s) distributed with this work for additional *
5 * information regarding copyright ownership. *
6 * *
7 * This program and the accompanying materials are made available under the *
8 * terms of the Eclipse Public License 2.0 which is available at *
9 * http://www.eclipse.org/legal/epl-2.0 *
10 * *
11 * SPDX-License-Identifier: EPL-2.0 *
12 ******************************************************************************/
13
14#include "keyple/core/service/AbstractReaderAdapter.hpp"
15
16#include <memory>
17#include <string>
18#include <vector>
19
20#include "keyple/core/util/KeypleAssert.hpp"
21#include "keyple/core/util/cpp/System.hpp"
22#include "keyple/core/util/cpp/exception/Exception.hpp"
23#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
24#include "keypop/card/CardBrokenCommunicationException.hpp"
25#include "keypop/card/UnexpectedStatusWordException.hpp"
26
27namespace keyple {
28namespace core {
29namespace service {
30
31using keyple::core::util::Assert;
32using keyple::core::util::cpp::System;
33using keyple::core::util::cpp::exception::Exception;
34using keyple::core::util::cpp::exception::IllegalStateException;
35using keypop::card::CardBrokenCommunicationException;
36using keypop::card::UnexpectedStatusWordException;
37
38AbstractReaderAdapter::AbstractReaderAdapter(
39 const std::string& readerName,
40 std::shared_ptr<KeypleReaderExtension> readerExtension,
41 const std::string& pluginName)
42: mReaderName(readerName)
43, mReaderExtension(readerExtension)
44, mPluginName(pluginName)
45, mIsRegistered(false)
46, mBefore(0)
47{
48}
49
50const std::string&
51AbstractReaderAdapter::getPluginName() const
52{
53 return mPluginName;
54}
55
56std::shared_ptr<KeypleReaderExtension>
57AbstractReaderAdapter::getExtension(
58 const std::type_info& /*readerExtensionClass*/) const
59{
60 checkStatus();
61
62 return mReaderExtension;
63}
64
65const std::vector<std::shared_ptr<CardSelectionResponseApi>>
66AbstractReaderAdapter::transmitCardSelectionRequests(
67 const std::vector<std::shared_ptr<CardSelectorBase>>& cardSelectors,
68 const std::vector<std::shared_ptr<CardSelectionRequestSpi>>&
69 cardSelectionRequests,
70 const MultiSelectionProcessing multiSelectionProcessing,
71 const ChannelControl channelControl)
72{
73 checkStatus();
74
75 std::vector<std::shared_ptr<CardSelectionResponseApi>>
76 cardSelectionResponses;
77
78 uint64_t timeStamp = System::nanoTime();
79 uint64_t elapsed10ms = (timeStamp - mBefore) / 100000;
80 mBefore = timeStamp;
81
82 mLogger->debug(
83 "[reader=%] Send [type=CardSelectionRequests, "
84 "cardSelectionRequestCount=%, elapsedMs=%]\n",
85 getName(),
86 cardSelectionRequests.size(),
87 elapsed10ms / 10.0);
88
89 try {
90 cardSelectionResponses = processCardSelectionRequests(
91 cardSelectors,
92 cardSelectionRequests,
93 multiSelectionProcessing,
94 channelControl);
95 } catch (const UnexpectedStatusWordException& e) {
96 throw CardBrokenCommunicationException(
97 e.getCardResponse(),
98 false,
99 "An unexpected status word was received during the processing of "
100 "the card selection requests",
101 std::make_shared<UnexpectedStatusWordException>(e));
102 }
103
104 timeStamp = System::nanoTime();
105 elapsed10ms = (timeStamp - mBefore) / 100000;
106 mBefore = timeStamp;
107
108 mLogger->debug(
109 "[reader=%] Receive [type=CardSelectionResponses, "
110 "cardSelectionResponseCount=%, elapsedMs=%]\n",
111 getName(),
112 cardSelectionResponses.size(),
113 elapsed10ms / 10.0);
114
115 return cardSelectionResponses;
116}
117
118void
119AbstractReaderAdapter::checkStatus() const
120{
121 if (!mIsRegistered) {
122 throw IllegalStateException(
123 "Reader '" + getName() + "' is not registered");
124 }
125}
126
127void
128AbstractReaderAdapter::doRegister()
129{
130 mIsRegistered = true;
131}
132
133void
134AbstractReaderAdapter::doUnregister()
135{
136 mIsRegistered = false;
137}
138
139const std::string&
140AbstractReaderAdapter::getName() const
141{
142 return mReaderName;
143}
144
145const std::shared_ptr<CardResponseApi>
146AbstractReaderAdapter::transmitCardRequest(
147 const std::shared_ptr<CardRequestSpi> cardRequest,
148 const ChannelControl channelControl)
149{
150 checkStatus();
151
152 Assert::getInstance().notNull(cardRequest, "cardRequest");
153
154 std::shared_ptr<CardResponseApi> cardResponse = nullptr;
155
156 uint64_t timeStamp = System::nanoTime();
157 uint64_t elapsed10ms = (timeStamp - mBefore) / 100000;
158 mBefore = timeStamp;
159
160 mLogger->debug(
161 "[reader=%] Send [type=CardRequest, apduRequestCount=%, "
162 "elapsedMs=%]\n",
163 getName(),
164 cardRequest->getApduRequests().size(),
165 elapsed10ms / 10.0);
166
167 try {
168 cardResponse = processCardRequest(cardRequest, channelControl);
169 } catch (const Exception& e) {
170 /* Finally block in Java */
171 (void)e;
172 timeStamp = System::nanoTime();
173 elapsed10ms = (timeStamp - mBefore) / 100000;
174 mBefore = timeStamp;
175 mLogger->debug(
176 "[reader=%] Receive [type=CardResponse, apduResponseCount=%, "
177 "elapsedMs=%]\n",
178 getName(),
179 cardResponse != nullptr ? cardResponse->getApduResponses().size()
180 : 0,
181 elapsed10ms / 10.0);
182 throw;
183 }
184
185 /* Finally block in Java */
186 timeStamp = System::nanoTime();
187 elapsed10ms = (timeStamp - mBefore) / 100000;
188 mBefore = timeStamp;
189 mLogger->debug(
190 "[%] receive => %, elapsed % ms\n",
191 getName(),
192 cardResponse,
193 elapsed10ms / 10.0);
194
195 return cardResponse;
196}
197
198} /* namespace service */
199} /* namespace core */
200} /* namespace keyple */