mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-08 21:14:11 +00:00
uses VSC_Error with code==VSC_SUCCESS instead. This means that the VSC_Error message is overloaded. Instead of the other option of adding a message id, since the connection is TCP so no messages may be dropped or reordered, by having each message followed by a response there is no ambiguity. Still this commit adds a queue for messages that we only have one of which outstanding at a time, i.e. send, wait for response, send the next, etc. This further simplifies the logic, while not adding much overhead since only when spicec starts up it has a situation where it needs to send two events (ReaderAdd and ATR for Card Insert).
145 lines
4.0 KiB
C++
145 lines
4.0 KiB
C++
#ifndef __SMART_CARD_H__
|
|
#define __SMART_CARD_H__
|
|
|
|
#include <map>
|
|
|
|
#include <vreadert.h>
|
|
#include <vscard_common.h>
|
|
#include <eventt.h>
|
|
|
|
#include "red_channel.h"
|
|
#include "red_peer.h"
|
|
|
|
class Application;
|
|
|
|
struct SmartcardOptions {
|
|
std::vector<std::string> certs;
|
|
std::string dbname;
|
|
bool enable;
|
|
SmartcardOptions();
|
|
};
|
|
|
|
void smartcard_init(const SmartcardOptions* options);
|
|
|
|
struct ReaderData {
|
|
ReaderData() :
|
|
vreader(NULL),
|
|
reader_id(VSCARD_UNDEFINED_READER_ID),
|
|
name(NULL),
|
|
card_insert_pending(false)
|
|
{}
|
|
VReader *vreader;
|
|
uint32_t reader_id;
|
|
char* name;
|
|
bool card_insert_pending;
|
|
};
|
|
|
|
void virtual_card_remove();
|
|
void virtual_card_insert();
|
|
|
|
class SmartCardChannel;
|
|
|
|
class VEventEvent : public Event {
|
|
public:
|
|
VEventEvent(SmartCardChannel* smartcard_channel, VEvent* vevent);
|
|
~VEventEvent();
|
|
SmartCardChannel* _smartcard_channel;
|
|
VReader* _vreader;
|
|
VEvent* _vevent;
|
|
};
|
|
|
|
class ReaderAddEvent: public VEventEvent {
|
|
public:
|
|
ReaderAddEvent(SmartCardChannel* smartcard_channel, VEvent* vevent)
|
|
: VEventEvent(smartcard_channel, vevent) {}
|
|
virtual void response(AbstractProcessLoop& events_loop);
|
|
};
|
|
|
|
class ReaderRemoveEvent: public VEventEvent {
|
|
public:
|
|
ReaderRemoveEvent(SmartCardChannel* smartcard_channel, VEvent* vevent)
|
|
: VEventEvent(smartcard_channel, vevent) {}
|
|
virtual void response(AbstractProcessLoop& events_loop);
|
|
};
|
|
|
|
class CardInsertEvent: public VEventEvent {
|
|
public:
|
|
CardInsertEvent(SmartCardChannel* smartcard_channel, VEvent* vevent)
|
|
: VEventEvent(smartcard_channel, vevent) {}
|
|
virtual void response(AbstractProcessLoop& events_loop);
|
|
};
|
|
|
|
class CardRemoveEvent: public VEventEvent {
|
|
public:
|
|
CardRemoveEvent(SmartCardChannel* smartcard_channel, VEvent* vevent)
|
|
: VEventEvent(smartcard_channel, vevent) {}
|
|
virtual void response(AbstractProcessLoop& events_loop);
|
|
};
|
|
|
|
class VSCMessageEvent: public Event {
|
|
public:
|
|
VSCMessageEvent(SmartCardChannel* smartcard_channel,
|
|
VSCMsgHeader* vheader);
|
|
~VSCMessageEvent();
|
|
SmartCardChannel* _smartcard_channel;
|
|
VSCMsgHeader* _vheader;
|
|
virtual void response(AbstractProcessLoop& events_loop);
|
|
};
|
|
|
|
typedef std::pair<VEventType, Event*> SmartCardEvent;
|
|
|
|
class SmartCardChannel : public RedChannel {
|
|
|
|
public:
|
|
SmartCardChannel(RedClient& client, uint32_t id);
|
|
void handle_smartcard_data(RedPeer::InMessage* message);
|
|
|
|
void virtual_card_remove();
|
|
void virtual_card_insert();
|
|
static ChannelFactory& Factory();
|
|
protected:
|
|
virtual void on_connect();
|
|
virtual void on_disconnect();
|
|
|
|
private:
|
|
static void* cac_card_events_thread_entry(void* data);
|
|
void cac_card_events_thread_main();
|
|
void send_message(uint32_t reader_id, VSCMsgType type, uint8_t* data, uint32_t len);
|
|
|
|
Thread* _event_thread;
|
|
|
|
Application* _app;
|
|
|
|
VReaderList *_reader_list;
|
|
typedef std::map<uint32_t, ReaderData*> readers_by_id_t;
|
|
readers_by_id_t _readers_by_id;
|
|
typedef std::map<VReader*, ReaderData*> readers_by_vreader_t;
|
|
readers_by_vreader_t _readers_by_vreader;
|
|
readers_by_vreader_t _unallocated_readers_by_vreader;
|
|
VEventType _next_sync_vevent;
|
|
std::list<SmartCardEvent> _sync_events;
|
|
|
|
void push_sync_event(VEventType type, Event *event);
|
|
void send_next_sync_event();
|
|
void handle_reader_add_response(VSCMsgHeader *vheader, VSCMsgError *error);
|
|
void handle_error_message(VSCMsgHeader *vheader, VSCMsgError *error);
|
|
|
|
ReaderData* reader_data_from_vreader(VReader* vreader);
|
|
ReaderData* reader_data_from_reader_id(uint32_t reader_id);
|
|
void add_unallocated_reader(VReader* vreader, const char* name);
|
|
ReaderData* add_reader(uint32_t reader_id);
|
|
void remove_reader(ReaderData* data);
|
|
void send_reader_added(const char* reader_name);
|
|
void send_reader_removed(uint32_t reader_id);
|
|
void send_atr(VReader* vreader);
|
|
|
|
friend class ReaderAddEvent;
|
|
friend class ReaderRemoveEvent;
|
|
friend class CardInsertEvent;
|
|
friend class CardRemoveEvent;
|
|
friend class VSCMessageEvent;
|
|
};
|
|
|
|
#endif // __SMART_CARD_H__
|
|
|