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
24extern bool nfc_debug_enabled;
25const char* APP_NAME = "NfcNci";
26uint8_t HciEventManager::sEsePipe;
27uint8_t HciEventManager::sSimPipe;
28
29using android::base::StringPrintf;
30
31HciEventManager::HciEventManager() : mNativeData(nullptr) {}
32
33HciEventManager& HciEventManager::getInstance() {
34  static HciEventManager sHciEventManager;
35  return sHciEventManager;
36}
37
38void 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
49void 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 */
96std::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
135void 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
179void HciEventManager::finalize() { mNativeData = NULL; }
180