Annotation of qemu/libcacard/vreader.c, revision 1.1.1.1

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: 
                     49:     reader = (VReader *)qemu_malloc(sizeof(VReader));
                     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) {
                     90:         qemu_free(reader->name);
                     91:     }
                     92:     if (reader->reader_private_free) {
                     93:         reader->reader_private_free(reader->reader_private);
                     94:     }
                     95:     qemu_free(reader);
                     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 *)
                    240:                                qemu_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;
                    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);
                    254:     qemu_free(entry);
                    255: }
                    256: 
                    257: 
                    258: static VReaderList *
                    259: vreader_list_new(void)
                    260: {
                    261:     VReaderList *new_reader_list;
                    262: 
                    263:     new_reader_list = (VReaderList *)qemu_malloc(sizeof(VReaderList));
                    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;
                    281:     qemu_free(list);
                    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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.