File: examplecard.c

package info (click to toggle)
libchipcard 5.1.0beta-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 4,688 kB
  • sloc: ansic: 21,052; xml: 6,746; sh: 4,177; makefile: 610; cpp: 448
file content (216 lines) | stat: -rw-r--r-- 6,079 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/***************************************************************************
    begin       : Mon Mar 01 2004
    copyright   : (C) 2004-2010 by Martin Preuss
    email       : martin@libchipcard.de

 ***************************************************************************
 *          Please see toplevel file COPYING for license details           *
 ***************************************************************************/


#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


#include "examplecard_p.h"
#include <gwenhywfar/debug.h>
#include <gwenhywfar/inherit.h>
#include <gwenhywfar/misc.h>
#include <chipcard/chipcard.h>
#include <chipcard/cards/processorcard.h>


/* This must be at the top of the file to tell GWEN that we are to inherit
 * another type in this file. Internally GWEN stores the hash value of the
 * types involved to speed up the lookup of type specific data in a base type
 * object.
 */
GWEN_INHERIT(LC_CARD, EXAMPLE_CARD)


/* This function establishes the heritage and sets its own Open() and Close()
 * functions. This function must be called before LC_Card_Open() is.
 * Also, this function must be called before using any other function of the
 * inheriting type.
 */
int ExampleCard_ExtendCard(LC_CARD *card){
  EXAMPLE_CARD *xc;
  int rv;

  rv=LC_ProcessorCard_ExtendCard(card);
  if (rv) {
    DBG_ERROR(LC_LOGDOMAIN, "Could not extend card as processor card");
    return rv;
  }

  GWEN_NEW_OBJECT(EXAMPLE_CARD, xc);

  xc->openFn=LC_Card_GetOpenFn(card);
  xc->closeFn=LC_Card_GetCloseFn(card);
  LC_Card_SetOpenFn(card, ExampleCard_Open);
  LC_Card_SetCloseFn(card, ExampleCard_Close);

  GWEN_INHERIT_SETDATA(LC_CARD, EXAMPLE_CARD, card, xc,
                       ExampleCard_freeData);
  return 0;
}



/* This function can be used to resolve the heritage established via
 * ExampleCard_ExtendCard(). After this function has been called no other
 * ExampleCard function (except ExampleCard_ExtendCard()) may be called.
 * Please note that this function resets the cards' internal Open() and
 * Close() function pointers to the values found upon execution of
 * ExampleCard_ExtendCard(), so after that the function ExampleCard_Close()
 * will no longer be called internally by LC_Card_Close().
 */
int ExampleCard_UnextendCard(LC_CARD *card){
  EXAMPLE_CARD *xc;
  int rv;

  xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
  assert(xc);
  LC_Card_SetOpenFn(card, xc->openFn);
  LC_Card_SetCloseFn(card, xc->closeFn);
  GWEN_INHERIT_UNLINK(LC_CARD, EXAMPLE_CARD, card);
  GWEN_FREE_OBJECT(xc);

  rv=LC_ProcessorCard_UnextendCard(card);
  if (rv) {
    DBG_INFO(LC_LOGDOMAIN, "here");
  }
  return rv;
}


/* This function is called internally by LC_Card_free() if the card is still
 * extended as an ExampleCard. It should free all data associated with the
 * LC_CARD object concerning ExampleCard data.
 * bp is a pointer to the lowest base type (in this case LC_CARD) and p is
 * a pointer to the derived type (in this case EXAMPLE_CARD). You need to cast
 * these pointers to their real types respectively.
 */
void GWENHYWFAR_CB ExampleCard_freeData(void *bp, void *p){
  EXAMPLE_CARD *xc;

  assert(bp);
  assert(p);
  xc=(EXAMPLE_CARD*)p;
  GWEN_FREE_OBJECT(xc);
}


/* This function is called internally by LC_Card_Open(). It is always a good
 * idea to call the Open() function found upon ExampleCard_ExtendCard(),
 * first. After that you can do whatever your card needs to be done.
 * Well, in the case of this example here we simply select the MasterFile
 * (otherwise called "root" in disk file systems).
 * Also, it is best to split the card specific stuff off into an extra
 * function called _Reopen() (in this case ExampleCard_Reopen), so that it
 * may later be used again, because the function LC_Card_Open() also does
 * the connection work and must therefore only be called *once*.
 */
LC_CLIENT_RESULT CHIPCARD_CB ExampleCard_Open(LC_CARD *card){
  LC_CLIENT_RESULT res;
  EXAMPLE_CARD *xc;

  DBG_DEBUG(LC_LOGDOMAIN, "Opening card as ExampleCard");

  assert(card);
  xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
  assert(xc);

  res=xc->openFn(card);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  res=ExampleCard_Reopen(card);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    xc->closeFn(card);
    return res;
  }

  return LC_Client_ResultOk;
}


/* As discussed above this is the card specific setup. */
LC_CLIENT_RESULT ExampleCard_Reopen(LC_CARD *card){
  LC_CLIENT_RESULT res;
  EXAMPLE_CARD *xc;

  DBG_DEBUG(LC_LOGDOMAIN, "Opening ExampleCard");

  assert(card);
  xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
  assert(xc);

  DBG_DEBUG(LC_LOGDOMAIN, "Selecting Example card application");
  res=LC_Card_SelectApp(card, "ExampleCard");
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  DBG_DEBUG(LC_LOGDOMAIN, "Selecting MF...");
  res=LC_Card_SelectMf(card);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  return LC_Client_ResultOk;
}


/* This function is called internally upon LC_Card_Close().
 * It *must* call the function found upon ExampleCard_ExtendCard() otherwise
 * the card is not released !
 * Additionally, you can do your own deinit stuff here before actually
 * releasing the card.
 */
LC_CLIENT_RESULT CHIPCARD_CB ExampleCard_Close(LC_CARD *card){
  LC_CLIENT_RESULT res;
  EXAMPLE_CARD *xc;

  assert(card);
  xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
  assert(xc);

  res=xc->closeFn(card);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  return res;
}


/* This is just an example of how to access data stored in the card type
 * extension
 */
int ExampleCard_GetExampleData(const LC_CARD *card){
  EXAMPLE_CARD *xc;

  assert(card);
  xc=GWEN_INHERIT_GETDATA(LC_CARD, EXAMPLE_CARD, card);
  assert(xc);

  return xc->exampleData;
}



int test_type(TYPE_VISIBLE *v) {
  return test_type(v);
  return ((EXAMPLE_CARD*)v)->exampleData;
}