lin
2025-08-14 dae8bad597b6607a449b32bf76c523423f7720ed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
 * 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;
}