/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include ESE_INCLUDE_HW(ESE_HW_NXP_PN80T_NQ_NCI); #include "AlaLib.h" #include "IChannel.h" static struct EseInterface static_ese; static INT16 static_ese_open() { ese_init((&static_ese), ESE_HW_NXP_PN80T_NQ_NCI); auto res = ese_open(&static_ese, nullptr); if (res != 0) { LOG(ERROR) << "ese_open result: " << (int) res; return EE_ERROR_OPEN_FAIL; } LOG(DEBUG) << "ese_open success"; return 1; // arbitrary fake channel } static bool static_ese_close(INT16 /* handle */) { LOG(DEBUG) << "ese_close"; ese_close(&static_ese); return true; } static void log_hexdump(const std::string& prefix, UINT8 *buf, size_t len) { for (size_t i = 0; i < len; i += 16) { std::ostringstream o; for (size_t j = i; j < i + 16 && j < len; j++) { o << std::hex << std::setw(2) << std::setfill('0') << (int)buf[j] << " "; } LOG(DEBUG) << prefix << ": " << o.str(); } } static bool static_ese_transceive(UINT8* xmitBuffer, INT32 xmitBufferSize, UINT8* recvBuffer, INT32 recvBufferMaxSize, INT32& recvBufferActualSize, INT32 /* timeoutMillisec */) { log_hexdump("tx", xmitBuffer, xmitBufferSize); auto res = ese_transceive(&static_ese, xmitBuffer, xmitBufferSize, recvBuffer, recvBufferMaxSize); if (res < 0 || ese_error(&static_ese)) { LOG(ERROR) << "ese_transceive result: " << (int) res << " code " << ese_error_code(&static_ese) << " message: " << ese_error_message(&static_ese); recvBufferActualSize = 0; return false; } recvBufferActualSize = res; log_hexdump("rx", recvBuffer, res); return true; } static void static_ese_doeSE_Reset() { LOG(DEBUG) << "static_ese_doeSE_Reset (doing nothing)"; } IChannel_t static_ese_ichannel = { static_ese_open, static_ese_close, static_ese_transceive, static_ese_doeSE_Reset, nullptr }; static bool readFileToString(const std::string& filename, std::string* result) { if (!android::base::ReadFileToString(filename, result)) { PLOG(ERROR) << "Failed to read from " << filename; return false; } return true; } typedef struct ls_update_t { std::string shadata; std::string source; std::string dest; } ls_update_t; static bool send_ls_update(const ls_update_t &update) { UINT8 version_buf[4]; auto status = ALA_lsGetVersion(version_buf); if (status != STATUS_SUCCESS) { LOG(ERROR) << "ALA_lsGetVersion failed with status " << (int) status; return false; } log_hexdump("version", version_buf, sizeof(version_buf)); UINT8 respSW_buf[4]; status = ALA_Start( const_cast(update.source.c_str()), const_cast(update.dest.c_str()), const_cast(reinterpret_cast(update.shadata.data())), update.shadata.size(), respSW_buf); if (status != STATUS_SUCCESS) { LOG(ERROR) << "ALA_Start failed with status " << (int) status; return false; } log_hexdump("respSW", respSW_buf, sizeof(respSW_buf)); LOG(DEBUG) << "All interactions completed"; return true; } static bool parse_args(char* argv[], ls_update_t *update) { char **argp = argv + 1; if (*argp == nullptr) { LOG(ERROR) << "No shadata supplied"; return false; } if (!readFileToString(*argp, &update->shadata)) { return false; } argp++; if (*argp == nullptr) { LOG(ERROR) << "No source supplied"; return false; } update->source = *argp; argp++; if (*argp == nullptr) { LOG(ERROR) << "No dest supplied"; return false; } update->dest = *argp; argp++; if (*argp != nullptr) { LOG(ERROR) << "Extra arguments present"; return false; } return true; } static bool ls_update_cli(char* argv[]) { ls_update_t update; if (!parse_args(argv, &update)) { return false; } auto status = ALA_Init(&static_ese_ichannel); if (status != STATUS_SUCCESS) { LOG(ERROR) << "ALA_Init failed with status " << (int) status; return false; } auto success = send_ls_update(update); if (ALA_DeInit()) { LOG(INFO) << "ALA_DeInit succeeded"; } else { LOG(ERROR) << "ALA_DeInit failed"; return false; } return success; } int main(int /* argc */, char* argv[]) { setenv("ANDROID_LOG_TAGS", "*:v", 1); // TODO: remove this line. android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM)); LOG(DEBUG) << "Start of ESE provisioning"; return ls_update_cli(argv) ? 0 : -1; }