|
|
1.1 root 1: /*
2: * emulate the reader
3: *
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.
6: */
7:
8: #include "qemu-common.h"
9: #include "qemu-thread.h"
10:
11: #include "vcard.h"
12: #include "vcard_emul.h"
13: #include "card_7816.h"
14: #include "vreader.h"
15: #include "vevent.h"
16:
17: struct VReaderStruct {
18: int reference_count;
19: VCard *card;
20: char *name;
21: vreader_id_t id;
22: QemuMutex lock;
23: VReaderEmul *reader_private;
24: VReaderEmulFree reader_private_free;
25: };
26:
27: /* manage locking */
28: static inline void
29: vreader_lock(VReader *reader)
30: {
31: qemu_mutex_lock(&reader->lock);
32: }
33:
34: static inline void
35: vreader_unlock(VReader *reader)
36: {
37: qemu_mutex_unlock(&reader->lock);
38: }
39:
40: /*
41: * vreader constructor
42: */
43: VReader *
44: vreader_new(const char *name, VReaderEmul *private,
45: VReaderEmulFree private_free)
46: {
47: VReader *reader;
48:
1.1.1.2 ! root 49: reader = (VReader *)g_malloc(sizeof(VReader));
1.1 root 50: qemu_mutex_init(&reader->lock);
51: reader->reference_count = 1;
52: reader->name = name ? strdup(name) : NULL;
53: reader->card = NULL;
54: reader->id = (vreader_id_t)-1;
55: reader->reader_private = private;
56: reader->reader_private_free = private_free;
57: return reader;
58: }
59:
60: /* get a reference */
61: VReader*
62: vreader_reference(VReader *reader)
63: {
64: if (reader == NULL) {
65: return NULL;
66: }
67: vreader_lock(reader);
68: reader->reference_count++;
69: vreader_unlock(reader);
70: return reader;
71: }
72:
73: /* free a reference */
74: void
75: vreader_free(VReader *reader)
76: {
77: if (reader == NULL) {
78: return;
79: }
80: vreader_lock(reader);
81: if (reader->reference_count-- > 1) {
82: vreader_unlock(reader);
83: return;
84: }
85: vreader_unlock(reader);
86: if (reader->card) {
87: vcard_free(reader->card);
88: }
89: if (reader->name) {
1.1.1.2 ! root 90: g_free(reader->name);
1.1 root 91: }
92: if (reader->reader_private_free) {
93: reader->reader_private_free(reader->reader_private);
94: }
1.1.1.2 ! root 95: g_free(reader);
1.1 root 96: return;
97: }
98:
99: static VCard *
100: vreader_get_card(VReader *reader)
101: {
102: VCard *card;
103:
104: vreader_lock(reader);
105: card = vcard_reference(reader->card);
106: vreader_unlock(reader);
107: return card;
108: }
109:
110: VReaderStatus
111: vreader_card_is_present(VReader *reader)
112: {
113: VCard *card = vreader_get_card(reader);
114:
115: if (card == NULL) {
116: return VREADER_NO_CARD;
117: }
118: vcard_free(card);
119: return VREADER_OK;
120: }
121:
122: vreader_id_t
123: vreader_get_id(VReader *reader)
124: {
125: if (reader == NULL) {
126: return (vreader_id_t)-1;
127: }
128: return reader->id;
129: }
130:
131: VReaderStatus
132: vreader_set_id(VReader *reader, vreader_id_t id)
133: {
134: if (reader == NULL) {
135: return VREADER_NO_CARD;
136: }
137: reader->id = id;
138: return VREADER_OK;
139: }
140:
141: const char *
142: vreader_get_name(VReader *reader)
143: {
144: if (reader == NULL) {
145: return NULL;
146: }
147: return reader->name;
148: }
149:
150: VReaderEmul *
151: vreader_get_private(VReader *reader)
152: {
153: return reader->reader_private;
154: }
155:
156: static VReaderStatus
157: vreader_reset(VReader *reader, VCardPower power, unsigned char *atr, int *len)
158: {
159: VCard *card = vreader_get_card(reader);
160:
161: if (card == NULL) {
162: return VREADER_NO_CARD;
163: }
164: /*
165: * clean up our state
166: */
167: vcard_reset(card, power);
168: if (atr) {
169: vcard_get_atr(card, atr, len);
170: }
171: vcard_free(card); /* free our reference */
172: return VREADER_OK;
173: }
174:
175: VReaderStatus
176: vreader_power_on(VReader *reader, unsigned char *atr, int *len)
177: {
178: return vreader_reset(reader, VCARD_POWER_ON, atr, len);
179: }
180:
181: VReaderStatus
182: vreader_power_off(VReader *reader)
183: {
184: return vreader_reset(reader, VCARD_POWER_OFF, NULL, 0);
185: }
186:
187:
188: VReaderStatus
189: vreader_xfr_bytes(VReader *reader,
190: unsigned char *send_buf, int send_buf_len,
191: unsigned char *receive_buf, int *receive_buf_len)
192: {
193: VCardAPDU *apdu;
194: VCardResponse *response = NULL;
195: VCardStatus card_status;
196: unsigned short status;
197: VCard *card = vreader_get_card(reader);
198:
199: if (card == NULL) {
200: return VREADER_NO_CARD;
201: }
202:
203: apdu = vcard_apdu_new(send_buf, send_buf_len, &status);
204: if (apdu == NULL) {
205: response = vcard_make_response(status);
206: card_status = VCARD_DONE;
207: } else {
208: card_status = vcard_process_apdu(card, apdu, &response);
209: }
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;
215: }
216: vcard_response_delete(response);
217: vcard_apdu_delete(apdu);
218: vcard_free(card); /* free our reference */
219: return VREADER_OK;
220: }
221:
222: struct VReaderListStruct {
223: VReaderListEntry *head;
224: VReaderListEntry *tail;
225: };
226:
227: struct VReaderListEntryStruct {
228: VReaderListEntry *next;
229: VReaderListEntry *prev;
230: VReader *reader;
231: };
232:
233:
234: static VReaderListEntry *
235: vreader_list_entry_new(VReader *reader)
236: {
237: VReaderListEntry *new_reader_list_entry;
238:
239: new_reader_list_entry = (VReaderListEntry *)
1.1.1.2 ! root 240: g_malloc(sizeof(VReaderListEntry));
1.1 root 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;
245: }
246:
247: static void
248: vreader_list_entry_delete(VReaderListEntry *entry)
249: {
250: if (entry == NULL) {
251: return;
252: }
253: vreader_free(entry->reader);
1.1.1.2 ! root 254: g_free(entry);
1.1 root 255: }
256:
257:
258: static VReaderList *
259: vreader_list_new(void)
260: {
261: VReaderList *new_reader_list;
262:
1.1.1.2 ! root 263: new_reader_list = (VReaderList *)g_malloc(sizeof(VReaderList));
1.1 root 264: new_reader_list->head = NULL;
265: new_reader_list->tail = NULL;
266: return new_reader_list;
267: }
268:
269: void
270: vreader_list_delete(VReaderList *list)
271: {
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);
278: }
279: list->head = NULL;
280: list->tail = NULL;
1.1.1.2 ! root 281: g_free(list);
1.1 root 282: }
283:
284:
285: VReaderListEntry *
286: vreader_list_get_first(VReaderList *list)
287: {
288: return list ? list->head : NULL;
289: }
290:
291: VReaderListEntry *
292: vreader_list_get_next(VReaderListEntry *current)
293: {
294: return current ? current->next : NULL;
295: }
296:
297: VReader *
298: vreader_list_get_reader(VReaderListEntry *entry)
299: {
300: return entry ? vreader_reference(entry->reader) : NULL;
301: }
302:
303: static void
304: vreader_queue(VReaderList *list, VReaderListEntry *entry)
305: {
306: if (entry == NULL) {
307: return;
308: }
309: entry->next = NULL;
310: entry->prev = list->tail;
311: if (list->head) {
312: list->tail->next = entry;
313: } else {
314: list->head = entry;
315: }
316: list->tail = entry;
317: }
318:
319: static void
320: vreader_dequeue(VReaderList *list, VReaderListEntry *entry)
321: {
322: if (entry == NULL) {
323: return;
324: }
325: if (entry->next == NULL) {
326: list->tail = entry->prev;
327: } else if (entry->prev == NULL) {
328: list->head = entry->next;
329: } else {
330: entry->prev->next = entry->next;
331: entry->next->prev = entry->prev;
332: }
333: if ((list->tail == NULL) || (list->head == NULL)) {
334: list->head = list->tail = NULL;
335: }
336: entry->next = entry->prev = NULL;
337: }
338:
339: static VReaderList *vreader_list;
340: static QemuMutex vreader_list_mutex;
341:
342: static void
343: vreader_list_init(void)
344: {
345: vreader_list = vreader_list_new();
346: qemu_mutex_init(&vreader_list_mutex);
347: }
348:
349: static void
350: vreader_list_lock(void)
351: {
352: qemu_mutex_lock(&vreader_list_mutex);
353: }
354:
355: static void
356: vreader_list_unlock(void)
357: {
358: qemu_mutex_unlock(&vreader_list_mutex);
359: }
360:
361: static VReaderList *
362: vreader_copy_list(VReaderList *list)
363: {
364: VReaderList *new_list = NULL;
365: VReaderListEntry *current_entry = NULL;
366:
367: new_list = vreader_list_new();
368: if (new_list == NULL) {
369: return NULL;
370: }
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);
375:
376: vreader_free(reader);
377: vreader_queue(new_list, new_entry);
378: }
379: return new_list;
380: }
381:
382: VReaderList *
383: vreader_get_reader_list(void)
384: {
385: VReaderList *new_reader_list;
386:
387: vreader_list_lock();
388: new_reader_list = vreader_copy_list(vreader_list);
389: vreader_list_unlock();
390: return new_reader_list;
391: }
392:
393: VReader *
394: vreader_get_reader_by_id(vreader_id_t id)
395: {
396: VReader *reader = NULL;
397: VReaderListEntry *current_entry = NULL;
398:
399: if (id == (vreader_id_t) -1) {
400: return NULL;
401: }
402:
403: vreader_list_lock();
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) {
408: reader = creader;
409: break;
410: }
411: vreader_free(creader);
412: }
413: vreader_list_unlock();
414: return reader;
415: }
416:
417: VReader *
418: vreader_get_reader_by_name(const char *name)
419: {
420: VReader *reader = NULL;
421: VReaderListEntry *current_entry = NULL;
422:
423: vreader_list_lock();
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) {
428: reader = creader;
429: break;
430: }
431: vreader_free(creader);
432: }
433: vreader_list_unlock();
434: return reader;
435: }
436:
437: /* called from card_emul to initialize the readers */
438: VReaderStatus
439: vreader_add_reader(VReader *reader)
440: {
441: VReaderListEntry *reader_entry;
442:
443: reader_entry = vreader_list_entry_new(reader);
444: if (reader_entry == NULL) {
445: return VREADER_OUT_OF_MEMORY;
446: }
447: vreader_list_lock();
448: vreader_queue(vreader_list, reader_entry);
449: vreader_list_unlock();
450: vevent_queue_vevent(vevent_new(VEVENT_READER_INSERT, reader, NULL));
451: return VREADER_OK;
452: }
453:
454:
455: VReaderStatus
456: vreader_remove_reader(VReader *reader)
457: {
458: VReaderListEntry *current_entry;
459:
460: vreader_list_lock();
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) {
464: break;
465: }
466: }
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));
471: return VREADER_OK;
472: }
473:
474: /*
475: * Generate VEVENT_CARD_INSERT or VEVENT_CARD_REMOVE based on vreader
476: * state. Separated from vreader_insert_card to allow replaying events
477: * for a given state.
478: */
479: void
480: vreader_queue_card_event(VReader *reader)
481: {
482: vevent_queue_vevent(vevent_new(
483: reader->card ? VEVENT_CARD_INSERT : VEVENT_CARD_REMOVE, reader,
484: reader->card));
485: }
486:
487: /*
488: * insert/remove a new card. for removal, card == NULL
489: */
490: VReaderStatus
491: vreader_insert_card(VReader *reader, VCard *card)
492: {
493: vreader_lock(reader);
494: if (reader->card) {
495: /* decrement reference count */
496: vcard_free(reader->card);
497: reader->card = NULL;
498: }
499: reader->card = vcard_reference(card);
500: vreader_unlock(reader);
501: vreader_queue_card_event(reader);
502: return VREADER_OK;
503: }
504:
505: /*
506: * initialize all the static reader structures
507: */
508: void
509: vreader_init(void)
510: {
511: vreader_list_init();
512: }
513:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.