Keyple Card Calypso C++ Library 2.2.5.6
Reference Terminal Reader API for C++
CmdCardSvGet.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
13#include "CmdCardSvGet.h"
14
15#include <sstream>
16
17/* Keyple Core Util */
18#include "ApduUtil.h"
19#include "ByteArrayUtil.h"
20#include "IllegalStateException.h"
21#include "System.h"
22
23/* Keyple Card Calypso */
24#include "CalypsoCardAdapter.h"
28#include "CardPinException.h"
34
35namespace keyple {
36namespace card {
37namespace calypso {
38
39using namespace keyple::core::util;
40
41const CalypsoCardCommand CmdCardSvGet::mCommand = CalypsoCardCommand::SV_GET;
42const std::map<const int, const std::shared_ptr<StatusProperties>>
43 CmdCardSvGet::STATUS_TABLE = initStatusTable();
44
45CmdCardSvGet::CmdCardSvGet(const std::shared_ptr<CalypsoCardAdapter> calypsoCard,
46 const SvOperation svOperation,
47 const bool useExtendedMode)
48: AbstractCardCommand(mCommand, -1, calypsoCard)
49{
50 const uint8_t cla = calypsoCard->getCardClass() == CalypsoCardClass::LEGACY ?
53
54 const uint8_t p1 = useExtendedMode ? 0x01 : 0x00;
55 const uint8_t p2 = svOperation == SvOperation::RELOAD ? 0x07 : 0x09;
56
57 uint8_t le;
58 if (useExtendedMode) {
59 le = 0x3D;
60 } else {
61 if (svOperation == SvOperation::RELOAD) {
62 le = 0x21;
63 } else {
64 le = 0x1E;
65 }
66 }
68
69 // APDU Case 2
71 std::make_shared<ApduRequestAdapter>(
72 ApduUtil::build(cla, mCommand.getInstructionByte(), p1, p2, le)));
73
74 std::stringstream ss;
75 ss << "OPERATION:" << svOperation;
76 addSubName(ss.str());
77
78 mHeader = std::vector<uint8_t>(4);
79 mHeader[0] = mCommand.getInstructionByte();
80 mHeader[1] = p1;
81 mHeader[2] = p2;
82 mHeader[3] = le;
83}
84
86{
87 return false;
88}
89
90void CmdCardSvGet::parseApduResponse(const std::shared_ptr<ApduResponseApi> apduResponse)
91{
93
94 const std::vector<uint8_t> cardResponse = apduResponse->getDataOut();
95
96 uint8_t currentKvc = 0;
97 int transactionNumber = 0;
98 int balance = 0;
99 std::shared_ptr<SvLoadLogRecord> loadLog = nullptr;
100 std::shared_ptr<SvDebitLogRecord> debitLog = nullptr;
101
102 switch (cardResponse.size()) {
103 case 0x21: /* Compatibility mode, Reload */
104 case 0x1E: /* Compatibility mode, Debit or Undebit */
105 {
106 std::vector<uint8_t> challengeOut(2);
107 std::vector<uint8_t> previousSignatureLo = std::vector<uint8_t>(3);
108 currentKvc = cardResponse[0];
109 transactionNumber = ByteArrayUtil::extractInt(cardResponse, 1, 2, false);
110 System::arraycopy(cardResponse, 3, previousSignatureLo, 0, 3);
111 challengeOut[0] = cardResponse[6];
112 challengeOut[1] = cardResponse[7];
113 balance = ByteArrayUtil::extractInt(cardResponse, 8, 3, true);
114
115 if (cardResponse.size() == 0x21) {
116
117 /* Reload */
118 loadLog = std::make_shared<SvLoadLogRecordAdapter>(cardResponse, 11);
119 debitLog = nullptr;
120
121 } else {
122
123 /* Debit */
124 loadLog = nullptr;
125 debitLog = std::make_shared<SvDebitLogRecordAdapter>(cardResponse, 11);
126 }
127
128 break;
129 }
130 case 0x3D: /* Revision 3.2 mode */
131 {
132 std::vector<uint8_t> challengeOut(8);
133 std::vector<uint8_t> previousSignatureLo(6);
134 System::arraycopy(cardResponse, 0, challengeOut, 0, 8);
135 currentKvc = cardResponse[8];
136 transactionNumber = ByteArrayUtil::extractInt(cardResponse, 9, 2, false);
137 System::arraycopy(cardResponse, 11, previousSignatureLo, 0, 6);
138 balance = ByteArrayUtil::extractInt(cardResponse, 17, 3, true);
139 loadLog = std::make_shared<SvLoadLogRecordAdapter>(cardResponse, 20);
140 debitLog = std::make_shared<SvDebitLogRecordAdapter>(cardResponse, 42);
141 break;
142 }
143 default:
144 throw IllegalStateException("Incorrect data length in response to SVGet");
145 }
146
147 getCalypsoCard()->setSvData(currentKvc,
148 mHeader,
149 apduResponse->getApdu(),
150 balance,
151 transactionNumber,
152 loadLog,
153 debitLog);
154}
155
156const std::map<const int, const std::shared_ptr<StatusProperties>>
157 CmdCardSvGet::initStatusTable()
158{
159 std::map<const int, const std::shared_ptr<StatusProperties>> m =
161
162 m.insert({0x6982,
163 std::make_shared<StatusProperties>("Security conditions not fulfilled.",
165 m.insert({0x6985,
166 std::make_shared<StatusProperties>("Preconditions not satisfied (a store value " \
167 "operation was already done in the current " \
168 "session).",
169 typeid(CalypsoSamAccessForbiddenException))});
170 m.insert({0x6A81,
171 std::make_shared<StatusProperties>("Incorrect P1 or P2.",
172 typeid(CardIllegalParameterException))});
173 m.insert({0x6A86,
174 std::make_shared<StatusProperties>("Le inconsistent with P2.",
175 typeid(CardIllegalParameterException))});
176 m.insert({0x6D00,
177 std::make_shared<StatusProperties>("SV function not present.",
178 typeid(CardIllegalParameterException))});
179
180 return m;
181}
182
183const std::map<const int, const std::shared_ptr<StatusProperties>>& CmdCardSvGet::getStatusTable()
184 const
185{
186 return STATUS_TABLE;
187}
188
189}
190}
191}
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
std::shared_ptr< CalypsoCardAdapter > getCalypsoCard() const
static const CalypsoCardClass LEGACY
static const CalypsoCardClass ISO
static const CalypsoCardClass LEGACY_STORED_VALUE
static const CalypsoCardCommand SV_GET
CmdCardSvGet(const std::shared_ptr< CalypsoCardAdapter > calypsoCard, const SvOperation svOperation, const bool useExtendedMode)
bool isSessionBufferUsed() const override
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override