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
);
100 vreader_get_card(VReader
*reader
)
104 vreader_lock(reader
);
105 card
= vcard_reference(reader
->card
);
106 vreader_unlock(reader
);
111 vreader_card_is_present(VReader
*reader
)
113 VCard
*card
= vreader_get_card(reader
);
116 return VREADER_NO_CARD
;
123 vreader_get_id(VReader
*reader
)
125 if (reader
== NULL
) {
126 return (vreader_id_t
)-1;
132 vreader_set_id(VReader
*reader
, vreader_id_t id
)
134 if (reader
== NULL
) {
135 return VREADER_NO_CARD
;
142 vreader_get_name(VReader
*reader
)
144 if (reader
== NULL
) {
151 vreader_get_private(VReader
*reader
)
153 return reader
->reader_private
;
157 vreader_reset(VReader
*reader
, VCardPower power
, unsigned char *atr
, int *len
)
159 VCard
*card
= vreader_get_card(reader
);
162 return VREADER_NO_CARD
;
167 vcard_reset(card
, power
);
169 vcard_get_atr(card
, atr
, len
);
171 vcard_free(card
); /* free our reference */
176 vreader_power_on(VReader
*reader
, unsigned char *atr
, int *len
)
178 return vreader_reset(reader
, VCARD_POWER_ON
, atr
, len
);
182 vreader_power_off(VReader
*reader
)
184 return vreader_reset(reader
, VCARD_POWER_OFF
, NULL
, 0);
189 vreader_xfr_bytes(VReader
*reader
,
190 unsigned char *send_buf
, int send_buf_len
,
191 unsigned char *receive_buf
, int *receive_buf_len
)
194 VCardResponse
*response
= NULL
;
195 VCardStatus card_status
;
196 unsigned short status
;
197 VCard
*card
= vreader_get_card(reader
);
200 return VREADER_NO_CARD
;
203 apdu
= vcard_apdu_new(send_buf
, send_buf_len
, &status
);
205 response
= vcard_make_response(status
);
206 card_status
= VCARD_DONE
;
208 card_status
= vcard_process_apdu(card
, apdu
, &response
);
210 assert(card_status
== VCARD_DONE
);
211 if (card_status
== VCARD_DONE
) {
212 int size
= MIN(*receive_buf_len
, response
->b_total_len
);
213 memcpy(receive_buf
, response
->b_data
, size
);
214 *receive_buf_len
= size
;
216 vcard_response_delete(response
);
217 vcard_apdu_delete(apdu
);
218 vcard_free(card
); /* free our reference */
222 struct VReaderListStruct
{
223 VReaderListEntry
*head
;
224 VReaderListEntry
*tail
;
227 struct VReaderListEntryStruct
{
228 VReaderListEntry
*next
;
229 VReaderListEntry
*prev
;
234 static VReaderListEntry
*
235 vreader_list_entry_new(VReader
*reader
)
237 VReaderListEntry
*new_reader_list_entry
;
239 new_reader_list_entry
= (VReaderListEntry
*)
240 g_malloc(sizeof(VReaderListEntry
));
241 new_reader_list_entry
->next
= NULL
;
242 new_reader_list_entry
->prev
= NULL
;
243 new_reader_list_entry
->reader
= vreader_reference(reader
);
244 return new_reader_list_entry
;
248 vreader_list_entry_delete(VReaderListEntry
*entry
)
253 vreader_free(entry
->reader
);
259 vreader_list_new(void)
261 VReaderList
*new_reader_list
;
263 new_reader_list
= (VReaderList
*)g_malloc(sizeof(VReaderList
));
264 new_reader_list
->head
= NULL
;
265 new_reader_list
->tail
= NULL
;
266 return new_reader_list
;
270 vreader_list_delete(VReaderList
*list
)
272 VReaderListEntry
*current_entry
;
273 VReaderListEntry
*next_entry
= NULL
;
274 for (current_entry
= vreader_list_get_first(list
); current_entry
;
275 current_entry
= next_entry
) {
276 next_entry
= vreader_list_get_next(current_entry
);
277 vreader_list_entry_delete(current_entry
);
286 vreader_list_get_first(VReaderList
*list
)
288 return list
? list
->head
: NULL
;
292 vreader_list_get_next(VReaderListEntry
*current
)
294 return current
? current
->next
: NULL
;
298 vreader_list_get_reader(VReaderListEntry
*entry
)
300 return entry
? vreader_reference(entry
->reader
) : NULL
;
304 vreader_queue(VReaderList
*list
, VReaderListEntry
*entry
)
310 entry
->prev
= list
->tail
;
312 list
->tail
->next
= entry
;
320 vreader_dequeue(VReaderList
*list
, VReaderListEntry
*entry
)
325 if (entry
->next
== NULL
) {
326 list
->tail
= entry
->prev
;
327 } else if (entry
->prev
== NULL
) {
328 list
->head
= entry
->next
;
330 entry
->prev
->next
= entry
->next
;
331 entry
->next
->prev
= entry
->prev
;
333 if ((list
->tail
== NULL
) || (list
->head
== NULL
)) {
334 list
->head
= list
->tail
= NULL
;
336 entry
->next
= entry
->prev
= NULL
;
339 static VReaderList
*vreader_list
;
340 static QemuMutex vreader_list_mutex
;
343 vreader_list_init(void)
345 vreader_list
= vreader_list_new();
346 qemu_mutex_init(&vreader_list_mutex
);
350 vreader_list_lock(void)
352 qemu_mutex_lock(&vreader_list_mutex
);
356 vreader_list_unlock(void)
358 qemu_mutex_unlock(&vreader_list_mutex
);
362 vreader_copy_list(VReaderList
*list
)
364 VReaderList
*new_list
= NULL
;
365 VReaderListEntry
*current_entry
= NULL
;
367 new_list
= vreader_list_new();
368 if (new_list
== NULL
) {
371 for (current_entry
= vreader_list_get_first(list
); current_entry
;
372 current_entry
= vreader_list_get_next(current_entry
)) {
373 VReader
*reader
= vreader_list_get_reader(current_entry
);
374 VReaderListEntry
*new_entry
= vreader_list_entry_new(reader
);
376 vreader_free(reader
);
377 vreader_queue(new_list
, new_entry
);
383 vreader_get_reader_list(void)
385 VReaderList
*new_reader_list
;
388 new_reader_list
= vreader_copy_list(vreader_list
);
389 vreader_list_unlock();
390 return new_reader_list
;
394 vreader_get_reader_by_id(vreader_id_t id
)
396 VReader
*reader
= NULL
;
397 VReaderListEntry
*current_entry
= NULL
;
399 if (id
== (vreader_id_t
) -1) {
404 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
405 current_entry
= vreader_list_get_next(current_entry
)) {
406 VReader
*creader
= vreader_list_get_reader(current_entry
);
407 if (creader
->id
== id
) {
411 vreader_free(creader
);
413 vreader_list_unlock();
418 vreader_get_reader_by_name(const char *name
)
420 VReader
*reader
= NULL
;
421 VReaderListEntry
*current_entry
= NULL
;
424 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
425 current_entry
= vreader_list_get_next(current_entry
)) {
426 VReader
*creader
= vreader_list_get_reader(current_entry
);
427 if (strcmp(creader
->name
, name
) == 0) {
431 vreader_free(creader
);
433 vreader_list_unlock();
437 /* called from card_emul to initialize the readers */
439 vreader_add_reader(VReader
*reader
)
441 VReaderListEntry
*reader_entry
;
443 reader_entry
= vreader_list_entry_new(reader
);
444 if (reader_entry
== NULL
) {
445 return VREADER_OUT_OF_MEMORY
;
448 vreader_queue(vreader_list
, reader_entry
);
449 vreader_list_unlock();
450 vevent_queue_vevent(vevent_new(VEVENT_READER_INSERT
, reader
, NULL
));
456 vreader_remove_reader(VReader
*reader
)
458 VReaderListEntry
*current_entry
;
461 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
462 current_entry
= vreader_list_get_next(current_entry
)) {
463 if (current_entry
->reader
== reader
) {
467 vreader_dequeue(vreader_list
, current_entry
);
468 vreader_list_unlock();
469 vreader_list_entry_delete(current_entry
);
470 vevent_queue_vevent(vevent_new(VEVENT_READER_REMOVE
, reader
, NULL
));
475 * Generate VEVENT_CARD_INSERT or VEVENT_CARD_REMOVE based on vreader
476 * state. Separated from vreader_insert_card to allow replaying events
480 vreader_queue_card_event(VReader
*reader
)
482 vevent_queue_vevent(vevent_new(
483 reader
->card
? VEVENT_CARD_INSERT
: VEVENT_CARD_REMOVE
, reader
,
488 * insert/remove a new card. for removal, card == NULL
491 vreader_insert_card(VReader
*reader
, VCard
*card
)
493 vreader_lock(reader
);
495 /* decrement reference count */
496 vcard_free(reader
->card
);
499 reader
->card
= vcard_reference(card
);
500 vreader_unlock(reader
);
501 vreader_queue_card_event(reader
);
506 * initialize all the static reader structures