14#include "keyple/card/calypso/CommandGetDataFci.hpp"
21#include "keyple/card/calypso/CalypsoCardAdapter.hpp"
22#include "keyple/card/calypso/CalypsoCardClass.hpp"
23#include "keyple/card/calypso/CalypsoCardConstant.hpp"
24#include "keyple/card/calypso/CardCommandRef.hpp"
25#include "keyple/card/calypso/CardDataAccessException.hpp"
26#include "keyple/core/util/ApduUtil.hpp"
27#include "keyple/core/util/BerTlvUtil.hpp"
28#include "keyple/core/util/HexUtil.hpp"
34using keyple::core::util::ApduUtil;
35using keyple::core::util::BerTlvUtil;
36using keyple::core::util::HexUtil;
38const int CommandGetDataFci::TAG_DF_NAME = 0x84;
39const int CommandGetDataFci::TAG_APPLICATION_SERIAL_NUMBER = 0xC7;
40const int CommandGetDataFci::TAG_DISCRETIONARY_DATA = 0x53;
42const std::map<int, const std::shared_ptr<Command::StatusProperties>>
43 CommandGetDataFci::STATUS_TABLE = [] {
44 std::map<int, const std::shared_ptr<Command::StatusProperties>> m(
45 Command::STATUS_TABLE);
49 std::make_shared<StatusProperties>(
50 "Data object not found (optional mode not "
52 typeid(CardDataAccessException))},
54 std::make_shared<StatusProperties>(
55 "P1 or P2 value not supported",
56 typeid(CardDataAccessException))},
58 std::make_shared<StatusProperties>(
59 "Successful execution, FCI request and DF is "
65CommandGetDataFci::CommandGetDataFci(
66 const std::shared_ptr<DtoAdapters::TransactionContextDto>&
68 const std::shared_ptr<DtoAdapters::CommandContextDto>& commandContext)
69: Command(CardCommandRef::GET_DATA, nullptr, transactionContext, commandContext)
71 const std::uint8_t cardClass
72 = transactionContext->getCard() !=
nullptr
73 ? transactionContext->getCard()->getCardClass().getValue()
74 : CalypsoCardClass::ISO.getValue();
78 std::make_shared<DtoAdapters::ApduRequestAdapter>(ApduUtil::build(
80 getCommandRef().getInstructionByte(),
81 CalypsoCardConstant::TAG_FCI_FOR_CURRENT_DF_MSB,
82 CalypsoCardConstant::TAG_FCI_FOR_CURRENT_DF_LSB,
85 addSubName(
"FCI_FOR_CURRENT_DF");
89CommandGetDataFci::finalizeRequest()
95CommandGetDataFci::isCryptoServiceRequiredToFinalizeRequest()
const
101CommandGetDataFci::synchronizeCryptoServiceBeforeCardProcessing()
107CommandGetDataFci::parseResponse(std::shared_ptr<ApduResponseApi> apduResponse)
109 Command::setApduResponseAndCheckStatus(apduResponse);
115 if (getApduResponse()->getStatusWord() == 0x6283) {
116 mLogger->debug(
"DF invalidated\n");
117 mIsDfInvalidated =
true;
123 const std::vector<uint8_t> responseData
124 = getApduResponse()->getDataOut();
131 const std::map<const int, const std::vector<uint8_t>> tags
132 = BerTlvUtil::parseSimple(responseData,
true);
134 auto it = tags.find(TAG_DF_NAME);
135 if (it == tags.end()) {
136 mLogger->error(
"DF name tag (84h) not found\n");
140 mDfName = it->second;
142 if (mDfName.size() < 5 || mDfName.size() > 16) {
144 std::string(
"DF name is not the correct length (should be in")
145 +
" range [5..16]) [actual=%]\n",
150 mLogger->debug(
"DF name = %\n", HexUtil::toHex(mDfName));
152 it = tags.find(TAG_APPLICATION_SERIAL_NUMBER);
153 if (it == tags.end()) {
154 mLogger->error(
"Serial number tag (C7h) not found\n");
158 mApplicationSN = it->second;
161 if (mApplicationSN.size() != 8) {
163 std::string(
"Application serial number is not the correct ")
164 +
"length (expected 8) [actual=%]\n",
165 mApplicationSN.size());
170 "Application Serial Number = %\n", HexUtil::toHex(mApplicationSN));
172 it = tags.find(TAG_DISCRETIONARY_DATA);
173 if (it == tags.end()) {
174 mLogger->error(
"Discretionary data tag (53h) not found\n");
178 mDiscretionaryData = it->second;
180 if (mDiscretionaryData.size() < 7) {
182 std::string(
"Startup info is not the correct length (should")
183 +
" be >= 7) [actual=%]\n",
184 mDiscretionaryData.size());
189 "Discretionary Data = %\n", HexUtil::toHex(mDiscretionaryData));
192 mIsValidCalypsoFCI =
true;
195 "DF parsed [dfName=%, serialNumber=%, discretionaryData=%]\n",
196 HexUtil::toHex(mDfName),
197 HexUtil::toHex(mApplicationSN),
198 HexUtil::toHex(mDiscretionaryData));
200 }
catch (
const Exception& e) {
203 "failed to parse FCI BER-TLV data structure [reason=%]\n",
207 getTransactionContext()->getCard()->initializeWithFci(shared_from_this());
211CommandGetDataFci::isValidCalypsoFCI()
const
213 return mIsValidCalypsoFCI;
216const std::vector<uint8_t>&
217CommandGetDataFci::getDfName()
const
222const std::vector<uint8_t>&
223CommandGetDataFci::getApplicationSerialNumber()
const
225 return mApplicationSN;
228const std::vector<uint8_t>&
229CommandGetDataFci::getDiscretionaryData()
const
231 return mDiscretionaryData;
235CommandGetDataFci::isDfInvalidated()
const
237 return mIsDfInvalidated;
240const std::map<int, const std::shared_ptr<Command::StatusProperties>>&
241CommandGetDataFci::getStatusTable()
const