1 /***************************************************************************
2 begin : Mon Mar 01 2004
3 copyright : (C) 2004-2010 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14
15
16 #include "examplecard_p.h"
17 #include <gwenhywfar/debug.h>
18 #include <gwenhywfar/inherit.h>
19 #include <gwenhywfar/misc.h>
20 #include <chipcard/chipcard.h>
21 #include <chipcard/cards/processorcard.h>
22
23
24 /* This must be at the top of the file to tell GWEN that we are to inherit
25 * another type in this file. Internally GWEN stores the hash value of the
26 * types involved to speed up the lookup of type specific data in a base type
27 * object.
28 */
GWEN_INHERIT(LC_CARD,EXAMPLE_CARD)29 GWEN_INHERIT(LC_CARD, EXAMPLE_CARD)
30
31
32 /* This function establishes the heritage and sets its own Open() and Close()
33 * functions. This function must be called before LC_Card_Open() is.
34 * Also, this function must be called before using any other function of the
35 * inheriting type.
36 */
37 int ExampleCard_ExtendCard(LC_CARD *card){
38 EXAMPLE_CARD *xc;
39 int rv;
40
41 rv=LC_ProcessorCard_ExtendCard(card);
42 if (rv) {
43 DBG_ERROR(LC_LOGDOMAIN, "Could not extend card as processor card");
44 return rv;
45 }
46
47 GWEN_NEW_OBJECT(EXAMPLE_CARD, xc);
48
49 xc->openFn=LC_Card_GetOpenFn(card);
50 xc->closeFn=LC_Card_GetCloseFn(card);
51 LC_Card_SetOpenFn(card, ExampleCard_Open);
52 LC_Card_SetCloseFn(card, ExampleCard_Close);
53
54 GWEN_INHERIT_SETDATA(LC_CARD, EXAMPLE_CARD, card, xc,
55 ExampleCard_freeData);
56 return 0;
57 }
58
59
60
61 /* This function can be used to resolve the heritage established via
62 * ExampleCard_ExtendCard(). After this function has been called no other
63 * ExampleCard function (except ExampleCard_ExtendCard()) may be called.
64 * Please note that this function resets the cards' internal Open() and
65 * Close() function pointers to the values found upon execution of
66 * ExampleCard_ExtendCard(), so after that the function ExampleCard_Close()
67 * will no longer be called internally by LC_Card_Close().
68 */
ExampleCard_UnextendCard(LC_CARD * card)69 int ExampleCard_UnextendCard(LC_CARD *card){
70 EXAMPLE_CARD *xc;
71 int rv;
72
73 xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
74 assert(xc);
75 LC_Card_SetOpenFn(card, xc->openFn);
76 LC_Card_SetCloseFn(card, xc->closeFn);
77 GWEN_INHERIT_UNLINK(LC_CARD, EXAMPLE_CARD, card);
78 GWEN_FREE_OBJECT(xc);
79
80 rv=LC_ProcessorCard_UnextendCard(card);
81 if (rv) {
82 DBG_INFO(LC_LOGDOMAIN, "here");
83 }
84 return rv;
85 }
86
87
88 /* This function is called internally by LC_Card_free() if the card is still
89 * extended as an ExampleCard. It should free all data associated with the
90 * LC_CARD object concerning ExampleCard data.
91 * bp is a pointer to the lowest base type (in this case LC_CARD) and p is
92 * a pointer to the derived type (in this case EXAMPLE_CARD). You need to cast
93 * these pointers to their real types respectively.
94 */
ExampleCard_freeData(void * bp,void * p)95 void GWENHYWFAR_CB ExampleCard_freeData(void *bp, void *p){
96 EXAMPLE_CARD *xc;
97
98 assert(bp);
99 assert(p);
100 xc=(EXAMPLE_CARD*)p;
101 GWEN_FREE_OBJECT(xc);
102 }
103
104
105 /* This function is called internally by LC_Card_Open(). It is always a good
106 * idea to call the Open() function found upon ExampleCard_ExtendCard(),
107 * first. After that you can do whatever your card needs to be done.
108 * Well, in the case of this example here we simply select the MasterFile
109 * (otherwise called "root" in disk file systems).
110 * Also, it is best to split the card specific stuff off into an extra
111 * function called _Reopen() (in this case ExampleCard_Reopen), so that it
112 * may later be used again, because the function LC_Card_Open() also does
113 * the connection work and must therefore only be called *once*.
114 */
ExampleCard_Open(LC_CARD * card)115 LC_CLIENT_RESULT CHIPCARD_CB ExampleCard_Open(LC_CARD *card){
116 LC_CLIENT_RESULT res;
117 EXAMPLE_CARD *xc;
118
119 DBG_DEBUG(LC_LOGDOMAIN, "Opening card as ExampleCard");
120
121 assert(card);
122 xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
123 assert(xc);
124
125 res=xc->openFn(card);
126 if (res!=LC_Client_ResultOk) {
127 DBG_INFO(LC_LOGDOMAIN, "here");
128 return res;
129 }
130
131 res=ExampleCard_Reopen(card);
132 if (res!=LC_Client_ResultOk) {
133 DBG_INFO(LC_LOGDOMAIN, "here");
134 xc->closeFn(card);
135 return res;
136 }
137
138 return LC_Client_ResultOk;
139 }
140
141
142 /* As discussed above this is the card specific setup. */
ExampleCard_Reopen(LC_CARD * card)143 LC_CLIENT_RESULT ExampleCard_Reopen(LC_CARD *card){
144 LC_CLIENT_RESULT res;
145 EXAMPLE_CARD *xc;
146
147 DBG_DEBUG(LC_LOGDOMAIN, "Opening ExampleCard");
148
149 assert(card);
150 xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
151 assert(xc);
152
153 DBG_DEBUG(LC_LOGDOMAIN, "Selecting Example card application");
154 res=LC_Card_SelectApp(card, "ExampleCard");
155 if (res!=LC_Client_ResultOk) {
156 DBG_INFO(LC_LOGDOMAIN, "here");
157 return res;
158 }
159
160 DBG_DEBUG(LC_LOGDOMAIN, "Selecting MF...");
161 res=LC_Card_SelectMf(card);
162 if (res!=LC_Client_ResultOk) {
163 DBG_INFO(LC_LOGDOMAIN, "here");
164 return res;
165 }
166
167 return LC_Client_ResultOk;
168 }
169
170
171 /* This function is called internally upon LC_Card_Close().
172 * It *must* call the function found upon ExampleCard_ExtendCard() otherwise
173 * the card is not released !
174 * Additionally, you can do your own deinit stuff here before actually
175 * releasing the card.
176 */
ExampleCard_Close(LC_CARD * card)177 LC_CLIENT_RESULT CHIPCARD_CB ExampleCard_Close(LC_CARD *card){
178 LC_CLIENT_RESULT res;
179 EXAMPLE_CARD *xc;
180
181 assert(card);
182 xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
183 assert(xc);
184
185 res=xc->closeFn(card);
186 if (res!=LC_Client_ResultOk) {
187 DBG_INFO(LC_LOGDOMAIN, "here");
188 return res;
189 }
190
191 return res;
192 }
193
194
195 /* This is just an example of how to access data stored in the card type
196 * extension
197 */
ExampleCard_GetExampleData(const LC_CARD * card)198 int ExampleCard_GetExampleData(const LC_CARD *card){
199 EXAMPLE_CARD *xc;
200
201 assert(card);
202 xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
203 assert(xc);
204
205 return xc->exampleData;
206 }
207
208
209
test_type(TYPE_VISIBLE * v)210 int test_type(TYPE_VISIBLE *v) {
211 return test_type(v);
212 return ((EXAMPLE_CARD*)v)->exampleData;
213 }
214
215
216
217