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