Keyple Card Calypso C++ Library 2.1.0
Reference Terminal Reader API for C++
CmdCardReadRecordMultiple.cpp
Go to the documentation of this file.
1/**************************************************************************************************
2 * Copyright (c) 2021 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
21/* Keyple Card Calypso */
27
28namespace keyple {
29namespace card {
30namespace calypso {
31
32using namespace keyple::core::util;
33using namespace keyple::core::util::cpp;
34
35const std::map<const int, const std::shared_ptr<StatusProperties>>
36 CmdCardReadRecordMultiple::STATUS_TABLE = initStatusTable();
37
39 const CalypsoCardClass calypsoCardClass,
40 const uint8_t sfi,
41 const uint8_t recordNumber,
42 const uint8_t offset,
43 const uint8_t length)
44: AbstractCardCommand(CalypsoCardCommand::READ_RECORD_MULTIPLE),
45 mSfi(sfi),
46 mRecordNumber(recordNumber),
47 mOffset(offset),
48 mLength(length)
49{
50 const uint8_t p2 = (sfi * 8 + 5);
51 const std::vector<uint8_t> dataIn = {0x54, 0x02, offset, length};
52
54 std::make_shared<ApduRequestAdapter>(
55 ApduUtil::build(calypsoCardClass.getValue(),
56 getCommandRef().getInstructionByte(),
57 recordNumber,
58 p2,
59 dataIn,
60 0)));
61
62 std::stringstream extraInfo;
63 extraInfo << "SFI:" << sfi << "h, "
64 << "RECORD_NUMBER:" << recordNumber << ", "
65 << "OFFSET:" << offset << ", "
66 << "LENGTH:" << length;
67
68 addSubName(extraInfo.str());
69}
70
72{
73 return false;
74}
75
76const std::map<const int, const std::shared_ptr<StatusProperties>>
77 CmdCardReadRecordMultiple::initStatusTable()
78{
79 std::map<const int, const std::shared_ptr<StatusProperties>> m =
81
82 m.insert({0x6700,
83 std::make_shared<StatusProperties>("Lc value not supported (<4).",
85 m.insert({0x6981,
86 std::make_shared<StatusProperties>("Incorrect EF type: Binary EF.",
87 typeid(CardDataAccessException))});
88 m.insert({0x6982,
89 std::make_shared<StatusProperties>("Security conditions not fulfilled (PIN code " \
90 "not presented, encryption required).",
91 typeid(CardSecurityContextException))});
92 m.insert({0x6985,
93 std::make_shared<StatusProperties>("Access forbidden (Never access mode, Stored " \
94 "Value log file and a Stored Value operation was" \
95 " done during the current secure session).",
96 typeid(CardAccessForbiddenException))});
97 m.insert({0x6986,
98 std::make_shared<StatusProperties>("Incorrect file type: the Current File is not " \
99 "an EF. Supersedes 6981h.",
100 typeid(CardDataAccessException))});
101 m.insert({0x6A80,
102 std::make_shared<StatusProperties>("Incorrect command data (incorrect Tag, " \
103 "incorrect Length, R. Length > RecSize, R. " \
104 "Offset + R. Length > RecSize, R. Length = 0).",
105 typeid(CardIllegalParameterException))});
106 m.insert({0x6A82,
107 std::make_shared<StatusProperties>("File not found.",
108 typeid(CardDataAccessException))});
109 m.insert({0x6A83,
110 std::make_shared<StatusProperties>("Record not found (record index is 0, or above " \
111 "NumRec).",
112 typeid(CardDataAccessException))});
113 m.insert({0x6B00,
114 std::make_shared<StatusProperties>("P1 or P2 value not supported.",
115 typeid(CardIllegalParameterException))});
116 m.insert({0x6200,
117 std::make_shared<StatusProperties>("Successful execution, partial read only: issue " \
118 "another Read Record Multiple from record (P1 + " \
119 "(Size of returned data) / (R. Length)) to " \
120 "continue reading.")});
121
122 return m;
123}
124
125const std::map<const int, const std::shared_ptr<StatusProperties>>&
127{
128 return STATUS_TABLE;
129}
130
132 const std::shared_ptr<ApduResponseApi> apduResponse)
133{
135
136 if (apduResponse->getDataOut().size() > 0) {
137 const std::vector<uint8_t> dataOut = apduResponse->getDataOut();
138 const uint8_t nbRecords = static_cast<uint8_t>(dataOut.size() / mLength);
139 for (int i = 0; i < nbRecords; i++) {
140 mResults.insert({static_cast<uint8_t>(mRecordNumber + i),
141 Arrays::copyOfRange(dataOut, i * mLength, (i + 1) * mLength)});
142 }
143 }
144
145 return *this;
146}
147
149{
150 return mSfi;
151}
152
154{
155 return mOffset;
156}
157
158const std::map<const uint8_t, const std::vector<uint8_t>>& CmdCardReadRecordMultiple::getResults()
159 const
160{
161 return mResults;
162}
163
164}
165}
166}
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
const CalypsoCardCommand & getCommandRef() const override
AbstractCardCommand & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const std::map< const uint8_t, const std::vector< uint8_t > > & getResults() const
CmdCardReadRecordMultiple(const CalypsoCardClass calypsoCardClass, const uint8_t sfi, const uint8_t recordNumber, const uint8_t offset, const uint8_t length)
CmdCardReadRecordMultiple & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override