Skip to content

Commit d0f842f

Browse files
UVV-ghJakuje
authored andcommitted
Add empty reader implementation that always succeeds
Signed-off-by: Vyacheslav Yurkov <uvv.mail@gmail.com>
1 parent dfe4e4a commit d0f842f

4 files changed

Lines changed: 164 additions & 2 deletions

File tree

src/libopensc/Makefile.am

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ libopensc_la_SOURCES_BASE = \
3535
\
3636
muscle.c muscle-filesystem.c \
3737
\
38-
ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \
38+
ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c reader-empty.c \
3939
\
4040
card-setcos.c card-flex.c \
4141
card-cardos.c card-cardos-common.c card-tcos.c card-default.c \
@@ -117,7 +117,7 @@ TIDY_FILES = \
117117
\
118118
muscle.c muscle-filesystem.c \
119119
\
120-
ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \
120+
ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c reader-empty.c \
121121
\
122122
card-setcos.c card-flex.c \
123123
card-cardos.c card-tcos.c card-default.c \

src/libopensc/ctx.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,8 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
10291029
ctx->reader_driver = sc_get_ctapi_driver();
10301030
#elif defined(ENABLE_OPENCT)
10311031
ctx->reader_driver = sc_get_openct_driver();
1032+
#else
1033+
ctx->reader_driver = sc_get_empty_driver();
10321034
#endif
10331035

10341036
r = ctx->reader_driver->ops->init(ctx);

src/libopensc/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ extern struct sc_reader_driver *sc_get_pcsc_driver(void);
295295
extern struct sc_reader_driver *sc_get_ctapi_driver(void);
296296
extern struct sc_reader_driver *sc_get_openct_driver(void);
297297
extern struct sc_reader_driver *sc_get_cryptotokenkit_driver(void);
298+
extern struct sc_reader_driver *sc_get_empty_driver(void);
298299

299300
#ifdef __cplusplus
300301
}

src/libopensc/reader-empty.c

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* reader-none.c: Reader driver stub with no functionality
3+
*
4+
* Copyright (C) 2026 Vyacheslav Yurkov <uvv.mail@gmail.com>
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#ifdef HAVE_CONFIG_H
22+
#include "config.h"
23+
#endif
24+
25+
#include <assert.h>
26+
#include <stdlib.h>
27+
#include <string.h>
28+
#include <time.h>
29+
30+
#include "internal.h"
31+
32+
static int
33+
empty_transmit(sc_reader_t *reader, sc_apdu_t *apdu)
34+
{
35+
return 0;
36+
}
37+
38+
static int
39+
empty_detect_card_presence(sc_reader_t *reader)
40+
{
41+
return SC_SUCCESS;
42+
}
43+
44+
static int
45+
empty_connect(sc_reader_t *reader)
46+
{
47+
return SC_SUCCESS;
48+
}
49+
50+
static int
51+
empty_disconnect(sc_reader_t * reader)
52+
{
53+
return SC_SUCCESS;
54+
}
55+
56+
static int
57+
empty_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data)
58+
{
59+
return SC_SUCCESS;
60+
}
61+
62+
static int
63+
empty_lock(sc_reader_t *reader)
64+
{
65+
return SC_SUCCESS;
66+
}
67+
68+
static int
69+
empty_unlock(sc_reader_t *reader)
70+
{
71+
return SC_SUCCESS;
72+
}
73+
74+
static int
75+
empty_release(sc_reader_t *reader)
76+
{
77+
return SC_SUCCESS;
78+
}
79+
80+
static int
81+
empty_reset(sc_reader_t *reader, int do_cold_reset)
82+
{
83+
return SC_SUCCESS;
84+
}
85+
86+
static int
87+
empty_cancel(sc_context_t *ctx)
88+
{
89+
return SC_SUCCESS;
90+
}
91+
92+
static int
93+
empty_init(sc_context_t *ctx)
94+
{
95+
return SC_SUCCESS;
96+
}
97+
98+
static int
99+
empty_finish(sc_context_t *ctx)
100+
{
101+
return SC_SUCCESS;
102+
}
103+
104+
static int
105+
empty_detect_readers(sc_context_t *ctx)
106+
{
107+
return SC_SUCCESS;
108+
}
109+
110+
static int
111+
empty_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
112+
int timeout, void **reader_states)
113+
{
114+
return SC_SUCCESS;
115+
}
116+
117+
int
118+
empty_perform_pace(struct sc_reader *reader, void *input_pace, void *output_pace)
119+
{
120+
return SC_SUCCESS;
121+
}
122+
123+
int
124+
empty_use_reader(sc_context_t *ctx, void *empty_context_handle, void *empty_card_handle)
125+
{
126+
return SC_SUCCESS;
127+
}
128+
129+
static struct sc_reader_operations empty_ops;
130+
131+
static struct sc_reader_driver empty_drv = {
132+
"Empty reader",
133+
"none",
134+
&empty_ops,
135+
NULL
136+
};
137+
138+
struct sc_reader_driver *
139+
sc_get_empty_driver(void)
140+
{
141+
empty_ops.init = empty_init;
142+
empty_ops.finish = empty_finish;
143+
empty_ops.detect_readers = empty_detect_readers;
144+
empty_ops.transmit = empty_transmit;
145+
empty_ops.detect_card_presence = empty_detect_card_presence;
146+
empty_ops.lock = empty_lock;
147+
empty_ops.unlock = empty_unlock;
148+
empty_ops.release = empty_release;
149+
empty_ops.connect = empty_connect;
150+
empty_ops.disconnect = empty_disconnect;
151+
empty_ops.perform_verify = empty_pin_cmd;
152+
empty_ops.wait_for_event = empty_wait_for_event;
153+
empty_ops.cancel = empty_cancel;
154+
empty_ops.reset = empty_reset;
155+
empty_ops.use_reader = empty_use_reader;
156+
empty_ops.perform_pace = empty_perform_pace;
157+
158+
return &empty_drv;
159+
}

0 commit comments

Comments
 (0)