Keyple Card Calypso C++ Library 2.1.0
Reference Terminal Reader API for C++
CmdCardSvUndebit.cpp
Go to the documentation of this file.
1/**************************************************************************************************
2 * Copyright (c) 2022 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * See the NOTICE file(s) distributed with this work for additional information regarding *
5 * copyright ownership. *
6 * *
7 * This program and the accompanying materials are made available under the terms of the Eclipse *
8 * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 *
9 * *
10 * SPDX-License-Identifier: EPL-2.0 *
11 **************************************************************************************************/
12
13#include "CmdCardSvUndebit.h"
14
15/* Keyple Card Calypso */
16#include "CalypsoCardAdapter.h"
17#include "CalypsoCardClass.h"
23#include "SamUtilAdapter.h"
24
25/* Keyple Core Util */
26#include "ApduUtil.h"
27#include "IllegalArgumentException.h"
28#include "IllegalStateException.h"
29#include "System.h"
30
31namespace keyple {
32namespace card {
33namespace calypso {
34
35using namespace keyple::core::util;
36using namespace keyple::core::util::cpp;
37using namespace keyple::core::util::cpp::exception;
38
39const CalypsoCardCommand CmdCardSvUndebit::mCommand = CalypsoCardCommand::SV_UNDEBIT;
40
41const std::map<const int, const std::shared_ptr<StatusProperties>>
42 CmdCardSvUndebit::STATUS_TABLE = initStatusTable();
43
44CmdCardSvUndebit::CmdCardSvUndebit(const std::shared_ptr<CalypsoCard> calypsoCard,
45 const int amount,
46 const uint8_t kvc,
47 const std::vector<uint8_t>& date,
48 const std::vector<uint8_t>& time)
49: AbstractCardCommand(mCommand)
50{
51 /*
52 * @see Calypso Layer ID 8.02 (200108)
53 * @see Ticketing Layer Recommendations 170 (200108)
54 */
55 if (amount < 0 || amount > 32767) {
56 throw IllegalArgumentException("Amount is outside allowed boundaries (0 <= amount <= " \
57 "32767)");
58 }
59
60 if (date.empty() || time.empty()) {
61 throw IllegalArgumentException("date and time cannot be null");
62 }
63
64 if (date.size() != 2 || time.size() != 2) {
65 throw IllegalArgumentException("date and time must be 2-byte arrays");
66 }
67
68 /* Keeps a copy of these fields until the command is finalized */
69 mCalypsoCard = calypsoCard;
70
71 /*
72 * Handle the dataIn size with signatureHi length according to card product type (3.2 rev have a
73 * 10-byte signature)
74 */
75 mDataIn = std::vector<uint8_t>(15 + (mCalypsoCard->isExtendedModeSupported() ? 10 : 5));
76
77 /* mDataIn[0] will be filled in at the finalization phase */
78 const short amountShort = static_cast<short>(amount);
79 mDataIn[1] = ((amountShort >> 8) & 0xFF);
80 mDataIn[2] = (amountShort & 0xFF);
81 mDataIn[3] = date[0];
82 mDataIn[4] = date[1];
83 mDataIn[5] = time[0];
84 mDataIn[6] = time[1];
85 mDataIn[7] = kvc;
86 /* mDataIn[8]..dataIn[8+7+sigLen] will be filled in at the finalization phase */
87}
88
89void CmdCardSvUndebit::finalizeCommand(const std::vector<uint8_t>& undebitComplementaryData)
90{
91 if ((mCalypsoCard->isExtendedModeSupported() && undebitComplementaryData.size() != 20) ||
92 (!mCalypsoCard->isExtendedModeSupported() && undebitComplementaryData.size() != 15)) {
93 throw IllegalArgumentException("Bad SV prepare load data length.");
94 }
95
96 const uint8_t p1 = undebitComplementaryData[4];
97 const uint8_t p2 = undebitComplementaryData[5];
98
99 mDataIn[0] = undebitComplementaryData[6];
100 System::arraycopy(undebitComplementaryData, 0, mDataIn, 8, 4);
101 System::arraycopy(undebitComplementaryData, 7, mDataIn, 12, 3);
102 System::arraycopy(undebitComplementaryData,
103 10,
104 mDataIn,
105 15,
106 undebitComplementaryData.size() - 10);
107
108 const auto adapter = std::dynamic_pointer_cast<CalypsoCardAdapter>(mCalypsoCard);
109 const uint8_t cardClass = adapter->getCardClass() == CalypsoCardClass::LEGACY ?
112
114 std::make_shared<ApduRequestAdapter>(
115 ApduUtil::build(cardClass,
116 mCommand.getInstructionByte(),
117 p1,
118 p2,
119 mDataIn)));
120}
121
122const std::vector<uint8_t> CmdCardSvUndebit::getSvUndebitData() const
123{
124 std::vector<uint8_t> svUndebitData(12);
125
126 svUndebitData[0] = mCommand.getInstructionByte();
127
128 /*
129 * svUndebitData[1,2] / P1P2 not set because ignored
130 * Lc is 5 bytes longer in product type 3.2
131 */
132 svUndebitData[3] = mCalypsoCard->isExtendedModeSupported() ? 0x19 : 0x14;
133
134 /* Appends the fixed part of dataIn */
135 System::arraycopy(mDataIn, 0, svUndebitData, 4, 8);
136
137 return svUndebitData;
138}
139
141{
142 return true;
143}
144
146 const std::shared_ptr<ApduResponseApi> apduResponse)
147{
149
150 const std::vector<uint8_t> dataOut = apduResponse->getDataOut();
151 if (dataOut.size() != 0 && dataOut.size() != 3 && dataOut.size() != 6) {
152 throw IllegalStateException("Bad length in response to SV Reload command.");
153 }
154
155 return *this;
156}
157
158const std::vector<uint8_t> CmdCardSvUndebit::getSignatureLo() const
159{
160 return getApduResponse()->getDataOut();
161}
162
163const std::map<const int, const std::shared_ptr<StatusProperties>>
164 CmdCardSvUndebit::initStatusTable()
165{
166 std::map<const int, const std::shared_ptr<StatusProperties>> m =
168
169 m.insert({0x6400,
170 std::make_shared<StatusProperties>("Too many modifications in session.",
172 m.insert({0x6700,
173 std::make_shared<StatusProperties>("Lc value not supported.",
174 typeid(CardIllegalParameterException))});
175 m.insert({0x6900,
176 std::make_shared<StatusProperties>("Transaction counter is 0 or SV TNum is FFFEh or" \
177 " FFFFh.",
178 typeid(CalypsoSamCounterOverflowException))});
179 m.insert({0x6985,
180 std::make_shared<StatusProperties>("Preconditions not satisfied.",
181 typeid(CalypsoSamAccessForbiddenException))});
182 m.insert({0x6988,
183 std::make_shared<StatusProperties>("Incorrect signatureHi.",
184 typeid(CardSecurityDataException))});
185 m.insert({0x6200,
186 std::make_shared<StatusProperties>("Successful execution, response data postponed " \
187 "until session closing.",
188 typeid(nullptr))});
189
190 return m;
191}
192
193const std::map<const int, const std::shared_ptr<StatusProperties>>&
195{
196 return STATUS_TABLE;
197}
198
199}
200}
201}
static const std::map< const int, const std::shared_ptr< StatusProperties > > STATUS_TABLE
virtual const std::shared_ptr< ApduResponseApi > getApduResponse() const final
virtual void setApduRequest(const std::shared_ptr< ApduRequestAdapter > apduRequest) final
AbstractCardCommand & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
static const CalypsoCardClass LEGACY
static const CalypsoCardClass ISO
static const CalypsoCardClass LEGACY_STORED_VALUE
static const CalypsoCardCommand SV_UNDEBIT
void finalizeCommand(const std::vector< uint8_t > &undebitComplementaryData)
CmdCardSvUndebit & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const std::vector< uint8_t > getSvUndebitData() const
CmdCardSvUndebit(const std::shared_ptr< CalypsoCard > calypsoCard, const int amount, const uint8_t kvc, const std::vector< uint8_t > &date, const std::vector< uint8_t > &time)
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override
const std::vector< uint8_t > getSignatureLo() const