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>
17 #define LIBMIFARE_MAGIC 0xDEADBEEF
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];
30 int openpcd_cl_auth(struct openpcd_state* state ,int page)
34 if(!state || page<=0 || page>MIFARE_CL_PAGE_MAX )
35 return PCDERROR_INVALID_PARAMETER;
38 return PCDERROR_CLOSED;
40 rc = mfcl_set_key(state->ph, state->key);
42 return PCDERROR_KEY_FORMAT;
44 rc = mfcl_auth(state->ph, state->cl_auth, page);
46 return rc<0 ? PCDERROR_KEY_AUTH : PCDERROR_NONE;
49 EXPORT int EXPORT_CONVENTION openpcd_set_key(MIFARE_HANDLE handle,unsigned int key_id,const void* key)
51 struct openpcd_state *state;
54 return PCDERROR_INVALID_PARAMETER;
55 state=(struct openpcd_state*)handle;
59 case PCDAUTH_KEYID_1A:
60 state->cl_auth=RFID_CMD_MIFARE_AUTH1A;
62 case PCDAUTH_KEYID_1B:
63 state->cl_auth=RFID_CMD_MIFARE_AUTH1B;
66 return PCDERROR_INVALID_PARAMETER;
69 memcpy(state->key,key,MIFARE_CL_KEY_LEN);
74 EXPORT int EXPORT_CONVENTION openpcd_select_card(MIFARE_HANDLE handle)
77 struct openpcd_state *state;
80 return PCDERROR_INVALID_PARAMETER;
81 state=(struct openpcd_state*)handle;
83 state->l2h = rfid_layer2_init(state->rh,RFID_LAYER2_ISO14443A);
85 res=PCDERROR_LAYER2_INIT;
88 if( rfid_layer2_open(state->l2h)>=0 )
90 state->ph = rfid_protocol_init(state->l2h,RFID_PROTOCOL_MIFARE_CLASSIC);
94 if(rfid_protocol_open(state->ph)>=0)
97 rfid_protocol_fini(state->ph);
100 res=PCDERROR_LAYER3_OPEN;
103 res=PCDERROR_LAYER3_INIT;
105 rfid_layer2_close(state->l2h);
108 res=PCDERROR_LAYER2_OPEN;
111 rfid_layer2_fini(state->l2h);
117 EXPORT int EXPORT_CONVENTION openpcd_deselect_card(MIFARE_HANDLE handle)
119 struct openpcd_state *state;
122 return PCDERROR_INVALID_PARAMETER;
123 state=(struct openpcd_state*)handle;
127 rfid_protocol_close(state->ph);
128 rfid_protocol_fini(state->ph);
129 rfid_layer2_close(state->l2h);
130 rfid_layer2_fini(state->l2h);
136 return PCDERROR_NONE;
139 return PCDERROR_CLOSED;
142 EXPORT int EXPORT_CONVENTION openpcd_get_card_id(MIFARE_HANDLE handle,unsigned int *uid)
144 unsigned int uid_len;
145 struct openpcd_state *state;
148 return PCDERROR_INVALID_PARAMETER;
149 state=(struct openpcd_state*)handle;
153 uid_len=sizeof(*uid);
154 if(rfid_layer2_getopt(state->l2h,RFID_OPT_LAYER2_UID,uid,&uid_len))
155 return PCDERROR_INVALID_PARAMETER;
157 return uid_len==4 ? PCDERROR_NONE:PCDERROR_READ_FAILED;
160 return PCDERROR_CLOSED;
163 EXPORT int EXPORT_CONVENTION openpcd_open_reader(MIFARE_HANDLE *handle)
165 struct rfid_reader_handle *rh;
166 struct openpcd_state *state;
169 return PCDERROR_INVALID_PARAMETER;
171 rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
173 return PCDERROR_NO_READER;
175 state=(struct openpcd_state*)malloc(sizeof(*state));
178 memset(state,0,sizeof(*state));
179 state->magic=LIBMIFARE_MAGIC;
181 state->cl_auth=RFID_CMD_MIFARE_AUTH1A;
182 memset(state->key,0xFF,sizeof(state->key));
185 openpcd_reset_reader((MIFARE_HANDLE)state);
188 state->rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
190 *handle=(MIFARE_HANDLE)state;
192 return PCDERROR_NONE;
196 rfid_reader_close(rh);
197 return PCDERROR_OUT_OF_MEMORY;
201 EXPORT int EXPORT_CONVENTION openpcd_close_reader(MIFARE_HANDLE handle)
203 struct openpcd_state *state;
206 return PCDERROR_INVALID_PARAMETER;
207 state=(struct openpcd_state*)handle;
209 openpcd_deselect_card(handle);
211 openpcd_reset_reader(handle);
215 rfid_reader_close(state->rh);
218 return PCDERROR_NONE;
221 EXPORT int EXPORT_CONVENTION openpcd_read(MIFARE_HANDLE handle,int page, void* data, int len)
225 unsigned char buf[MIFARE_CL_PAGE_SIZE];
226 struct openpcd_state *state;
228 if( !handle || !buf || page<0 || page>MIFARE_CL_PAGE_MAX || len<=0 || len>sizeof(buf))
229 return PCDERROR_INVALID_PARAMETER;
231 state=(struct openpcd_state*)handle;
232 if ( (res=openpcd_cl_auth(state,page)) < 0)
236 res = rfid_protocol_read(state->ph, page, buf, &count);
238 memcpy(data,buf,len);
241 return PCDERROR_READ_FAILED;
246 EXPORT int EXPORT_CONVENTION openpcd_write(MIFARE_HANDLE handle,int page,const void *data,int len)
249 unsigned char buf[16];
250 struct openpcd_state *state;
252 if( !handle || !buf || page<0 || page>MIFARE_CL_PAGE_MAX || len<=0 || len>sizeof(buf))
253 return PCDERROR_INVALID_PARAMETER;
255 state=(struct openpcd_state*)handle;
256 if ( (res=openpcd_cl_auth(state,page)) < 0)
259 memcpy(buf,data,len);
260 memset(&buf[len],0,sizeof(buf)-len);
262 res = rfid_protocol_write(state->ph, page, buf, sizeof(buf));
264 return (res<0 && res!=-101) ? PCDERROR_WRITE_FAILED : len;
267 EXPORT int EXPORT_CONVENTION openpcd_get_api_version(MIFARE_HANDLE handle, unsigned int *version)
270 struct openpcd_state *state;
272 if( !handle || !version )
273 return PCDERROR_INVALID_PARAMETER;
274 state=(struct openpcd_state*)handle;
278 if(state->rh->reader->get_api_version(state->rh,&b)<0)
279 return PCDERROR_READER_VERSION;
283 return PCDERROR_NONE;
287 EXPORT int EXPORT_CONVENTION openpcd_reset_reader(MIFARE_HANDLE handle)
289 struct openpcd_state *state;
292 return PCDERROR_INVALID_PARAMETER;
293 state=(struct openpcd_state*)handle;
295 return (state->rh->reader->reset(state->rh)<0) ? PCDERROR_WRITE_FAILED : PCDERROR_NONE;
298 EXPORT int EXPORT_CONVENTION openpcd_get_environment(
299 MIFARE_HANDLE handle,
304 struct openpcd_state *state;
307 return PCDERROR_INVALID_PARAMETER;
308 state=(struct openpcd_state*)handle;
310 return (state->rh->reader->get_environment(state->rh,count,data)<0) ? PCDERROR_READ_FAILED : PCDERROR_NONE;
313 EXPORT int EXPORT_CONVENTION openpcd_set_environment(
314 MIFARE_HANDLE handle,
316 const unsigned char* data)
318 struct openpcd_state *state;
321 return PCDERROR_INVALID_PARAMETER;
322 state=(struct openpcd_state*)handle;
324 return (state->rh->reader->set_environment(state->rh,count,data)<0) ? PCDERROR_WRITE_FAILED : PCDERROR_NONE;
327 EXPORT char* EXPORT_CONVENTION openpcd_get_error_text(int error)
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
347 const int count=sizeof(msg)/sizeof(msg[0]);
354 return (error>=count) ? "PCDERROR_UNKNOWN" : (char*)msg[error];