diff --git a/ethereum-plugin-sdk b/ethereum-plugin-sdk index b9777e7..1fe4085 160000 --- a/ethereum-plugin-sdk +++ b/ethereum-plugin-sdk @@ -1 +1 @@ -Subproject commit b9777e7a81a9c33b3f8997ffa23396fa2b3f861d +Subproject commit 1fe4085d04a88f4238103a4ed3db1484fdb69c63 diff --git a/src/handle_finalize.c b/src/handle_finalize.c index b12f3af..48fa0c1 100644 --- a/src/handle_finalize.c +++ b/src/handle_finalize.c @@ -20,8 +20,7 @@ void handle_receive_address_lookup(ethPluginFinalize_t *msg, context_t *context) } } -void handle_finalize(void *parameters) { - ethPluginFinalize_t *msg = (ethPluginFinalize_t *) parameters; +void handle_finalize(ethPluginFinalize_t *msg) { context_t *context = (context_t *) msg->pluginContext; if (context->valid) { @@ -53,4 +52,4 @@ void handle_finalize(void *parameters) { PRINTF("Context not valid\n"); msg->result = ETH_PLUGIN_RESULT_FALLBACK; } -} \ No newline at end of file +} diff --git a/src/handle_init_contract.c b/src/handle_init_contract.c index a839b70..bf0cc6c 100644 --- a/src/handle_init_contract.c +++ b/src/handle_init_contract.c @@ -8,9 +8,7 @@ static void handle_amount_value(const ethPluginInitContract_t *msg, context_t *c } // Called once to init. -void handle_init_contract(void *parameters) { - ethPluginInitContract_t *msg = (ethPluginInitContract_t *) parameters; - +void handle_init_contract(ethPluginInitContract_t *msg) { if (msg->interfaceVersion != ETH_PLUGIN_INTERFACE_VERSION_LATEST) { msg->result = ETH_PLUGIN_RESULT_UNAVAILABLE; return; diff --git a/src/handle_provide_parameter.c b/src/handle_provide_parameter.c index 81b9bea..98eb23d 100644 --- a/src/handle_provide_parameter.c +++ b/src/handle_provide_parameter.c @@ -240,8 +240,7 @@ void handle_batch_call(ethPluginProvideParameter_t *msg, context_t *context) { } } -void handle_provide_parameter(void *parameters) { - ethPluginProvideParameter_t *msg = (ethPluginProvideParameter_t *) parameters; +void handle_provide_parameter(ethPluginProvideParameter_t *msg) { context_t *context = (context_t *) msg->pluginContext; msg->result = ETH_PLUGIN_RESULT_OK; diff --git a/src/handle_provide_token.c b/src/handle_provide_token.c index 4be6d4e..df55188 100644 --- a/src/handle_provide_token.c +++ b/src/handle_provide_token.c @@ -68,8 +68,7 @@ void handle_received_address(const ethPluginProvideInfo_t *msg, context_t *conte sizeof(context->contract_address_received)); } -void handle_provide_token(void *parameters) { - ethPluginProvideInfo_t *msg = (ethPluginProvideInfo_t *) parameters; +void handle_provide_token(ethPluginProvideInfo_t *msg) { context_t *context = (context_t *) msg->pluginContext; switch (context->selectorIndex) { diff --git a/src/handle_query_contract_id.c b/src/handle_query_contract_id.c index 3874a49..29910c2 100644 --- a/src/handle_query_contract_id.c +++ b/src/handle_query_contract_id.c @@ -12,8 +12,7 @@ void handle_init_cfa_screen(ethQueryContractID_t *msg, const context_t *context) } } -void handle_query_contract_id(void *parameters) { - ethQueryContractID_t *msg = (ethQueryContractID_t *) parameters; +void handle_query_contract_id(ethQueryContractID_t *msg) { const context_t *context = (context_t *) msg->pluginContext; strlcpy(msg->name, PLUGIN_NAME, msg->nameLength); @@ -36,4 +35,4 @@ void handle_query_contract_id(void *parameters) { return; } msg->result = ETH_PLUGIN_RESULT_OK; -} \ No newline at end of file +} diff --git a/src/handle_query_contract_ui.c b/src/handle_query_contract_ui.c index d103a96..f9a7a13 100644 --- a/src/handle_query_contract_ui.c +++ b/src/handle_query_contract_ui.c @@ -1,3 +1,4 @@ +#include #include "ricochet_plugin.h" #include @@ -39,18 +40,18 @@ static void decimalToAmount(unsigned long long value, context_t *context) { } while (value != 0); } -static void set_amount_ui(ethQueryContractUI_t *msg, const context_t *context) { +static bool set_amount_ui(ethQueryContractUI_t *msg, const context_t *context) { strlcpy(msg->title, "Send", msg->titleLength); - amountToString(context->amount, - sizeof(context->amount), - DEFAULT_DECIMAL, - context->ticker_sent, - msg->msg, - msg->msgLength); + return amountToString(context->amount, + sizeof(context->amount), + DEFAULT_DECIMAL, + context->ticker_sent, + msg->msg, + msg->msgLength); } -static int set_cfa_from_ui(ethQueryContractUI_t *msg, context_t *context) { +static bool set_cfa_from_ui(ethQueryContractUI_t *msg, context_t *context) { strlcpy(msg->title, "From", msg->titleLength); contract_address_ticker_t *currentTicker = NULL; @@ -70,29 +71,31 @@ static int set_cfa_from_ui(ethQueryContractUI_t *msg, context_t *context) { if (context->method_id != STOP_STREAM) { unsigned long long value; if (amountToDecimal(context, sizeof(context->amount), &value)) { - return -1; + return false; } // switch from token per sec to token per month for UX only. if (__builtin_umulll_overflow(value, 2592000, &value)) { - return -1; + return false; } decimalToAmount(value, context); - amountToString(context->amount, - sizeof(context->amount), - DEFAULT_DECIMAL, - context->ticker_sent, - msg->msg, - msg->msgLength); + if (!amountToString(context->amount, + sizeof(context->amount), + DEFAULT_DECIMAL, + context->ticker_sent, + msg->msg, + msg->msgLength)) { + return false; + } strlcat(msg->msg, " per month", msg->msgLength); } else { strlcpy(msg->msg, context->ticker_sent, msg->msgLength); } - return 0; + return true; } -static void set_cfa_to_ui(ethQueryContractUI_t *msg, context_t *context) { +static bool set_cfa_to_ui(ethQueryContractUI_t *msg, context_t *context) { strlcpy(msg->title, "To", msg->titleLength); contract_address_ticker_t *currentTicker = NULL; @@ -109,9 +112,10 @@ static void set_cfa_to_ui(ethQueryContractUI_t *msg, context_t *context) { } } strlcpy(msg->msg, context->ticker_received, msg->msgLength); + return true; } -static int set_batch_call_from_ui(ethQueryContractUI_t *msg, context_t *context) { +static bool set_batch_call_from_ui(ethQueryContractUI_t *msg, context_t *context) { strlcpy(msg->title, "From", msg->titleLength); contract_address_ticker_t *currentTicker = NULL; @@ -130,26 +134,28 @@ static int set_batch_call_from_ui(ethQueryContractUI_t *msg, context_t *context) unsigned long long value; if (amountToDecimal(context, sizeof(context->amount), &value)) { - return -1; + return false; } // switch from token per sec to token per month for UX only. if (__builtin_umulll_overflow(value, 2592000, &value)) { - return -1; + return false; } decimalToAmount(value, context); - amountToString(context->amount, - sizeof(context->amount), - DEFAULT_DECIMAL, - context->ticker_sent, - msg->msg, - msg->msgLength); + if (!amountToString(context->amount, + sizeof(context->amount), + DEFAULT_DECIMAL, + context->ticker_sent, + msg->msg, + msg->msgLength)) { + return false; + } strlcat(msg->msg, " per month", msg->msgLength); - return 0; + return true; } -static void set_batch_call_to_ui(ethQueryContractUI_t *msg, context_t *context) { +static bool set_batch_call_to_ui(ethQueryContractUI_t *msg, context_t *context) { strlcpy(msg->title, "To", msg->titleLength); contract_address_ticker_t *currentTicker = NULL; @@ -166,38 +172,39 @@ static void set_batch_call_to_ui(ethQueryContractUI_t *msg, context_t *context) } } strlcpy(msg->msg, context->ticker_received, msg->msgLength); + return true; } -static void set_upgrade_to_eth_send_ui(ethQueryContractUI_t *msg, const context_t *context) { +static bool set_upgrade_to_eth_send_ui(ethQueryContractUI_t *msg, const context_t *context) { strlcpy(msg->title, "Send", msg->titleLength); - amountToString(msg->pluginSharedRO->txContent->value.value, - msg->pluginSharedRO->txContent->value.length, - DEFAULT_DECIMAL, - context->ticker_sent, - msg->msg, - msg->msgLength); + return amountToString(msg->pluginSharedRO->txContent->value.value, + msg->pluginSharedRO->txContent->value.length, + DEFAULT_DECIMAL, + context->ticker_sent, + msg->msg, + msg->msgLength); } -static void set_upgrade_to_eth_received_ui(ethQueryContractUI_t *msg, const context_t *context) { +static bool set_upgrade_to_eth_received_ui(ethQueryContractUI_t *msg, const context_t *context) { strlcpy(msg->title, "Receive", msg->titleLength); - amountToString(msg->pluginSharedRO->txContent->value.value, - msg->pluginSharedRO->txContent->value.length, - DEFAULT_DECIMAL, - context->ticker_received, - msg->msg, - msg->msgLength); + return amountToString(msg->pluginSharedRO->txContent->value.value, + msg->pluginSharedRO->txContent->value.length, + DEFAULT_DECIMAL, + context->ticker_received, + msg->msg, + msg->msgLength); } -static void set_receive_ui(ethQueryContractUI_t *msg, const context_t *context) { +static bool set_receive_ui(ethQueryContractUI_t *msg, const context_t *context) { strlcpy(msg->title, "Receive", msg->titleLength); - amountToString(context->amount, - sizeof(context->amount), - DEFAULT_DECIMAL, - context->ticker_received, - msg->msg, - msg->msgLength); + return amountToString(context->amount, + sizeof(context->amount), + DEFAULT_DECIMAL, + context->ticker_received, + msg->msg, + msg->msgLength); } // Helper function that returns the enum corresponding to the screen that should be displayed. @@ -214,13 +221,12 @@ static screens_t get_screen(const ethQueryContractUI_t *msg) { } } -void handle_query_contract_ui(void *parameters) { - ethQueryContractUI_t *msg = (ethQueryContractUI_t *) parameters; +void handle_query_contract_ui(ethQueryContractUI_t *msg) { context_t *context = (context_t *) msg->pluginContext; + bool ret = false; memset(msg->title, 0, msg->titleLength); memset(msg->msg, 0, msg->msgLength); - msg->result = ETH_PLUGIN_RESULT_OK; screens_t screen = get_screen(msg); @@ -230,57 +236,47 @@ void handle_query_contract_ui(void *parameters) { case UPGRADE: switch (screen) { case SEND_SCREEN: - set_amount_ui(msg, context); + ret = set_amount_ui(msg, context); break; case RECEIVE_SCREEN: - set_receive_ui(msg, context); + ret = set_receive_ui(msg, context); break; default: PRINTF("Received an invalid screenIndex\n"); - msg->result = ETH_PLUGIN_RESULT_ERROR; - return; } break; case CALL_AGREEMENT: switch (screen) { case SEND_SCREEN: - if (set_cfa_from_ui(msg, context)) { - msg->result = ETH_PLUGIN_RESULT_ERROR; - } + ret = set_cfa_from_ui(msg, context); break; case RECEIVE_SCREEN: - set_cfa_to_ui(msg, context); + ret = set_cfa_to_ui(msg, context); break; default: PRINTF("Received an invalid screenIndex\n"); - msg->result = ETH_PLUGIN_RESULT_ERROR; - return; } break; case UPGRADE_TO_ETH: switch (screen) { case SEND_SCREEN: - set_upgrade_to_eth_send_ui(msg, context); + ret = set_upgrade_to_eth_send_ui(msg, context); break; case RECEIVE_SCREEN: - set_upgrade_to_eth_received_ui(msg, context); + ret = set_upgrade_to_eth_received_ui(msg, context); break; default: PRINTF("Received an invalid screenIndex\n"); - msg->result = ETH_PLUGIN_RESULT_ERROR; - return; } break; case BATCH_CALL: switch (screen) { case SEND_SCREEN: - if (set_batch_call_from_ui(msg, context)) { - msg->result = ETH_PLUGIN_RESULT_ERROR; - } + ret = set_batch_call_from_ui(msg, context); break; case RECEIVE_SCREEN: - set_batch_call_to_ui(msg, context); + ret = set_batch_call_to_ui(msg, context); break; default: break; @@ -289,7 +285,6 @@ void handle_query_contract_ui(void *parameters) { default: PRINTF("Missing selectorIndex: %d\n", context->selectorIndex); - msg->result = ETH_PLUGIN_RESULT_ERROR; - return; } -} \ No newline at end of file + msg->result = ret ? ETH_PLUGIN_RESULT_OK : ETH_PLUGIN_RESULT_ERROR; +} diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 4f6afb2..0000000 --- a/src/main.c +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************* - * Ricochet Plugin Application - * (c) 2020 Ledger - * - * 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 -#include -#include - -#include "os.h" -#include "cx.h" -#include "glyphs.h" - -#include "ricochet_plugin.h" - -// Function to dispatch calls from the ethereum app. -void dispatch_plugin_calls(int message, void *parameters) { - switch (message) { - case ETH_PLUGIN_INIT_CONTRACT: - handle_init_contract(parameters); - break; - case ETH_PLUGIN_PROVIDE_PARAMETER: - handle_provide_parameter(parameters); - break; - case ETH_PLUGIN_PROVIDE_INFO: - handle_provide_token(parameters); - break; - case ETH_PLUGIN_FINALIZE: - handle_finalize(parameters); - break; - case ETH_PLUGIN_QUERY_CONTRACT_ID: - handle_query_contract_id(parameters); - break; - case ETH_PLUGIN_QUERY_CONTRACT_UI: - handle_query_contract_ui(parameters); - break; - default: - PRINTF("Unhandled message %d\n", message); - break; - } -} - -void handle_query_ui_exception(unsigned int *args) { - switch (args[0]) { - case ETH_PLUGIN_QUERY_CONTRACT_UI: - ((ethQueryContractUI_t *) args[1])->result = ETH_PLUGIN_RESULT_ERROR; - break; - default: - break; - } -} - -// Calls the ethereum app. -void call_app_ethereum() { - unsigned int libcall_params[5]; - - libcall_params[0] = (unsigned int) "Ethereum"; - libcall_params[1] = 0x100; - libcall_params[2] = RUN_APPLICATION; - libcall_params[3] = (unsigned int) NULL; -#ifdef HAVE_NBGL - caller_app_t capp; - const char name[] = APPNAME; - nbgl_icon_details_t icon_details; - uint8_t bitmap[sizeof(ICONBITMAP)]; - - memcpy(&icon_details, &ICONGLYPH, sizeof(ICONGLYPH)); - memcpy(&bitmap, &ICONBITMAP, sizeof(bitmap)); - icon_details.bitmap = (const uint8_t *) bitmap; - capp.name = name; - capp.icon = &icon_details; - libcall_params[4] = (unsigned int) &capp; -#else - libcall_params[4] = (unsigned int) NULL; -#endif - os_lib_call((unsigned int *) &libcall_params); -} - -// Weird low-level black magic. No need to edit this. -__attribute__((section(".boot"))) int main(int arg0) { - // Exit critical section - __asm volatile("cpsie i"); - - // Ensure exception will work as planned - os_boot(); - - // Try catch block. Please read the docs for more information on how to use those! - BEGIN_TRY { - TRY { - // Low-level black magic. - check_api_level(CX_COMPAT_APILEVEL); - - // Check if we are called from the dashboard. - if (!arg0) { - // Called from dashboard, launch Ethereum app - call_app_ethereum(); - return 0; - } else { - // Not called from dashboard: called from the ethereum app! - const unsigned int *args = (const unsigned int *) arg0; - - // If `ETH_PLUGIN_CHECK_PRESENCE` is set, this means the caller is just trying to - // know whether this app exists or not. We can skip `dispatch_plugin_calls`. - if (args[0] != ETH_PLUGIN_CHECK_PRESENCE) { - dispatch_plugin_calls(args[0], (void *) args[1]); - } - } - } - CATCH_OTHER(e) { - switch (e) { - // These exceptions are only generated on handle_query_contract_ui() - case 0x6502: - case EXCEPTION_OVERFLOW: - handle_query_ui_exception((unsigned int *) arg0); - break; - default: - break; - } - PRINTF("Exception 0x%x caught\n", e); - } - FINALLY { - // Call `os_lib_end`, go back to the ethereum app. - os_lib_end(); - } - } - END_TRY; - - // Will not get reached. - return 0; -} diff --git a/src/ricochet_plugin.h b/src/ricochet_plugin.h index 54d3d84..729d106 100644 --- a/src/ricochet_plugin.h +++ b/src/ricochet_plugin.h @@ -115,11 +115,4 @@ typedef struct context_t { // this check. _Static_assert(sizeof(context_t) <= 5 * 32, "Structure of parameters too big."); -void handle_init_contract(void *parameters); -void handle_provide_parameter(void *parameters); -void handle_query_contract_ui(void *parameters); -void handle_finalize(void *parameters); -void handle_provide_token(void *parameters); -void handle_query_contract_id(void *parameters); - -char compare_array(const uint8_t a[], const uint8_t b[], size_t size); \ No newline at end of file +char compare_array(const uint8_t a[], const uint8_t b[], size_t size);