]> git.saurik.com Git - apple/securityd.git/blob - src/reader.cpp
10dd3940ab52cb94cb1c2893cfc4944570f1a24c
[apple/securityd.git] / src / reader.cpp
1 /*
2 * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26
27 //
28 // reader - token reader objects
29 //
30 #include "reader.h"
31
32
33 Reader::Reader(const PCSC::ReaderState &state)
34 : mToken(NULL)
35 {
36 mName = state.name();
37 secdebug("reader", "%p (%s) new reader", this, name().c_str());
38 transit(state);
39 }
40
41
42 Reader::~Reader()
43 {
44 secdebug("reader", "%p (%s) destroyed", this, name().c_str());
45 }
46
47
48 void Reader::kill()
49 {
50 if (mToken)
51 removeToken();
52 NodeCore::kill();
53 }
54
55
56 void Reader::update(const PCSC::ReaderState &state)
57 {
58 transit(state);
59 }
60
61
62 //
63 // State transition matrix for a reader, based on PCSC state changes
64 //
65 void Reader::transit(const PCSC::ReaderState &state)
66 {
67 if (state.state(SCARD_STATE_UNAVAILABLE)) {
68 // reader is unusable (probably being removed)
69 secdebug("reader", "%p (%s) unavailable (0x%lx)",
70 this, name().c_str(), state.state());
71 if (mToken)
72 removeToken();
73 } else if (state.state(SCARD_STATE_EMPTY)) {
74 // reader is empty (no token present)
75 secdebug("reader", "%p (%s) empty (0x%lx)",
76 this, name().c_str(), state.state());
77 if (mToken)
78 removeToken();
79 } else if (state.state(SCARD_STATE_PRESENT)) {
80 // reader has a token inserted
81 secdebug("reader", "%p (%s) card present (0x%lx)",
82 this, name().c_str(), state.state());
83 //@@@ is this hack worth it (with notifications in)??
84 if (mToken && CssmData(state) != CssmData(pcscState()))
85 removeToken(); // incomplete but better than nothing
86 //@@@ or should we call some verify-still-the-same function of tokend?
87 if (!mToken)
88 insertToken();
89 } else {
90 secdebug("reader", "%p (%s) unexpected state change (0x%ld to 0x%lx)",
91 this, name().c_str(), mState.state(), state.state());
92 }
93 mState = state;
94 }
95
96
97 void Reader::insertToken()
98 {
99 RefPointer<Token> token = new Token();
100 token->insert(*this);
101 mToken = token;
102 addReference(*token);
103 secdebug("reader", "%p (%s) inserted token %p",
104 this, name().c_str(), mToken);
105 }
106
107
108 void Reader::removeToken()
109 {
110 secdebug("reader", "%p (%s) removing token %p",
111 this, name().c_str(), mToken);
112 assert(mToken);
113 mToken->remove();
114 removeReference(*mToken);
115 mToken = NULL;
116 }
117
118
119 //
120 // Debug dump support
121 //
122 #if defined(DEBUGDUMP)
123
124 void Reader::dumpNode()
125 {
126 PerGlobal::dumpNode();
127 Debug::dump(" [%s] state=0x%lx", name().c_str(), mState.state());
128 }
129
130 #endif //DEBUGDUMP