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