Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
swap_error_code_helpers.h
Go to the documentation of this file.
1#pragma once
2#ifdef HAVE_SWAP
3
4#include "io.h"
5#include "buffer.h"
6
7// clang-format off
8/*
9--8<-- [start:intro]
10# Error responses for applications started by Exchange in SWAP context
11
12This specification applies to the error responses returned by the Coin applications when started by
13Exchange for the final payment transaction of a SWAP.
14
15Replying valuable data when a final payment transaction is refused eases a lot the analysis,
16especially if the issue happens in production context and / or is hard to reproduce.
17
18## RAPDU status word
19
20Each application must define a unique status word for every Exchange-related error.
21
22## RAPDU data
23
24The first 2 bytes of the RAPDU data represent the error code. Format is 16 bits integer in big endian.
25
26The upper byte is common between all applications. It must be one of the following value:
27
28| Name | Value | Description |
29| ----------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
30| ERROR_INTERNAL | 0x00 | Internal application error, forward to the Firmware team for analysis. |
31| ERROR_WRONG_AMOUNT | 0x01 | The amount does not match the one validated in Exchange. |
32| ERROR_WRONG_DESTINATION | 0x02 | The destination address does not match the one validated in Exchange. |
33| ERROR_WRONG_FEES | 0x03 | The fees are different from what was validated in Exchange. |
34| ERROR_WRONG_METHOD | 0x04 | The method used is invalid in Exchange context. |
35| ERROR_CROSSCHAIN_WRONG_MODE | 0x05 | The mode used for the cross-chain hash validation is not supported. |
36| ERROR_CROSSCHAIN_WRONG_METHOD | 0x06 | The method used is invalid in cross-chain Exchange context. |
37| ERROR_CROSSCHAIN_WRONG_HASH | 0x07 | The hash for the cross-chain transaction does not match the validated value. |
38| ERROR_GENERIC | 0xFF | A generic or unspecified error not covered by the specific error codes above.<br>Refer to the remaining bytes for further details on the error. |
39
40The lower byte can be set by the application to refine the error code returned.
41
42So the error code for `ERROR_WRONG_METHOD` would be `0x04XX` with `XX` being application specific
43(can be `00` if there is nothing to refine).
44
45The remaining bytes of the data are application-specific and can include, but are not limited to:
46
47- Debugging information (e.g., error logs or internal state).
48- Field values (e.g., expected vs actual amounts, destination, fees).
49- More specific error codes tailored to the application's context.
50
51The standard application library define several helper function to return error codes from the Coin
52application.
53--8<-- [end:intro]
54*/
55// clang-format on
56
57typedef enum swap_error_common_code_e {
58 SWAP_EC_ERROR_INTERNAL = 0x00,
59 SWAP_EC_ERROR_WRONG_AMOUNT = 0x01,
60 SWAP_EC_ERROR_WRONG_DESTINATION = 0x02,
61 SWAP_EC_ERROR_WRONG_FEES = 0x03,
62 SWAP_EC_ERROR_WRONG_METHOD = 0x04,
63 SWAP_EC_ERROR_CROSSCHAIN_WRONG_MODE = 0x05,
64 SWAP_EC_ERROR_CROSSCHAIN_WRONG_METHOD = 0x06,
65 SWAP_EC_ERROR_CROSSCHAIN_WRONG_HASH = 0x07,
66 SWAP_EC_ERROR_GENERIC = 0xFF,
67} swap_error_common_code_t;
68
69// --8<-- [start:helpers]
77__attribute__((noreturn)) void send_swap_error_simple(uint16_t status_word,
78 uint8_t common_error_code,
79 uint8_t application_specific_error_code);
80
89__attribute__((noreturn)) void send_swap_error_with_buffer(uint16_t status_word,
90 uint8_t common_error_code,
91 uint8_t application_specific_error_code,
92 const buffer_t buffer_data);
93
103#define SWAP_ERROR_HELPER_MAX_BUFFER_COUNT 8
104__attribute__((noreturn)) void send_swap_error_with_buffers(uint16_t status_word,
105 uint8_t common_error_code,
106 uint8_t application_specific_error_code,
107 const buffer_t *buffer_data,
108 size_t count);
109
120// Immediately call snprintf here (no function wrapping it cleanly in a .c file).
121// This is because we don't have a vsnprintf implementation which would be needed if
122// we were to pass the va_args to an intermediate function.
123// See https://stackoverflow.com/a/150578
124#define send_swap_error_with_string( \
125 status_word, common_error_code, application_specific_error_code, format, ...) \
126 do { \
127 /* Up to a full data apdu minus the status word and the swap error code */ \
128 char format_buffer[sizeof(G_io_apdu_buffer) - sizeof(status_word) - 2] = {0}; \
129 /* snprintf always returns 0 on our platform, don't check the return value */ \
130 /* See https://github.com/LedgerHQ/ledger-secure-sdk/issues/236 */ \
131 snprintf(format_buffer, sizeof(format_buffer), format, ##__VA_ARGS__); \
132 PRINTF("send_swap_error_with_string %s\n", format_buffer); \
133 buffer_t string_buffer; \
134 string_buffer.ptr = (uint8_t *) &format_buffer; \
135 string_buffer.size = strnlen(format_buffer, sizeof(format_buffer)); \
136 string_buffer.offset = 0; \
137 send_swap_error_with_buffers( \
138 status_word, common_error_code, application_specific_error_code, &string_buffer, 1); \
139 } while (0)
140// --8<-- [end:helpers]
141
142#endif // HAVE_SWAP
__attribute__((section("._nbgl_fonts_"))) const
return the non-unicode font corresponding to the given font ID
Definition nbgl_fonts.c:67
unsigned short uint16_t
Definition usbd_conf.h:54
unsigned char uint8_t
Definition usbd_conf.h:53