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