2424
2525#include " controllerchildthread.hpp"
2626
27+ #include " utils/utils.hpp"
28+
2729class CardEventMonitorThread : public ControllerChildThread
2830{
2931 Q_OBJECT
3032
3133public:
3234 using eid_ptr = electronic_id::ElectronicID::ptr;
33- using eid_ptr_vector = std::vector<electronic_id::ElectronicID::ptr >;
35+ using eid_ptr_vector = std::vector<eid_ptr >;
3436
35- CardEventMonitorThread (QObject* parent, CommandType commandType) :
36- ControllerChildThread (commandType, parent)
37+ CardEventMonitorThread (QObject* parent, CommandType commandType, eid_ptr_vector eids,
38+ bool watchPnpNotifications = false ) :
39+ ControllerChildThread (commandType, parent), eids(std::move(eids)),
40+ monitor (makeMonitor(this ->eids, watchPnpNotifications))
3741 {
3842 }
3943
40- void run () override
44+ void cancelWait ()
4145 {
42- QMutexLocker lock {&controllerChildThreadMutex};
46+ requestInterruption ();
47+ monitor.cancel ();
48+ }
4349
50+ void run () override
51+ {
4452 qDebug () << " Starting" << metaObject ()->className () << uintptr_t (this ) << " for command"
4553 << commandType ();
4654
47- auto initialCards = getSupportedCardsIgnoringExceptions ();
48- sortByReaderNameAndAtr (initialCards);
49-
50- while (!isInterruptionRequested ()) {
51- using namespace std ::chrono_literals;
52- waitForControllerNotify.wait (&controllerChildThreadMutex, 1s);
53-
54- eid_ptr_vector updatedCards {};
55-
56- try {
57- updatedCards = electronic_id::availableSupportedCards ();
58- sortByReaderNameAndAtr (updatedCards);
59- } catch (const std::exception& error) {
60- // Ignore smart card layer errors, they will be handled during next card operation.
61- qWarning () << metaObject ()->className () << " ignoring" << commandType ()
62- << " error:" << error;
63- }
64-
65- // If interruption was requested during wait, exit without emitting.
66- if (isInterruptionRequested ()) {
67- return ;
68- }
69-
70- // If there was a change in connected supported cards, exit after emitting a card event.
71- if (!areEqualByReaderNameAndAtr (initialCards, updatedCards)) {
72- qDebug () << metaObject ()->className () << " card change detected" ;
73- emit cardEvent ();
74- return ;
75- }
55+ if (monitor.wait () && !isInterruptionRequested ()) {
56+ qDebug () << metaObject ()->className () << " card change detected" ;
57+ emit cardEvent ();
7658 }
7759 }
7860
@@ -82,42 +64,21 @@ class CardEventMonitorThread : public ControllerChildThread
8264private:
8365 void doRun () override
8466 {
85- // Unused as run() has been overriden .
67+ // Unused as run() has been overridden .
8668 }
8769
88- eid_ptr_vector getSupportedCardsIgnoringExceptions ()
70+ static pcsc_cpp::CardEventMonitor makeMonitor (const eid_ptr_vector& eids,
71+ bool watchPnpNotifications)
8972 {
90- while (!isInterruptionRequested ()) {
91- try {
92- return electronic_id::availableSupportedCards ();
93- } catch (const std::exception& error) {
94- // Ignore smart card layer errors, they will be handled during next card operation.
95- qWarning () << metaObject ()->className () << " ignoring" << commandType ()
96- << " error:" << error;
97- }
98- using namespace std ::chrono_literals;
99- waitForControllerNotify.wait (&controllerChildThreadMutex, 1s);
73+ REQUIRE_NOT_EMPTY_CONTAINS_NON_NULL_PTRS (eids)
74+ std::vector<std::reference_wrapper<const pcsc_cpp::SmartCard>> cards;
75+ cards.reserve (eids.size ());
76+ for (const auto & eid : eids) {
77+ cards.push_back (eid->smartcard ());
10078 }
101- // Interruption was requested, return empty list.
102- return {};
79+ return pcsc_cpp::CardEventMonitor (std::move (cards), watchPnpNotifications);
10380 }
10481
105- static void sortByReaderNameAndAtr (eid_ptr_vector& a)
106- {
107- std::sort (a.begin (), a.end (), [](const eid_ptr& c1, const eid_ptr& c2) {
108- if (c1->smartcard ().readerName () != c2->smartcard ().readerName ()) {
109- return c1->smartcard ().readerName () < c2->smartcard ().readerName ();
110- }
111- return c1->smartcard ().atr () < c2->smartcard ().atr ();
112- });
113- }
114-
115- static bool areEqualByReaderNameAndAtr (const eid_ptr_vector& a, const eid_ptr_vector& b)
116- {
117- return std::equal (a.cbegin (), a.cend (), b.cbegin (), b.cend (),
118- [](const eid_ptr& c1, const eid_ptr& c2) {
119- return c1->smartcard ().readerName () == c2->smartcard ().readerName ()
120- && c1->smartcard ().atr () == c2->smartcard ().atr ();
121- });
122- }
82+ eid_ptr_vector eids;
83+ pcsc_cpp::CardEventMonitor monitor;
12384};
0 commit comments