Keyple Card Calypso C++ Library 2.2.5.6
Reference Terminal Reader API for C++
CmdCardGetDataFci.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 "CmdCardGetDataFci.h"
14
15/* Keyple Card Calypso */
16#include "ApduRequestAdapter.h"
18
19/* Keyple Core Util */
20#include "ApduUtil.h"
21#include "BerTlvUtil.h"
22#include "HexUtil.h"
23
24namespace keyple {
25namespace card {
26namespace calypso {
27
28using namespace keyple::core::util;
29using namespace keyple::core::util::cpp;
30
31const int CmdCardGetDataFci::TAG_DF_NAME = 0x84;
32const int CmdCardGetDataFci::TAG_APPLICATION_SERIAL_NUMBER = 0xC7;
33const int CmdCardGetDataFci::TAG_DISCRETIONARY_DATA = 0x53;
34const CalypsoCardCommand CmdCardGetDataFci::mCommand = CalypsoCardCommand::GET_DATA;
35const std::map<const int, const std::shared_ptr<StatusProperties>>
36 CmdCardGetDataFci::STATUS_TABLE = initStatusTable();
37
38CmdCardGetDataFci::CmdCardGetDataFci(const std::shared_ptr<CalypsoCardAdapter> calypsoCard)
39: AbstractCardCommand(mCommand, -1, calypsoCard)
40{
41 buildCommand(calypsoCard->getCardClass());
42}
43
45: AbstractCardCommand(mCommand, -1, nullptr)
46{
47 buildCommand(calypsoCardClass);
48}
49
50void CmdCardGetDataFci::buildCommand(const CalypsoCardClass calypsoCardClass)
51{
52 // APDU Case 2 - always outside secure session
54 std::make_shared<ApduRequestAdapter>(
55 ApduUtil::build(calypsoCardClass.getValue(),
56 mCommand.getInstructionByte(),
57 0x00,
58 0x6F,
59 0x00)));
60}
61
63{
64 return false;
65}
66
67void CmdCardGetDataFci::parseApduResponse(const std::shared_ptr<ApduResponseApi> apduResponse)
68{
70
71 /*
72 * Check the command status to determine if the DF has been invalidated
73 * CL-INV-STATUS.1
74 */
75 if (getApduResponse()->getStatusWord() == 0x6283) {
76 mLogger->debug("The response to the select application command status word indicates that" \
77 " the DF has been invalidated\n");
78 mIsDfInvalidated = true;
79 }
80
81 /* Parse the raw data with the help of the TLV class */
82 try {
83 /* Init TLV object with the raw data and extract the FCI Template */
84 const std::vector<uint8_t> responseData = getApduResponse()->getDataOut();
85
86 /*
87 * CL-SEL-TLVDATA.1
88 * CL-TLV-VAR.1
89 * CL-TLV-ORDER.1
90 */
91 const std::map<const int, const std::vector<uint8_t>> tags =
92 BerTlvUtil::parseSimple(responseData, true);
93
94 auto it = tags.find(TAG_DF_NAME);
95 if (it == tags.end()) {
96 mLogger->error("DF name tag (84h) not found\n");
97 return;
98 }
99
100 mDfName = it->second;
101
102 if (mDfName.size() < 5 || mDfName.size() > 16) {
103 mLogger->error("Invalid DF name length: %. Should be between 5 and 16\n",
104 mDfName.size());
105 return;
106 }
107
108 mLogger->debug("DF name = %\n", HexUtil::toHex(mDfName));
109
110 it = tags.find(TAG_APPLICATION_SERIAL_NUMBER);
111 if (it == tags.end()) {
112 mLogger->error("Serial Number tag (C7h) not found\n");
113 return;
114 }
115
116 mApplicationSN = it->second;
117
118 /* CL-SEL-CSN.1 */
119 if (mApplicationSN.size() != 8) {
120 mLogger->error("Invalid application serial number length: %. Should be 8\n",
121 mApplicationSN.size());
122 return;
123 }
124
125 mLogger->debug("Application Serial Number = %\n", HexUtil::toHex(mApplicationSN));
126
127 it = tags.find(TAG_DISCRETIONARY_DATA);
128 if (it == tags.end()) {
129 mLogger->error("Discretionary data tag (53h) not found\n");
130 return;
131 }
132
133 mDiscretionaryData = it->second;
134
135 if (mDiscretionaryData.size() < 7) {
136 mLogger->error("Invalid startup info length: %. Should be >= 7\n",
137 mDiscretionaryData.size());
138 return;
139 }
140
141 mLogger->debug("Discretionary Data = %\n", HexUtil::toHex(mDiscretionaryData));
142
143 /* All 3 main fields were retrieved */
144 mIsValidCalypsoFCI = true;
145
146 } catch (const Exception& e) {
147
148 /* Silently ignore problems decoding TLV structure. Just log. */
149 mLogger->debug("Error while parsing the FCI BER-TLV data structure (%)\n", e.getMessage());
150 }
151
152 getCalypsoCard()->initializeWithFci(shared_from_this());
153}
154
156{
157 return mIsValidCalypsoFCI;
158}
159
160const std::vector<uint8_t>& CmdCardGetDataFci::getDfName() const
161{
162 return mDfName;
163}
164
165const std::vector<uint8_t>& CmdCardGetDataFci::getApplicationSerialNumber() const
166{
167 return mApplicationSN;
168}
169
170const std::vector<uint8_t>& CmdCardGetDataFci::getDiscretionaryData() const
171{
172 return mDiscretionaryData;
173}
174
176{
177 return mIsDfInvalidated;
178}
179
180const std::map<const int, const std::shared_ptr<StatusProperties>>
181 CmdCardGetDataFci::initStatusTable()
182{
183 std::map<const int, const std::shared_ptr<StatusProperties>> m =
185
186 m.insert({0x6A88,
187 std::make_shared<StatusProperties>("Data object not found (optional mode not " \
188 "available).",
189 typeid(CardDataAccessException))});
190 m.insert({0x6B00,
191 std::make_shared<StatusProperties>("P1 or P2 value not supported.",
192 typeid(CardDataAccessException))});
193 m.insert({0x6283,
194 std::make_shared<StatusProperties>("Successful execution, FCI request and DF is " \
195 "invalidated.",
196 typeid(nullptr))});
197
198 return m;
199}
200
201const std::map<const int, const std::shared_ptr<StatusProperties>>&
203{
204 return STATUS_TABLE;
205}
206
207}
208}
209}
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
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
std::shared_ptr< CalypsoCardAdapter > getCalypsoCard() const
static const CalypsoCardCommand GET_DATA
CmdCardGetDataFci(const std::shared_ptr< CalypsoCardAdapter > calypsoCard)
void parseApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const std::vector< uint8_t > & getDfName() const
const std::vector< uint8_t > & getDiscretionaryData() const
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override
const std::vector< uint8_t > & getApplicationSerialNumber() const