Keyple Card Calypso C++ Library 2.1.0
Reference Terminal Reader API for C++
CmdCardSvReload.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 "CmdCardSvReload.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 CmdCardSvReload::mCommand = CalypsoCardCommand::SV_RELOAD;
40
41const std::map<const int, const std::shared_ptr<StatusProperties>>
42 CmdCardSvReload::STATUS_TABLE = initStatusTable();
43
44CmdCardSvReload::CmdCardSvReload(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 const std::vector<uint8_t>& free)
50: AbstractCardCommand(mCommand)
51{
52 if (amount < -8388608 || amount > 8388607) {
53 throw IllegalArgumentException("Amount is outside allowed boundaries (-8388608 <= amount " \
54 "<= 8388607)");
55 }
56
57 if (date.empty() || time.empty() || free.empty()) {
58 throw IllegalArgumentException("date, time and free cannot be null");
59 }
60
61 if (date.size() != 2 || time.size() != 2 || free.size() != 2) {
62 throw IllegalArgumentException("date, time and free must be 2-byte arrays");
63 }
64
65 /* Keeps a copy of these fields until the builder is finalized */
66 mCalypsoCard = calypsoCard;
67
68 /*
69 * Handle the dataIn size with signatureHi length according to card revision (3.2 rev have a
70 * 10-byte signature)
71 */
72 mDataIn = std::vector<uint8_t>(18 + (mCalypsoCard->isExtendedModeSupported() ? 10 : 5));
73
74 /* dataIn[0] will be filled in at the finalization phase */
75 mDataIn[1] = date[0];
76 mDataIn[2] = date[1];
77 mDataIn[3] = free[0];
78 mDataIn[4] = kvc;
79 mDataIn[5] = free[1];
80 mDataIn[6] = ((amount >> 16) & 0xFF);
81 mDataIn[7] = ((amount >> 8) & 0xFF);
82 mDataIn[8] = (amount & 0xFF);
83 mDataIn[9] = time[0];
84 mDataIn[10] = time[1];
85 /* mDataIn[11]..mDataIn[11+7+sigLen] will be filled in at the finalization phase */
86}
87
88void CmdCardSvReload::finalizeCommand(const std::vector<uint8_t>& reloadComplementaryData)
89{
90 if ((mCalypsoCard->isExtendedModeSupported() && reloadComplementaryData.size() != 20) ||
91 (!mCalypsoCard->isExtendedModeSupported() && reloadComplementaryData.size() != 15)) {
92 throw IllegalArgumentException("Bad SV prepare load data length.");
93 }
94
95 const uint8_t p1 = reloadComplementaryData[4];
96 const uint8_t p2 = reloadComplementaryData[5];
97
98 mDataIn[0] = reloadComplementaryData[6];
99 System::arraycopy(reloadComplementaryData, 0, mDataIn, 11, 4);
100 System::arraycopy(reloadComplementaryData, 7, mDataIn, 15, 3);
101 System::arraycopy(reloadComplementaryData, 10, mDataIn, 18, reloadComplementaryData.size()-10);
102
103 const auto adapter = std::dynamic_pointer_cast<CalypsoCardAdapter>(mCalypsoCard);
104 const uint8_t cardClass = adapter->getCardClass() == CalypsoCardClass::LEGACY ?
107
109 std::make_shared<ApduRequestAdapter>(
110 ApduUtil::build(cardClass,
111 mCommand.getInstructionByte(),
112 p1,
113 p2,
114 mDataIn)));
115}
116
117const std::vector<uint8_t> CmdCardSvReload::getSvReloadData() const
118{
119 std::vector<uint8_t> svReloadData(15);
120
121 svReloadData[0] = mCommand.getInstructionByte();
122
123 /*
124 * svReloadData[1,2] / P1P2 not set because ignored
125 * Lc is 5 bytes longer in revision 3.2
126 */
127 svReloadData[3] = mCalypsoCard->isExtendedModeSupported() ? 0x1C : 0x17;
128
129 /* Appends the fixed part of dataIn */
130 System::arraycopy(mDataIn, 0, svReloadData, 4, 11);
131
132 return svReloadData;
133}
134
136{
137 return true;
138}
139
140CmdCardSvReload& CmdCardSvReload::setApduResponse(const std::shared_ptr<ApduResponseApi> apduResponse)
141{
143
144 const std::vector<uint8_t> dataOut = apduResponse->getDataOut();
145 if (dataOut.size() != 0 && dataOut.size() != 3 && dataOut.size() != 6) {
146 throw IllegalStateException("Bad length in response to SV Reload command.");
147 }
148
149 return *this;
150}
151
152const std::vector<uint8_t> CmdCardSvReload::getSignatureLo() const
153{
154 return getApduResponse()->getDataOut();
155}
156
157const std::map<const int, const std::shared_ptr<StatusProperties>>
158 CmdCardSvReload::initStatusTable()
159{
160 std::map<const int, const std::shared_ptr<StatusProperties>> m =
162
163 m.insert({0x6400,
164 std::make_shared<StatusProperties>("Too many modifications in session.",
166 m.insert({0x6700,
167 std::make_shared<StatusProperties>("Lc value not supported.",
168 typeid(CardIllegalParameterException))});
169 m.insert({0x6900,
170 std::make_shared<StatusProperties>("Transaction counter is 0 or SV TNum is FFFEh or" \
171 " FFFFh.",
172 typeid(CalypsoSamCounterOverflowException))});
173 m.insert({0x6985,
174 std::make_shared<StatusProperties>("Preconditions not satisfied.",
175 typeid(CalypsoSamAccessForbiddenException))});
176 m.insert({0x6988,
177 std::make_shared<StatusProperties>("Incorrect signatureHi.",
178 typeid(CardSecurityDataException))});
179 m.insert({0x6200,
180 std::make_shared<StatusProperties>("Successful execution, response data postponed " \
181 "until session closing.",
182 typeid(nullptr))});
183
184 return m;
185}
186
187const std::map<const int, const std::shared_ptr<StatusProperties>>&
189{
190 return STATUS_TABLE;
191}
192
193}
194}
195}
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_RELOAD
CmdCardSvReload(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::vector< uint8_t > &free)
const std::vector< uint8_t > getSvReloadData() const
const std::vector< uint8_t > getSignatureLo() const
CmdCardSvReload & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override
void finalizeCommand(const std::vector< uint8_t > &reloadComplementaryData)