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 }
93 if (charD == '\0') {
94 break;
95 }
96 lastByteD = charD;
97 isContinue = CheckOperationRes(lastByteD, HIGH_BITS_MASK, 0);
98 }
99 return true;
100 }
101
CheckAtrDataParam(const std::string & atr)102 bool ResetResponse::CheckAtrDataParam(const std::string &atr)
103 {
104 if (atr.empty() || atr.length() % BYTE_TO_HEX_LEN != 0) {
105 TELEPHONY_LOGE("ATR length %zu is not even.", atr.length());
106 return false;
107 }
108
109 if (atr.length() < MIN_ATR_DATA_LENGTH) {
110 TELEPHONY_LOGE("ATR is Valid, it must at least contains TS and T0.");
111 return false;
112 }
113 return true;
114 }
115
AnalysisAtrData(const std::string & atr)116 bool ResetResponse::AnalysisAtrData(const std::string &atr)
117 {
118 TELEPHONY_LOGD("AnalysisAtrData ATR string enter.");
119 if (!CheckAtrDataParam(atr)) {
120 TELEPHONY_LOGE("failed to check AtrData param!");
121 return false;
122 }
123 std::vector<uint8_t> atrData = Asn1Utils::HexStrToBytes(atr);
124 uint32_t atrDataLen = atrData.size();
125 if (atrDataLen == 0) {
126 TELEPHONY_LOGE("failed to transform HexStr To Bytes.");
127 return false;
128 }
129 // convention byte
130 uint32_t index = 0;
131 if (atrData[index] != POSITIVE_AGREEMENT && atrData[index] != REVERSED_AGREEMENT) {
132 TELEPHONY_LOGE("convention byte is valid!");
133 return false;
134 }
135 index++;
136 if (index >= atrDataLen) {
137 return false;
138 }
139 // format byte
140 formatByte_ = atrData[index];
141 index++;
142 if (index >= atrDataLen) {
143 return false;
144 }
145 return AnalysisInterfaceData(atrData, atrDataLen, index);
146 }
147 } // namespace Telephony
148 } // namespace OHOS