Skip to content

Commit fe42406

Browse files
committed
Merge remote-tracking branch 'origin/release-candidate' into release
2 parents 8ea6a3d + 09cfb57 commit fe42406

File tree

185 files changed

+2391
-858
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

185 files changed

+2391
-858
lines changed

SConstruct

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,15 @@ firmware_debug = distenv.PhonyTarget(
234234
)
235235
distenv.Depends(firmware_debug, firmware_flash)
236236

237-
distenv.PhonyTarget(
237+
firmware_blackmagic = distenv.PhonyTarget(
238238
"blackmagic",
239239
"${GDBPYCOM}",
240240
source=firmware_env["FW_ELF"],
241241
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
242242
GDBREMOTE="${BLACKMAGIC_ADDR}",
243243
FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"],
244244
)
245+
distenv.Depends(firmware_blackmagic, firmware_flash)
245246

246247
# Debug alien elf
247248
debug_other_opts = [

applications/debug/ccid_test/ccid_test_app.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void ccid_test_app_free(CcidTestApp* app) {
105105
furi_record_close(RECORD_GUI);
106106
app->gui = NULL;
107107

108-
free(app->iso7816_handler);
108+
iso7816_handler_free(app->iso7816_handler);
109109

110110
// Free rest
111111
free(app);
@@ -121,8 +121,7 @@ int32_t ccid_test_app(void* p) {
121121
furi_hal_usb_unlock();
122122

123123
furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true);
124-
furi_hal_usb_ccid_set_callbacks(
125-
(CcidCallbacks*)&app->iso7816_handler->ccid_callbacks, app->iso7816_handler);
124+
iso7816_handler_set_usb_ccid_callbacks();
126125
furi_hal_usb_ccid_insert_smartcard();
127126

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

144143
//tear down USB
145-
furi_hal_usb_ccid_set_callbacks(NULL, NULL);
144+
iso7816_handler_reset_usb_ccid_callbacks();
146145
furi_hal_usb_set_config(usb_mode_prev, NULL);
147146

148147
//teardown view

applications/debug/ccid_test/iso7816/iso7816_handler.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@
66
#include <furi.h>
77
#include <furi_hal.h>
88

9+
#include "iso7816_handler.h"
10+
911
#include "iso7816_t0_apdu.h"
1012
#include "iso7816_atr.h"
11-
#include "iso7816_handler.h"
1213
#include "iso7816_response.h"
1314

15+
static Iso7816Handler* iso7816_handler;
16+
static CcidCallbacks* ccid_callbacks;
17+
static uint8_t* command_apdu_buffer;
18+
static uint8_t* response_apdu_buffer;
19+
1420
void iso7816_icc_power_on_callback(uint8_t* atr_data, uint32_t* atr_data_len, void* context) {
1521
furi_check(context);
1622

@@ -40,12 +46,11 @@ void iso7816_xfr_datablock_callback(
4046

4147
Iso7816Handler* handler = (Iso7816Handler*)context;
4248

43-
ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)&handler->response_apdu_buffer;
44-
45-
ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)&handler->command_apdu_buffer;
49+
ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)response_apdu_buffer;
50+
ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)command_apdu_buffer;
4651

4752
uint8_t result = iso7816_read_command_apdu(
48-
command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len);
53+
command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len, CCID_SHORT_APDU_SIZE);
4954

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

6368
Iso7816Handler* iso7816_handler_alloc() {
64-
Iso7816Handler* handler = malloc(sizeof(Iso7816Handler));
65-
handler->ccid_callbacks.icc_power_on_callback = iso7816_icc_power_on_callback;
66-
handler->ccid_callbacks.xfr_datablock_callback = iso7816_xfr_datablock_callback;
67-
return handler;
69+
iso7816_handler = malloc(sizeof(Iso7816Handler));
70+
71+
command_apdu_buffer = malloc(sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE);
72+
response_apdu_buffer = malloc(sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE);
73+
74+
ccid_callbacks = malloc(sizeof(CcidCallbacks));
75+
ccid_callbacks->icc_power_on_callback = iso7816_icc_power_on_callback;
76+
ccid_callbacks->xfr_datablock_callback = iso7816_xfr_datablock_callback;
77+
78+
return iso7816_handler;
79+
}
80+
81+
void iso7816_handler_set_usb_ccid_callbacks() {
82+
furi_hal_usb_ccid_set_callbacks(ccid_callbacks, iso7816_handler);
83+
}
84+
85+
void iso7816_handler_reset_usb_ccid_callbacks() {
86+
furi_hal_usb_ccid_set_callbacks(NULL, NULL);
87+
}
88+
89+
void iso7816_handler_free(Iso7816Handler* handler) {
90+
free(ccid_callbacks);
91+
92+
free(command_apdu_buffer);
93+
free(response_apdu_buffer);
94+
95+
free(handler);
6896
}

applications/debug/ccid_test/iso7816/iso7816_handler.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
#include "iso7816_t0_apdu.h"
66

77
typedef struct {
8-
CcidCallbacks ccid_callbacks;
98
void (*iso7816_answer_to_reset)(Iso7816Atr* atr);
109
void (*iso7816_process_command)(
1110
const ISO7816_Command_APDU* command,
1211
ISO7816_Response_APDU* response);
13-
14-
uint8_t command_apdu_buffer[sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE];
15-
uint8_t response_apdu_buffer[sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE];
1612
} Iso7816Handler;
1713

1814
Iso7816Handler* iso7816_handler_alloc();
15+
16+
void iso7816_handler_free(Iso7816Handler* handler);
17+
void iso7816_handler_set_usb_ccid_callbacks();
18+
void iso7816_handler_reset_usb_ccid_callbacks();

applications/debug/ccid_test/iso7816/iso7816_t0_apdu.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,48 @@
11
/* Implements rudimentary iso7816-3 support for APDU (T=0) */
22
#include <stdint.h>
33
#include <string.h>
4-
#include <furi.h>
5-
#include <furi_hal.h>
64
#include "iso7816_t0_apdu.h"
75

8-
//reads dataBuffer with dataLen size, translate it into a ISO7816_Command_APDU type
6+
//reads pc_to_reader_datablock_len with pc_to_reader_datablock_len size, translate it into a ISO7816_Command_APDU type
97
//extra data will be pointed to commandDataBuffer
108
uint8_t iso7816_read_command_apdu(
119
ISO7816_Command_APDU* command,
12-
const uint8_t* dataBuffer,
13-
uint32_t dataLen) {
14-
command->CLA = dataBuffer[0];
15-
command->INS = dataBuffer[1];
16-
command->P1 = dataBuffer[2];
17-
command->P2 = dataBuffer[3];
10+
const uint8_t* pc_to_reader_datablock,
11+
uint32_t pc_to_reader_datablock_len,
12+
uint32_t max_apdu_size) {
13+
command->CLA = pc_to_reader_datablock[0];
14+
command->INS = pc_to_reader_datablock[1];
15+
command->P1 = pc_to_reader_datablock[2];
16+
command->P2 = pc_to_reader_datablock[3];
1817

19-
if(dataLen == 4) {
18+
if(pc_to_reader_datablock_len == 4) {
2019
command->Lc = 0;
2120
command->Le = 0;
2221
command->LePresent = false;
2322

2423
return ISO7816_READ_COMMAND_APDU_OK;
25-
} else if(dataLen == 5) {
24+
} else if(pc_to_reader_datablock_len == 5) {
2625
//short le
2726

2827
command->Lc = 0;
29-
command->Le = dataBuffer[4];
28+
command->Le = pc_to_reader_datablock[4];
3029
command->LePresent = true;
3130

3231
return ISO7816_READ_COMMAND_APDU_OK;
33-
} else if(dataLen > 5 && dataBuffer[4] != 0x00) {
32+
} else if(pc_to_reader_datablock_len > 5 && pc_to_reader_datablock[4] != 0x00) {
3433
//short lc
3534

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

4039
//does it have a short le too?
41-
if(dataLen == (uint32_t)(command->Lc + 5)) {
40+
if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 5)) {
4241
command->Le = 0;
4342
command->LePresent = false;
4443
return ISO7816_READ_COMMAND_APDU_OK;
45-
} else if(dataLen == (uint32_t)(command->Lc + 6)) {
46-
command->Le = dataBuffer[dataLen - 1];
44+
} else if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 6)) {
45+
command->Le = pc_to_reader_datablock[pc_to_reader_datablock_len - 1];
4746
command->LePresent = true;
4847

4948
return ISO7816_READ_COMMAND_APDU_OK;

applications/debug/ccid_test/iso7816/iso7816_t0_apdu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ typedef struct {
3434
uint8_t iso7816_read_command_apdu(
3535
ISO7816_Command_APDU* command,
3636
const uint8_t* pc_to_reader_datablock,
37-
uint32_t pc_to_reader_datablock_len);
37+
uint32_t pc_to_reader_datablock_len,
38+
uint32_t max_apdu_size);
3839
void iso7816_write_response_apdu(
3940
const ISO7816_Response_APDU* response,
4041
uint8_t* reader_to_pc_datablock,

applications/debug/expansion_test/expansion_test.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,27 @@
66
* 13 -> 16 (USART TX to LPUART RX)
77
* 14 -> 15 (USART RX to LPUART TX)
88
*
9+
* Optional: Connect an LED with an appropriate series resistor
10+
* between pins 1 and 8. It will always be on if the device is
11+
* connected to USB power, so unplug it before running the app.
12+
*
913
* What this application does:
1014
*
1115
* - Enables module support and emulates the module on a single device
1216
* (hence the above connection),
1317
* - Connects to the expansion module service, sets baud rate,
18+
* - Enables OTG (5V) on GPIO via plain expansion protocol,
19+
* - Waits 5 cycles of idle loop (1 second),
1420
* - Starts the RPC session,
21+
* - Disables OTG (5V) on GPIO via RPC messages,
22+
* - Waits 5 cycles of idle loop (1 second),
1523
* - Creates a directory at `/ext/ExpansionTest` and writes a file
1624
* named `test.txt` under it,
1725
* - Plays an audiovisual alert (sound and blinking display),
18-
* - Waits 10 cycles of idle loop,
26+
* - Enables OTG (5V) on GPIO via RPC messages,
27+
* - Waits 5 cycles of idle loop (1 second),
1928
* - Stops the RPC session,
20-
* - Waits another 10 cycles of idle loop,
29+
* - Disables OTG (5V) on GPIO via plain expansion protocol,
2130
* - Exits (plays a sound if any of the above steps failed).
2231
*/
2332
#include <furi.h>
@@ -302,6 +311,22 @@ static bool expansion_test_app_handshake(ExpansionTestApp* instance) {
302311
return success;
303312
}
304313

314+
static bool expansion_test_app_enable_otg(ExpansionTestApp* instance, bool enable) {
315+
bool success = false;
316+
317+
do {
318+
const ExpansionFrameControlCommand command = enable ?
319+
ExpansionFrameControlCommandEnableOtg :
320+
ExpansionFrameControlCommandDisableOtg;
321+
if(!expansion_test_app_send_control_request(instance, command)) break;
322+
if(!expansion_test_app_receive_frame(instance, &instance->frame)) break;
323+
if(!expansion_test_app_is_success_response(&instance->frame)) break;
324+
success = true;
325+
} while(false);
326+
327+
return success;
328+
}
329+
305330
static bool expansion_test_app_start_rpc(ExpansionTestApp* instance) {
306331
bool success = false;
307332

@@ -396,6 +421,27 @@ static bool expansion_test_app_rpc_alert(ExpansionTestApp* instance) {
396421
return success;
397422
}
398423

424+
static bool expansion_test_app_rpc_enable_otg(ExpansionTestApp* instance, bool enable) {
425+
bool success = false;
426+
427+
instance->msg.command_id++;
428+
instance->msg.command_status = PB_CommandStatus_OK;
429+
instance->msg.which_content = PB_Main_gpio_set_otg_mode_tag;
430+
instance->msg.content.gpio_set_otg_mode.mode = enable ? PB_Gpio_GpioOtgMode_ON :
431+
PB_Gpio_GpioOtgMode_OFF;
432+
instance->msg.has_next = false;
433+
434+
do {
435+
if(!expansion_test_app_send_rpc_request(instance, &instance->msg)) break;
436+
if(!expansion_test_app_receive_rpc_request(instance, &instance->msg)) break;
437+
if(instance->msg.which_content != PB_Main_empty_tag) break;
438+
if(instance->msg.command_status != PB_CommandStatus_OK) break;
439+
success = true;
440+
} while(false);
441+
442+
return success;
443+
}
444+
399445
static bool expansion_test_app_idle(ExpansionTestApp* instance, uint32_t num_cycles) {
400446
uint32_t num_cycles_done;
401447
for(num_cycles_done = 0; num_cycles_done < num_cycles; ++num_cycles_done) {
@@ -434,13 +480,18 @@ int32_t expansion_test_app(void* p) {
434480
if(!expansion_test_app_send_presence(instance)) break;
435481
if(!expansion_test_app_wait_ready(instance)) break;
436482
if(!expansion_test_app_handshake(instance)) break;
483+
if(!expansion_test_app_enable_otg(instance, true)) break;
484+
if(!expansion_test_app_idle(instance, 5)) break;
437485
if(!expansion_test_app_start_rpc(instance)) break;
486+
if(!expansion_test_app_rpc_enable_otg(instance, false)) break;
487+
if(!expansion_test_app_idle(instance, 5)) break;
438488
if(!expansion_test_app_rpc_mkdir(instance)) break;
439489
if(!expansion_test_app_rpc_write(instance)) break;
440490
if(!expansion_test_app_rpc_alert(instance)) break;
441-
if(!expansion_test_app_idle(instance, 10)) break;
491+
if(!expansion_test_app_rpc_enable_otg(instance, true)) break;
492+
if(!expansion_test_app_idle(instance, 5)) break;
442493
if(!expansion_test_app_stop_rpc(instance)) break;
443-
if(!expansion_test_app_idle(instance, 10)) break;
494+
if(!expansion_test_app_enable_otg(instance, false)) break;
444495
success = true;
445496
} while(false);
446497

applications/debug/rpc_debug_app/rpc_debug_app.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ static void rpc_debug_app_tick_event_callback(void* context) {
2424
static void
2525
rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) {
2626
if(data == NULL || data_size == 0) {
27-
strncpy(buf, "<Data empty>", buf_size);
27+
strlcpy(buf, "<Data empty>", buf_size);
2828
return;
2929
}
3030

applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "../rpc_debug_app.h"
22

3+
#include <lib/toolbox/strint.h>
4+
35
static bool rpc_debug_app_scene_input_error_code_validator_callback(
46
const char* text,
57
FuriString* error,
@@ -24,7 +26,7 @@ static void rpc_debug_app_scene_input_error_code_result_callback(void* context)
2426

2527
void rpc_debug_app_scene_input_error_code_on_enter(void* context) {
2628
RpcDebugApp* app = context;
27-
strncpy(app->text_store, "666", TEXT_STORE_SIZE);
29+
strlcpy(app->text_store, "666", TEXT_STORE_SIZE);
2830
text_input_set_header_text(app->text_input, "Enter error code");
2931
text_input_set_validator(
3032
app->text_input, rpc_debug_app_scene_input_error_code_validator_callback, NULL);
@@ -44,9 +46,8 @@ bool rpc_debug_app_scene_input_error_code_on_event(void* context, SceneManagerEv
4446

4547
if(event.type == SceneManagerEventTypeCustom) {
4648
if(event.event == RpcDebugAppCustomEventInputErrorCode) {
47-
char* end;
48-
int error_code = strtol(app->text_store, &end, 10);
49-
if(!*end) {
49+
uint32_t error_code;
50+
if(strint_to_uint32(app->text_store, NULL, &error_code, 10) == StrintParseNoError) {
5051
rpc_system_app_set_error_code(app->rpc, error_code);
5152
}
5253
scene_manager_previous_scene(app->scene_manager);

applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ static void rpc_debug_app_scene_input_error_text_result_callback(void* context)
77

88
void rpc_debug_app_scene_input_error_text_on_enter(void* context) {
99
RpcDebugApp* app = context;
10-
strncpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
10+
strlcpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
1111
text_input_set_header_text(app->text_input, "Enter error text");
1212
text_input_set_result_callback(
1313
app->text_input,

0 commit comments

Comments
 (0)