-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathccid.h
132 lines (108 loc) · 3.99 KB
/
ccid.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* This file is part of the SECCID distribution (https://github.com/ckahlo/seccid).
* Copyright (c) 2023 - 2025 Christian Kahlo.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _H_CCID_
#define _H_CCID_
#include <Adafruit_TinyUSB.h>
#define CFG_TUD_CCID (1)
#define CFG_TUD_CCID_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_CCID_RX_BUFSIZE (256)
#define CFG_TUD_CCID_TX_BUFSIZE (256)
#define CCID_HDR_SZ (10) // CCID message header size
#define CCID_DESC_SZ (54) // CCID function descriptor size
#define CCID_DESC_TYPE_CCID (0x21) // CCID Descriptor
#define CCID_VERSION (0x0110)
#define CCID_IFSD (1024)
#define CCID_FEATURES (0x40000 | 0x40 | 0x20 | 0x10 | 0x08 | 0x04 | 0x02)
#define CCID_MSGLEN (CCID_IFSD + CCID_HDR_SZ)
#define CCID_CLAGET (0xFF)
#define CCID_CLAENV (0xFF)
// CCID Descriptor Template
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
#define TUD_CCID_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
/* CCID Interface */\
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_SMART_CARD, 0, 0, _stridx,\
/* CCID Function, version, max slot index, supported voltages and protocols */\
CCID_DESC_SZ, CCID_DESC_TYPE_CCID, U16_TO_U8S_LE(CCID_VERSION), 0, 0x7, U32_TO_U8S_LE(3),\
/* default clock, maximum clock, num clocks, current datarate, max datarate */\
U32_TO_U8S_LE(4000), U32_TO_U8S_LE(5000), 0, U32_TO_U8S_LE(9600), U32_TO_U8S_LE(625000),\
/* num datarates, max IFSD, sync. protocols, mechanical, features */\
0, U32_TO_U8S_LE(CCID_IFSD), U32_TO_U8S_LE(0), U32_TO_U8S_LE(0), U32_TO_U8S_LE(CCID_FEATURES),\
/* max msg len, get response CLA, envelope CLA, LCD layout, PIN support, max busy slots */\
U32_TO_U8S_LE(CCID_MSGLEN), CCID_CLAGET, CCID_CLAENV, U16_TO_U8S_LE(0), 0, 1,\
\
/* Endpoint Out */\
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
/* Endpoint In */\
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0\
// CCID reqests
#define ICC_POWER_ON (0x62)
#define ICC_POWER_OFF (0x63)
#define GET_SLOT_STATUS (0x65)
#define XFR_BLOCK (0x6F)
#define GET_PARAMETERS (0x6C)
#define RESET_PARAMETERS (0x6D)
#define SET_PARAMETERS (0x61)
// CCID responses
#define DATA_BLOCK (0x80)
#define SLOT_STATUS (0x81)
#define PARAMETERS (0x82)
// status values
#define SLOT_STATUS_OK (0)
#define SLOT_STATUS_FAILED (1 << 6)
// do not modify
#pragma scalar_storage_order little-endian
typedef struct {
uint8_t type;
uint32_t length;
uint8_t slot;
uint8_t seq;
uint8_t status;
uint8_t error;
uint8_t param;
uint8_t data[CCID_IFSD];
} __attribute__((packed)) ccid_msg_t;
/**
* application driver for CCID decive class
*
*/
class SECCID_USBD_CCID: public Adafruit_USBD_Interface {
public:
virtual ~SECCID_USBD_CCID() {}
SECCID_USBD_CCID(void);
// from Adafruit_USBD_Interface
uint16_t getInterfaceDescriptor(uint8_t itfnum, uint8_t *buf, uint16_t bufsize);
bool begin();
static uint8_t getInstanceCount(void);
void end(void);
typedef uint32_t (*apdu_callback_t)(uint8_t*, uint32_t);
apdu_callback_t set_apdu_callback(apdu_callback_t);
void process();
private:
enum {
INVALID_INSTANCE = 0xFF
};
static uint8_t _instance_count;
uint8_t _instance = INVALID_INSTANCE;
bool isValid(void) {
return _instance != INVALID_INSTANCE;
}
apdu_callback_t cb;
};
#endif
//
TU_ATTR_WEAK void tud_ccid_rx_cb(uint8_t itf);
TU_ATTR_WEAK void tud_ccid_tx_cb(uint8_t itf, uint16_t xferred_bytes);