1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "reset_response.h"
17 #include "asn1_constants.h"
18 #include "asn1_node.h"
19 #include "asn1_utils.h"
20 #include "telephony_log_wrapper.h"
21
22 namespace OHOS {
23 namespace Telephony {
24 namespace {
25 const uint32_t BIT2_MASK = 0x02;
26 const uint32_t BIT5_MASK = 0x10;
27 const uint32_t BIT7_MASK = 0x40;
28 const uint32_t HIGH_BITS_MASK = 0xF0;
29 const uint32_t LOW_BITS_MASK = 0x0F;
30 const uint32_t MIN_ATR_DATA_LENGTH = 4;
31 const uint32_t MAX_INTERFACE_VALUE = 0x0F;
32 const uint8_t REVERSED_AGREEMENT = 0x3B;
33 const uint8_t POSITIVE_AGREEMENT = 0x3F;
34 }
35
IsEuiccAvailable()36 bool ResetResponse::IsEuiccAvailable()
37 {
38 return isEuiccAvailable_;
39 }
40
CheckIsEuiccAvailable(uint8_t charB,uint8_t charD)41 bool ResetResponse::CheckIsEuiccAvailable(uint8_t charB, uint8_t charD)
42 {
43 if (charB != '\0' && charD != '\0' && CheckOperationRes(charD, LOW_BITS_MASK, MAX_INTERFACE_VALUE)) {
44 if ((!CheckOperationRes(charB, BIT8_MASK, 0)) && (!CheckOperationRes(charB, BIT2_MASK, 0))) {
45 isEuiccAvailable_ = true;
46 return true;
47 }
48 }
49 return false;
50 }
51
CheckOperationRes(uint8_t chr,const uint32_t tMask,const uint32_t comparedVal)52 bool ResetResponse::CheckOperationRes(uint8_t chr, const uint32_t tMask, const uint32_t comparedVal)
53 {
54 return ((chr & tMask) == comparedVal);
55 }
56
AnalysisInterfaceData(const std::vector<uint8_t> & atrData,uint32_t atrDataLen,uint32_t & index)57 bool ResetResponse::AnalysisInterfaceData(const std::vector<uint8_t> &atrData, uint32_t atrDataLen, uint32_t &index)
58 {
59 uint8_t lastByteD = formatByte_;
60 bool isContinue = CheckOperationRes(lastByteD, HIGH_BITS_MASK, 0);
61 uint8_t charB = '\0';
62 uint8_t charD = '\0';
63 while (!isContinue) {
64 if (!CheckOperationRes(lastByteD, BIT5_MASK, 0)) {
65 if (index >= atrDataLen) {
66 return false;
67 }
68 index++;
69 }
70 if (!CheckOperationRes(lastByteD, BIT6_MASK, 0)) {
71 if (index >= atrDataLen) {
72 return false;
73 }
74 charB = atrData[index];
75 index++;
76 if (charD != '\0' && (CheckIsEuiccAvailable(charB, charD))) {
77 return true;
78 }
79 }
80 if (!CheckOperationRes(lastByteD, BIT7_MASK, 0)) {
81 if (index >= atrDataLen) {
82 return false;
83 }
84 index++;
85 }
86 if (!CheckOperationRes(lastByteD, BIT8_MASK, 0)) {
87 if (index >= atrDataLen) {
88 return false;
89 }
90 charD = atrData[index];
91 index++;
92 } else {
93 TELEPHONY_LOGE("ATR find tdx end, final td: 0x%{public}x", charD);
94 break;
95 }
96 if (charD == '\0') {
97 break;
98 }
99 lastByteD = charD;
100 isContinue = CheckOperationRes(lastByteD, HIGH_BITS_MASK, 0);
101 }
102 return true;
103 }
104
CheckAtrDataParam(const std::string & atr)105 bool ResetResponse::CheckAtrDataParam(const std::string &atr)
106 {
107 if (atr.empty() || atr.length() % BYTE_TO_HEX_LEN != 0) {
108 TELEPHONY_LOGE("ATR length %zu is not even.", atr.length());
109 return false;
110 }
111
112 if (atr.length() < MIN_ATR_DATA_LENGTH) {
113 TELEPHONY_LOGE("ATR is Valid, it must at least contains TS and T0.");
114 return false;
115 }
116 return true;
117 }
118
AnalysisAtrData(const std::string & atr)119 bool ResetResponse::AnalysisAtrData(const std::string &atr)
120 {
121 TELEPHONY_LOGD("AnalysisAtrData ATR string enter.");
122 if (!CheckAtrDataParam(atr)) {
123 TELEPHONY_LOGE("failed to check AtrData param!");
124 return false;
125 }
126 std::vector<uint8_t> atrData = Asn1Utils::HexStrToBytes(atr);
127 uint32_t atrDataLen = atrData.size();
128 if (atrDataLen == 0) {
129 TELEPHONY_LOGE("failed to transform HexStr To Bytes.");
130 return false;
131 }
132 // convention byte
133 uint32_t index = 0;
134 if (atrData[index] != POSITIVE_AGREEMENT && atrData[index] != REVERSED_AGREEMENT) {
135 TELEPHONY_LOGE("convention byte is valid!");
136 return false;
137 }
138 index++;
139 if (index >= atrDataLen) {
140 return false;
141 }
142 // format byte
143 formatByte_ = atrData[index];
144 index++;
145 if (index >= atrDataLen) {
146 return false;
147 }
148 return AnalysisInterfaceData(atrData, atrDataLen, index);
149 }
150 } // namespace Telephony
151 } // namespace OHOS