parent
7eb62a0898
commit
c92e3b4f98
|
@ -254,12 +254,12 @@ int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out)
|
|||
* Note that zero means no limitations at all.
|
||||
*/
|
||||
if ((card->max_recv_size == 0) ||
|
||||
((reader->driver->max_recv_size != 0) && (reader->driver->max_recv_size < card->max_recv_size)))
|
||||
card->max_recv_size = reader->driver->max_recv_size;
|
||||
((reader->max_recv_size != 0) && (reader->max_recv_size < card->max_recv_size)))
|
||||
card->max_recv_size = reader->max_recv_size;
|
||||
|
||||
if ((card->max_send_size == 0) ||
|
||||
((reader->driver->max_send_size != 0) && (reader->driver->max_send_size < card->max_send_size)))
|
||||
card->max_send_size = reader->driver->max_send_size;
|
||||
((reader->max_send_size != 0) && (reader->max_send_size < card->max_send_size)))
|
||||
card->max_send_size = reader->max_send_size;
|
||||
|
||||
sc_log(ctx, "card info name:'%s', type:%i, flags:0x%X, max_send/recv_size:%i/%i",
|
||||
card->name, card->type, card->flags, card->max_send_size, card->max_recv_size);
|
||||
|
|
|
@ -289,15 +289,28 @@ static void load_reader_driver_options(sc_context_t *ctx)
|
|||
{
|
||||
struct sc_reader_driver *driver = ctx->reader_driver;
|
||||
scconf_block *conf_block = NULL;
|
||||
|
||||
driver->max_send_size = 0;
|
||||
driver->max_recv_size = 0;
|
||||
sc_reader_t *reader;
|
||||
int max_send_size;
|
||||
int max_recv_size;
|
||||
|
||||
conf_block = sc_get_conf_block(ctx, "reader_driver", driver->short_name, 1);
|
||||
|
||||
if (conf_block != NULL) {
|
||||
driver->max_send_size = scconf_get_int(conf_block, "max_send_size", driver->max_send_size);
|
||||
driver->max_recv_size = scconf_get_int(conf_block, "max_recv_size", driver->max_recv_size);
|
||||
max_send_size = scconf_get_int(conf_block, "max_send_size", -1);
|
||||
max_recv_size = scconf_get_int(conf_block, "max_recv_size", -1);
|
||||
if (max_send_size >= 0 || max_recv_size >= 0) {
|
||||
if (list_iterator_start(&ctx->readers)) {
|
||||
reader = list_iterator_next(&ctx->readers);
|
||||
while (reader) {
|
||||
if (max_send_size >= 0)
|
||||
reader->max_send_size = max_send_size;
|
||||
if (max_recv_size >= 0)
|
||||
reader->max_recv_size = max_recv_size;
|
||||
reader = list_iterator_next(&ctx->readers);
|
||||
}
|
||||
list_iterator_stop(&ctx->readers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -739,7 +752,6 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
|
|||
ctx->reader_driver = sc_get_openct_driver();
|
||||
#endif
|
||||
|
||||
load_reader_driver_options(ctx);
|
||||
r = ctx->reader_driver->ops->init(ctx);
|
||||
if (r != SC_SUCCESS) {
|
||||
sc_release_context(ctx);
|
||||
|
@ -755,6 +767,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
|
|||
}
|
||||
del_drvs(&opts);
|
||||
sc_ctx_detect_readers(ctx);
|
||||
load_reader_driver_options(ctx);
|
||||
*ctx_out = ctx;
|
||||
|
||||
return SC_SUCCESS;
|
||||
|
|
|
@ -200,6 +200,7 @@ typedef LONG (PCSC_API *SCardGetAttrib_t)(SCARDHANDLE hCard, DWORD dwAttrId,\
|
|||
#define PCSCv2_PART10_PROPERTY_bMaxPINSize 7
|
||||
#define PCSCv2_PART10_PROPERTY_sFirmwareID 8
|
||||
#define PCSCv2_PART10_PROPERTY_bPPDUSupport 9
|
||||
#define PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize 10
|
||||
|
||||
/* structures used (but not defined) in PCSC Part 10:
|
||||
* "IFDs with Secure Pin Entry Capabilities" */
|
||||
|
|
|
@ -275,8 +275,6 @@ struct sc_reader_driver {
|
|||
const char *short_name;
|
||||
struct sc_reader_operations *ops;
|
||||
|
||||
size_t max_send_size; /* Max Lc supported by the reader layer */
|
||||
size_t max_recv_size; /* Mac Le supported by the reader layer */
|
||||
void *dll;
|
||||
};
|
||||
|
||||
|
@ -305,6 +303,8 @@ typedef struct sc_reader {
|
|||
|
||||
unsigned long flags, capabilities;
|
||||
unsigned int supported_protocols, active_protocol;
|
||||
size_t max_send_size; /* Max Lc supported by the reader layer */
|
||||
size_t max_recv_size; /* Mac Le supported by the reader layer */
|
||||
|
||||
struct sc_atr atr;
|
||||
struct _atr_info {
|
||||
|
|
|
@ -620,7 +620,7 @@ static struct sc_reader_driver pcsc_drv = {
|
|||
"PC/SC reader",
|
||||
"pcsc",
|
||||
&pcsc_ops,
|
||||
0, 0, NULL
|
||||
NULL
|
||||
};
|
||||
|
||||
static int pcsc_init(sc_context_t *ctx)
|
||||
|
@ -817,6 +817,50 @@ err:
|
|||
return flags;
|
||||
}
|
||||
|
||||
static int
|
||||
part10_find_property_by_tag(unsigned char buffer[], int length,
|
||||
int tag_searched);
|
||||
/**
|
||||
* @brief Detects reader's maximum data size
|
||||
*
|
||||
* @param reader reader to probe (\c get_tlv_properties must be initialized)
|
||||
*
|
||||
* @return maximum data size
|
||||
*/
|
||||
static size_t part10_detect_max_data(sc_reader_t *reader, SCARDHANDLE card_handle)
|
||||
{
|
||||
u8 rbuf[256];
|
||||
DWORD rcount = sizeof rbuf;
|
||||
struct pcsc_private_data *priv;
|
||||
/* 0 means no limitations */
|
||||
size_t max_data = 0;
|
||||
int r;
|
||||
|
||||
if (!reader)
|
||||
goto err;
|
||||
priv = GET_PRIV_DATA(reader);
|
||||
if (!priv)
|
||||
goto err;
|
||||
|
||||
if (priv->get_tlv_properties && priv->gpriv) {
|
||||
if (SCARD_S_SUCCESS != priv->gpriv->SCardControl(card_handle,
|
||||
priv->get_tlv_properties, NULL, 0, rbuf, sizeof(rbuf),
|
||||
&rcount)) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL,
|
||||
"PC/SC v2 part 10: Get TLV properties failed!");
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = part10_find_property_by_tag(rbuf, rcount,
|
||||
PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize);
|
||||
if (r >= 0)
|
||||
max_data = r;
|
||||
}
|
||||
|
||||
err:
|
||||
return max_data;
|
||||
}
|
||||
|
||||
static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) {
|
||||
sc_context_t *ctx = reader->ctx;
|
||||
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data;
|
||||
|
@ -940,6 +984,12 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle)
|
|||
sc_log(ctx, "%s %s", log_text, log_disabled);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set reader max_send_size and max_recv_size based on detected max_data */
|
||||
if (priv->get_tlv_properties) {
|
||||
reader->max_send_size = part10_detect_max_data(reader, card_handle);
|
||||
reader->max_recv_size = reader->max_send_size;
|
||||
}
|
||||
}
|
||||
|
||||
static int pcsc_detect_readers(sc_context_t *ctx)
|
||||
|
|
Loading…
Reference in New Issue