Home | History | Annotate | Download | only in jni
      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 
     31 HciEventManager::HciEventManager() : mNativeData(nullptr) {}
     32 
     33 HciEventManager& HciEventManager::getInstance() {
     34   static HciEventManager sHciEventManager;
     35   return sHciEventManager;
     36 }
     37 
     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 
     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  */
     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 
    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 
    179 void HciEventManager::finalize() { mNativeData = NULL; }
    180