@trezor/transport
Version:
Low level library facilitating protocol buffers based communication with Trezor devices
98 lines (97 loc) • 3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.sendThpMessage = void 0;
const protocol_1 = require("@trezor/protocol");
const utils_1 = require("@trezor/utils");
const readWithExpectedHeaders_1 = require("../utils/readWithExpectedHeaders");
const result_1 = require("../utils/result");
const send_1 = require("../utils/send");
const ATTEMPTS_LIMIT = 10;
const THP_ACK_DEADLINE = 30_000;
const sendThpMessage = async ({
thpState,
skipAck,
chunks,
apiWrite,
apiRead,
signal,
graceful,
logger
}) => {
if (!thpState) {
return (0, result_1.error)({
error: 'ThpStateMissing'
});
}
const expectedResponses = protocol_1.thp.getExpectedResponses(chunks[0]);
const isAckExpected = protocol_1.thp.isAckExpected(chunks[0]);
if (skipAck || !isAckExpected || expectedResponses.length === 0) {
const sendResult = await (0, send_1.sendChunks)(chunks, apiWrite);
if (!sendResult.success) {
return sendResult;
}
thpState.setExpectedResponses(expectedResponses);
return sendResult;
}
thpState.setExpectedResponses([0x20]);
let attempt = 0;
const apiReadWithExpectedHeaders = (0, readWithExpectedHeaders_1.readWithExpectedHeaders)(apiRead, {
signal,
graceful,
logger
});
try {
const result = await (0, utils_1.scheduleAction)(async attemptSignal => {
logger?.debug(`sendThpMessage attempt ${attempt} start`);
const sendResult = await (0, send_1.sendChunks)(chunks, apiWrite);
logger?.debug(`sendThpMessage success: ${sendResult.success}`);
if (!sendResult.success) {
return sendResult;
}
logger?.debug(`sendThpMessage read ThpAck`);
return (0, utils_1.scheduleAction)(signal => apiReadWithExpectedHeaders(thpState, signal), {
signal: attemptSignal,
graceful,
deadline: Date.now() + THP_ACK_DEADLINE
});
}, {
signal,
attempts: ATTEMPTS_LIMIT,
attemptFailureHandler: error => {
if (error.message !== 'Aborted by deadline') {
logger?.error(`sendThpMessage error ${error.message}`);
return error;
}
attempt++;
logger?.debug(`sendThpMessage retransmission ${attempt} start`);
}
});
if (!result.success) {
return result;
}
const decodedResult = protocol_1.thp.decodeSendAck(protocol_1.v2.decode(result.payload));
if (decodedResult?.type === 'ThpError') {
const {
code,
message
} = decodedResult.message;
return (0, result_1.error)({
error: code,
message
});
}
logger?.debug('sendThpMessage done');
thpState.setExpectedResponses(expectedResponses);
return (0, result_1.success)(undefined);
} catch (err) {
logger?.error(`sendThpMessage error ${err.message}`);
return (0, result_1.error)({
error: err.code,
message: err.message
});
}
};
exports.sendThpMessage = sendThpMessage;
//# sourceMappingURL=send.js.map