184 lines
5.4 KiB
C++
184 lines
5.4 KiB
C++
/*
|
|
* 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 <cstdint>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
#include <android-base/file.h>
|
|
#include <android-base/logging.h>
|
|
|
|
#include <ese/ese.h>
|
|
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<char *>(update.source.c_str()),
|
|
const_cast<char *>(update.dest.c_str()),
|
|
const_cast<UINT8 *>(reinterpret_cast<const UINT8*>(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;
|
|
}
|