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