4 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
5 * See the COPYING.LIB file in the top-level directory.
8 #include "qemu-common.h"
9 #include "qemu/thread.h"
12 #include "vcard_emul.h"
13 #include "card_7816.h"
17 struct VReaderStruct
{
23 VReaderEmul
*reader_private
;
24 VReaderEmulFree reader_private_free
;
29 vreader_lock(VReader
*reader
)
31 qemu_mutex_lock(&reader
->lock
);
35 vreader_unlock(VReader
*reader
)
37 qemu_mutex_unlock(&reader
->lock
);
44 vreader_new(const char *name
, VReaderEmul
*private,
45 VReaderEmulFree private_free
)
49 reader
= (VReader
*)g_malloc(sizeof(VReader
));
50 qemu_mutex_init(&reader
->lock
);
51 reader
->reference_count
= 1;
52 reader
->name
= name
? strdup(name
) : NULL
;
54 reader
->id
= (vreader_id_t
)-1;
55 reader
->reader_private
= private;
56 reader
->reader_private_free
= private_free
;
62 vreader_reference(VReader
*reader
)
68 reader
->reference_count
++;
69 vreader_unlock(reader
);
73 /* free a reference */
75 vreader_free(VReader
*reader
)
81 if (reader
->reference_count
-- > 1) {
82 vreader_unlock(reader
);
85 vreader_unlock(reader
);
87 vcard_free(reader
->card
);
92 if (reader
->reader_private_free
) {
93 reader
->reader_private_free(reader
->reader_private
);
99 vreader_get_card(VReader
*reader
)
103 vreader_lock(reader
);
104 card
= vcard_reference(reader
->card
);
105 vreader_unlock(reader
);
110 vreader_card_is_present(VReader
*reader
)
112 VCard
*card
= vreader_get_card(reader
);
115 return VREADER_NO_CARD
;
122 vreader_get_id(VReader
*reader
)
124 if (reader
== NULL
) {
125 return (vreader_id_t
)-1;
131 vreader_set_id(VReader
*reader
, vreader_id_t id
)
133 if (reader
== NULL
) {
134 return VREADER_NO_CARD
;
141 vreader_get_name(VReader
*reader
)
143 if (reader
== NULL
) {
150 vreader_get_private(VReader
*reader
)
152 return reader
->reader_private
;
156 vreader_reset(VReader
*reader
, VCardPower power
, unsigned char *atr
, int *len
)
158 VCard
*card
= vreader_get_card(reader
);
161 return VREADER_NO_CARD
;
166 vcard_reset(card
, power
);
168 vcard_get_atr(card
, atr
, len
);
170 vcard_free(card
); /* free our reference */
175 vreader_power_on(VReader
*reader
, unsigned char *atr
, int *len
)
177 return vreader_reset(reader
, VCARD_POWER_ON
, atr
, len
);
181 vreader_power_off(VReader
*reader
)
183 return vreader_reset(reader
, VCARD_POWER_OFF
, NULL
, 0);
188 vreader_xfr_bytes(VReader
*reader
,
189 unsigned char *send_buf
, int send_buf_len
,
190 unsigned char *receive_buf
, int *receive_buf_len
)
193 VCardResponse
*response
= NULL
;
194 VCardStatus card_status
;
195 unsigned short status
;
196 VCard
*card
= vreader_get_card(reader
);
199 return VREADER_NO_CARD
;
202 apdu
= vcard_apdu_new(send_buf
, send_buf_len
, &status
);
204 response
= vcard_make_response(status
);
205 card_status
= VCARD_DONE
;
207 card_status
= vcard_process_apdu(card
, apdu
, &response
);
209 assert(card_status
== VCARD_DONE
);
210 if (card_status
== VCARD_DONE
) {
211 int size
= MIN(*receive_buf_len
, response
->b_total_len
);
212 memcpy(receive_buf
, response
->b_data
, size
);
213 *receive_buf_len
= size
;
215 vcard_response_delete(response
);
216 vcard_apdu_delete(apdu
);
217 vcard_free(card
); /* free our reference */
221 struct VReaderListStruct
{
222 VReaderListEntry
*head
;
223 VReaderListEntry
*tail
;
226 struct VReaderListEntryStruct
{
227 VReaderListEntry
*next
;
228 VReaderListEntry
*prev
;
233 static VReaderListEntry
*
234 vreader_list_entry_new(VReader
*reader
)
236 VReaderListEntry
*new_reader_list_entry
;
238 new_reader_list_entry
= (VReaderListEntry
*)
239 g_malloc(sizeof(VReaderListEntry
));
240 new_reader_list_entry
->next
= NULL
;
241 new_reader_list_entry
->prev
= NULL
;
242 new_reader_list_entry
->reader
= vreader_reference(reader
);
243 return new_reader_list_entry
;
247 vreader_list_entry_delete(VReaderListEntry
*entry
)
252 vreader_free(entry
->reader
);
258 vreader_list_new(void)
260 VReaderList
*new_reader_list
;
262 new_reader_list
= (VReaderList
*)g_malloc(sizeof(VReaderList
));
263 new_reader_list
->head
= NULL
;
264 new_reader_list
->tail
= NULL
;
265 return new_reader_list
;
269 vreader_list_delete(VReaderList
*list
)
271 VReaderListEntry
*current_entry
;
272 VReaderListEntry
*next_entry
= NULL
;
273 for (current_entry
= vreader_list_get_first(list
); current_entry
;
274 current_entry
= next_entry
) {
275 next_entry
= vreader_list_get_next(current_entry
);
276 vreader_list_entry_delete(current_entry
);
285 vreader_list_get_first(VReaderList
*list
)
287 return list
? list
->head
: NULL
;
291 vreader_list_get_next(VReaderListEntry
*current
)
293 return current
? current
->next
: NULL
;
297 vreader_list_get_reader(VReaderListEntry
*entry
)
299 return entry
? vreader_reference(entry
->reader
) : NULL
;
303 vreader_queue(VReaderList
*list
, VReaderListEntry
*entry
)
309 entry
->prev
= list
->tail
;
311 list
->tail
->next
= entry
;
319 vreader_dequeue(VReaderList
*list
, VReaderListEntry
*entry
)
324 if (entry
->next
== NULL
) {
325 list
->tail
= entry
->prev
;
326 } else if (entry
->prev
== NULL
) {
327 list
->head
= entry
->next
;
329 entry
->prev
->next
= entry
->next
;
330 entry
->next
->prev
= entry
->prev
;
332 if ((list
->tail
== NULL
) || (list
->head
== NULL
)) {
333 list
->head
= list
->tail
= NULL
;
335 entry
->next
= entry
->prev
= NULL
;
338 static VReaderList
*vreader_list
;
339 static QemuMutex vreader_list_mutex
;
342 vreader_list_init(void)
344 vreader_list
= vreader_list_new();
345 qemu_mutex_init(&vreader_list_mutex
);
349 vreader_list_lock(void)
351 qemu_mutex_lock(&vreader_list_mutex
);
355 vreader_list_unlock(void)
357 qemu_mutex_unlock(&vreader_list_mutex
);
361 vreader_copy_list(VReaderList
*list
)
363 VReaderList
*new_list
= NULL
;
364 VReaderListEntry
*current_entry
= NULL
;
366 new_list
= vreader_list_new();
367 if (new_list
== NULL
) {
370 for (current_entry
= vreader_list_get_first(list
); current_entry
;
371 current_entry
= vreader_list_get_next(current_entry
)) {
372 VReader
*reader
= vreader_list_get_reader(current_entry
);
373 VReaderListEntry
*new_entry
= vreader_list_entry_new(reader
);
375 vreader_free(reader
);
376 vreader_queue(new_list
, new_entry
);
382 vreader_get_reader_list(void)
384 VReaderList
*new_reader_list
;
387 new_reader_list
= vreader_copy_list(vreader_list
);
388 vreader_list_unlock();
389 return new_reader_list
;
393 vreader_get_reader_by_id(vreader_id_t id
)
395 VReader
*reader
= NULL
;
396 VReaderListEntry
*current_entry
= NULL
;
398 if (id
== (vreader_id_t
) -1) {
403 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
404 current_entry
= vreader_list_get_next(current_entry
)) {
405 VReader
*creader
= vreader_list_get_reader(current_entry
);
406 if (creader
->id
== id
) {
410 vreader_free(creader
);
412 vreader_list_unlock();
417 vreader_get_reader_by_name(const char *name
)
419 VReader
*reader
= NULL
;
420 VReaderListEntry
*current_entry
= NULL
;
423 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
424 current_entry
= vreader_list_get_next(current_entry
)) {
425 VReader
*creader
= vreader_list_get_reader(current_entry
);
426 if (strcmp(creader
->name
, name
) == 0) {
430 vreader_free(creader
);
432 vreader_list_unlock();
436 /* called from card_emul to initialize the readers */
438 vreader_add_reader(VReader
*reader
)
440 VReaderListEntry
*reader_entry
;
442 reader_entry
= vreader_list_entry_new(reader
);
443 if (reader_entry
== NULL
) {
444 return VREADER_OUT_OF_MEMORY
;
447 vreader_queue(vreader_list
, reader_entry
);
448 vreader_list_unlock();
449 vevent_queue_vevent(vevent_new(VEVENT_READER_INSERT
, reader
, NULL
));
455 vreader_remove_reader(VReader
*reader
)
457 VReaderListEntry
*current_entry
;
460 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
461 current_entry
= vreader_list_get_next(current_entry
)) {
462 if (current_entry
->reader
== reader
) {
466 vreader_dequeue(vreader_list
, current_entry
);
467 vreader_list_unlock();
468 vreader_list_entry_delete(current_entry
);
469 vevent_queue_vevent(vevent_new(VEVENT_READER_REMOVE
, reader
, NULL
));
474 * Generate VEVENT_CARD_INSERT or VEVENT_CARD_REMOVE based on vreader
475 * state. Separated from vreader_insert_card to allow replaying events
479 vreader_queue_card_event(VReader
*reader
)
481 vevent_queue_vevent(vevent_new(
482 reader
->card
? VEVENT_CARD_INSERT
: VEVENT_CARD_REMOVE
, reader
,
487 * insert/remove a new card. for removal, card == NULL
490 vreader_insert_card(VReader
*reader
, VCard
*card
)
492 vreader_lock(reader
);
494 /* decrement reference count */
495 vcard_free(reader
->card
);
498 reader
->card
= vcard_reference(card
);
499 vreader_unlock(reader
);
500 vreader_queue_card_event(reader
);
505 * initialize all the static reader structures