14#include "keyple/card/generic/CardTransactionManagerAdapter.hpp"
20#include "keyple/card/generic/ApduRequestAdapter.hpp"
21#include "keyple/card/generic/CardRequestAdapter.hpp"
22#include "keyple/core/util/ApduUtil.hpp"
23#include "keyple/core/util/ByteArrayUtil.hpp"
24#include "keyple/core/util/HexUtil.hpp"
25#include "keyple/core/util/KeypleAssert.hpp"
26#include "keyple/core/util/cpp/exception/Exception.hpp"
27#include "keypop/card/CardBrokenCommunicationException.hpp"
28#include "keypop/card/CardResponseApi.hpp"
29#include "keypop/card/ChannelControl.hpp"
30#include "keypop/card/ProxyReaderApi.hpp"
31#include "keypop/card/ReaderBrokenCommunicationException.hpp"
32#include "keypop/card/UnexpectedStatusWordException.hpp"
33#include "keypop/reader/CardCommunicationException.hpp"
34#include "keypop/reader/InvalidCardResponseException.hpp"
35#include "keypop/reader/ReaderCommunicationException.hpp"
41using keyple::core::util::ApduUtil;
42using keyple::core::util::Assert;
43using keyple::core::util::ByteArrayUtil;
44using keyple::core::util::HexUtil;
45using keyple::core::util::cpp::exception::Exception;
46using keypop::card::CardBrokenCommunicationException;
47using keypop::card::CardResponseApi;
48using keypop::card::ProxyReaderApi;
49using keypop::card::ReaderBrokenCommunicationException;
50using keypop::card::UnexpectedStatusWordException;
51using keypop::reader::CardCommunicationException;
52using keypop::reader::InvalidCardResponseException;
53using keypop::reader::ReaderCommunicationException;
55const std::string CardTransactionManagerAdapter::APDU_COMMAND =
"apduCommand";
57CardTransactionManagerAdapter::CardTransactionManagerAdapter(
58 std::shared_ptr<CardReader> reader,
const std::shared_ptr<SmartCard> card)
61 Assert::getInstance().notNull(reader,
"reader").notNull(card,
"card");
64CardTransactionManager&
65CardTransactionManagerAdapter::prepareApdu(
const std::string& apduCommand)
68 .notEmpty(apduCommand, APDU_COMMAND)
69 .isTrue(HexUtil::isValid(apduCommand), APDU_COMMAND);
71 prepareApdu(HexUtil::toByteArray(apduCommand));
76CardTransactionManager&
77CardTransactionManagerAdapter::prepareApdu(
78 const std::vector<uint8_t>& apduCommand)
80 Assert::getInstance().isInRange(
81 static_cast<int>(apduCommand.size()), 5, 261,
"length");
83 mApduRequests.push_back(std::make_shared<ApduRequestAdapter>(apduCommand));
88CardTransactionManager&
89CardTransactionManagerAdapter::prepareApdu(
94 const std::vector<uint8_t>& dataIn,
97 mApduRequests.push_back(
98 std::make_shared<ApduRequestAdapter>(
99 ApduUtil::build(cla, ins, p1, p2, dataIn, le)));
104CardTransactionManager&
105CardTransactionManagerAdapter::prepareApdu(
110 const std::vector<uint8_t>& dataIn)
112 mApduRequests.push_back(
113 std::make_shared<ApduRequestAdapter>(
114 ApduUtil::build(cla, ins, p1, p2, dataIn)));
119CardTransactionManager&
120CardTransactionManagerAdapter::processCommands(
121 const ChannelControl channelControl)
123 mApduResponses.clear();
125 if (mApduRequests.empty()) {
129 std::shared_ptr<CardResponseApi> cardResponse;
133 = std::make_shared<CardRequestAdapter>(mApduRequests,
false);
134 auto control = channelControl == ChannelControl::CLOSE_AFTER
135 ? keypop::card::ChannelControl::CLOSE_AFTER
136 : keypop::card::ChannelControl::KEEP_OPEN;
138 cardResponse = std::dynamic_pointer_cast<ProxyReaderApi>(mReader)
139 ->transmitCardRequest(cardRequest, control);
141 }
catch (
const ReaderBrokenCommunicationException& e) {
142 mApduRequests.clear();
143 throw ReaderCommunicationException(
"Reader communication error", e);
145 }
catch (
const CardBrokenCommunicationException& e) {
146 mApduRequests.clear();
147 throw CardCommunicationException(
"Card communication error", e);
149 }
catch (
const UnexpectedStatusWordException& e) {
150 mApduRequests.clear();
151 throw InvalidCardResponseException(
"APDU error", e);
154 mApduRequests.clear();
156 for (
const auto& apduResponse : cardResponse->getApduResponses()) {
157 mApduResponses.push_back(apduResponse->getApdu());
163const std::vector<std::vector<uint8_t>>
164CardTransactionManagerAdapter::getResponsesAsByteArrays()
166 return mApduResponses;
169const std::vector<std::string>
170CardTransactionManagerAdapter::getResponsesAsHexStrings()
172 std::vector<std::string> apduResponsesHex;
174 for (
const auto& bytes : mApduResponses) {
175 apduResponsesHex.push_back(HexUtil::toHex(bytes));
178 return apduResponsesHex;