14#include "keyple/card/generic/CardTransactionManagerAdapter.hpp"
20#include "keyple/card/generic/ApduRequestAdapter.hpp"
21#include "keyple/card/generic/CardRequestAdapter.hpp"
22#include "keyple/card/generic/ChannelControl.hpp"
23#include "keyple/card/generic/TransactionException.hpp"
24#include "keyple/core/util/ApduUtil.hpp"
25#include "keyple/core/util/ByteArrayUtil.hpp"
26#include "keyple/core/util/HexUtil.hpp"
27#include "keyple/core/util/KeypleAssert.hpp"
28#include "keyple/core/util/cpp/exception/Exception.hpp"
29#include "keypop/card/CardBrokenCommunicationException.hpp"
30#include "keypop/card/CardResponseApi.hpp"
31#include "keypop/card/ProxyReaderApi.hpp"
32#include "keypop/card/ReaderBrokenCommunicationException.hpp"
33#include "keypop/card/UnexpectedStatusWordException.hpp"
39using keyple::core::util::ApduUtil;
40using keyple::core::util::Assert;
41using keyple::core::util::ByteArrayUtil;
42using keyple::core::util::HexUtil;
43using keyple::core::util::cpp::exception::Exception;
44using keypop::card::CardBrokenCommunicationException;
45using keypop::card::CardResponseApi;
46using keypop::card::ProxyReaderApi;
47using keypop::card::ReaderBrokenCommunicationException;
48using keypop::card::UnexpectedStatusWordException;
50const std::string CardTransactionManagerAdapter::APDU_COMMAND =
"apduCommand";
52CardTransactionManagerAdapter::CardTransactionManagerAdapter(
53 std::shared_ptr<CardReader> reader,
const std::shared_ptr<SmartCard> card)
56 Assert::getInstance().notNull(reader,
"reader").notNull(card,
"card");
59CardTransactionManager&
60CardTransactionManagerAdapter::prepareApdu(
const std::string& apduCommand)
63 .notEmpty(apduCommand, APDU_COMMAND)
64 .isTrue(HexUtil::isValid(apduCommand), APDU_COMMAND);
66 prepareApdu(HexUtil::toByteArray(apduCommand));
71CardTransactionManager&
72CardTransactionManagerAdapter::prepareApdu(
73 const std::vector<uint8_t>& apduCommand)
75 Assert::getInstance().isInRange(
76 static_cast<int>(apduCommand.size()), 5, 251,
"length");
78 mApduRequests.push_back(std::make_shared<ApduRequestAdapter>(apduCommand));
83CardTransactionManager&
84CardTransactionManagerAdapter::prepareApdu(
89 const std::vector<uint8_t>& dataIn,
92 mApduRequests.push_back(
93 std::make_shared<ApduRequestAdapter>(
94 ApduUtil::build(cla, ins, p1, p2, dataIn, le)));
99CardTransactionManager&
100CardTransactionManagerAdapter::prepareApdu(
105 const std::vector<uint8_t>& dataIn)
107 mApduRequests.push_back(
108 std::make_shared<ApduRequestAdapter>(
109 ApduUtil::build(cla, ins, p1, p2, dataIn)));
114const std::vector<std::vector<uint8_t>>
115CardTransactionManagerAdapter::processApdusToByteArrays(
116 const ChannelControl channelControl)
118 std::shared_ptr<CardResponseApi> cardResponse;
119 std::vector<std::vector<uint8_t>> apduResponsesBytes;
121 if (mApduRequests.empty()) {
122 return apduResponsesBytes;
127 = std::make_shared<CardRequestAdapter>(mApduRequests,
false);
128 auto control = channelControl == ChannelControl::CLOSE_AFTER
129 ? keypop::card::ChannelControl::CLOSE_AFTER
130 : keypop::card::ChannelControl::KEEP_OPEN;
132 cardResponse = std::dynamic_pointer_cast<ProxyReaderApi>(mReader)
133 ->transmitCardRequest(cardRequest, control);
135 }
catch (
const ReaderBrokenCommunicationException& e) {
136 throw TransactionException(
137 "Reader communication error", Exception(e.getMessage()));
139 }
catch (
const CardBrokenCommunicationException& e) {
140 throw TransactionException(
141 "Card communication error", Exception(e.getMessage()));
143 }
catch (
const UnexpectedStatusWordException& e) {
144 throw TransactionException(
"Apdu error", Exception(e.getMessage()));
147 mApduRequests.clear();
149 for (
const auto& apduResponse : cardResponse->getApduResponses()) {
150 apduResponsesBytes.push_back(apduResponse->getApdu());
153 return apduResponsesBytes;
156const std::vector<std::string>
157CardTransactionManagerAdapter::processApdusToHexStrings(
158 const ChannelControl channelControl)
160 std::vector<std::string> apduResponsesHex;
161 const std::vector<std::vector<uint8_t>> apduResponsesBytes
162 = processApdusToByteArrays(channelControl);
164 for (
const auto& bytes : apduResponsesBytes) {
165 apduResponsesHex.push_back(HexUtil::toHex(bytes));
168 return apduResponsesHex;