Keyple Util C++ Library 2.0.0
Reference Terminal Reader API for C++
ApduUtil.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
13#include "ApduUtil.h"
14
15/* Util */
16#include "System.h"
17
18namespace keyple {
19namespace core {
20namespace util {
21
22using namespace keyple::core::util::cpp;
23
24ApduUtil::ApduUtil() {}
25
26const std::vector<uint8_t> ApduUtil::build(const uint8_t cla,
27 const uint8_t ins,
28 const uint8_t p1,
29 const uint8_t p2,
30 const std::vector<uint8_t>& dataIn,
31 const uint8_t le)
32{
33 std::vector<uint8_t> apduCommand;
34
35 /* Buffer allocation */
36 apduCommand = allocateBuffer(dataIn, le);
37
38 /* Build APDU buffer from provided arguments */
39 apduCommand[0] = cla;
40 apduCommand[1] = ins;
41 apduCommand[2] = p1;
42 apduCommand[3] = p2;
43
44 /* ISO7618 case determination and Le management */
45 if (dataIn.size() != 0) {
46 /* Append Lc and ingoing data */
47 apduCommand[4] = static_cast<uint8_t>(dataIn.size());
48 System::arraycopy(dataIn, 0, apduCommand, 5, static_cast<int>(dataIn.size()));
49 apduCommand[apduCommand.size() - 1] = le;
50 } else {
51 /* Case2: outgoing data only */
52 apduCommand[4] = le;
53 }
54
55 return apduCommand;
56}
57
58const std::vector<uint8_t> ApduUtil::build(const uint8_t cla,
59 const uint8_t ins,
60 const uint8_t p1,
61 const uint8_t p2,
62 const std::vector<uint8_t>& dataIn)
63{
64 std::vector<uint8_t> apduCommand;
65
66 /* Buffer allocation */
67 apduCommand = allocateBuffer(dataIn);
68
69 /* Build APDU buffer from provided arguments */
70 apduCommand[0] = cla;
71 apduCommand[1] = ins;
72 apduCommand[2] = p1;
73 apduCommand[3] = p2;
74
75 /* ISO7618 case determination and Le management */
76 if (dataIn.size() != 0) {
77 /* append Lc and ingoing data */
78 apduCommand[4] = static_cast<uint8_t>(dataIn.size());
79 System::arraycopy(dataIn, 0, apduCommand, 5, static_cast<int>(dataIn.size()));
80 /* Case3: ingoing data only, no Le */
81 } else {
82 /* Case1: no ingoing, no outgoing data, P3/Le = 0 */
83 apduCommand[4] = 0x00;
84 }
85 return apduCommand;
86}
87
88const std::vector<uint8_t> ApduUtil::build(const uint8_t cla,
89 const uint8_t ins,
90 const uint8_t p1,
91 const uint8_t p2,
92 const uint8_t le)
93{
94 std::vector<uint8_t> apduCommand;
95
96 /* Buffer allocation */
97 apduCommand = allocateBuffer(le);
98
99 /* Build APDU buffer from provided arguments */
100 apduCommand[0] = cla;
101 apduCommand[1] = ins;
102 apduCommand[2] = p1;
103 apduCommand[3] = p2;
104
105 /* ISO7618 case determination and Le management */
106 /* Case2: outgoing data only */
107 apduCommand[4] = le;
108
109 return apduCommand;
110}
111
112const std::vector<uint8_t> ApduUtil::build(const uint8_t cla,
113 const uint8_t ins,
114 const uint8_t p1,
115 const uint8_t p2)
116{
117 std::vector<uint8_t> apduCommand;
118
119 /* Buffer allocation */
120 apduCommand = allocateBuffer();
121
122 /* Build APDU buffer from provided arguments */
123 apduCommand[0] = cla;
124 apduCommand[1] = ins;
125 apduCommand[2] = p1;
126 apduCommand[3] = p2;
127
128 /* ISO7618 case determination and Le management */
129 /* Case1: no ingoing, no outgoing data, P3/Le = 0 */
130 apduCommand[4] = 0x00;
131
132 return apduCommand;
133}
134
135std::vector<uint8_t> ApduUtil::allocateBuffer(const std::vector<uint8_t>& data, const uint8_t le)
136{
137 (void)le;
138
139 int length = 4; // Header
140
141 length += static_cast<int>(data.size() + 1); // Lc + data
142 length += 1; // Le
143
144 return std::vector<uint8_t>(length);
145}
146
147std::vector<uint8_t> ApduUtil::allocateBuffer(const std::vector<uint8_t>& data)
148{
149 int length = 4; // Header
150
151 length += static_cast<int>(data.size() + 1); // Lc + data
152
153 return std::vector<uint8_t>(length);
154}
155
156std::vector<uint8_t> ApduUtil::allocateBuffer(const uint8_t le)
157{
158 (void)le;
159
160 int length = 4; // Header
161
162 length += 1; // Le
163
164 return std::vector<uint8_t>(length);
165}
166
167std::vector<uint8_t> ApduUtil::allocateBuffer()
168{
169 int length = 4; // Header
170
171 /* Case 1: 5-byte apdu, le=0 */
172 length += 1; // Le
173
174 return std::vector<uint8_t>(length);
175}
176
177bool ApduUtil::isCase4(const std::vector<uint8_t>& apduCommand)
178{
179 if (apduCommand.size() > 4) {
180 return apduCommand[4] == apduCommand.size() - 6;
181 }
182
183 return false;
184}
185
186}
187}
188}
static bool isCase4(const std::vector< uint8_t > &apduCommand)
Definition: ApduUtil.cpp:177
static std::vector< uint8_t > allocateBuffer()
Definition: ApduUtil.cpp:167
static const std::vector< uint8_t > build(const uint8_t cla, const uint8_t ins, const uint8_t p1, const uint8_t p2, const std::vector< uint8_t > &dataIn, const uint8_t le)
Definition: ApduUtil.cpp:26
static void arraycopy(const std::vector< char > &src, size_t srcPos, std::vector< char > &dest, size_t destPos, size_t length)
Definition: System.h:53