1 /*
2 * Copyright (C) 2018 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 #include "HciEventManager.h"
17 #include <android-base/stringprintf.h>
18 #include <base/logging.h>
19 #include <log/log.h>
20 #include <nativehelper/ScopedLocalRef.h>
21 #include "JavaClassConstants.h"
22 #include "NfcJniUtil.h"
23 #include "nfc_config.h"
24
25 extern bool nfc_debug_enabled;
26 const char* APP_NAME = "NfcNci";
27 uint8_t HciEventManager::sEsePipe;
28 uint8_t HciEventManager::sSimPipe;
29
30 using android::base::StringPrintf;
31
HciEventManager()32 HciEventManager::HciEventManager() : mNativeData(nullptr) {}
33
getInstance()34 HciEventManager& HciEventManager::getInstance() {
35 static HciEventManager sHciEventManager;
36 return sHciEventManager;
37 }
38
initialize(nfc_jni_native_data * native)39 void HciEventManager::initialize(nfc_jni_native_data* native) {
40 mNativeData = native;
41 tNFA_STATUS nfaStat = NFA_HciRegister(const_cast<char*>(APP_NAME),
42 (tNFA_HCI_CBACK*)&nfaHciCallback, true);
43 if (nfaStat != NFA_STATUS_OK) {
44 LOG(ERROR) << "HCI registration failed; status=" << nfaStat;
45 }
46 sEsePipe = NfcConfig::getUnsigned(NAME_OFF_HOST_ESE_PIPE_ID, 0x16);
47 sSimPipe = NfcConfig::getUnsigned(NAME_OFF_HOST_SIM_PIPE_ID, 0x0A);
48 }
49
notifyTransactionListenersOfAid(std::vector<uint8_t> aid,std::vector<uint8_t> data,std::string evtSrc)50 void HciEventManager::notifyTransactionListenersOfAid(std::vector<uint8_t> aid,
51 std::vector<uint8_t> data,
52 std::string evtSrc) {
53 if (aid.empty()) {
54 return;
55 }
56
57 JNIEnv* e = NULL;
58 ScopedAttach attach(mNativeData->vm, &e);
59 CHECK(e);
60
61 ScopedLocalRef<jobject> aidJavaArray(e, e->NewByteArray(aid.size()));
62 CHECK(aidJavaArray.get());
63 e->SetByteArrayRegion((jbyteArray)aidJavaArray.get(), 0, aid.size(),
64 (jbyte*)&aid[0]);
65 CHECK(!e->ExceptionCheck());
66
67 ScopedLocalRef<jobject> srcJavaString(e, e->NewStringUTF(evtSrc.c_str()));
68 CHECK(srcJavaString.get());
69
70 if (data.size() > 0) {
71 ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(data.size()));
72 CHECK(dataJavaArray.get());
73 e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0, data.size(),
74 (jbyte*)&data[0]);
75 CHECK(!e->ExceptionCheck());
76 e->CallVoidMethod(mNativeData->manager,
77 android::gCachedNfcManagerNotifyTransactionListeners,
78 aidJavaArray.get(), dataJavaArray.get(),
79 srcJavaString.get());
80 } else {
81 e->CallVoidMethod(mNativeData->manager,
82 android::gCachedNfcManagerNotifyTransactionListeners,
83 aidJavaArray.get(), NULL, srcJavaString.get());
84 }
85 }
86
87 /**
88 * BerTlv has the following format:
89 *
90 * byte1 byte2 byte3 byte4 byte5 byte6
91 * 00-7F - - - - -
92 * 81 00-FF - - - -
93 * 82 0000-FFFF - - -
94 * 83 000000-FFFFFF - -
95 * 84 00000000-FFFFFFFF -
96 */
getDataFromBerTlv(std::vector<uint8_t> berTlv)97 std::vector<uint8_t> HciEventManager::getDataFromBerTlv(
98 std::vector<uint8_t> berTlv) {
99 if (berTlv.empty()) {
100 return std::vector<uint8_t>();
101 }
102 size_t lengthTag = berTlv[0];
103 DLOG_IF(INFO, nfc_debug_enabled) << "decodeBerTlv: berTlv[0]=" << berTlv[0];
104
105 /* As per ISO/IEC 7816, read the first byte to determine the length and
106 * the start index accordingly
107 */
108 if (lengthTag < 0x80 && berTlv.size() == (lengthTag + 1)) {
109 return std::vector<uint8_t>(berTlv.begin() + 1, berTlv.end());
110 } else if (lengthTag == 0x81 && berTlv.size() > 2) {
111 size_t length = berTlv[1];
112 if ((length + 2) == berTlv.size()) {
113 return std::vector<uint8_t>(berTlv.begin() + 2, berTlv.end());
114 }
115 } else if (lengthTag == 0x82 && berTlv.size() > 3) {
116 size_t length = ((berTlv[1] << 8) | berTlv[2]);
117 if ((length + 3) == berTlv.size()) {
118 return std::vector<uint8_t>(berTlv.begin() + 3, berTlv.end());
119 }
120 } else if (lengthTag == 0x83 && berTlv.size() > 4) {
121 size_t length = (berTlv[1] << 16) | (berTlv[2] << 8) | berTlv[3];
122 if ((length + 4) == berTlv.size()) {
123 return std::vector<uint8_t>(berTlv.begin() + 4, berTlv.end());
124 }
125 } else if (lengthTag == 0x84 && berTlv.size() > 5) {
126 size_t length =
127 (berTlv[1] << 24) | (berTlv[2] << 16) | (berTlv[3] << 8) | berTlv[4];
128 if ((length + 5) == berTlv.size()) {
129 return std::vector<uint8_t>(berTlv.begin() + 5, berTlv.end());
130 }
131 }
132 LOG(ERROR) << "Error in TLV length encoding!";
133 return std::vector<uint8_t>();
134 }
135
nfaHciCallback(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * eventData)136 void HciEventManager::nfaHciCallback(tNFA_HCI_EVT event,
137 tNFA_HCI_EVT_DATA* eventData) {
138 if (eventData == nullptr) {
139 return;
140 }
141
142 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
143 "event=%d code=%d pipe=%d len=%d", event, eventData->rcvd_evt.evt_code,
144 eventData->rcvd_evt.pipe, eventData->rcvd_evt.evt_len);
145
146 std::string evtSrc;
147 if (eventData->rcvd_evt.pipe == sEsePipe) {
148 evtSrc = "eSE1";
149 } else if (eventData->rcvd_evt.pipe == sSimPipe) {
150 evtSrc = "SIM1";
151 } else {
152 LOG(WARNING) << "Incorrect Pipe Id";
153 return;
154 }
155
156 uint8_t* buff = eventData->rcvd_evt.p_evt_buf;
157 uint32_t buffLength = eventData->rcvd_evt.evt_len;
158 std::vector<uint8_t> event_buff(buff, buff + buffLength);
159 // Check the event and check if it contains the AID
160 if (event == NFA_HCI_EVENT_RCVD_EVT &&
161 eventData->rcvd_evt.evt_code == NFA_HCI_EVT_TRANSACTION &&
162 buffLength > 3 && event_buff[0] == 0x81) {
163 uint32_t aidlen = event_buff[1];
164 if (aidlen < (buffLength - 1)) {
165 std::vector<uint8_t> aid(event_buff.begin() + 2,
166 event_buff.begin() + aidlen + 2);
167
168 int32_t berTlvStart = aidlen + 2 + 1;
169 int32_t berTlvLen = buffLength - berTlvStart;
170 std::vector<uint8_t> data;
171 if (berTlvLen > 0 && event_buff[2 + aidlen] == 0x82) {
172 std::vector<uint8_t> berTlv(event_buff.begin() + berTlvStart,
173 event_buff.end());
174 // BERTLV decoding here, to support extended data length for params.
175 data = getInstance().getDataFromBerTlv(berTlv);
176 }
177 getInstance().notifyTransactionListenersOfAid(aid, data, evtSrc);
178 } else {
179 android_errorWriteLog(0x534e4554, "181346545");
180 LOG(ERROR) << StringPrintf("error: aidlen(%d) is too big", aidlen);
181 }
182 }
183 }
184
finalize()185 void HciEventManager::finalize() { mNativeData = NULL; }
186