• 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 #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