Merge remote-tracking branch 'OFW/dev' into dev [ci skip]
@@ -133,8 +133,8 @@ void handle_instruction_01(ISO7816_Response_APDU* responseAPDU) {
|
|||||||
void handle_instruction_02(
|
void handle_instruction_02(
|
||||||
uint8_t p1,
|
uint8_t p1,
|
||||||
uint8_t p2,
|
uint8_t p2,
|
||||||
uint8_t lc,
|
uint16_t lc,
|
||||||
uint8_t le,
|
uint16_t le,
|
||||||
ISO7816_Response_APDU* responseAPDU) {
|
ISO7816_Response_APDU* responseAPDU) {
|
||||||
if(p1 == 0 && p2 == 0 && lc == 0 && le >= 2) {
|
if(p1 == 0 && p2 == 0 && lc == 0 && le >= 2) {
|
||||||
responseAPDU->Data[0] = 0x62;
|
responseAPDU->Data[0] = 0x62;
|
||||||
@@ -153,7 +153,11 @@ void handle_instruction_02(
|
|||||||
//Instruction 3: sends a command with a body with two bytes, receives a response with no bytes
|
//Instruction 3: sends a command with a body with two bytes, receives a response with no bytes
|
||||||
//APDU example: 0x01:0x03:0x00:0x00:0x02:CA:FE
|
//APDU example: 0x01:0x03:0x00:0x00:0x02:CA:FE
|
||||||
//response SW1=0x90, SW2=0x00
|
//response SW1=0x90, SW2=0x00
|
||||||
void handle_instruction_03(uint8_t p1, uint8_t p2, uint8_t lc, ISO7816_Response_APDU* responseAPDU) {
|
void handle_instruction_03(
|
||||||
|
uint8_t p1,
|
||||||
|
uint8_t p2,
|
||||||
|
uint16_t lc,
|
||||||
|
ISO7816_Response_APDU* responseAPDU) {
|
||||||
if(p1 == 0 && p2 == 0 && lc == 2) {
|
if(p1 == 0 && p2 == 0 && lc == 2) {
|
||||||
responseAPDU->DataLen = 0;
|
responseAPDU->DataLen = 0;
|
||||||
iso7816_set_response(responseAPDU, ISO7816_RESPONSE_OK);
|
iso7816_set_response(responseAPDU, ISO7816_RESPONSE_OK);
|
||||||
@@ -170,8 +174,8 @@ void handle_instruction_03(uint8_t p1, uint8_t p2, uint8_t lc, ISO7816_Response_
|
|||||||
void handle_instruction_04(
|
void handle_instruction_04(
|
||||||
uint8_t p1,
|
uint8_t p1,
|
||||||
uint8_t p2,
|
uint8_t p2,
|
||||||
uint8_t lc,
|
uint16_t lc,
|
||||||
uint8_t le,
|
uint16_t le,
|
||||||
const uint8_t* commandApduDataBuffer,
|
const uint8_t* commandApduDataBuffer,
|
||||||
ISO7816_Response_APDU* responseAPDU) {
|
ISO7816_Response_APDU* responseAPDU) {
|
||||||
if(p1 == 0 && p2 == 0 && lc > 0 && le > 0 && le >= lc) {
|
if(p1 == 0 && p2 == 0 && lc > 0 && le > 0 && le >= lc) {
|
||||||
@@ -249,8 +253,10 @@ int32_t ccid_test_app(void* p) {
|
|||||||
|
|
||||||
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
|
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
|
||||||
furi_hal_usb_unlock();
|
furi_hal_usb_unlock();
|
||||||
furi_hal_ccid_set_callbacks((CcidCallbacks*)&ccid_cb, NULL);
|
|
||||||
furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true);
|
furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true);
|
||||||
|
furi_hal_usb_ccid_set_callbacks((CcidCallbacks*)&ccid_cb, NULL);
|
||||||
|
furi_hal_usb_ccid_insert_smartcard();
|
||||||
|
|
||||||
iso7816_set_callbacks((Iso7816Callbacks*)&iso87816_cb);
|
iso7816_set_callbacks((Iso7816Callbacks*)&iso87816_cb);
|
||||||
|
|
||||||
@@ -271,8 +277,8 @@ int32_t ccid_test_app(void* p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//tear down USB
|
//tear down USB
|
||||||
|
furi_hal_usb_ccid_set_callbacks(NULL, NULL);
|
||||||
furi_hal_usb_set_config(usb_mode_prev, NULL);
|
furi_hal_usb_set_config(usb_mode_prev, NULL);
|
||||||
furi_hal_ccid_set_callbacks(NULL, NULL);
|
|
||||||
|
|
||||||
iso7816_set_callbacks(NULL);
|
iso7816_set_callbacks(NULL);
|
||||||
|
|
||||||
|
|||||||
9
applications/debug/ccid_test/client/ccid_client.py
Normal file → Executable file
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
# pylint: disable=missing-module-docstring, too-many-arguments, consider-using-f-string, missing-function-docstring
|
# pylint: disable=missing-module-docstring, too-many-arguments, consider-using-f-string, missing-function-docstring
|
||||||
from smartcard.System import readers
|
from smartcard.System import readers
|
||||||
|
|
||||||
@@ -100,12 +101,14 @@ def main():
|
|||||||
small_apdu,
|
small_apdu,
|
||||||
)
|
)
|
||||||
|
|
||||||
max_apdu = list(range(0, 0x30))
|
upper_bound = 0xF0
|
||||||
|
max_apdu = list(range(0, upper_bound))
|
||||||
|
|
||||||
test_apdu(
|
test_apdu(
|
||||||
connection,
|
connection,
|
||||||
"INS 0x04: Lc=0x30, data=max_apdu, Le=0x30. Expect 0x30 bytes data in return",
|
"INS 0x04: Lc=0x%x, data=max_apdu, Le=0x%x. Expect 0x%x bytes data in return"
|
||||||
[0x01, 0x04, 0x00, 0x00, 0x30] + max_apdu + [0x30],
|
% (upper_bound, upper_bound, upper_bound),
|
||||||
|
[0x01, 0x04, 0x00, 0x00, upper_bound] + max_apdu + [upper_bound],
|
||||||
0x90,
|
0x90,
|
||||||
0x00,
|
0x00,
|
||||||
max_apdu,
|
max_apdu,
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 112 B |
BIN
applications/system/hid_app/assets/Alt_active_17x9.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 556 B After Width: | Height: | Size: 116 B |
BIN
applications/system/hid_app/assets/Cmd_active_17x9.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 552 B After Width: | Height: | Size: 116 B |
BIN
applications/system/hid_app/assets/Ctrl_active_17x9.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 116 B |
BIN
applications/system/hid_app/assets/Enter_11x7.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 117 B |
BIN
applications/system/hid_app/assets/Shift_active_7x9.png
Normal file
|
After Width: | Height: | Size: 113 B |
BIN
applications/system/hid_app/assets/Shift_inactive_7x9.png
Normal file
|
After Width: | Height: | Size: 116 B |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 549 B After Width: | Height: | Size: 110 B |
BIN
applications/system/hid_app/assets/Tab_19x12.png
Executable file
|
After Width: | Height: | Size: 984 B |
BIN
applications/system/hid_app/assets/apostrophe_button_9x11.png
Normal file
|
After Width: | Height: | Size: 94 B |
BIN
applications/system/hid_app/assets/backslash_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/backspace_19x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/backspace_hovered_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/backtick_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/brace_left_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/brace_right_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/equals_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/hash_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/percent_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/quote_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/slash_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/sq_bracket_left_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/sq_bracket_right_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/system/hid_app/assets/underscore_button_9x11.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
@@ -30,6 +30,7 @@ typedef struct {
|
|||||||
char key;
|
char key;
|
||||||
char shift_key;
|
char shift_key;
|
||||||
const Icon* icon;
|
const Icon* icon;
|
||||||
|
const Icon* icon_shift;
|
||||||
const Icon* icon_toggled;
|
const Icon* icon_toggled;
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
} HidKeyboardKey;
|
} HidKeyboardKey;
|
||||||
@@ -40,10 +41,10 @@ typedef struct {
|
|||||||
} HidKeyboardPoint;
|
} HidKeyboardPoint;
|
||||||
// 4 BY 12
|
// 4 BY 12
|
||||||
#define MARGIN_TOP 0
|
#define MARGIN_TOP 0
|
||||||
#define MARGIN_LEFT 4
|
#define MARGIN_LEFT 3
|
||||||
#define KEY_WIDTH 9
|
#define KEY_WIDTH 11
|
||||||
#define KEY_HEIGHT 12
|
#define KEY_HEIGHT 13
|
||||||
#define KEY_PADDING 1
|
#define KEY_PADDING -1
|
||||||
#define ROW_COUNT 7
|
#define ROW_COUNT 7
|
||||||
#define COLUMN_COUNT 12
|
#define COLUMN_COUNT 12
|
||||||
|
|
||||||
@@ -66,15 +67,23 @@ const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = {
|
|||||||
{
|
{
|
||||||
{.width = 1, .icon = NULL, .key = '1', .shift_key = '!', .value = HID_KEYBOARD_1},
|
{.width = 1, .icon = NULL, .key = '1', .shift_key = '!', .value = HID_KEYBOARD_1},
|
||||||
{.width = 1, .icon = NULL, .key = '2', .shift_key = '@', .value = HID_KEYBOARD_2},
|
{.width = 1, .icon = NULL, .key = '2', .shift_key = '@', .value = HID_KEYBOARD_2},
|
||||||
{.width = 1, .icon = NULL, .key = '3', .shift_key = '#', .value = HID_KEYBOARD_3},
|
{.width = 1,
|
||||||
|
.icon = NULL,
|
||||||
|
.icon_shift = &I_hash_button_9x11,
|
||||||
|
.key = '3',
|
||||||
|
.value = HID_KEYBOARD_3},
|
||||||
{.width = 1, .icon = NULL, .key = '4', .shift_key = '$', .value = HID_KEYBOARD_4},
|
{.width = 1, .icon = NULL, .key = '4', .shift_key = '$', .value = HID_KEYBOARD_4},
|
||||||
{.width = 1, .icon = NULL, .key = '5', .shift_key = '%', .value = HID_KEYBOARD_5},
|
{.width = 1,
|
||||||
|
.icon = NULL,
|
||||||
|
.icon_shift = &I_percent_button_9x11,
|
||||||
|
.key = '5',
|
||||||
|
.value = HID_KEYBOARD_5},
|
||||||
{.width = 1, .icon = NULL, .key = '6', .shift_key = '^', .value = HID_KEYBOARD_6},
|
{.width = 1, .icon = NULL, .key = '6', .shift_key = '^', .value = HID_KEYBOARD_6},
|
||||||
{.width = 1, .icon = NULL, .key = '7', .shift_key = '&', .value = HID_KEYBOARD_7},
|
{.width = 1, .icon = NULL, .key = '7', .shift_key = '&', .value = HID_KEYBOARD_7},
|
||||||
{.width = 1, .icon = NULL, .key = '8', .shift_key = '*', .value = HID_KEYBOARD_8},
|
{.width = 1, .icon = NULL, .key = '8', .shift_key = '*', .value = HID_KEYBOARD_8},
|
||||||
{.width = 1, .icon = NULL, .key = '9', .shift_key = '(', .value = HID_KEYBOARD_9},
|
{.width = 1, .icon = NULL, .key = '9', .shift_key = '(', .value = HID_KEYBOARD_9},
|
||||||
{.width = 1, .icon = NULL, .key = '0', .shift_key = ')', .value = HID_KEYBOARD_0},
|
{.width = 1, .icon = NULL, .key = '0', .shift_key = ')', .value = HID_KEYBOARD_0},
|
||||||
{.width = 2, .icon = &I_Backspace_9x7, .value = HID_KEYBOARD_DELETE},
|
{.width = 2, .icon = &I_backspace_19x11, .value = HID_KEYBOARD_DELETE},
|
||||||
{.width = 0, .value = HID_KEYBOARD_DELETE},
|
{.width = 0, .value = HID_KEYBOARD_DELETE},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -88,11 +97,13 @@ const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = {
|
|||||||
{.width = 1, .icon = NULL, .key = 'i', .shift_key = 'I', .value = HID_KEYBOARD_I},
|
{.width = 1, .icon = NULL, .key = 'i', .shift_key = 'I', .value = HID_KEYBOARD_I},
|
||||||
{.width = 1, .icon = NULL, .key = 'o', .shift_key = 'O', .value = HID_KEYBOARD_O},
|
{.width = 1, .icon = NULL, .key = 'o', .shift_key = 'O', .value = HID_KEYBOARD_O},
|
||||||
{.width = 1, .icon = NULL, .key = 'p', .shift_key = 'P', .value = HID_KEYBOARD_P},
|
{.width = 1, .icon = NULL, .key = 'p', .shift_key = 'P', .value = HID_KEYBOARD_P},
|
||||||
{.width = 1, .icon = NULL, .key = '[', .shift_key = '{', .value = HID_KEYBOARD_OPEN_BRACKET},
|
|
||||||
{.width = 1,
|
{.width = 1,
|
||||||
.icon = NULL,
|
.icon = &I_sq_bracket_left_button_9x11,
|
||||||
.key = ']',
|
.icon_shift = &I_brace_left_button_9x11,
|
||||||
.shift_key = '}',
|
.value = HID_KEYBOARD_OPEN_BRACKET},
|
||||||
|
{.width = 1,
|
||||||
|
.icon = &I_sq_bracket_right_button_9x11,
|
||||||
|
.icon_shift = &I_brace_right_button_9x11,
|
||||||
.value = HID_KEYBOARD_CLOSE_BRACKET},
|
.value = HID_KEYBOARD_CLOSE_BRACKET},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -117,16 +128,26 @@ const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = {
|
|||||||
{.width = 1, .icon = NULL, .key = 'b', .shift_key = 'B', .value = HID_KEYBOARD_B},
|
{.width = 1, .icon = NULL, .key = 'b', .shift_key = 'B', .value = HID_KEYBOARD_B},
|
||||||
{.width = 1, .icon = NULL, .key = 'n', .shift_key = 'N', .value = HID_KEYBOARD_N},
|
{.width = 1, .icon = NULL, .key = 'n', .shift_key = 'N', .value = HID_KEYBOARD_N},
|
||||||
{.width = 1, .icon = NULL, .key = 'm', .shift_key = 'M', .value = HID_KEYBOARD_M},
|
{.width = 1, .icon = NULL, .key = 'm', .shift_key = 'M', .value = HID_KEYBOARD_M},
|
||||||
{.width = 1, .icon = NULL, .key = '/', .shift_key = '?', .value = HID_KEYBOARD_SLASH},
|
{.width = 1, .icon = &I_slash_button_9x11, .shift_key = '?', .value = HID_KEYBOARD_SLASH},
|
||||||
{.width = 1, .icon = NULL, .key = '\\', .shift_key = '|', .value = HID_KEYBOARD_BACKSLASH},
|
{.width = 1,
|
||||||
{.width = 1, .icon = NULL, .key = '`', .shift_key = '~', .value = HID_KEYBOARD_GRAVE_ACCENT},
|
.icon = &I_backslash_button_9x11,
|
||||||
|
.shift_key = '|',
|
||||||
|
.value = HID_KEYBOARD_BACKSLASH},
|
||||||
|
{.width = 1,
|
||||||
|
.icon = &I_backtick_button_9x11,
|
||||||
|
.shift_key = '~',
|
||||||
|
.value = HID_KEYBOARD_GRAVE_ACCENT},
|
||||||
{.width = 1, .icon = &I_ButtonUp_7x4, .value = HID_KEYBOARD_UP_ARROW},
|
{.width = 1, .icon = &I_ButtonUp_7x4, .value = HID_KEYBOARD_UP_ARROW},
|
||||||
{.width = 1, .icon = NULL, .key = '-', .shift_key = '_', .value = HID_KEYBOARD_MINUS},
|
{.width = 1,
|
||||||
|
.icon = NULL,
|
||||||
|
.icon_shift = &I_underscore_button_9x11,
|
||||||
|
.key = '-',
|
||||||
|
.value = HID_KEYBOARD_MINUS},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{.width = 1,
|
{.width = 1,
|
||||||
.icon = &I_Pin_arrow_up_7x9,
|
.icon = &I_Shift_inactive_7x9,
|
||||||
.icon_toggled = &I_Shift_pressed_7x10,
|
.icon_toggled = &I_Shift_active_7x9,
|
||||||
.value = HID_KEYBOARD_L_SHIFT},
|
.value = HID_KEYBOARD_L_SHIFT},
|
||||||
{.width = 1, .icon = NULL, .key = ',', .shift_key = '<', .value = HID_KEYBOARD_COMMA},
|
{.width = 1, .icon = NULL, .key = ',', .shift_key = '<', .value = HID_KEYBOARD_COMMA},
|
||||||
{.width = 1, .icon = NULL, .key = '.', .shift_key = '>', .value = HID_KEYBOARD_DOT},
|
{.width = 1, .icon = NULL, .key = '.', .shift_key = '>', .value = HID_KEYBOARD_DOT},
|
||||||
@@ -134,8 +155,14 @@ const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = {
|
|||||||
{.width = 0, .value = HID_KEYBOARD_SPACEBAR},
|
{.width = 0, .value = HID_KEYBOARD_SPACEBAR},
|
||||||
{.width = 0, .value = HID_KEYBOARD_SPACEBAR},
|
{.width = 0, .value = HID_KEYBOARD_SPACEBAR},
|
||||||
{.width = 0, .value = HID_KEYBOARD_SPACEBAR},
|
{.width = 0, .value = HID_KEYBOARD_SPACEBAR},
|
||||||
{.width = 1, .icon = NULL, .key = '\'', .shift_key = '\"', .value = HID_KEYBOARD_APOSTROPHE},
|
{.width = 1,
|
||||||
{.width = 1, .icon = NULL, .key = '=', .shift_key = '+', .value = HID_KEYBOARD_EQUAL_SIGN},
|
.icon = &I_apostrophe_button_9x11,
|
||||||
|
.icon_shift = &I_quote_button_9x11,
|
||||||
|
.value = HID_KEYBOARD_APOSTROPHE},
|
||||||
|
{.width = 1,
|
||||||
|
.icon = &I_equals_button_9x11,
|
||||||
|
.shift_key = '+',
|
||||||
|
.value = HID_KEYBOARD_EQUAL_SIGN},
|
||||||
{.width = 1, .icon = &I_ButtonLeft_4x7, .value = HID_KEYBOARD_LEFT_ARROW},
|
{.width = 1, .icon = &I_ButtonLeft_4x7, .value = HID_KEYBOARD_LEFT_ARROW},
|
||||||
{.width = 1, .icon = &I_ButtonDown_7x4, .value = HID_KEYBOARD_DOWN_ARROW},
|
{.width = 1, .icon = &I_ButtonDown_7x4, .value = HID_KEYBOARD_DOWN_ARROW},
|
||||||
{.width = 1, .icon = &I_ButtonRight_4x7, .value = HID_KEYBOARD_RIGHT_ARROW},
|
{.width = 1, .icon = &I_ButtonRight_4x7, .value = HID_KEYBOARD_RIGHT_ARROW},
|
||||||
@@ -143,17 +170,17 @@ const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = {
|
|||||||
{
|
{
|
||||||
{.width = 2,
|
{.width = 2,
|
||||||
.icon = &I_Ctrl_17x10,
|
.icon = &I_Ctrl_17x10,
|
||||||
.icon_toggled = &I_Ctrl_pressed_17x10,
|
.icon_toggled = &I_Ctrl_active_17x9,
|
||||||
.value = HID_KEYBOARD_L_CTRL},
|
.value = HID_KEYBOARD_L_CTRL},
|
||||||
{.width = 0, .value = HID_KEYBOARD_L_CTRL},
|
{.width = 0, .value = HID_KEYBOARD_L_CTRL},
|
||||||
{.width = 2,
|
{.width = 2,
|
||||||
.icon = &I_Alt_17x10,
|
.icon = &I_Alt_17x10,
|
||||||
.icon_toggled = &I_Alt_pressed_17x10,
|
.icon_toggled = &I_Alt_active_17x9,
|
||||||
.value = HID_KEYBOARD_L_ALT},
|
.value = HID_KEYBOARD_L_ALT},
|
||||||
{.width = 0, .value = HID_KEYBOARD_L_ALT},
|
{.width = 0, .value = HID_KEYBOARD_L_ALT},
|
||||||
{.width = 2,
|
{.width = 2,
|
||||||
.icon = &I_Cmd_17x10,
|
.icon = &I_Cmd_17x10,
|
||||||
.icon_toggled = &I_Cmd_pressed_17x10,
|
.icon_toggled = &I_Cmd_active_17x9,
|
||||||
.value = HID_KEYBOARD_L_GUI},
|
.value = HID_KEYBOARD_L_GUI},
|
||||||
{.width = 0, .value = HID_KEYBOARD_L_GUI},
|
{.width = 0, .value = HID_KEYBOARD_L_GUI},
|
||||||
{.width = 2, .icon = &I_Tab_17x10, .value = HID_KEYBOARD_TAB},
|
{.width = 2, .icon = &I_Tab_17x10, .value = HID_KEYBOARD_TAB},
|
||||||
@@ -194,8 +221,47 @@ static void hid_keyboard_draw_key(
|
|||||||
keyWidth,
|
keyWidth,
|
||||||
KEY_HEIGHT);
|
KEY_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(model->shift && key.icon_shift != NULL) {
|
||||||
|
// Icon and shift
|
||||||
|
const Icon* key_icon = key.icon_shift;
|
||||||
|
|
||||||
|
if((model->ctrl && key.value == HID_KEYBOARD_L_CTRL) ||
|
||||||
|
(model->alt && key.value == HID_KEYBOARD_L_ALT) ||
|
||||||
|
(key.value == HID_KEYBOARD_L_SHIFT) ||
|
||||||
|
(model->gui && key.value == HID_KEYBOARD_L_GUI)) {
|
||||||
|
if(key.icon_toggled) {
|
||||||
|
key_icon = key.icon_toggled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Draw the icon centered on the button
|
||||||
|
canvas_draw_icon(
|
||||||
|
canvas,
|
||||||
|
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 - key_icon->width / 2,
|
||||||
|
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2 - key_icon->height / 2,
|
||||||
|
key_icon);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(model->shift && key.shift_key != 0) {
|
||||||
|
// Text and shift
|
||||||
|
char key_str[2] = {key.shift_key, '\0'};
|
||||||
|
|
||||||
|
canvas_draw_str_aligned(
|
||||||
|
canvas,
|
||||||
|
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 + 1,
|
||||||
|
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2 + 1,
|
||||||
|
AlignCenter,
|
||||||
|
AlignCenter,
|
||||||
|
key_str);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(key.icon != NULL) {
|
if(key.icon != NULL) {
|
||||||
|
// Icon with no shift
|
||||||
const Icon* key_icon = key.icon;
|
const Icon* key_icon = key.icon;
|
||||||
|
|
||||||
if((model->ctrl && key.value == HID_KEYBOARD_L_CTRL) ||
|
if((model->ctrl && key.value == HID_KEYBOARD_L_CTRL) ||
|
||||||
(model->alt && key.value == HID_KEYBOARD_L_ALT) ||
|
(model->alt && key.value == HID_KEYBOARD_L_ALT) ||
|
||||||
(model->shift && key.value == HID_KEYBOARD_L_SHIFT) ||
|
(model->shift && key.value == HID_KEYBOARD_L_SHIFT) ||
|
||||||
@@ -210,17 +276,29 @@ static void hid_keyboard_draw_key(
|
|||||||
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 - key_icon->width / 2,
|
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 - key_icon->width / 2,
|
||||||
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2 - key_icon->height / 2,
|
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2 - key_icon->height / 2,
|
||||||
key_icon);
|
key_icon);
|
||||||
} else {
|
|
||||||
char key_str[2] = "\0\0";
|
return;
|
||||||
// If shift is toggled use the shift key when available
|
}
|
||||||
key_str[0] = (model->shift && key.shift_key != 0) ? key.shift_key : key.key;
|
|
||||||
|
if(key.key != 0) {
|
||||||
|
// Text with no shift
|
||||||
|
char key_str[2] = {key.key, '\0'};
|
||||||
|
uint8_t key_offset = 0;
|
||||||
|
|
||||||
|
// Special case for numbers, draw them one pixel lower
|
||||||
|
if(key.value >= HID_KEYBOARD_1 && key.value <= HID_KEYBOARD_0) {
|
||||||
|
key_offset = 1;
|
||||||
|
}
|
||||||
|
|
||||||
canvas_draw_str_aligned(
|
canvas_draw_str_aligned(
|
||||||
canvas,
|
canvas,
|
||||||
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 + 1,
|
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 + 1,
|
||||||
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2,
|
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2 + key_offset,
|
||||||
AlignCenter,
|
AlignCenter,
|
||||||
AlignCenter,
|
AlignCenter,
|
||||||
key_str);
|
key_str);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,68.1,,
|
Version,+,69.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
@@ -1178,9 +1178,6 @@ Function,+,furi_hal_bus_enable,void,FuriHalBus
|
|||||||
Function,+,furi_hal_bus_init_early,void,
|
Function,+,furi_hal_bus_init_early,void,
|
||||||
Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus
|
Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus
|
||||||
Function,+,furi_hal_bus_reset,void,FuriHalBus
|
Function,+,furi_hal_bus_reset,void,FuriHalBus
|
||||||
Function,+,furi_hal_ccid_ccid_insert_smartcard,void,
|
|
||||||
Function,+,furi_hal_ccid_ccid_remove_smartcard,void,
|
|
||||||
Function,+,furi_hal_ccid_set_callbacks,void,"CcidCallbacks*, void*"
|
|
||||||
Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t
|
Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t
|
||||||
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t
|
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t
|
||||||
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
|
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
|
||||||
@@ -1454,6 +1451,9 @@ Function,-,furi_hal_spi_config_init_early,void,
|
|||||||
Function,-,furi_hal_spi_dma_init,void,
|
Function,-,furi_hal_spi_dma_init,void,
|
||||||
Function,+,furi_hal_spi_release,void,FuriHalSpiBusHandle*
|
Function,+,furi_hal_spi_release,void,FuriHalSpiBusHandle*
|
||||||
Function,+,furi_hal_switch,void,void*
|
Function,+,furi_hal_switch,void,void*
|
||||||
|
Function,+,furi_hal_usb_ccid_insert_smartcard,void,
|
||||||
|
Function,+,furi_hal_usb_ccid_remove_smartcard,void,
|
||||||
|
Function,+,furi_hal_usb_ccid_set_callbacks,void,"CcidCallbacks*, void*"
|
||||||
Function,+,furi_hal_usb_disable,void,
|
Function,+,furi_hal_usb_disable,void,
|
||||||
Function,+,furi_hal_usb_enable,void,
|
Function,+,furi_hal_usb_enable,void,
|
||||||
Function,+,furi_hal_usb_get_config,FuriHalUsbInterface*,
|
Function,+,furi_hal_usb_get_config,FuriHalUsbInterface*,
|
||||||
|
|||||||
|
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,68.1,,
|
Version,+,69.0,,
|
||||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||||
@@ -1317,9 +1317,6 @@ Function,+,furi_hal_bus_enable,void,FuriHalBus
|
|||||||
Function,+,furi_hal_bus_init_early,void,
|
Function,+,furi_hal_bus_init_early,void,
|
||||||
Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus
|
Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus
|
||||||
Function,+,furi_hal_bus_reset,void,FuriHalBus
|
Function,+,furi_hal_bus_reset,void,FuriHalBus
|
||||||
Function,+,furi_hal_ccid_ccid_insert_smartcard,void,
|
|
||||||
Function,+,furi_hal_ccid_ccid_remove_smartcard,void,
|
|
||||||
Function,+,furi_hal_ccid_set_callbacks,void,"CcidCallbacks*, void*"
|
|
||||||
Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t
|
Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t
|
||||||
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t
|
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t
|
||||||
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
|
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
|
||||||
@@ -1704,6 +1701,9 @@ Function,+,furi_hal_subghz_stop_async_tx,void,
|
|||||||
Function,+,furi_hal_subghz_tx,_Bool,
|
Function,+,furi_hal_subghz_tx,_Bool,
|
||||||
Function,+,furi_hal_subghz_write_packet,void,"const uint8_t*, uint8_t"
|
Function,+,furi_hal_subghz_write_packet,void,"const uint8_t*, uint8_t"
|
||||||
Function,+,furi_hal_switch,void,void*
|
Function,+,furi_hal_switch,void,void*
|
||||||
|
Function,+,furi_hal_usb_ccid_insert_smartcard,void,
|
||||||
|
Function,+,furi_hal_usb_ccid_remove_smartcard,void,
|
||||||
|
Function,+,furi_hal_usb_ccid_set_callbacks,void,"CcidCallbacks*, void*"
|
||||||
Function,+,furi_hal_usb_disable,void,
|
Function,+,furi_hal_usb_disable,void,
|
||||||
Function,+,furi_hal_usb_enable,void,
|
Function,+,furi_hal_usb_enable,void,
|
||||||
Function,+,furi_hal_usb_get_config,FuriHalUsbInterface*,
|
Function,+,furi_hal_usb_get_config,FuriHalUsbInterface*,
|
||||||
|
|||||||
|
@@ -4,28 +4,27 @@
|
|||||||
#include <furi_hal_usb_ccid.h>
|
#include <furi_hal_usb_ccid.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
#include "usb.h"
|
#include <usb_ccid.h>
|
||||||
#include "usb_ccid.h"
|
|
||||||
|
|
||||||
static const uint8_t USB_DEVICE_NO_CLASS = 0x0;
|
#define USB_DEVICE_NO_CLASS (0x0)
|
||||||
static const uint8_t USB_DEVICE_NO_SUBCLASS = 0x0;
|
#define USB_DEVICE_NO_SUBCLASS (0x0)
|
||||||
static const uint8_t USB_DEVICE_NO_PROTOCOL = 0x0;
|
#define USB_DEVICE_NO_PROTOCOL (0x0)
|
||||||
|
|
||||||
#define FIXED_CONTROL_ENDPOINT_SIZE 8
|
#define FIXED_CONTROL_ENDPOINT_SIZE (8)
|
||||||
#define IF_NUM_MAX 1
|
#define IF_NUM_MAX (1)
|
||||||
|
|
||||||
#define CCID_VID_DEFAULT 0x1234
|
#define CCID_VID_DEFAULT (0x1234)
|
||||||
#define CCID_PID_DEFAULT 0xABCD
|
#define CCID_PID_DEFAULT (0xABCD)
|
||||||
#define CCID_TOTAL_SLOTS 1
|
#define CCID_TOTAL_SLOTS (1)
|
||||||
#define CCID_SLOT_INDEX 0
|
#define CCID_SLOT_INDEX (0)
|
||||||
|
|
||||||
#define CCID_DATABLOCK_SIZE \
|
#define CCID_DATABLOCK_SIZE \
|
||||||
(4 + 1 + CCID_SHORT_APDU_SIZE + 1) //APDU Header + Lc + Short APDU size + Le
|
(4 + 1 + CCID_SHORT_APDU_SIZE + 1) //APDU Header + Lc + Short APDU size + Le
|
||||||
|
|
||||||
#define ENDPOINT_DIR_IN 0x80
|
#define ENDPOINT_DIR_IN (0x80)
|
||||||
#define ENDPOINT_DIR_OUT 0x00
|
#define ENDPOINT_DIR_OUT (0x00)
|
||||||
|
|
||||||
#define INTERFACE_ID_CCID 0
|
#define INTERFACE_ID_CCID (0)
|
||||||
|
|
||||||
#define CCID_IN_EPADDR (ENDPOINT_DIR_IN | 2)
|
#define CCID_IN_EPADDR (ENDPOINT_DIR_IN | 2)
|
||||||
|
|
||||||
@@ -65,6 +64,18 @@ enum CCID_Features_ExchangeLevel_t {
|
|||||||
CCID_Features_ExchangeLevel_ShortExtendedAPDU = 0x00040000
|
CCID_Features_ExchangeLevel_ShortExtendedAPDU = 0x00040000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WorkerEvtStop = (1 << 0),
|
||||||
|
WorkerEvtRequest = (1 << 1),
|
||||||
|
} WorkerEvtFlags;
|
||||||
|
|
||||||
|
typedef struct ccid_bulk_message_header {
|
||||||
|
uint8_t bMessageType;
|
||||||
|
uint32_t dwLength;
|
||||||
|
uint8_t bSlot;
|
||||||
|
uint8_t bSeq;
|
||||||
|
} FURI_PACKED ccid_bulk_message_header_t;
|
||||||
|
|
||||||
/* Device descriptor */
|
/* Device descriptor */
|
||||||
static struct usb_device_descriptor ccid_device_desc = {
|
static struct usb_device_descriptor ccid_device_desc = {
|
||||||
.bLength = sizeof(struct usb_device_descriptor),
|
.bLength = sizeof(struct usb_device_descriptor),
|
||||||
@@ -163,6 +174,7 @@ static void ccid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
|
|||||||
static void ccid_deinit(usbd_device* dev);
|
static void ccid_deinit(usbd_device* dev);
|
||||||
static void ccid_on_wakeup(usbd_device* dev);
|
static void ccid_on_wakeup(usbd_device* dev);
|
||||||
static void ccid_on_suspend(usbd_device* dev);
|
static void ccid_on_suspend(usbd_device* dev);
|
||||||
|
static int32_t ccid_worker(void* context);
|
||||||
|
|
||||||
FuriHalUsbInterface usb_ccid = {
|
FuriHalUsbInterface usb_ccid = {
|
||||||
.init = ccid_init,
|
.init = ccid_init,
|
||||||
@@ -181,11 +193,22 @@ FuriHalUsbInterface usb_ccid = {
|
|||||||
|
|
||||||
static usbd_respond ccid_ep_config(usbd_device* dev, uint8_t cfg);
|
static usbd_respond ccid_ep_config(usbd_device* dev, uint8_t cfg);
|
||||||
static usbd_respond ccid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback);
|
static usbd_respond ccid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback);
|
||||||
static usbd_device* usb_dev;
|
|
||||||
static bool connected = false;
|
typedef struct {
|
||||||
static bool smartcard_inserted = true;
|
bool connected;
|
||||||
static CcidCallbacks* callbacks[CCID_TOTAL_SLOTS] = {NULL};
|
bool smartcard_inserted;
|
||||||
static void* cb_ctx[CCID_TOTAL_SLOTS];
|
CcidCallbacks* callbacks[CCID_TOTAL_SLOTS];
|
||||||
|
void* cb_ctx[CCID_TOTAL_SLOTS];
|
||||||
|
FuriThread* ccid_thread;
|
||||||
|
FuriSemaphore* ccid_semaphore;
|
||||||
|
usbd_device* usb_dev;
|
||||||
|
|
||||||
|
uint16_t receive_buffer_data_index;
|
||||||
|
uint8_t send_buffer[sizeof(ccid_bulk_message_header_t) + CCID_DATABLOCK_SIZE];
|
||||||
|
uint8_t receive_buffer[sizeof(ccid_bulk_message_header_t) + CCID_DATABLOCK_SIZE];
|
||||||
|
} FuriHalUsbCcid;
|
||||||
|
|
||||||
|
static FuriHalUsbCcid* furi_hal_usb_ccid = NULL;
|
||||||
|
|
||||||
static void* ccid_set_string_descr(char* str) {
|
static void* ccid_set_string_descr(char* str) {
|
||||||
furi_check(str);
|
furi_check(str);
|
||||||
@@ -205,7 +228,11 @@ static void ccid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
|
|||||||
|
|
||||||
FuriHalUsbCcidConfig* cfg = (FuriHalUsbCcidConfig*)ctx;
|
FuriHalUsbCcidConfig* cfg = (FuriHalUsbCcidConfig*)ctx;
|
||||||
|
|
||||||
usb_dev = dev;
|
furi_check(furi_hal_usb_ccid == NULL);
|
||||||
|
furi_hal_usb_ccid = malloc(sizeof(FuriHalUsbCcid));
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->usb_dev = dev;
|
||||||
|
furi_hal_usb_ccid->ccid_semaphore = furi_semaphore_alloc(1, 1);
|
||||||
|
|
||||||
usb_ccid.dev_descr->iManufacturer = 0;
|
usb_ccid.dev_descr->iManufacturer = 0;
|
||||||
usb_ccid.dev_descr->iProduct = 0;
|
usb_ccid.dev_descr->iProduct = 0;
|
||||||
@@ -233,42 +260,50 @@ static void ccid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) {
|
|||||||
usbd_reg_control(dev, ccid_control);
|
usbd_reg_control(dev, ccid_control);
|
||||||
|
|
||||||
usbd_connect(dev, true);
|
usbd_connect(dev, true);
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->receive_buffer_data_index = 0;
|
||||||
|
furi_hal_usb_ccid->ccid_thread = furi_thread_alloc_ex("CcidWorker", 2048, ccid_worker, ctx);
|
||||||
|
furi_thread_start(furi_hal_usb_ccid->ccid_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccid_deinit(usbd_device* dev) {
|
static void ccid_deinit(usbd_device* dev) {
|
||||||
|
furi_thread_flags_set(furi_thread_get_id(furi_hal_usb_ccid->ccid_thread), WorkerEvtStop);
|
||||||
|
furi_thread_join(furi_hal_usb_ccid->ccid_thread);
|
||||||
|
furi_thread_free(furi_hal_usb_ccid->ccid_thread);
|
||||||
|
|
||||||
usbd_reg_config(dev, NULL);
|
usbd_reg_config(dev, NULL);
|
||||||
usbd_reg_control(dev, NULL);
|
usbd_reg_control(dev, NULL);
|
||||||
|
|
||||||
free(usb_ccid.str_prod_descr);
|
free(usb_ccid.str_prod_descr);
|
||||||
free(usb_ccid.str_serial_descr);
|
free(usb_ccid.str_serial_descr);
|
||||||
|
|
||||||
|
free(furi_hal_usb_ccid);
|
||||||
|
|
||||||
|
furi_hal_usb_ccid = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccid_on_wakeup(usbd_device* dev) {
|
static void ccid_on_wakeup(usbd_device* dev) {
|
||||||
UNUSED(dev);
|
UNUSED(dev);
|
||||||
connected = true;
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccid_on_suspend(usbd_device* dev) {
|
static void ccid_on_suspend(usbd_device* dev) {
|
||||||
UNUSED(dev);
|
UNUSED(dev);
|
||||||
connected = false;
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct ccid_bulk_message_header {
|
|
||||||
uint8_t bMessageType;
|
|
||||||
uint32_t dwLength;
|
|
||||||
uint8_t bSlot;
|
|
||||||
uint8_t bSeq;
|
|
||||||
} FURI_PACKED ccid_bulk_message_header_t;
|
|
||||||
|
|
||||||
uint8_t SendBuffer[sizeof(ccid_bulk_message_header_t) + CCID_DATABLOCK_SIZE];
|
|
||||||
|
|
||||||
//stores the data p
|
|
||||||
uint8_t ReceiveBuffer[sizeof(ccid_bulk_message_header_t) + CCID_DATABLOCK_SIZE];
|
|
||||||
|
|
||||||
void CALLBACK_CCID_GetSlotStatus(
|
void CALLBACK_CCID_GetSlotStatus(
|
||||||
uint8_t slot,
|
uint8_t slot,
|
||||||
uint8_t seq,
|
uint8_t seq,
|
||||||
struct rdr_to_pc_slot_status* responseSlotStatus) {
|
struct rdr_to_pc_slot_status* responseSlotStatus) {
|
||||||
|
furi_check(responseSlotStatus);
|
||||||
|
|
||||||
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
responseSlotStatus->bMessageType = RDR_TO_PC_SLOTSTATUS;
|
responseSlotStatus->bMessageType = RDR_TO_PC_SLOTSTATUS;
|
||||||
|
|
||||||
responseSlotStatus->bSlot = slot;
|
responseSlotStatus->bSlot = slot;
|
||||||
@@ -279,7 +314,7 @@ void CALLBACK_CCID_GetSlotStatus(
|
|||||||
|
|
||||||
if(responseSlotStatus->bSlot == CCID_SLOT_INDEX) {
|
if(responseSlotStatus->bSlot == CCID_SLOT_INDEX) {
|
||||||
responseSlotStatus->bError = CCID_ERROR_NOERROR;
|
responseSlotStatus->bError = CCID_ERROR_NOERROR;
|
||||||
if(smartcard_inserted) {
|
if(furi_hal_usb_ccid->smartcard_inserted) {
|
||||||
responseSlotStatus->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
responseSlotStatus->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||||
} else {
|
} else {
|
||||||
@@ -293,9 +328,16 @@ void CALLBACK_CCID_GetSlotStatus(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CALLBACK_CCID_SetParametersT0(
|
void CALLBACK_CCID_SetParametersT0(
|
||||||
|
|
||||||
struct pc_to_rdr_set_parameters_t0* requestSetParametersT0,
|
struct pc_to_rdr_set_parameters_t0* requestSetParametersT0,
|
||||||
struct rdr_to_pc_parameters_t0* responseSetParametersT0) {
|
struct rdr_to_pc_parameters_t0* responseSetParametersT0) {
|
||||||
|
furi_check(requestSetParametersT0);
|
||||||
|
furi_check(responseSetParametersT0);
|
||||||
|
|
||||||
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
furi_check(requestSetParametersT0->bProtocolNum == 0x00); //T0
|
furi_check(requestSetParametersT0->bProtocolNum == 0x00); //T0
|
||||||
|
|
||||||
responseSetParametersT0->bMessageType = RDR_TO_PC_PARAMETERS;
|
responseSetParametersT0->bMessageType = RDR_TO_PC_PARAMETERS;
|
||||||
responseSetParametersT0->bSlot = requestSetParametersT0->bSlot;
|
responseSetParametersT0->bSlot = requestSetParametersT0->bSlot;
|
||||||
responseSetParametersT0->bSeq = requestSetParametersT0->bSeq;
|
responseSetParametersT0->bSeq = requestSetParametersT0->bSeq;
|
||||||
@@ -305,7 +347,7 @@ void CALLBACK_CCID_SetParametersT0(
|
|||||||
|
|
||||||
if(responseSetParametersT0->bSlot == CCID_SLOT_INDEX) {
|
if(responseSetParametersT0->bSlot == CCID_SLOT_INDEX) {
|
||||||
responseSetParametersT0->bError = CCID_ERROR_NOERROR;
|
responseSetParametersT0->bError = CCID_ERROR_NOERROR;
|
||||||
if(smartcard_inserted) {
|
if(furi_hal_usb_ccid->smartcard_inserted) {
|
||||||
responseSetParametersT0->bProtocolNum = requestSetParametersT0->bProtocolNum;
|
responseSetParametersT0->bProtocolNum = requestSetParametersT0->bProtocolNum;
|
||||||
responseSetParametersT0->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
responseSetParametersT0->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||||
@@ -323,6 +365,10 @@ void CALLBACK_CCID_IccPowerOn(
|
|||||||
uint8_t slot,
|
uint8_t slot,
|
||||||
uint8_t seq,
|
uint8_t seq,
|
||||||
struct rdr_to_pc_data_block* responseDataBlock) {
|
struct rdr_to_pc_data_block* responseDataBlock) {
|
||||||
|
furi_check(responseDataBlock);
|
||||||
|
|
||||||
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
responseDataBlock->bMessageType = RDR_TO_PC_DATABLOCK;
|
responseDataBlock->bMessageType = RDR_TO_PC_DATABLOCK;
|
||||||
responseDataBlock->dwLength = 0;
|
responseDataBlock->dwLength = 0;
|
||||||
responseDataBlock->bSlot = slot;
|
responseDataBlock->bSlot = slot;
|
||||||
@@ -330,12 +376,12 @@ void CALLBACK_CCID_IccPowerOn(
|
|||||||
|
|
||||||
if(responseDataBlock->bSlot == CCID_SLOT_INDEX) {
|
if(responseDataBlock->bSlot == CCID_SLOT_INDEX) {
|
||||||
responseDataBlock->bError = CCID_ERROR_NOERROR;
|
responseDataBlock->bError = CCID_ERROR_NOERROR;
|
||||||
if(smartcard_inserted) {
|
if(furi_hal_usb_ccid->smartcard_inserted) {
|
||||||
if(callbacks[CCID_SLOT_INDEX] != NULL) {
|
if(furi_hal_usb_ccid->callbacks[CCID_SLOT_INDEX] != NULL) {
|
||||||
callbacks[CCID_SLOT_INDEX]->icc_power_on_callback(
|
furi_hal_usb_ccid->callbacks[CCID_SLOT_INDEX]->icc_power_on_callback(
|
||||||
responseDataBlock->abData,
|
responseDataBlock->abData,
|
||||||
&responseDataBlock->dwLength,
|
&responseDataBlock->dwLength,
|
||||||
cb_ctx[CCID_SLOT_INDEX]);
|
furi_hal_usb_ccid->cb_ctx[CCID_SLOT_INDEX]);
|
||||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||||
} else {
|
} else {
|
||||||
@@ -355,6 +401,11 @@ void CALLBACK_CCID_IccPowerOn(
|
|||||||
void CALLBACK_CCID_XfrBlock(
|
void CALLBACK_CCID_XfrBlock(
|
||||||
struct pc_to_rdr_xfr_block* receivedXfrBlock,
|
struct pc_to_rdr_xfr_block* receivedXfrBlock,
|
||||||
struct rdr_to_pc_data_block* responseDataBlock) {
|
struct rdr_to_pc_data_block* responseDataBlock) {
|
||||||
|
furi_check(receivedXfrBlock);
|
||||||
|
furi_check(responseDataBlock);
|
||||||
|
|
||||||
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
responseDataBlock->bMessageType = RDR_TO_PC_DATABLOCK;
|
responseDataBlock->bMessageType = RDR_TO_PC_DATABLOCK;
|
||||||
responseDataBlock->bSlot = receivedXfrBlock->bSlot;
|
responseDataBlock->bSlot = receivedXfrBlock->bSlot;
|
||||||
responseDataBlock->bSeq = receivedXfrBlock->bSeq;
|
responseDataBlock->bSeq = receivedXfrBlock->bSeq;
|
||||||
@@ -362,14 +413,14 @@ void CALLBACK_CCID_XfrBlock(
|
|||||||
|
|
||||||
if(responseDataBlock->bSlot == CCID_SLOT_INDEX) {
|
if(responseDataBlock->bSlot == CCID_SLOT_INDEX) {
|
||||||
responseDataBlock->bError = CCID_ERROR_NOERROR;
|
responseDataBlock->bError = CCID_ERROR_NOERROR;
|
||||||
if(smartcard_inserted) {
|
if(furi_hal_usb_ccid->smartcard_inserted) {
|
||||||
if(callbacks[CCID_SLOT_INDEX] != NULL) {
|
if(furi_hal_usb_ccid->callbacks[CCID_SLOT_INDEX] != NULL) {
|
||||||
callbacks[CCID_SLOT_INDEX]->xfr_datablock_callback(
|
furi_hal_usb_ccid->callbacks[CCID_SLOT_INDEX]->xfr_datablock_callback(
|
||||||
(const uint8_t*)receivedXfrBlock->abData,
|
(const uint8_t*)receivedXfrBlock->abData,
|
||||||
receivedXfrBlock->dwLength,
|
receivedXfrBlock->dwLength,
|
||||||
responseDataBlock->abData,
|
responseDataBlock->abData,
|
||||||
&responseDataBlock->dwLength,
|
&responseDataBlock->dwLength,
|
||||||
cb_ctx[CCID_SLOT_INDEX]);
|
furi_hal_usb_ccid->cb_ctx[CCID_SLOT_INDEX]);
|
||||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||||
} else {
|
} else {
|
||||||
@@ -386,118 +437,177 @@ void CALLBACK_CCID_XfrBlock(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_ccid_ccid_insert_smartcard(void) {
|
void furi_hal_usb_ccid_insert_smartcard(void) {
|
||||||
smartcard_inserted = true;
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->smartcard_inserted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_ccid_ccid_remove_smartcard(void) {
|
void furi_hal_usb_ccid_remove_smartcard(void) {
|
||||||
smartcard_inserted = false;
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->smartcard_inserted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_ccid_set_callbacks(CcidCallbacks* cb, void* context) {
|
void furi_hal_usb_ccid_set_callbacks(CcidCallbacks* cb, void* context) {
|
||||||
callbacks[CCID_SLOT_INDEX] = cb;
|
furi_check(furi_hal_usb_ccid);
|
||||||
cb_ctx[CCID_SLOT_INDEX] = context;
|
|
||||||
|
furi_hal_usb_ccid->callbacks[CCID_SLOT_INDEX] = cb;
|
||||||
|
furi_hal_usb_ccid->cb_ctx[CCID_SLOT_INDEX] = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ccid_send_packet(uint8_t* data, uint8_t len) {
|
||||||
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
|
if(furi_hal_usb_ccid->ccid_semaphore == NULL || furi_hal_usb_ccid->connected == false) return;
|
||||||
|
furi_check(
|
||||||
|
furi_semaphore_acquire(furi_hal_usb_ccid->ccid_semaphore, FuriWaitForever) ==
|
||||||
|
FuriStatusOk);
|
||||||
|
if(furi_hal_usb_ccid->connected == true) {
|
||||||
|
usbd_ep_write(furi_hal_usb_ccid->usb_dev, CCID_IN_EPADDR, data, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ccid_send_response(uint8_t* data, uint32_t len) {
|
||||||
|
uint32_t data_to_send = len;
|
||||||
|
uint32_t data_index = 0;
|
||||||
|
while(data_to_send >= CCID_EPSIZE) {
|
||||||
|
ccid_send_packet(&data[data_index], CCID_EPSIZE);
|
||||||
|
data_to_send = data_to_send - CCID_EPSIZE;
|
||||||
|
data_index = data_index + CCID_EPSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccid_send_packet(&data[data_index], data_to_send);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccid_rx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
|
static void ccid_rx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
|
||||||
UNUSED(dev);
|
UNUSED(dev);
|
||||||
UNUSED(event);
|
UNUSED(event);
|
||||||
UNUSED(ep);
|
UNUSED(ep);
|
||||||
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
|
furi_semaphore_release(furi_hal_usb_ccid->ccid_semaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccid_tx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
|
static void ccid_tx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
|
||||||
UNUSED(dev);
|
UNUSED(dev);
|
||||||
|
UNUSED(ep);
|
||||||
if(event == usbd_evt_eprx) {
|
if(event == usbd_evt_eprx) {
|
||||||
if(connected == false) return;
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
|
||||||
//read initial CCID message header
|
|
||||||
|
|
||||||
int32_t bytes_read = usbd_ep_read(
|
int32_t bytes_read = usbd_ep_read(
|
||||||
usb_dev, ep, &ReceiveBuffer, sizeof(ccid_bulk_message_header_t) + CCID_DATABLOCK_SIZE);
|
furi_hal_usb_ccid->usb_dev,
|
||||||
//minimum request size is header size
|
CCID_OUT_EPADDR,
|
||||||
furi_check((uint16_t)bytes_read >= sizeof(ccid_bulk_message_header_t));
|
&furi_hal_usb_ccid->receive_buffer[furi_hal_usb_ccid->receive_buffer_data_index],
|
||||||
ccid_bulk_message_header_t* message = (ccid_bulk_message_header_t*)&ReceiveBuffer; //-V641
|
CCID_EPSIZE);
|
||||||
|
|
||||||
if(message->bMessageType == PC_TO_RDR_ICCPOWERON) {
|
if(bytes_read > 0) {
|
||||||
struct pc_to_rdr_icc_power_on* requestDataBlock =
|
furi_hal_usb_ccid->receive_buffer_data_index =
|
||||||
(struct pc_to_rdr_icc_power_on*)message; //-V641
|
furi_hal_usb_ccid->receive_buffer_data_index + bytes_read;
|
||||||
struct rdr_to_pc_data_block* responseDataBlock =
|
|
||||||
(struct rdr_to_pc_data_block*)&SendBuffer;
|
|
||||||
|
|
||||||
CALLBACK_CCID_IccPowerOn(
|
furi_thread_flags_set(
|
||||||
requestDataBlock->bSlot, requestDataBlock->bSeq, responseDataBlock);
|
furi_thread_get_id(furi_hal_usb_ccid->ccid_thread), WorkerEvtRequest);
|
||||||
|
|
||||||
usbd_ep_write(
|
|
||||||
usb_dev,
|
|
||||||
CCID_IN_EPADDR,
|
|
||||||
responseDataBlock,
|
|
||||||
sizeof(struct rdr_to_pc_data_block) +
|
|
||||||
(sizeof(uint8_t) * responseDataBlock->dwLength));
|
|
||||||
} else if(message->bMessageType == PC_TO_RDR_ICCPOWEROFF) {
|
|
||||||
struct pc_to_rdr_icc_power_off* requestIccPowerOff =
|
|
||||||
(struct pc_to_rdr_icc_power_off*)message; //-V641
|
|
||||||
struct rdr_to_pc_slot_status* responseSlotStatus =
|
|
||||||
(struct rdr_to_pc_slot_status*)&SendBuffer; //-V641
|
|
||||||
|
|
||||||
CALLBACK_CCID_GetSlotStatus(
|
|
||||||
requestIccPowerOff->bSlot, requestIccPowerOff->bSeq, responseSlotStatus);
|
|
||||||
|
|
||||||
usbd_ep_write(
|
|
||||||
usb_dev, CCID_IN_EPADDR, responseSlotStatus, sizeof(struct rdr_to_pc_slot_status));
|
|
||||||
} else if(message->bMessageType == PC_TO_RDR_GETSLOTSTATUS) {
|
|
||||||
struct pc_to_rdr_get_slot_status* requestSlotStatus =
|
|
||||||
(struct pc_to_rdr_get_slot_status*)message; //-V641
|
|
||||||
struct rdr_to_pc_slot_status* responseSlotStatus =
|
|
||||||
(struct rdr_to_pc_slot_status*)&SendBuffer; //-V641
|
|
||||||
|
|
||||||
CALLBACK_CCID_GetSlotStatus(
|
|
||||||
requestSlotStatus->bSlot, requestSlotStatus->bSeq, responseSlotStatus);
|
|
||||||
|
|
||||||
usbd_ep_write(
|
|
||||||
usb_dev, CCID_IN_EPADDR, responseSlotStatus, sizeof(struct rdr_to_pc_slot_status));
|
|
||||||
} else if(message->bMessageType == PC_TO_RDR_XFRBLOCK) {
|
|
||||||
struct pc_to_rdr_xfr_block* receivedXfrBlock = (struct pc_to_rdr_xfr_block*)message;
|
|
||||||
struct rdr_to_pc_data_block* responseDataBlock =
|
|
||||||
(struct rdr_to_pc_data_block*)&SendBuffer;
|
|
||||||
|
|
||||||
furi_check(receivedXfrBlock->dwLength <= CCID_DATABLOCK_SIZE);
|
|
||||||
furi_check(
|
|
||||||
(uint16_t)bytes_read >=
|
|
||||||
sizeof(ccid_bulk_message_header_t) + receivedXfrBlock->dwLength);
|
|
||||||
|
|
||||||
CALLBACK_CCID_XfrBlock(receivedXfrBlock, responseDataBlock);
|
|
||||||
|
|
||||||
furi_check(responseDataBlock->dwLength <= CCID_DATABLOCK_SIZE);
|
|
||||||
|
|
||||||
usbd_ep_write(
|
|
||||||
usb_dev,
|
|
||||||
CCID_IN_EPADDR,
|
|
||||||
responseDataBlock,
|
|
||||||
sizeof(struct rdr_to_pc_data_block) +
|
|
||||||
(sizeof(uint8_t) * responseDataBlock->dwLength));
|
|
||||||
} else if(message->bMessageType == PC_TO_RDR_SETPARAMETERS) {
|
|
||||||
struct pc_to_rdr_set_parameters_t0* requestSetParametersT0 =
|
|
||||||
(struct pc_to_rdr_set_parameters_t0*)message; //-V641
|
|
||||||
struct rdr_to_pc_parameters_t0* responseSetParametersT0 =
|
|
||||||
(struct rdr_to_pc_parameters_t0*)&SendBuffer; //-V641
|
|
||||||
|
|
||||||
furi_check(requestSetParametersT0->dwLength <= CCID_DATABLOCK_SIZE);
|
|
||||||
furi_check(
|
|
||||||
(uint16_t)bytes_read >=
|
|
||||||
sizeof(ccid_bulk_message_header_t) + requestSetParametersT0->dwLength);
|
|
||||||
|
|
||||||
CALLBACK_CCID_SetParametersT0(requestSetParametersT0, responseSetParametersT0);
|
|
||||||
|
|
||||||
usbd_ep_write(
|
|
||||||
usb_dev,
|
|
||||||
CCID_IN_EPADDR,
|
|
||||||
responseSetParametersT0,
|
|
||||||
sizeof(struct rdr_to_pc_parameters_t0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t ccid_worker(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
furi_check(furi_hal_usb_ccid);
|
||||||
|
uint32_t flags = furi_thread_flags_wait(
|
||||||
|
WorkerEvtStop | WorkerEvtRequest, FuriFlagWaitAny, FuriWaitForever);
|
||||||
|
|
||||||
|
if(flags & WorkerEvtRequest) {
|
||||||
|
//read initial CCID message header
|
||||||
|
|
||||||
|
ccid_bulk_message_header_t* message =
|
||||||
|
(ccid_bulk_message_header_t*)&furi_hal_usb_ccid->receive_buffer; //-V641
|
||||||
|
|
||||||
|
furi_check(message);
|
||||||
|
|
||||||
|
if(message->bMessageType == PC_TO_RDR_ICCPOWERON) {
|
||||||
|
struct pc_to_rdr_icc_power_on* requestDataBlock =
|
||||||
|
(struct pc_to_rdr_icc_power_on*)message; //-V641
|
||||||
|
struct rdr_to_pc_data_block* responseDataBlock =
|
||||||
|
(struct rdr_to_pc_data_block*)&furi_hal_usb_ccid->send_buffer;
|
||||||
|
|
||||||
|
CALLBACK_CCID_IccPowerOn(
|
||||||
|
requestDataBlock->bSlot, requestDataBlock->bSeq, responseDataBlock);
|
||||||
|
|
||||||
|
ccid_send_response(
|
||||||
|
furi_hal_usb_ccid->send_buffer,
|
||||||
|
sizeof(struct rdr_to_pc_data_block) +
|
||||||
|
(sizeof(uint8_t) * responseDataBlock->dwLength));
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->receive_buffer_data_index = 0;
|
||||||
|
|
||||||
|
} else if(message->bMessageType == PC_TO_RDR_ICCPOWEROFF) {
|
||||||
|
struct pc_to_rdr_icc_power_off* requestIccPowerOff =
|
||||||
|
(struct pc_to_rdr_icc_power_off*)message; //-V641
|
||||||
|
struct rdr_to_pc_slot_status* responseSlotStatus =
|
||||||
|
(struct rdr_to_pc_slot_status*)&furi_hal_usb_ccid->send_buffer; //-V641
|
||||||
|
|
||||||
|
CALLBACK_CCID_GetSlotStatus(
|
||||||
|
requestIccPowerOff->bSlot, requestIccPowerOff->bSeq, responseSlotStatus);
|
||||||
|
|
||||||
|
ccid_send_response(
|
||||||
|
furi_hal_usb_ccid->send_buffer, sizeof(struct rdr_to_pc_slot_status));
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->receive_buffer_data_index = 0;
|
||||||
|
|
||||||
|
} else if(message->bMessageType == PC_TO_RDR_GETSLOTSTATUS) {
|
||||||
|
struct pc_to_rdr_get_slot_status* requestSlotStatus =
|
||||||
|
(struct pc_to_rdr_get_slot_status*)message; //-V641
|
||||||
|
struct rdr_to_pc_slot_status* responseSlotStatus =
|
||||||
|
(struct rdr_to_pc_slot_status*)&furi_hal_usb_ccid->send_buffer; //-V641
|
||||||
|
|
||||||
|
CALLBACK_CCID_GetSlotStatus(
|
||||||
|
requestSlotStatus->bSlot, requestSlotStatus->bSeq, responseSlotStatus);
|
||||||
|
|
||||||
|
ccid_send_response(
|
||||||
|
furi_hal_usb_ccid->send_buffer, sizeof(struct rdr_to_pc_slot_status));
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->receive_buffer_data_index = 0;
|
||||||
|
|
||||||
|
} else if(message->bMessageType == PC_TO_RDR_XFRBLOCK) {
|
||||||
|
struct pc_to_rdr_xfr_block* receivedXfrBlock =
|
||||||
|
(struct pc_to_rdr_xfr_block*)message;
|
||||||
|
struct rdr_to_pc_data_block* responseDataBlock =
|
||||||
|
(struct rdr_to_pc_data_block*)&furi_hal_usb_ccid->send_buffer;
|
||||||
|
|
||||||
|
if(furi_hal_usb_ccid->receive_buffer_data_index >=
|
||||||
|
sizeof(struct pc_to_rdr_xfr_block) + receivedXfrBlock->dwLength) {
|
||||||
|
CALLBACK_CCID_XfrBlock(receivedXfrBlock, responseDataBlock);
|
||||||
|
|
||||||
|
ccid_send_response(
|
||||||
|
furi_hal_usb_ccid->send_buffer,
|
||||||
|
sizeof(struct rdr_to_pc_data_block) +
|
||||||
|
(sizeof(uint8_t) * responseDataBlock->dwLength));
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->receive_buffer_data_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(message->bMessageType == PC_TO_RDR_SETPARAMETERS) {
|
||||||
|
struct pc_to_rdr_set_parameters_t0* requestSetParametersT0 =
|
||||||
|
(struct pc_to_rdr_set_parameters_t0*)message; //-V641
|
||||||
|
struct rdr_to_pc_parameters_t0* responseSetParametersT0 =
|
||||||
|
(struct rdr_to_pc_parameters_t0*)&furi_hal_usb_ccid->send_buffer; //-V641
|
||||||
|
|
||||||
|
CALLBACK_CCID_SetParametersT0(requestSetParametersT0, responseSetParametersT0);
|
||||||
|
|
||||||
|
ccid_send_response(
|
||||||
|
furi_hal_usb_ccid->send_buffer, sizeof(struct rdr_to_pc_parameters_t0));
|
||||||
|
|
||||||
|
furi_hal_usb_ccid->receive_buffer_data_index = 0;
|
||||||
|
}
|
||||||
|
} else if(flags & WorkerEvtStop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure endpoints */
|
/* Configure endpoints */
|
||||||
static usbd_respond ccid_ep_config(usbd_device* dev, uint8_t cfg) {
|
static usbd_respond ccid_ep_config(usbd_device* dev, uint8_t cfg) {
|
||||||
switch(cfg) {
|
switch(cfg) {
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "hid_usage_desktop.h"
|
#include "hid_usage_desktop.h"
|
||||||
#include "hid_usage_button.h"
|
#include "hid_usage_button.h"
|
||||||
#include "hid_usage_keyboard.h"
|
#include "hid_usage_keyboard.h"
|
||||||
#include "hid_usage_consumer.h"
|
#include "hid_usage_consumer.h"
|
||||||
#include "hid_usage_led.h"
|
#include "hid_usage_led.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define CCID_SHORT_APDU_SIZE (0xFF)
|
#define CCID_SHORT_APDU_SIZE (0xFF)
|
||||||
|
|
||||||
@@ -28,10 +30,18 @@ typedef struct {
|
|||||||
void* context);
|
void* context);
|
||||||
} CcidCallbacks;
|
} CcidCallbacks;
|
||||||
|
|
||||||
void furi_hal_ccid_set_callbacks(CcidCallbacks* cb, void* context);
|
/** Set CCID callbacks
|
||||||
|
*
|
||||||
|
* @param cb CcidCallbacks instance
|
||||||
|
* @param context The context for callbacks
|
||||||
|
*/
|
||||||
|
void furi_hal_usb_ccid_set_callbacks(CcidCallbacks* cb, void* context);
|
||||||
|
|
||||||
void furi_hal_ccid_ccid_insert_smartcard(void);
|
/** Insert Smart Card */
|
||||||
void furi_hal_ccid_ccid_remove_smartcard(void);
|
void furi_hal_usb_ccid_insert_smartcard(void);
|
||||||
|
|
||||||
|
/** Remove Smart Card */
|
||||||
|
void furi_hal_usb_ccid_remove_smartcard(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||