Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/release-candidate' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
skotopes committed Sep 10, 2024
2 parents 8ea6a3d + 09cfb57 commit fe42406
Show file tree
Hide file tree
Showing 185 changed files with 2,391 additions and 858 deletions.
3 changes: 2 additions & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,15 @@ firmware_debug = distenv.PhonyTarget(
)
distenv.Depends(firmware_debug, firmware_flash)

distenv.PhonyTarget(
firmware_blackmagic = distenv.PhonyTarget(
"blackmagic",
"${GDBPYCOM}",
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
GDBREMOTE="${BLACKMAGIC_ADDR}",
FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"],
)
distenv.Depends(firmware_blackmagic, firmware_flash)

# Debug alien elf
debug_other_opts = [
Expand Down
7 changes: 3 additions & 4 deletions applications/debug/ccid_test/ccid_test_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ void ccid_test_app_free(CcidTestApp* app) {
furi_record_close(RECORD_GUI);
app->gui = NULL;

free(app->iso7816_handler);
iso7816_handler_free(app->iso7816_handler);

// Free rest
free(app);
Expand All @@ -121,8 +121,7 @@ int32_t ccid_test_app(void* p) {
furi_hal_usb_unlock();

furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true);
furi_hal_usb_ccid_set_callbacks(
(CcidCallbacks*)&app->iso7816_handler->ccid_callbacks, app->iso7816_handler);
iso7816_handler_set_usb_ccid_callbacks();
furi_hal_usb_ccid_insert_smartcard();

//handle button events
Expand All @@ -142,7 +141,7 @@ int32_t ccid_test_app(void* p) {
}

//tear down USB
furi_hal_usb_ccid_set_callbacks(NULL, NULL);
iso7816_handler_reset_usb_ccid_callbacks();
furi_hal_usb_set_config(usb_mode_prev, NULL);

//teardown view
Expand Down
46 changes: 37 additions & 9 deletions applications/debug/ccid_test/iso7816/iso7816_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@
#include <furi.h>
#include <furi_hal.h>

#include "iso7816_handler.h"

#include "iso7816_t0_apdu.h"
#include "iso7816_atr.h"
#include "iso7816_handler.h"
#include "iso7816_response.h"

static Iso7816Handler* iso7816_handler;
static CcidCallbacks* ccid_callbacks;
static uint8_t* command_apdu_buffer;
static uint8_t* response_apdu_buffer;

void iso7816_icc_power_on_callback(uint8_t* atr_data, uint32_t* atr_data_len, void* context) {
furi_check(context);

Expand Down Expand Up @@ -40,12 +46,11 @@ void iso7816_xfr_datablock_callback(

Iso7816Handler* handler = (Iso7816Handler*)context;

ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)&handler->response_apdu_buffer;

ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)&handler->command_apdu_buffer;
ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)response_apdu_buffer;
ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)command_apdu_buffer;

uint8_t result = iso7816_read_command_apdu(
command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len);
command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len, CCID_SHORT_APDU_SIZE);

if(result == ISO7816_READ_COMMAND_APDU_OK) {
handler->iso7816_process_command(command_apdu, response_apdu);
Expand All @@ -61,8 +66,31 @@ void iso7816_xfr_datablock_callback(
}

Iso7816Handler* iso7816_handler_alloc() {
Iso7816Handler* handler = malloc(sizeof(Iso7816Handler));
handler->ccid_callbacks.icc_power_on_callback = iso7816_icc_power_on_callback;
handler->ccid_callbacks.xfr_datablock_callback = iso7816_xfr_datablock_callback;
return handler;
iso7816_handler = malloc(sizeof(Iso7816Handler));

command_apdu_buffer = malloc(sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE);
response_apdu_buffer = malloc(sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE);

ccid_callbacks = malloc(sizeof(CcidCallbacks));
ccid_callbacks->icc_power_on_callback = iso7816_icc_power_on_callback;
ccid_callbacks->xfr_datablock_callback = iso7816_xfr_datablock_callback;

return iso7816_handler;
}

void iso7816_handler_set_usb_ccid_callbacks() {
furi_hal_usb_ccid_set_callbacks(ccid_callbacks, iso7816_handler);
}

void iso7816_handler_reset_usb_ccid_callbacks() {
furi_hal_usb_ccid_set_callbacks(NULL, NULL);
}

void iso7816_handler_free(Iso7816Handler* handler) {
free(ccid_callbacks);

free(command_apdu_buffer);
free(response_apdu_buffer);

free(handler);
}
8 changes: 4 additions & 4 deletions applications/debug/ccid_test/iso7816/iso7816_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
#include "iso7816_t0_apdu.h"

typedef struct {
CcidCallbacks ccid_callbacks;
void (*iso7816_answer_to_reset)(Iso7816Atr* atr);
void (*iso7816_process_command)(
const ISO7816_Command_APDU* command,
ISO7816_Response_APDU* response);

uint8_t command_apdu_buffer[sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE];
uint8_t response_apdu_buffer[sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE];
} Iso7816Handler;

Iso7816Handler* iso7816_handler_alloc();

void iso7816_handler_free(Iso7816Handler* handler);
void iso7816_handler_set_usb_ccid_callbacks();
void iso7816_handler_reset_usb_ccid_callbacks();
37 changes: 18 additions & 19 deletions applications/debug/ccid_test/iso7816/iso7816_t0_apdu.c
Original file line number Diff line number Diff line change
@@ -1,49 +1,48 @@
/* Implements rudimentary iso7816-3 support for APDU (T=0) */
#include <stdint.h>
#include <string.h>
#include <furi.h>
#include <furi_hal.h>
#include "iso7816_t0_apdu.h"

//reads dataBuffer with dataLen size, translate it into a ISO7816_Command_APDU type
//reads pc_to_reader_datablock_len with pc_to_reader_datablock_len size, translate it into a ISO7816_Command_APDU type
//extra data will be pointed to commandDataBuffer
uint8_t iso7816_read_command_apdu(
ISO7816_Command_APDU* command,
const uint8_t* dataBuffer,
uint32_t dataLen) {
command->CLA = dataBuffer[0];
command->INS = dataBuffer[1];
command->P1 = dataBuffer[2];
command->P2 = dataBuffer[3];
const uint8_t* pc_to_reader_datablock,
uint32_t pc_to_reader_datablock_len,
uint32_t max_apdu_size) {
command->CLA = pc_to_reader_datablock[0];
command->INS = pc_to_reader_datablock[1];
command->P1 = pc_to_reader_datablock[2];
command->P2 = pc_to_reader_datablock[3];

if(dataLen == 4) {
if(pc_to_reader_datablock_len == 4) {
command->Lc = 0;
command->Le = 0;
command->LePresent = false;

return ISO7816_READ_COMMAND_APDU_OK;
} else if(dataLen == 5) {
} else if(pc_to_reader_datablock_len == 5) {
//short le

command->Lc = 0;
command->Le = dataBuffer[4];
command->Le = pc_to_reader_datablock[4];
command->LePresent = true;

return ISO7816_READ_COMMAND_APDU_OK;
} else if(dataLen > 5 && dataBuffer[4] != 0x00) {
} else if(pc_to_reader_datablock_len > 5 && pc_to_reader_datablock[4] != 0x00) {
//short lc

command->Lc = dataBuffer[4];
if(command->Lc > 0 && command->Lc < CCID_SHORT_APDU_SIZE) { //-V560
memcpy(command->Data, &dataBuffer[5], command->Lc);
command->Lc = pc_to_reader_datablock[4];
if(command->Lc > 0 && command->Lc < max_apdu_size) { //-V560
memcpy(command->Data, &pc_to_reader_datablock[5], command->Lc);

//does it have a short le too?
if(dataLen == (uint32_t)(command->Lc + 5)) {
if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 5)) {
command->Le = 0;
command->LePresent = false;
return ISO7816_READ_COMMAND_APDU_OK;
} else if(dataLen == (uint32_t)(command->Lc + 6)) {
command->Le = dataBuffer[dataLen - 1];
} else if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 6)) {
command->Le = pc_to_reader_datablock[pc_to_reader_datablock_len - 1];
command->LePresent = true;

return ISO7816_READ_COMMAND_APDU_OK;
Expand Down
3 changes: 2 additions & 1 deletion applications/debug/ccid_test/iso7816/iso7816_t0_apdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ typedef struct {
uint8_t iso7816_read_command_apdu(
ISO7816_Command_APDU* command,
const uint8_t* pc_to_reader_datablock,
uint32_t pc_to_reader_datablock_len);
uint32_t pc_to_reader_datablock_len,
uint32_t max_apdu_size);
void iso7816_write_response_apdu(
const ISO7816_Response_APDU* response,
uint8_t* reader_to_pc_datablock,
Expand Down
59 changes: 55 additions & 4 deletions applications/debug/expansion_test/expansion_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@
* 13 -> 16 (USART TX to LPUART RX)
* 14 -> 15 (USART RX to LPUART TX)
*
* Optional: Connect an LED with an appropriate series resistor
* between pins 1 and 8. It will always be on if the device is
* connected to USB power, so unplug it before running the app.
*
* What this application does:
*
* - Enables module support and emulates the module on a single device
* (hence the above connection),
* - Connects to the expansion module service, sets baud rate,
* - Enables OTG (5V) on GPIO via plain expansion protocol,
* - Waits 5 cycles of idle loop (1 second),
* - Starts the RPC session,
* - Disables OTG (5V) on GPIO via RPC messages,
* - Waits 5 cycles of idle loop (1 second),
* - Creates a directory at `/ext/ExpansionTest` and writes a file
* named `test.txt` under it,
* - Plays an audiovisual alert (sound and blinking display),
* - Waits 10 cycles of idle loop,
* - Enables OTG (5V) on GPIO via RPC messages,
* - Waits 5 cycles of idle loop (1 second),
* - Stops the RPC session,
* - Waits another 10 cycles of idle loop,
* - Disables OTG (5V) on GPIO via plain expansion protocol,
* - Exits (plays a sound if any of the above steps failed).
*/
#include <furi.h>
Expand Down Expand Up @@ -302,6 +311,22 @@ static bool expansion_test_app_handshake(ExpansionTestApp* instance) {
return success;
}

static bool expansion_test_app_enable_otg(ExpansionTestApp* instance, bool enable) {
bool success = false;

do {
const ExpansionFrameControlCommand command = enable ?
ExpansionFrameControlCommandEnableOtg :
ExpansionFrameControlCommandDisableOtg;
if(!expansion_test_app_send_control_request(instance, command)) break;
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
if(!expansion_test_app_is_success_response(&instance->frame)) break;
success = true;
} while(false);

return success;
}

static bool expansion_test_app_start_rpc(ExpansionTestApp* instance) {
bool success = false;

Expand Down Expand Up @@ -396,6 +421,27 @@ static bool expansion_test_app_rpc_alert(ExpansionTestApp* instance) {
return success;
}

static bool expansion_test_app_rpc_enable_otg(ExpansionTestApp* instance, bool enable) {
bool success = false;

instance->msg.command_id++;
instance->msg.command_status = PB_CommandStatus_OK;
instance->msg.which_content = PB_Main_gpio_set_otg_mode_tag;
instance->msg.content.gpio_set_otg_mode.mode = enable ? PB_Gpio_GpioOtgMode_ON :
PB_Gpio_GpioOtgMode_OFF;
instance->msg.has_next = false;

do {
if(!expansion_test_app_send_rpc_request(instance, &instance->msg)) break;
if(!expansion_test_app_receive_rpc_request(instance, &instance->msg)) break;
if(instance->msg.which_content != PB_Main_empty_tag) break;
if(instance->msg.command_status != PB_CommandStatus_OK) break;
success = true;
} while(false);

return success;
}

static bool expansion_test_app_idle(ExpansionTestApp* instance, uint32_t num_cycles) {
uint32_t num_cycles_done;
for(num_cycles_done = 0; num_cycles_done < num_cycles; ++num_cycles_done) {
Expand Down Expand Up @@ -434,13 +480,18 @@ int32_t expansion_test_app(void* p) {
if(!expansion_test_app_send_presence(instance)) break;
if(!expansion_test_app_wait_ready(instance)) break;
if(!expansion_test_app_handshake(instance)) break;
if(!expansion_test_app_enable_otg(instance, true)) break;
if(!expansion_test_app_idle(instance, 5)) break;
if(!expansion_test_app_start_rpc(instance)) break;
if(!expansion_test_app_rpc_enable_otg(instance, false)) break;
if(!expansion_test_app_idle(instance, 5)) break;
if(!expansion_test_app_rpc_mkdir(instance)) break;
if(!expansion_test_app_rpc_write(instance)) break;
if(!expansion_test_app_rpc_alert(instance)) break;
if(!expansion_test_app_idle(instance, 10)) break;
if(!expansion_test_app_rpc_enable_otg(instance, true)) break;
if(!expansion_test_app_idle(instance, 5)) break;
if(!expansion_test_app_stop_rpc(instance)) break;
if(!expansion_test_app_idle(instance, 10)) break;
if(!expansion_test_app_enable_otg(instance, false)) break;
success = true;
} while(false);

Expand Down
2 changes: 1 addition & 1 deletion applications/debug/rpc_debug_app/rpc_debug_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static void rpc_debug_app_tick_event_callback(void* context) {
static void
rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) {
if(data == NULL || data_size == 0) {
strncpy(buf, "<Data empty>", buf_size);
strlcpy(buf, "<Data empty>", buf_size);
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "../rpc_debug_app.h"

#include <lib/toolbox/strint.h>

static bool rpc_debug_app_scene_input_error_code_validator_callback(
const char* text,
FuriString* error,
Expand All @@ -24,7 +26,7 @@ static void rpc_debug_app_scene_input_error_code_result_callback(void* context)

void rpc_debug_app_scene_input_error_code_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "666", TEXT_STORE_SIZE);
strlcpy(app->text_store, "666", TEXT_STORE_SIZE);
text_input_set_header_text(app->text_input, "Enter error code");
text_input_set_validator(
app->text_input, rpc_debug_app_scene_input_error_code_validator_callback, NULL);
Expand All @@ -44,9 +46,8 @@ bool rpc_debug_app_scene_input_error_code_on_event(void* context, SceneManagerEv

if(event.type == SceneManagerEventTypeCustom) {
if(event.event == RpcDebugAppCustomEventInputErrorCode) {
char* end;
int error_code = strtol(app->text_store, &end, 10);
if(!*end) {
uint32_t error_code;
if(strint_to_uint32(app->text_store, NULL, &error_code, 10) == StrintParseNoError) {
rpc_system_app_set_error_code(app->rpc, error_code);
}
scene_manager_previous_scene(app->scene_manager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ static void rpc_debug_app_scene_input_error_text_result_callback(void* context)

void rpc_debug_app_scene_input_error_text_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
strlcpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
text_input_set_header_text(app->text_input, "Enter error text");
text_input_set_result_callback(
app->text_input,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);
strlcpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);

text_box_set_text(app->text_box, app->text_store);
text_box_set_font(app->text_box, TextBoxFontHex);
Expand Down
4 changes: 3 additions & 1 deletion applications/debug/uart_echo/uart_echo.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <gui/view_dispatcher.h>
#include <gui/modules/dialog_ex.h>

#include <lib/toolbox/strint.h>

#include <notification/notification.h>
#include <notification/notification_messages.h>

Expand Down Expand Up @@ -320,7 +322,7 @@ int32_t uart_echo_app(void* p) {
uint32_t baudrate = DEFAULT_BAUD_RATE;
if(p) {
const char* baudrate_str = p;
if(sscanf(baudrate_str, "%lu", &baudrate) != 1) {
if(strint_to_uint32(baudrate_str, NULL, &baudrate, 10) != StrintParseNoError) {
FURI_LOG_E(TAG, "Invalid baudrate: %s", baudrate_str);
baudrate = DEFAULT_BAUD_RATE;
}
Expand Down
Loading

0 comments on commit fe42406

Please sign in to comment.