1*5c4dab75SAndroid Build Coastguard Worker /*
2*5c4dab75SAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*5c4dab75SAndroid Build Coastguard Worker *
4*5c4dab75SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*5c4dab75SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*5c4dab75SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*5c4dab75SAndroid Build Coastguard Worker *
8*5c4dab75SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*5c4dab75SAndroid Build Coastguard Worker *
10*5c4dab75SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*5c4dab75SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*5c4dab75SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5c4dab75SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*5c4dab75SAndroid Build Coastguard Worker * limitations under the License.
15*5c4dab75SAndroid Build Coastguard Worker */
16*5c4dab75SAndroid Build Coastguard Worker
17*5c4dab75SAndroid Build Coastguard Worker #include <apdu/apdu.h>
18*5c4dab75SAndroid Build Coastguard Worker
19*5c4dab75SAndroid Build Coastguard Worker #include <limits>
20*5c4dab75SAndroid Build Coastguard Worker
21*5c4dab75SAndroid Build Coastguard Worker namespace android {
22*5c4dab75SAndroid Build Coastguard Worker
CommandApdu(const uint8_t cla,const uint8_t ins,const uint8_t p1,const uint8_t p2,const size_t lc,const size_t le)23*5c4dab75SAndroid Build Coastguard Worker CommandApdu::CommandApdu(const uint8_t cla, const uint8_t ins, const uint8_t p1, const uint8_t p2,
24*5c4dab75SAndroid Build Coastguard Worker const size_t lc, const size_t le) {
25*5c4dab75SAndroid Build Coastguard Worker constexpr size_t headerSize = 4;
26*5c4dab75SAndroid Build Coastguard Worker constexpr size_t shortLcMax = std::numeric_limits<uint8_t>::max();
27*5c4dab75SAndroid Build Coastguard Worker constexpr size_t shortLeMax = std::numeric_limits<uint8_t>::max() + 1;
28*5c4dab75SAndroid Build Coastguard Worker //constexpr size_t extendedLcMax = std::numeric_limits<uint16_t>::max();
29*5c4dab75SAndroid Build Coastguard Worker constexpr size_t extendedLeMax = std::numeric_limits<uint16_t>::max() + 1;
30*5c4dab75SAndroid Build Coastguard Worker
31*5c4dab75SAndroid Build Coastguard Worker const bool extended = lc > shortLcMax || le > shortLeMax;
32*5c4dab75SAndroid Build Coastguard Worker const bool hasLc = lc > 0;
33*5c4dab75SAndroid Build Coastguard Worker const bool hasLe = le > 0;
34*5c4dab75SAndroid Build Coastguard Worker const size_t lcSize = hasLc ? (extended ? 3 : 1) : 0;
35*5c4dab75SAndroid Build Coastguard Worker const size_t leSize = hasLe ? (extended ? (hasLc ? 2 : 3) : 1) : 0;
36*5c4dab75SAndroid Build Coastguard Worker const size_t commandSize = headerSize + lcSize + lc + leSize;
37*5c4dab75SAndroid Build Coastguard Worker mCommand.resize(commandSize, 0);
38*5c4dab75SAndroid Build Coastguard Worker
39*5c4dab75SAndroid Build Coastguard Worker // All cases have the header
40*5c4dab75SAndroid Build Coastguard Worker auto it = mCommand.begin();
41*5c4dab75SAndroid Build Coastguard Worker *it++ = cla;
42*5c4dab75SAndroid Build Coastguard Worker *it++ = ins;
43*5c4dab75SAndroid Build Coastguard Worker *it++ = p1;
44*5c4dab75SAndroid Build Coastguard Worker *it++ = p2;
45*5c4dab75SAndroid Build Coastguard Worker
46*5c4dab75SAndroid Build Coastguard Worker // Cases 3 & 4 send data
47*5c4dab75SAndroid Build Coastguard Worker if (hasLc) {
48*5c4dab75SAndroid Build Coastguard Worker if (extended) {
49*5c4dab75SAndroid Build Coastguard Worker *it++ = 0;
50*5c4dab75SAndroid Build Coastguard Worker *it++ = 0xff & (lc >> 8);
51*5c4dab75SAndroid Build Coastguard Worker }
52*5c4dab75SAndroid Build Coastguard Worker *it++ = 0xff & lc;
53*5c4dab75SAndroid Build Coastguard Worker mDataBegin = it;
54*5c4dab75SAndroid Build Coastguard Worker it += lc;
55*5c4dab75SAndroid Build Coastguard Worker mDataEnd = it;
56*5c4dab75SAndroid Build Coastguard Worker } else {
57*5c4dab75SAndroid Build Coastguard Worker mDataBegin = mDataEnd = mCommand.end();
58*5c4dab75SAndroid Build Coastguard Worker }
59*5c4dab75SAndroid Build Coastguard Worker
60*5c4dab75SAndroid Build Coastguard Worker // Cases 2 & 4 expect data back
61*5c4dab75SAndroid Build Coastguard Worker if (hasLe) {
62*5c4dab75SAndroid Build Coastguard Worker if (extended) {
63*5c4dab75SAndroid Build Coastguard Worker if (!hasLc) {
64*5c4dab75SAndroid Build Coastguard Worker *it++ = 0;
65*5c4dab75SAndroid Build Coastguard Worker }
66*5c4dab75SAndroid Build Coastguard Worker const bool isLeMax = le == extendedLeMax;
67*5c4dab75SAndroid Build Coastguard Worker *it++ = (isLeMax ? 0 : 0xff & (le >> 8));
68*5c4dab75SAndroid Build Coastguard Worker *it++ = (isLeMax ? 0 : 0xff & le);
69*5c4dab75SAndroid Build Coastguard Worker } else {
70*5c4dab75SAndroid Build Coastguard Worker *it++ = (le == shortLeMax ? 0 : 0xff & le);
71*5c4dab75SAndroid Build Coastguard Worker }
72*5c4dab75SAndroid Build Coastguard Worker }
73*5c4dab75SAndroid Build Coastguard Worker }
74*5c4dab75SAndroid Build Coastguard Worker
75*5c4dab75SAndroid Build Coastguard Worker } // namespace android
76