Keyple Card Calypso C++ Library 2.2.5.6
Reference Terminal Reader API for C++
CmdCardIncreaseOrDecrease.cpp
Go to the documentation of this file.
1/**************************************************************************************************
2 * Copyright (c) 2023 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
14
15#include <sstream>
16
17/* Keyple Core Util */
18#include "ApduUtil.h"
19#include "Arrays.h"
20#include "ByteArrayUtil.h"
21
22/* Keyple Card Calypso */
30
31namespace keyple {
32namespace card {
33namespace calypso {
34
35using namespace keyple::core::util;
36using namespace keyple::core::util::cpp;
37
38const int CmdCardIncreaseOrDecrease::SW_POSTPONED_DATA = 0x6200;
39
40const std::map<const int, const std::shared_ptr<StatusProperties>>
41 CmdCardIncreaseOrDecrease::STATUS_TABLE = initStatusTable();
42
44 const bool isDecreaseCommand,
45 const std::shared_ptr<CalypsoCardAdapter> calypsoCard,
46 const uint8_t sfi,
47 const uint8_t counterNumber,
48 const int incDecValue)
49: AbstractCardCommand(isDecreaseCommand ? CalypsoCardCommand::DECREASE :
50 CalypsoCardCommand::INCREASE,
51 3,
52 calypsoCard),
53 mSfi(sfi),
54 mCounterNumber(counterNumber),
55 mIncDecValue(incDecValue)
56{
57 const uint8_t cla = calypsoCard->getCardClass().getValue();
58
59 /*
60 * Convert the integer value into a 3-byte buffer
61 * CL-COUN-DATAIN.1
62 */
63 std::vector<uint8_t> valueBuffer = ByteArrayUtil::extractBytes(incDecValue, 3);
64
65 const uint8_t p2 = sfi * 8;
66
67 std::shared_ptr<ApduRequestAdapter> apduRequest;
68
69 if (!calypsoCard->isCounterValuePostponed()) {
70 /* This is a case4 command, we set Le = 0 */
71 apduRequest = std::make_shared<ApduRequestAdapter>(
72 ApduUtil::build(cla,
73 getCommandRef().getInstructionByte(),
74 mCounterNumber,
75 p2,
76 valueBuffer,
77 0x00));
78 } else {
79 /* This command is considered as a case 3, we do not set Le */
80 apduRequest = std::make_shared<ApduRequestAdapter>(
81 ApduUtil::build(cla,
82 getCommandRef().getInstructionByte(),
83 mCounterNumber,
84 p2,
85 valueBuffer));
87 apduRequest->addSuccessfulStatusWord(SW_POSTPONED_DATA);
88 }
89
90 setApduRequest(apduRequest);
91
92 std::stringstream extraInfo;
93 extraInfo << "SFI:" << sfi << "h, "
94 << "COUNTER:" << mCounterNumber << ", ";
95 if (isDecreaseCommand) {
96 extraInfo << "DECREMENT";
97 } else {
98 extraInfo << "INCREMENT";
99 }
100 extraInfo << ":" << incDecValue;
101
102 addSubName(extraInfo.str());
103}
104
106 const std::shared_ptr<ApduResponseApi> apduResponse)
107{
109
110 if (apduResponse->getStatusWord() == SW_POSTPONED_DATA) {
111
112 if (!getCalypsoCard()->isCounterValuePostponed()) {
113
114 throw CardUnknownStatusException("Unexpected status word: 6200h",
116 std::make_shared<int>(SW_POSTPONED_DATA));
117 }
118
119 /* Set computed value */
120 getCalypsoCard()->setCounter(mSfi, mCounterNumber, mComputedData);
121
122 } else {
123
124 /* Set returned value */
125 getCalypsoCard()->setCounter(mSfi, mCounterNumber, apduResponse->getDataOut());
126 }
127}
128
129void CmdCardIncreaseOrDecrease::setComputedData(const std::vector<uint8_t>& data)
130{
131 mComputedData = data;
132}
133
135{
136 return true;
137}
138
140{
141 return mSfi;
142}
143
145{
146 return mCounterNumber;
147}
148
150{
151 return mIncDecValue;
152}
153
154const std::map<const int, const std::shared_ptr<StatusProperties>>
155 CmdCardIncreaseOrDecrease::initStatusTable()
156{
157 std::map<const int, const std::shared_ptr<StatusProperties>> m =
159
160 m.insert({0x6400,
161 std::make_shared<StatusProperties>("Too many modifications in session.",
163 m.insert({0x6700,
164 std::make_shared<StatusProperties>("Lc value not supported.",
165 typeid(CardIllegalParameterException))});
166 m.insert({0x6981,
167 std::make_shared<StatusProperties>("The current EF is not a Counters or Simulated " \
168 "Counter EF.",
169 typeid(CardDataAccessException))});
170 m.insert({0x6982,
171 std::make_shared<StatusProperties>("Security conditions not fulfilled (no session, " \
172 "wrong key, encryption required).",
173 typeid(CardSecurityContextException))});
174 m.insert({0x6985,
175 std::make_shared<StatusProperties>("Access forbidden (Never access mode, DF is " \
176 "invalidated, etc.)",
177 typeid(CardAccessForbiddenException))});
178 m.insert({0x6986,
179 std::make_shared<StatusProperties>("Command not allowed (no current EF).",
180 typeid(CardDataAccessException))});
181 m.insert({0x6A80,
182 std::make_shared<StatusProperties>("Overflow error.",
183 typeid(CardDataOutOfBoundsException))});
184 m.insert({0x6A82,
185 std::make_shared<StatusProperties>("File not found.",
186 typeid(CardDataAccessException))});
187 m.insert({0x6B00,
188 std::make_shared<StatusProperties>("P1 or P2 value not supported.",
189 typeid(CardDataAccessException))});
190 m.insert({0x6103,
191 std::make_shared<StatusProperties>("Successful execution (possible only in ISO7816 " \
192 "T=0).",
193 typeid(nullptr))});
194 m.insert({SW_POSTPONED_DATA,
195 std::make_shared<StatusProperties>("Successful execution, response data postponed " \
196 "until session closing.",
197 typeid(nullptr))});
198
199 return m;
200}
201
202const std::map<const int, const std::shared_ptr<StatusProperties>>&
204{
205 return STATUS_TABLE;
206}
207
208}
209}
210}
static const std::map< const int, const std::shared_ptr< StatusProperties > > STATUS_TABLE
virtual void addSubName(const std::string &subName) final
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
void setComputedData(const std::vector< uint8_t > &data)
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
CmdCardIncreaseOrDecrease(const bool isDecreaseCommand, const std::shared_ptr< CalypsoCardAdapter > calypsoCard, const uint8_t sfi, const uint8_t counterValue, const int incDecValue)
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override