File:  [Qemu by Fabrice Bellard] / qemu / libcacard / vreader.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:31:39 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1101, qemu1001, HEAD
qemu 1.0.1

    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 *)g_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:         g_free(reader->name);
   91:     }
   92:     if (reader->reader_private_free) {
   93:         reader->reader_private_free(reader->reader_private);
   94:     }
   95:     g_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:                                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;
  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:     g_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 *)g_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:     g_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