27#include "ByteArrayUtil.h"
28#include "IllegalArgumentException.h"
29#include "IllegalStateException.h"
36using namespace keyple::core::util;
37using namespace keyple::core::util::cpp;
38using namespace keyple::core::util::cpp::exception;
40const int CmdCardSvDebitOrUndebit::SW_POSTPONED_DATA = 0x6200;
41const std::map<const int, const std::shared_ptr<StatusProperties>>
42 CmdCardSvDebitOrUndebit::STATUS_TABLE = initStatusTable();
45 const bool isDebitCommand,
46 const std::shared_ptr<CalypsoCardAdapter> calypsoCard,
48 const std::vector<uint8_t>& date,
49 const std::vector<uint8_t>& time,
50 const bool isSessionOpen,
51 const bool isExtendedModeAllowed)
57 mIsSessionOpen(isSessionOpen),
58 mIsExtendedModeAllowed(isExtendedModeAllowed)
64 if (amount < 0 || amount > 32767) {
66 throw IllegalArgumentException(
"Amount is outside allowed boundaries (0 <= amount <= " \
70 if (date.empty() || time.empty()) {
72 throw IllegalArgumentException(
"date and time cannot be null");
75 if (date.size() != 2 || time.size() != 2) {
77 throw IllegalArgumentException(
"date and time must be 2-byte arrays");
84 mDataIn = std::vector<uint8_t>(15 + (isExtendedModeAllowed ? 10 : 5));
87 const short amountShort = isDebitCommand ?
88 static_cast<short>(-amount) :
static_cast<short>(amount);
89 ByteArrayUtil::copyBytes(amountShort, mDataIn, 1, 2);
94 mDataIn[7] = calypsoCard->getSvKvc();
99 const std::vector<uint8_t>& debitOrUndebitComplementaryData)
101 if ((mIsExtendedModeAllowed && debitOrUndebitComplementaryData.size() != 20) ||
102 (!mIsExtendedModeAllowed && debitOrUndebitComplementaryData.size() != 15)) {
104 throw IllegalArgumentException(
"Bad SV prepare load data length.");
109 if (mIsSessionOpen) {
112 if(mIsExtendedModeAllowed) {
121 const uint8_t p1 = debitOrUndebitComplementaryData[4];
122 const uint8_t p2 = debitOrUndebitComplementaryData[5];
124 mDataIn[0] = debitOrUndebitComplementaryData[6];
125 System::arraycopy(debitOrUndebitComplementaryData, 0, mDataIn, 8, 4);
126 System::arraycopy(debitOrUndebitComplementaryData, 7, mDataIn, 12, 3);
127 System::arraycopy(debitOrUndebitComplementaryData,
131 debitOrUndebitComplementaryData.size() - 10);
137 std::shared_ptr<ApduRequestAdapter> apduRequest;
140 apduRequest = std::make_shared<ApduRequestAdapter>(
141 ApduUtil::build(cardClass,
148 apduRequest = std::make_shared<ApduRequestAdapter>(
149 ApduUtil::build(cardClass,
156 apduRequest->addSuccessfulStatusWord(SW_POSTPONED_DATA);
162 std::vector<uint8_t> svDebitOrUndebitData(12);
170 svDebitOrUndebitData[3] = mIsExtendedModeAllowed ? 0x19 : 0x14;
173 System::arraycopy(mDataIn, 0, svDebitOrUndebitData, 4, 8);
175 return svDebitOrUndebitData;
187 const std::vector<uint8_t> dataOut = apduResponse->getDataOut();
189 if (dataOut.size() != 0 && dataOut.size() != 3 && dataOut.size() != 6) {
191 throw IllegalStateException(
"Bad length in response to SV Debit/Undebit command.");
194 getCalypsoCard()->setSvOperationSignature(apduResponse->getDataOut());
197const std::map<const int, const std::shared_ptr<StatusProperties>>
198 CmdCardSvDebitOrUndebit::initStatusTable()
200 std::map<const int, const std::shared_ptr<StatusProperties>> m =
203 m.insert({SW_POSTPONED_DATA,
204 std::make_shared<StatusProperties>(
"Successful execution, response data postponed " \
205 "until session closing.",
208 std::make_shared<StatusProperties>(
"Too many modifications in session.",
209 typeid(CardSessionBufferOverflowException))});
211 std::make_shared<StatusProperties>(
"Lc value not supported.",
212 typeid(CardIllegalParameterException))});
214 std::make_shared<StatusProperties>(
"Transaction counter is 0 or SV TNum is FFFEh or" \
216 typeid(CalypsoSamCounterOverflowException))});
218 std::make_shared<StatusProperties>(
"Preconditions not satisfied.",
219 typeid(CalypsoSamAccessForbiddenException))});
221 std::make_shared<StatusProperties>(
"Incorrect signatureHi.",
222 typeid(CardSecurityDataException))});
227const std::map<const int, const std::shared_ptr<StatusProperties>>&
static const std::map< const int, const std::shared_ptr< StatusProperties > > STATUS_TABLE
virtual void setApduRequest(const std::shared_ptr< ApduRequestAdapter > apduRequest) final
virtual void setExpectedResponseLength(const int expectedResponseLength) final
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const CalypsoCardCommand & getCommandRef() const override
std::shared_ptr< CalypsoCardAdapter > getCalypsoCard() const
static const CalypsoCardClass LEGACY
static const CalypsoCardClass ISO
static const CalypsoCardClass LEGACY_STORED_VALUE
uint8_t getInstructionByte() const
const std::vector< uint8_t > getSvDebitOrUndebitData() const
void finalizeCommand(const std::vector< uint8_t > &debitOrUndebitComplementaryData)
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override
bool isSessionBufferUsed() const override
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
CmdCardSvDebitOrUndebit(const bool isDebitCommand, const std::shared_ptr< CalypsoCardAdapter > calypsoCard, const int amount, const std::vector< uint8_t > &date, const std::vector< uint8_t > &time, const bool isSessionOpen, const bool isExtendedModeAllowed)