updated win32 support for MINGW32-compiler/cross-compiler
[librfid] / win32 / openpcd.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <windows.h>
7
8 #include <librfid/rfid.h>
9 #include <librfid/rfid_scan.h>
10 #include <librfid/rfid_reader.h>
11 #include <librfid/rfid_protocol.h>
12 #include <librfid/rfid_protocol_mifare_classic.h>
13
14 #define BUILD_DLL
15 #include "openpcd.h"
16
17 #define LIBMIFARE_MAGIC 0xDEADBEEF
18
19 struct openpcd_state
20 {
21     unsigned int magic;    
22     unsigned int cl_auth;
23     struct rfid_reader_handle *rh;
24     struct rfid_layer2_handle *l2h;
25     struct rfid_protocol_handle *ph;
26     unsigned char key[MIFARE_CL_KEY_LEN];
27     unsigned int uid;
28 } openpcd_state;
29
30 int openpcd_cl_auth(struct openpcd_state* state ,int page)
31 {
32     int rc;
33
34     if(!state || page<=0 || page>MIFARE_CL_PAGE_MAX )
35         return PCDERROR_INVALID_PARAMETER;
36         
37     if(!state->ph)
38         return PCDERROR_CLOSED;
39
40     rc = mfcl_set_key(state->ph, state->key);
41     if (rc < 0)
42         return PCDERROR_KEY_FORMAT;
43         
44     rc = mfcl_auth(state->ph, state->cl_auth, page);
45
46     return rc<0 ? PCDERROR_KEY_AUTH : PCDERROR_NONE;
47 }
48
49 EXPORT int EXPORT_CONVENTION openpcd_set_key(MIFARE_HANDLE handle,unsigned int key_id,const void* key)
50 {
51     struct openpcd_state *state;
52
53     if(!handle)
54         return PCDERROR_INVALID_PARAMETER;
55     state=(struct openpcd_state*)handle;
56     
57     switch(key_id)
58     {
59         case PCDAUTH_KEYID_1A:
60             state->cl_auth=RFID_CMD_MIFARE_AUTH1A;
61             break;
62         case PCDAUTH_KEYID_1B:
63             state->cl_auth=RFID_CMD_MIFARE_AUTH1B;
64             break;
65         default:
66             return PCDERROR_INVALID_PARAMETER;
67     }
68     
69     memcpy(state->key,key,MIFARE_CL_KEY_LEN);
70     
71     return PCDERROR_NONE;
72 }
73
74 EXPORT int EXPORT_CONVENTION openpcd_select_card(MIFARE_HANDLE handle)
75 {
76     int res;
77     struct openpcd_state *state;
78         
79     if(!handle)
80         return PCDERROR_INVALID_PARAMETER;
81     state=(struct openpcd_state*)handle;
82     
83     state->l2h = rfid_layer2_init(state->rh,RFID_LAYER2_ISO14443A);
84     if(!state->l2h)
85         res=PCDERROR_LAYER2_INIT;
86     else
87     {        
88         if( rfid_layer2_open(state->l2h)>=0 ) 
89         {
90             state->ph = rfid_protocol_init(state->l2h,RFID_PROTOCOL_MIFARE_CLASSIC);
91         
92             if(state->ph)
93             {
94                 if(rfid_protocol_open(state->ph)>=0)
95                     return PCDERROR_NONE;
96                 
97                 rfid_protocol_fini(state->ph);
98                 state->ph=NULL;
99         
100                 res=PCDERROR_LAYER3_OPEN;
101             }
102             else
103                 res=PCDERROR_LAYER3_INIT;
104
105             rfid_layer2_close(state->l2h);      
106         }
107         else
108             res=PCDERROR_LAYER2_OPEN;
109     }
110     
111     rfid_layer2_fini(state->l2h);
112     state->l2h=NULL;
113     
114     return res; 
115 }
116
117 EXPORT int EXPORT_CONVENTION openpcd_deselect_card(MIFARE_HANDLE handle)
118 {
119     struct openpcd_state *state;
120         
121     if(!handle)
122         return PCDERROR_INVALID_PARAMETER;
123     state=(struct openpcd_state*)handle;
124     
125     if(state->ph)
126     {
127         rfid_protocol_close(state->ph);
128         rfid_protocol_fini(state->ph);
129         rfid_layer2_close(state->l2h);
130         rfid_layer2_fini(state->l2h);
131
132         state->ph=NULL;
133         state->l2h=NULL;
134         state->uid=0;
135         
136         return PCDERROR_NONE;
137     }    
138     else
139         return PCDERROR_CLOSED;
140 }
141
142 EXPORT int EXPORT_CONVENTION openpcd_get_card_id(MIFARE_HANDLE handle,unsigned int *uid)
143 {
144     unsigned int uid_len;
145     struct openpcd_state *state;
146         
147     if(!handle || !uid)
148         return PCDERROR_INVALID_PARAMETER;
149     state=(struct openpcd_state*)handle;
150     
151     if(state->ph)
152     {
153         uid_len=sizeof(*uid);
154         if(rfid_layer2_getopt(state->l2h,RFID_OPT_LAYER2_UID,uid,&uid_len))
155             return PCDERROR_INVALID_PARAMETER;
156         else
157             return uid_len==4 ? PCDERROR_NONE:PCDERROR_READ_FAILED;
158     }
159     else
160         return PCDERROR_CLOSED;    
161 }
162
163 EXPORT int EXPORT_CONVENTION openpcd_open_reader(MIFARE_HANDLE *handle)
164 {
165     struct rfid_reader_handle *rh;
166     struct openpcd_state *state;
167     
168     if(!handle)
169         return PCDERROR_INVALID_PARAMETER;
170         
171     rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
172     if(!rh)
173         return PCDERROR_NO_READER;
174     
175     state=(struct openpcd_state*)malloc(sizeof(*state));
176     if(state)
177     {
178         memset(state,0,sizeof(*state));
179         state->magic=LIBMIFARE_MAGIC;
180         state->rh=rh;
181         state->cl_auth=RFID_CMD_MIFARE_AUTH1A;
182         memset(state->key,0xFF,sizeof(state->key));
183         
184         // do initial reset
185         openpcd_reset_reader((MIFARE_HANDLE)state);
186         Sleep(1500);
187         // reopen
188         state->rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
189         
190         *handle=(MIFARE_HANDLE)state;
191         
192         return PCDERROR_NONE;
193     }
194     else
195     {   
196         rfid_reader_close(rh);
197         return PCDERROR_OUT_OF_MEMORY;
198     }
199 }
200
201 EXPORT int EXPORT_CONVENTION openpcd_close_reader(MIFARE_HANDLE handle)
202 {
203     struct openpcd_state *state;
204     
205     if(!handle)
206         return PCDERROR_INVALID_PARAMETER;
207     state=(struct openpcd_state*)handle;
208
209     openpcd_deselect_card(handle);
210
211     openpcd_reset_reader(handle);
212     Sleep(500);
213
214     state->magic=0;
215     rfid_reader_close(state->rh);
216     free(state);    
217     
218     return PCDERROR_NONE;
219 }
220
221 EXPORT int EXPORT_CONVENTION openpcd_read(MIFARE_HANDLE handle,int page, void* data, int len)
222 {
223     int res;
224     unsigned int count;
225     unsigned char buf[MIFARE_CL_PAGE_SIZE];
226     struct openpcd_state *state;        
227     
228     if( !handle || !buf || page<0 || page>MIFARE_CL_PAGE_MAX || len<=0 || len>sizeof(buf))
229         return PCDERROR_INVALID_PARAMETER;
230         
231     state=(struct openpcd_state*)handle;
232     if ( (res=openpcd_cl_auth(state,page)) < 0)
233         return res;
234         
235     count = sizeof(buf);
236     res = rfid_protocol_read(state->ph, page, buf, &count);    
237     if(res>=0)
238         memcpy(data,buf,len);
239
240     if ( res<0 )
241         return PCDERROR_READ_FAILED;
242     else
243         return count;
244 }
245
246 EXPORT int EXPORT_CONVENTION openpcd_write(MIFARE_HANDLE handle,int page,const void *data,int len)
247 {
248     int res;
249     unsigned char buf[16];
250     struct openpcd_state *state;
251
252     if( !handle || !buf || page<0 || page>MIFARE_CL_PAGE_MAX || len<=0 || len>sizeof(buf))
253         return PCDERROR_INVALID_PARAMETER;
254         
255     state=(struct openpcd_state*)handle;
256     if ( (res=openpcd_cl_auth(state,page)) < 0)
257         return res;
258
259     memcpy(buf,data,len);
260     memset(&buf[len],0,sizeof(buf)-len);
261     
262     res = rfid_protocol_write(state->ph, page, buf, sizeof(buf));
263     
264     return (res<0 && res!=-101) ? PCDERROR_WRITE_FAILED : len;
265 }
266
267 EXPORT int EXPORT_CONVENTION openpcd_get_api_version(MIFARE_HANDLE handle, unsigned int *version)
268 {
269     unsigned char b;
270     struct openpcd_state *state;
271
272     if( !handle || !version )
273         return PCDERROR_INVALID_PARAMETER;
274     state=(struct openpcd_state*)handle;
275     
276     b=0;
277         
278     if(state->rh->reader->get_api_version(state->rh,&b)<0)
279         return PCDERROR_READER_VERSION;
280     else
281     {
282         *version=b;
283         return PCDERROR_NONE;
284     }
285 }
286
287 EXPORT int EXPORT_CONVENTION openpcd_reset_reader(MIFARE_HANDLE handle)
288 {
289     struct openpcd_state *state;
290
291     if( !handle )
292         return PCDERROR_INVALID_PARAMETER;
293     state=(struct openpcd_state*)handle;
294         
295     return (state->rh->reader->reset(state->rh)<0) ? PCDERROR_WRITE_FAILED : PCDERROR_NONE;
296 }
297
298 EXPORT int EXPORT_CONVENTION openpcd_get_environment(
299     MIFARE_HANDLE handle,
300     unsigned char count,
301     unsigned char* data
302     )
303 {
304     struct openpcd_state *state;
305
306     if( !handle )
307         return PCDERROR_INVALID_PARAMETER;
308     state=(struct openpcd_state*)handle;
309         
310     return (state->rh->reader->get_environment(state->rh,count,data)<0) ? PCDERROR_READ_FAILED : PCDERROR_NONE;
311 }
312
313 EXPORT int EXPORT_CONVENTION openpcd_set_environment(
314     MIFARE_HANDLE handle,
315     unsigned char count,
316     const unsigned char* data)
317 {
318     struct openpcd_state *state;
319
320     if( !handle )
321         return PCDERROR_INVALID_PARAMETER;
322     state=(struct openpcd_state*)handle;
323         
324     return (state->rh->reader->set_environment(state->rh,count,data)<0) ? PCDERROR_WRITE_FAILED : PCDERROR_NONE;
325 }
326
327 EXPORT char* EXPORT_CONVENTION openpcd_get_error_text(int error)
328 {
329     const static char* msg[]={
330         "PCDERROR_NONE",                //  0
331         "PCDERROR_INVALID_PARAMETER",   // -1
332         "PCDERROR_KEY_FORMAT",          // -2
333         "PCDERROR_KEY_AUTH",            // -3
334         "PCDERROR_NO_CARD_FOUND",       // -4
335         "PCDERROR_LAYER2_INIT",         // -5
336         "PCDERROR_LAYER2_OPEN",         // -6
337         "PCDERROR_LAYER3_INIT",         // -7
338         "PCDERROR_LAYER3_OPEN",         // -8
339         "PCDERROR_SELECT",              // -9
340         "PCDERROR_READ_FAILED",         // -10
341         "PCDERROR_WRITE_FAILED",        // -11
342         "PCDERROR_CLOSED",              // -12
343         "PCDERROR_NO_READER",           // -13
344         "PCDERROR_OUT_OF_MEMORY",       // -14
345         "PCDERROR_READER_VERSION"       // -15
346     };
347     const int count=sizeof(msg)/sizeof(msg[0]);
348     
349     if(error>0)
350         error=0;
351     else
352         error=-error;
353                 
354     return (error>=count) ? "PCDERROR_UNKNOWN" : (char*)msg[error];
355 }