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