@trezor/transport
Version:
Low level library facilitating protocol buffers based communication with Trezor devices
71 lines • 3.15 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 = 3000;
const sendThpMessage = async ({ thpState, skipAck, chunks, apiWrite, apiRead, signal, 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 });
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)(() => apiReadWithExpectedHeaders(protocol_1.thp.getExpectedHeaders(thpState)), {
signal: attemptSignal,
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