195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna/******************************************************************************
295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *
395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  Copyright 2018 NXP
495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *
595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  Licensed under the Apache License, Version 2.0 (the "License");
695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  you may not use this file except in compliance with the License.
795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  You may obtain a copy of the License at
895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *
995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  http://www.apache.org/licenses/LICENSE-2.0
1095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *
1195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  Unless required by applicable law or agreed to in writing, software
1295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  distributed under the License is distributed on an "AS IS" BASIS,
1395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  See the License for the specific language governing permissions and
1595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *  limitations under the License.
1695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna *
1795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna ******************************************************************************/
1895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna#define LOG_TAG "NxpEseHal"
1995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna#include <log/log.h>
2095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
21697ae4b2040860ed35fa45a865f196cf33074868Love Khanna#include "LsClient.h"
2295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna#include "SecureElement.h"
2395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna#include "phNxpEse_Api.h"
2495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
2595faecf9216aeb01b97ca5416ef9cc085303015fLove Khannaextern bool ese_debug_enabled;
2695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
2795faecf9216aeb01b97ca5416ef9cc085303015fLove Khannanamespace android {
2895faecf9216aeb01b97ca5416ef9cc085303015fLove Khannanamespace hardware {
2995faecf9216aeb01b97ca5416ef9cc085303015fLove Khannanamespace secure_element {
3095faecf9216aeb01b97ca5416ef9cc085303015fLove Khannanamespace V1_0 {
3195faecf9216aeb01b97ca5416ef9cc085303015fLove Khannanamespace implementation {
3295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
3395faecf9216aeb01b97ca5416ef9cc085303015fLove Khannasp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
3495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
3595faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaSecureElement::SecureElement()
3695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    : mOpenedchannelCount(0),
3795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      mOpenedChannels{false, false, false, false} {}
3895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
3995faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaReturn<void> SecureElement::init(
4095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    const sp<
4195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna        ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
4295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna        clientCallback) {
4395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  ESESTATUS status = ESESTATUS_SUCCESS;
4495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
4595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (clientCallback == nullptr) {
4695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    return Void();
4795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else {
4895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    mCallbackV1_0 = clientCallback;
4995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (!mCallbackV1_0->linkToDeath(this, 0 /*cookie*/)) {
5095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      ALOGE("%s: Failed to register death notification", __func__);
5195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
5295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
539406bd700454e148fd93a0b34364c9652c619fd6Jizhou Liao  if (isSeInitialized()) {
54697ae4b2040860ed35fa45a865f196cf33074868Love Khanna    clientCallback->onStateChange(true);
55697ae4b2040860ed35fa45a865f196cf33074868Love Khanna    return Void();
56697ae4b2040860ed35fa45a865f196cf33074868Love Khanna  }
5795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
5895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  status = seHalInit();
5995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (status != ESESTATUS_SUCCESS) {
6095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    clientCallback->onStateChange(false);
6195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    return Void();
6295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
6395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
64697ae4b2040860ed35fa45a865f196cf33074868Love Khanna  LSCSTATUS lsStatus = LSC_doDownload(clientCallback);
65697ae4b2040860ed35fa45a865f196cf33074868Love Khanna  /*
66697ae4b2040860ed35fa45a865f196cf33074868Love Khanna   * LSC_doDownload returns LSCSTATUS_FAILED in case thread creation fails.
67697ae4b2040860ed35fa45a865f196cf33074868Love Khanna   * So return callback as false.
68697ae4b2040860ed35fa45a865f196cf33074868Love Khanna   * Otherwise callback will be called in LSDownload module.
69697ae4b2040860ed35fa45a865f196cf33074868Love Khanna   */
70697ae4b2040860ed35fa45a865f196cf33074868Love Khanna  if (lsStatus != LSCSTATUS_SUCCESS) {
71697ae4b2040860ed35fa45a865f196cf33074868Love Khanna    ALOGE("%s: LSDownload thread creation failed!!!", __func__);
72697ae4b2040860ed35fa45a865f196cf33074868Love Khanna    SecureElementStatus sestatus = seHalDeInit();
73697ae4b2040860ed35fa45a865f196cf33074868Love Khanna    if (sestatus != SecureElementStatus::SUCCESS) {
74697ae4b2040860ed35fa45a865f196cf33074868Love Khanna      ALOGE("%s: seHalDeInit failed!!!", __func__);
75697ae4b2040860ed35fa45a865f196cf33074868Love Khanna    }
76697ae4b2040860ed35fa45a865f196cf33074868Love Khanna    clientCallback->onStateChange(false);
77697ae4b2040860ed35fa45a865f196cf33074868Love Khanna  }
7895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  return Void();
7995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
8095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
8195faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaReturn<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
8295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  hidl_vec<uint8_t> response;
8395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  _hidl_cb(response);
8495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  return Void();
8595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
8695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
8795faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaReturn<bool> SecureElement::isCardPresent() { return true; }
8895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
8995faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaReturn<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
9095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna                                     transmit_cb _hidl_cb) {
91697ae4b2040860ed35fa45a865f196cf33074868Love Khanna  ESESTATUS status = ESESTATUS_FAILED;
9295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_data cmdApdu;
9395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_data rspApdu;
9495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
9595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
9695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
9795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  cmdApdu.len = data.size();
9895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (cmdApdu.len >= MIN_APDU_LENGTH) {
9995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
10095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    memcpy(cmdApdu.p_data, data.data(), cmdApdu.len);
10195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
10295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
10395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
10495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  hidl_vec<uint8_t> result;
10595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (status != ESESTATUS_SUCCESS) {
10695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    ALOGE("%s: transmit failed!!!", __func__);
10795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else {
10895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    result.resize(rspApdu.len);
10995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    memcpy(&result[0], rspApdu.p_data, rspApdu.len);
11095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
11195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  _hidl_cb(result);
11295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_free(cmdApdu.p_data);
11395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_free(rspApdu.p_data);
11495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  return Void();
11595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
11695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
11795faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaReturn<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
11895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna                                               uint8_t p2,
11995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna                                               openLogicalChannel_cb _hidl_cb) {
12095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
12195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
12295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  LogicalChannelResponse resApduBuff;
12395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  resApduBuff.channelNumber = 0xff;
12495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  memset(&resApduBuff, 0x00, sizeof(resApduBuff));
12595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
1269406bd700454e148fd93a0b34364c9652c619fd6Jizhou Liao  if (!isSeInitialized()) {
12795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    ESESTATUS status = seHalInit();
12895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (status != ESESTATUS_SUCCESS) {
12995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      ALOGE("%s: seHalInit Failed!!!", __func__);
13095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
13195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      return Void();
13295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
13395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
13495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
13595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  SecureElementStatus sestatus = SecureElementStatus::IOERROR;
13695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  ESESTATUS status = ESESTATUS_FAILED;
13795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_data cmdApdu;
13895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_data rspApdu;
13995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
14095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
14195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
14295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
14395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  cmdApdu.len = manageChannelCommand.size();
14495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
14595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna                                               sizeof(uint8_t));
14695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (cmdApdu.p_data != NULL) {
14795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
14895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
14995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
15095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (status != ESESTATUS_SUCCESS) {
15195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*Transceive failed*/
15295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    sestatus = SecureElementStatus::IOERROR;
15395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
15495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna             rspApdu.p_data[rspApdu.len - 1] == 0x00) {
15595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*ManageChannel successful*/
15695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    resApduBuff.channelNumber = rspApdu.p_data[0];
15795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    mOpenedchannelCount++;
15895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    mOpenedChannels[resApduBuff.channelNumber] = true;
15995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    sestatus = SecureElementStatus::SUCCESS;
16095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
16195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna             rspApdu.p_data[rspApdu.len - 1] == 0x81) {
16295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
16395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
16495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna              (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
16595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna             rspApdu.p_data[rspApdu.len - 1] == 0x00) {
16695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
16795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
16895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
16995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  /*Free the allocations*/
17095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_free(cmdApdu.p_data);
17195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_free(rspApdu.p_data);
17295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
17395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (sestatus != SecureElementStatus::SUCCESS) {
17495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*If manageChanle is failed in any of above cases
17595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    send the callback and return*/
17695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    _hidl_cb(resApduBuff, sestatus);
17795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    return Void();
17895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
17995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
18095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  ALOGD_IF(ese_debug_enabled, "%s: Sending selectApdu", __func__);
18195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  /*Reset variables if manageChannel is success*/
18295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  sestatus = SecureElementStatus::IOERROR;
18395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  status = ESESTATUS_FAILED;
18495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
18595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
18695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
18795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
18895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  cmdApdu.len = (int32_t)(5 + aid.size());
18995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
19095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (cmdApdu.p_data != NULL) {
19195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    uint8_t xx = 0;
19295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = resApduBuff.channelNumber;
19395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = 0xA4;        // INS
19495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = 0x04;        // P1
19595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = p2;          // P2
19695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = aid.size();  // Lc
19795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
19895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
19995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
20095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
20195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
20295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (status != ESESTATUS_SUCCESS) {
20395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*Transceive failed*/
20495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    sestatus = SecureElementStatus::IOERROR;
20595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else {
20695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
20795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
20895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*Return response on success, empty vector on failure*/
20995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*Status is success*/
21095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (sw1 == 0x90 && sw2 == 0x00) {
21195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      /*Copy the response including status word*/
21295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      resApduBuff.selectResponse.resize(rspApdu.len);
21395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len);
21495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::SUCCESS;
21595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
21695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*AID provided doesn't match any applet on the secure element*/
21795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    else if (sw1 == 0x6A && sw2 == 0x82) {
21895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
21995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
22095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*Operation provided by the P2 parameter is not permitted by the applet.*/
22195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    else if (sw1 == 0x6A && sw2 == 0x86) {
22295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
22395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
22495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
22595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
22695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (sestatus != SecureElementStatus::SUCCESS) {
22795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    SecureElementStatus closeChannelStatus =
22895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna        closeChannel(resApduBuff.channelNumber);
22995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (closeChannelStatus != SecureElementStatus::SUCCESS) {
23095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      ALOGE("%s: closeChannel Failed", __func__);
23195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    } else {
23295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      resApduBuff.channelNumber = 0xff;
23395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
23495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
23595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  _hidl_cb(resApduBuff, sestatus);
23695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_free(cmdApdu.p_data);
23795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_free(rspApdu.p_data);
23895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
23995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  return Void();
24095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
24195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
24295faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaReturn<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
24395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna                                             uint8_t p2,
24495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna                                             openBasicChannel_cb _hidl_cb) {
24595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  hidl_vec<uint8_t> result;
24695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
2479406bd700454e148fd93a0b34364c9652c619fd6Jizhou Liao  if (!isSeInitialized()) {
24895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    ESESTATUS status = seHalInit();
24995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (status != ESESTATUS_SUCCESS) {
25095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      ALOGE("%s: seHalInit Failed!!!", __func__);
25195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      _hidl_cb(result, SecureElementStatus::IOERROR);
25295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      return Void();
25395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
25495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
25595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
25695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  SecureElementStatus sestatus = SecureElementStatus::IOERROR;
25795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  ESESTATUS status = ESESTATUS_FAILED;
25895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_data cmdApdu;
25995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_data rspApdu;
26095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
26195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
26295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
26395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
26495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  cmdApdu.len = (int32_t)(5 + aid.size());
26595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
26695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (cmdApdu.p_data != NULL) {
26795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    uint8_t xx = 0;
26895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = 0x00;        // basic channel
26995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = 0xA4;        // INS
27095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = 0x04;        // P1
27195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = p2;          // P2
27295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data[xx++] = aid.size();  // Lc
27395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
27495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
27595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
27695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
27795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
27895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (status != ESESTATUS_SUCCESS) {
27995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /* Transceive failed */
28095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    sestatus = SecureElementStatus::IOERROR;
28195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else {
28295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
28395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
28495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*Return response on success, empty vector on failure*/
28595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*Status is success*/
28695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if ((sw1 == 0x90) && (sw2 == 0x00)) {
28795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      /*Copy the response including status word*/
28895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      result.resize(rspApdu.len);
28995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      memcpy(&result[0], rspApdu.p_data, rspApdu.len);
29095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      /*Set basic channel reference if it is not set */
29195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      if (!mOpenedChannels[0]) {
29295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna        mOpenedChannels[0] = true;
29395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna        mOpenedchannelCount++;
29495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      }
29595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::SUCCESS;
29695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
29795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*AID provided doesn't match any applet on the secure element*/
29895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    else if (sw1 == 0x6A && sw2 == 0x82) {
29995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
30095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
30195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*Operation provided by the P2 parameter is not permitted by the applet.*/
30295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    else if (sw1 == 0x6A && sw2 == 0x86) {
30395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
30495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
30595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
30695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
30795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if ((sestatus != SecureElementStatus::SUCCESS) && mOpenedChannels[0]) {
30895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    SecureElementStatus closeChannelStatus =
30995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna        closeChannel(DEFAULT_BASIC_CHANNEL);
31095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (closeChannelStatus != SecureElementStatus::SUCCESS) {
31195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      ALOGE("%s: closeChannel Failed", __func__);
31295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
31395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
31495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  _hidl_cb(result, sestatus);
31595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_free(cmdApdu.p_data);
31695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_free(rspApdu.p_data);
31795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  return Void();
31895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
31995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
32095faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaReturn<::android::hardware::secure_element::V1_0::SecureElementStatus>
32195faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaSecureElement::closeChannel(uint8_t channelNumber) {
32295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  ESESTATUS status = ESESTATUS_FAILED;
32395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  SecureElementStatus sestatus = SecureElementStatus::FAILED;
32495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
32595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_data cmdApdu;
32695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_data rspApdu;
32795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
32895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if ((channelNumber < DEFAULT_BASIC_CHANNEL) ||
32995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      (channelNumber >= MAX_LOGICAL_CHANNELS) ||
33095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      (mOpenedChannels[channelNumber] == false)) {
33195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    ALOGE("%s: invalid channel!!!", __func__);
33295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    sestatus = SecureElementStatus::FAILED;
33395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
33495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
33595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
33695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t));
33795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (cmdApdu.p_data != NULL) {
33895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      uint8_t xx = 0;
33995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
34095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      cmdApdu.p_data[xx++] = channelNumber;
34195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      cmdApdu.p_data[xx++] = 0x70;           // INS
34295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      cmdApdu.p_data[xx++] = 0x80;           // P1
34395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      cmdApdu.p_data[xx++] = channelNumber;  // P2
34495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      cmdApdu.p_data[xx++] = 0x00;           // Lc
34595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      cmdApdu.len = xx;
34695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
34795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
34895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
34995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (status != ESESTATUS_SUCCESS) {
35095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::FAILED;
35195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
35295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna               (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
35395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::SUCCESS;
35495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    } else {
35595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::FAILED;
35695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
35795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    phNxpEse_free(cmdApdu.p_data);
35895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    phNxpEse_free(rspApdu.p_data);
35995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
36095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
36195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if ((channelNumber == DEFAULT_BASIC_CHANNEL) ||
36295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      (sestatus == SecureElementStatus::SUCCESS)) {
36395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    mOpenedChannels[channelNumber] = false;
36495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    mOpenedchannelCount--;
36595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    /*If there are no channels remaining close secureElement*/
36695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (mOpenedchannelCount == 0) {
36795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = seHalDeInit();
36895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    } else {
36995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::SUCCESS;
37095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
37195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
37295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  return sestatus;
37395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
37495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
37595faecf9216aeb01b97ca5416ef9cc085303015fLove Khannavoid SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
37695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  ALOGE("%s: SecureElement serviceDied!!!", __func__);
37795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  SecureElementStatus sestatus = seHalDeInit();
37895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (sestatus != SecureElementStatus::SUCCESS) {
37995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    ALOGE("%s: seHalDeInit Faliled!!!", __func__);
38095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
38195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (mCallbackV1_0 != nullptr) {
38295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    mCallbackV1_0->unlinkToDeath(this);
38395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
38495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
38595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
3869406bd700454e148fd93a0b34364c9652c619fd6Jizhou Liaobool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
3879406bd700454e148fd93a0b34364c9652c619fd6Jizhou Liao
38895faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaESESTATUS SecureElement::seHalInit() {
38995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  ESESTATUS status = ESESTATUS_SUCCESS;
39095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  phNxpEse_initParams initParams;
39195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
39295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  initParams.initMode = ESE_MODE_NORMAL;
39395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
39495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  status = phNxpEse_open(initParams);
39595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (status != ESESTATUS_SUCCESS) {
39695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    ALOGE("%s: SecureElement open failed!!!", __func__);
39795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else {
39895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    status = phNxpEse_init(initParams);
39995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (status != ESESTATUS_SUCCESS) {
40095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      ALOGE("%s: SecureElement init failed!!!", __func__);
40195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
40295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
40395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  return status;
40495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
40595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
40695faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaReturn<::android::hardware::secure_element::V1_0::SecureElementStatus>
40795faecf9216aeb01b97ca5416ef9cc085303015fLove KhannaSecureElement::seHalDeInit() {
40895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  ESESTATUS status = ESESTATUS_SUCCESS;
40995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  SecureElementStatus sestatus = SecureElementStatus::FAILED;
41095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  status = phNxpEse_deInit();
41195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  if (status != ESESTATUS_SUCCESS) {
41295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    sestatus = SecureElementStatus::FAILED;
41395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  } else {
41495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    status = phNxpEse_close();
41595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    if (status != ESESTATUS_SUCCESS) {
41695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::FAILED;
41795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    } else {
41895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      sestatus = SecureElementStatus::SUCCESS;
41995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
42095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
42195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna        mOpenedChannels[xx] = false;
42295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      }
42395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna      mOpenedchannelCount = 0;
42495faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna    }
42595faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  }
42695faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna  return sestatus;
42795faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}
42895faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna
42995faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}  // namespace implementation
43095faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}  // namespace V1_0
43195faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}  // namespace secure_element
43295faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}  // namespace hardware
43395faecf9216aeb01b97ca5416ef9cc085303015fLove Khanna}  // namespace android
434