LibDriver MIFARE_CLASSIC
Loading...
Searching...
No Matches
driver_mifare_classic.c
Go to the documentation of this file.
1
36
38
42#define CHIP_NAME "NXP MIFARE Classic EV1"
43#define MANUFACTURER_NAME "NXP"
44#define SUPPLY_VOLTAGE_MIN 3.3f
45#define SUPPLY_VOLTAGE_MAX 4.0f
46#define MAX_CURRENT 30.0f
47#define TEMPERATURE_MIN -25.0f
48#define TEMPERATURE_MAX 70.0f
49#define DRIVER_VERSION 1000
50
54#define MIFARE_CLASSIC_COMMAND_REQUEST 0x26
55#define MIFARE_CLASSIC_COMMAND_WAKE_UP 0x52
56#define MIFARE_CLASSIC_COMMAND_ANTICOLLISION_CL1 0x9320U
57#define MIFARE_CLASSIC_COMMAND_SELECT_CL1 0x9370U
58#define MIFARE_CLASSIC_COMMAND_ANTICOLLISION_CL2 0x9520U
59#define MIFARE_CLASSIC_COMMAND_SELECT_CL2 0x9570U
60#define MIFARE_CLASSIC_COMMAND_HALT 0x5000U
61#define MIFARE_CLASSIC_COMMAND_AUTHENTICATION_WITH_KEY_A 0x60
62#define MIFARE_CLASSIC_COMMAND_AUTHENTICATION_WITH_KEY_B 0x61
63#define MIFARE_CLASSIC_COMMAND_PERSONALIZE_UID_USAGE 0x40
64#define MIFARE_CLASSIC_COMMAND_SET_MOD_TYPE 0x43
65#define MIFARE_CLASSIC_COMMAND_MIFARE_READ 0x30
66#define MIFARE_CLASSIC_COMMAND_MIFARE_WRITE 0xA0
67#define MIFARE_CLASSIC_COMMAND_MIFARE_DECREMENT 0xC0
68#define MIFARE_CLASSIC_COMMAND_MIFARE_INCREMENT 0xC1
69#define MIFARE_CLASSIC_COMMAND_MIFARE_RESTORE 0xC2
70#define MIFARE_CLASSIC_COMMAND_MIFARE_TRANSFER 0xB0
71
78static void a_mifare_classic_iso14443a_crc(uint8_t *p, uint8_t len, uint8_t output[2])
79{
80 uint32_t w_crc = 0x6363;
81
82 do
83 {
84 uint8_t bt;
85
86 bt = *p++; /* get one byte */
87 bt = (bt ^ (uint8_t)(w_crc & 0x00FF)); /* xor */
88 bt = (bt ^ (bt << 4)); /* xor */
89 w_crc = (w_crc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4); /* get the crc */
90 } while (--len); /* len-- */
91
92 output[0] = (uint8_t)(w_crc & 0xFF); /* lsb */
93 output[1] = (uint8_t)((w_crc >> 8) & 0xFF); /* msb */
94}
95
107{
108 uint8_t res;
109
110 if (handle == NULL) /* check handle */
111 {
112 return 2; /* return error */
113 }
114 if (handle->debug_print == NULL) /* check debug_print */
115 {
116 return 3; /* return error */
117 }
118 if (handle->contactless_init == NULL) /* check contactless_init */
119 {
120 handle->debug_print("mifare_classic: contactless_init is null.\n"); /* contactless_init is null */
121
122 return 3; /* return error */
123 }
124 if (handle->contactless_deinit == NULL) /* check contactless_deinit */
125 {
126 handle->debug_print("mifare_classic: contactless_deinit is null.\n"); /* contactless_deinit is null */
127
128 return 3; /* return error */
129 }
130 if (handle->contactless_transceiver == NULL) /* check contactless_transceiver */
131 {
132 handle->debug_print("mifare_classic: contactless_transceiver is null.\n"); /* contactless_transceiver is null */
133
134 return 3; /* return error */
135 }
136 if (handle->delay_ms == NULL) /* check delay_ms */
137 {
138 handle->debug_print("mifare_classic: delay_ms is null.\n"); /* delay_ms is null */
139
140 return 3; /* return error */
141 }
142
143 res = handle->contactless_init(); /* contactless init */
144 if (res != 0) /* check the result */
145 {
146 handle->debug_print("mifare_classic: contactless init failed.\n"); /* contactless init failed */
147
148 return 1; /* return error */
149 }
150 handle->type = MIFARE_CLASSIC_TYPE_INVALID; /* set the invalid type */
151 handle->inited = 1; /* flag inited */
152
153 return 0; /* success return 0 */
154}
155
167{
168 uint8_t res;
169
170 if (handle == NULL) /* check handle */
171 {
172 return 2; /* return error */
173 }
174 if (handle->inited != 1) /* check handle initialization */
175 {
176 return 3; /* return error */
177 }
178
179 res = handle->contactless_deinit(); /* contactless deinit */
180 if (res != 0) /* check the result */
181 {
182 handle->debug_print("mifare_classic: contactless deinit failed.\n"); /* contactless deinit failed */
183
184 return 1; /* return error */
185 }
186 handle->inited = 0; /* flag closed */
187
188 return 0; /* success return 0 */
189}
190
205{
206 uint8_t res;
207 uint8_t input_len;
208 uint8_t input_buf[1];
209 uint8_t output_len;
210 uint8_t output_buf[2];
211
212 if (handle == NULL) /* check handle */
213 {
214 return 2; /* return error */
215 }
216 if (handle->inited != 1) /* check handle initialization */
217 {
218 return 3; /* return error */
219 }
220
221 input_len = 1; /* set the input length */
222 input_buf[0] = MIFARE_CLASSIC_COMMAND_REQUEST; /* set the command */
223 output_len = 2; /* set the output length */
224 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
225 if (res != 0) /* check the result */
226 {
227 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
228
229 return 1; /* return error */
230 }
231 if (output_len != 2) /* check the output_len */
232 {
233 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
234
235 return 4; /* return error */
236 }
237 if ((output_buf[0] == 0x04) && (output_buf[1] == 0x00)) /* check classic type */
238 {
239 *type = MIFARE_CLASSIC_TYPE_S50; /* s50 */
240 handle->type = *type; /* save the type */
241
242 return 0; /* success return 0 */
243 }
244 else if ((output_buf[0] == 0x02) && (output_buf[1] == 0x00)) /* check classic type */
245 {
246 *type = MIFARE_CLASSIC_TYPE_S70; /* s70 */
247 handle->type = *type; /* save the type */
248
249 return 0; /* success return 0 */
250 }
251 else
252 {
253 *type = MIFARE_CLASSIC_TYPE_INVALID; /* invalid */
254 handle->type = *type; /* save the type */
255 handle->debug_print("mifare_classic: type is invalid.\n"); /* type is invalid */
256
257 return 5; /* return error */
258 }
259}
260
275{
276 uint8_t res;
277 uint8_t input_len;
278 uint8_t input_buf[1];
279 uint8_t output_len;
280 uint8_t output_buf[2];
281
282 if (handle == NULL) /* check handle */
283 {
284 return 2; /* return error */
285 }
286 if (handle->inited != 1) /* check handle initialization */
287 {
288 return 3; /* return error */
289 }
290
291 input_len = 1; /* set the input length */
292 input_buf[0] = MIFARE_CLASSIC_COMMAND_WAKE_UP; /* set the command */
293 output_len = 2; /* set the output length */
294 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
295 if (res != 0) /* check the result */
296 {
297 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
298
299 return 1; /* return error */
300 }
301 if (output_len != 2) /* check the output_len */
302 {
303 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
304
305 return 4; /* return error */
306 }
307 if ((output_buf[0] == 0x04) && (output_buf[1] == 0x00)) /* check classic type */
308 {
309 *type = MIFARE_CLASSIC_TYPE_S50; /* s50 */
310 handle->type = *type; /* save the type */
311
312 return 0; /* success return 0 */
313 }
314 else if ((output_buf[0] == 0x02) && (output_buf[1] == 0x00)) /* check classic type */
315 {
316 *type = MIFARE_CLASSIC_TYPE_S70; /* s70 */
317 handle->type = *type; /* save the type */
318
319 return 0; /* success return 0 */
320 }
321 else
322 {
323 *type = MIFARE_CLASSIC_TYPE_INVALID; /* invalid */
324 handle->type = *type; /* save the type */
325 handle->debug_print("mifare_classic: type is invalid.\n"); /* type is invalid */
326
327 return 5; /* return error */
328 }
329}
330
342{
343 uint8_t input_len;
344 uint8_t input_buf[4];
345 uint8_t output_len;
346 uint8_t output_buf[1];
347
348 if (handle == NULL) /* check handle */
349 {
350 return 2; /* return error */
351 }
352 if (handle->inited != 1) /* check handle initialization */
353 {
354 return 3; /* return error */
355 }
356
357 input_len = 4; /* set the input length */
358 input_buf[0] = (MIFARE_CLASSIC_COMMAND_HALT >> 8) & 0xFF; /* set the command */
359 input_buf[1] = (MIFARE_CLASSIC_COMMAND_HALT >> 0) & 0xFF; /* set the command */
360 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
361 output_len = 1; /* set the output length */
362 (void)handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
363
364 return 0; /* success return 0 */
365
366}
367
382{
383 uint8_t res;
384 uint8_t input_len;
385 uint8_t input_buf[4];
386 uint8_t output_len;
387 uint8_t output_buf[1];
388
389 if (handle == NULL) /* check handle */
390 {
391 return 2; /* return error */
392 }
393 if (handle->inited != 1) /* check handle initialization */
394 {
395 return 3; /* return error */
396 }
397
398 input_len = 4; /* set the input length */
399 input_buf[0] = MIFARE_CLASSIC_COMMAND_SET_MOD_TYPE; /* set the command */
400 input_buf[1] = mod; /* set the mod */
401 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
402 output_len = 1; /* set the output length */
403 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
404 if (res != 0) /* check the result */
405 {
406 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
407
408 return 1; /* return error */
409 }
410 if (output_len != 1) /* check the output_len */
411 {
412 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
413
414 return 4; /* return error */
415 }
416 if (output_buf[0] == 0xA) /* check the result */
417 {
418 return 0; /* success return 0 */
419 }
420 else
421 {
422 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
423
424 return 5; /* return error */
425 }
426
427}
428
443{
444 uint8_t res;
445 uint8_t input_len;
446 uint8_t input_buf[4];
447 uint8_t output_len;
448 uint8_t output_buf[1];
449
450 if (handle == NULL) /* check handle */
451 {
452 return 2; /* return error */
453 }
454 if (handle->inited != 1) /* check handle initialization */
455 {
456 return 3; /* return error */
457 }
458
459 input_len = 4; /* set the input length */
460 input_buf[0] = MIFARE_CLASSIC_COMMAND_PERSONALIZE_UID_USAGE; /* set the command */
461 input_buf[1] = type; /* set the mod */
462 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
463 output_len = 1; /* set the output length */
464 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
465 if (res != 0) /* check the result */
466 {
467 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
468
469 return 1; /* return error */
470 }
471 if (output_len != 1) /* check the output_len */
472 {
473 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
474
475 return 4; /* return error */
476 }
477 if (output_buf[0] == 0xA) /* check the result */
478 {
479 return 0; /* success return 0 */
480 }
481 else
482 {
483 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
484
485 return 5; /* return error */
486 }
487
488}
489
504{
505 uint8_t res;
506 uint8_t i;
507 uint8_t check;
508 uint8_t input_len;
509 uint8_t input_buf[2];
510 uint8_t output_len;
511 uint8_t output_buf[5];
512
513 if (handle == NULL) /* check handle */
514 {
515 return 2; /* return error */
516 }
517 if (handle->inited != 1) /* check handle initialization */
518 {
519 return 3; /* return error */
520 }
521
522 input_len = 2; /* set the input length */
523 input_buf[0] = (MIFARE_CLASSIC_COMMAND_ANTICOLLISION_CL1 >> 8) & 0xFF; /* set the command */
524 input_buf[1] = (MIFARE_CLASSIC_COMMAND_ANTICOLLISION_CL1 >> 0) & 0xFF; /* set the command */
525 output_len = 5; /* set the output length */
526 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
527 if (res != 0) /* check the result */
528 {
529 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
530
531 return 1; /* return error */
532 }
533 if (output_len != 5) /* check the output_len */
534 {
535 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
536
537 return 4; /* return error */
538 }
539 check = 0; /* init 0 */
540 for (i = 0; i < 4; i++) /* run 4 times */
541 {
542 id[i] = output_buf[i]; /* get one id */
543 check ^= output_buf[i]; /* xor */
544 }
545 if (check != output_buf[4]) /* check the result */
546 {
547 handle->debug_print("mifare_classic: check error.\n"); /* check error */
548
549 return 5; /* return error */
550 }
551
552 return 0; /* success return 0 */
553}
554
569{
570 uint8_t res;
571 uint8_t i;
572 uint8_t check;
573 uint8_t input_len;
574 uint8_t input_buf[2];
575 uint8_t output_len;
576 uint8_t output_buf[5];
577
578 if (handle == NULL) /* check handle */
579 {
580 return 2; /* return error */
581 }
582 if (handle->inited != 1) /* check handle initialization */
583 {
584 return 3; /* return error */
585 }
586
587 input_len = 2; /* set the input length */
588 input_buf[0] = (MIFARE_CLASSIC_COMMAND_ANTICOLLISION_CL2 >> 8) & 0xFF; /* set the command */
589 input_buf[1] = (MIFARE_CLASSIC_COMMAND_ANTICOLLISION_CL2 >> 0) & 0xFF; /* set the command */
590 output_len = 5; /* set the output length */
591 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
592 if (res != 0) /* check the result */
593 {
594 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
595
596 return 1; /* return error */
597 }
598 if (output_len != 5) /* check the output_len */
599 {
600 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
601
602 return 4; /* return error */
603 }
604 check = 0; /* init 0 */
605 for (i = 0; i < 4; i++) /* run 4 times */
606 {
607 id[i] = output_buf[i]; /* get one id */
608 check ^= output_buf[i]; /* xor */
609 }
610 if (check != output_buf[4]) /* check the result */
611 {
612 handle->debug_print("mifare_classic: check error.\n"); /* check error */
613
614 return 5; /* return error */
615 }
616
617 return 0; /* success return 0 */
618}
619
634{
635 uint8_t res;
636 uint8_t i;
637 uint8_t input_len;
638 uint8_t input_buf[9];
639 uint8_t output_len;
640 uint8_t output_buf[1];
641
642 if (handle == NULL) /* check handle */
643 {
644 return 2; /* return error */
645 }
646 if (handle->inited != 1) /* check handle initialization */
647 {
648 return 3; /* return error */
649 }
650
651 input_len = 9; /* set the input length */
652 input_buf[0] = (MIFARE_CLASSIC_COMMAND_SELECT_CL1 >> 8) & 0xFF; /* set the command */
653 input_buf[1] = (MIFARE_CLASSIC_COMMAND_SELECT_CL1 >> 0) & 0xFF; /* set the command */
654 input_buf[6] = 0; /* init 0 */
655 for (i = 0; i < 4; i++) /* run 4 times */
656 {
657 input_buf[2 + i] = id[i]; /* get one id */
658 input_buf[6] ^= id[i]; /* xor */
659 }
660 a_mifare_classic_iso14443a_crc(input_buf, 7, input_buf + 7); /* get the crc */
661 output_len = 1; /* set the output length */
662 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
663 if (res != 0) /* check the result */
664 {
665 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
666
667 return 1; /* return error */
668 }
669 if (output_len != 1) /* check the output_len */
670 {
671 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
672
673 return 4; /* return error */
674 }
675 if ((output_buf[0] == 0x08) || (output_buf[0] == 0x18)) /* check the sak */
676 {
677 return 0; /* success return 0 */
678 }
679 else
680 {
681 handle->debug_print("mifare_classic: sak error.\n"); /* sak error */
682
683 return 5; /* return error */
684 }
685}
686
701{
702 uint8_t res;
703 uint8_t i;
704 uint8_t input_len;
705 uint8_t input_buf[9];
706 uint8_t output_len;
707 uint8_t output_buf[1];
708
709 if (handle == NULL) /* check handle */
710 {
711 return 2; /* return error */
712 }
713 if (handle->inited != 1) /* check handle initialization */
714 {
715 return 3; /* return error */
716 }
717
718 input_len = 9; /* set the input length */
719 input_buf[0] = (MIFARE_CLASSIC_COMMAND_SELECT_CL2 >> 8) & 0xFF; /* set the command */
720 input_buf[1] = (MIFARE_CLASSIC_COMMAND_SELECT_CL2 >> 0) & 0xFF; /* set the command */
721 input_buf[6] = 0; /* init 0 */
722 for (i = 0; i < 4; i++) /* run 4 times */
723 {
724 input_buf[2 + i] = id[i]; /* get one id */
725 input_buf[6] ^= id[i]; /* xor */
726 }
727 a_mifare_classic_iso14443a_crc(input_buf, 7, input_buf + 7); /* get the crc */
728 output_len = 1; /* set the output length */
729 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
730 if (res != 0) /* check the result */
731 {
732 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
733
734 return 1; /* return error */
735 }
736 if (output_len != 1) /* check the output_len */
737 {
738 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
739
740 return 4; /* return error */
741 }
742 if ((output_buf[0] == 0x08) || (output_buf[0] == 0x18)) /* check the sak */
743 {
744 return 0; /* success return 0 */
745 }
746 else
747 {
748 handle->debug_print("mifare_classic: sak error.\n"); /* sak error */
749
750 return 5; /* return error */
751 }
752}
753
768uint8_t mifare_classic_authentication(mifare_classic_handle_t *handle, uint8_t id[4], uint8_t block,
769 mifare_classic_authentication_key_t key_type, uint8_t key[6])
770{
771 uint8_t res;
772 uint8_t i;
773 uint8_t input_len;
774 uint8_t input_buf[12];
775 uint8_t output_len;
776 uint8_t output_buf[1];
777
778 if (handle == NULL) /* check handle */
779 {
780 return 2; /* return error */
781 }
782 if (handle->inited != 1) /* check handle initialization */
783 {
784 return 3; /* return error */
785 }
786
787 input_len = 12; /* set the input length */
788 if (key_type == MIFARE_CLASSIC_AUTHENTICATION_KEY_A) /* key a */
789 {
790 input_buf[0] = MIFARE_CLASSIC_COMMAND_AUTHENTICATION_WITH_KEY_A; /* set the command */
791 }
792 else /* key b */
793 {
794 input_buf[0] = MIFARE_CLASSIC_COMMAND_AUTHENTICATION_WITH_KEY_B; /* set the command */
795 }
796 input_buf[1] = block; /* set the block */
797 for (i = 0; i < 6; i++) /* 6 times */
798 {
799 input_buf[2 + i] = key[i]; /* copy the keys */
800 }
801 for (i = 0; i < 4; i++) /* 4 times */
802 {
803 input_buf[8 + i] = id[i]; /* copy the id */
804 }
805
806 output_len = 0; /* set the output length */
807 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
808 if (res != 0) /* check the result */
809 {
810 handle->debug_print("mifare_classic: authentication failed.\n"); /* authentication failed */
811
812 return 1; /* return error */
813 }
814
815 return 0; /* success return 0 */
816}
817
832uint8_t mifare_classic_read(mifare_classic_handle_t *handle, uint8_t block, uint8_t data[16])
833{
834 uint8_t res;
835 uint8_t input_len;
836 uint8_t input_buf[4];
837 uint8_t output_len;
838 uint8_t output_buf[18];
839 uint8_t crc_buf[2];
840
841 if (handle == NULL) /* check handle */
842 {
843 return 2; /* return error */
844 }
845 if (handle->inited != 1) /* check handle initialization */
846 {
847 return 3; /* return error */
848 }
849
850 input_len = 4; /* set the input length */
851 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_READ; /* set the command */
852 input_buf[1] = block; /* set the block */
853 a_mifare_classic_iso14443a_crc(input_buf , 2, input_buf + 2); /* get the crc */
854 output_len = 18; /* set the output length */
855 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
856 if (res != 0) /* check the result */
857 {
858 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
859
860 return 1; /* return error */
861 }
862 if (output_len != 18) /* check the output_len */
863 {
864 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
865
866 return 4; /* return error */
867 }
868 a_mifare_classic_iso14443a_crc(output_buf, 16, crc_buf); /* get the crc */
869 if ((output_buf[16] == crc_buf[0]) && (output_buf[17] == crc_buf[1])) /* check the crc */
870 {
871 memcpy(data, output_buf, 16); /* copy the data */
872
873 return 0; /* success return 0 */
874 }
875 else
876 {
877 handle->debug_print("mifare_classic: crc error.\n"); /* crc error */
878
879 return 5; /* return error */
880 }
881}
882
897uint8_t mifare_classic_write(mifare_classic_handle_t *handle, uint8_t block, uint8_t data[16])
898{
899 uint8_t res;
900 uint8_t i;
901 uint8_t input_len;
902 uint8_t input_buf[18];
903 uint8_t output_len;
904 uint8_t output_buf[1];
905
906 if (handle == NULL) /* check handle */
907 {
908 return 2; /* return error */
909 }
910 if (handle->inited != 1) /* check handle initialization */
911 {
912 return 3; /* return error */
913 }
914
915 input_len = 4; /* set the input length */
916 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_WRITE; /* set the command */
917 input_buf[1] = block; /* set the block */
918 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
919 output_len = 1; /* set the output length */
920 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
921 if (res != 0) /* check the result */
922 {
923 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
924
925 return 1; /* return error */
926 }
927 if (output_len != 1) /* check the output_len */
928 {
929 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
930
931 return 4; /* return error */
932 }
933 if (output_buf[0] != 0xA) /* check the result */
934 {
935 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
936
937 return 5; /* return error */
938 }
939
940 for (i = 0; i < 16; i ++) /* 16 times */
941 {
942 input_buf[i] = data[i]; /* copy data */
943 }
944 a_mifare_classic_iso14443a_crc(input_buf, 16, input_buf + 16); /* get the crc */
945 input_len = 18; /* set the input length */
946 output_len = 1; /* set the output length */
947 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
948 if (res != 0) /* check the result */
949 {
950 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
951
952 return 1; /* return error */
953 }
954 if (output_buf[0] != 0xA) /* check the result */
955 {
956 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
957
958 return 5; /* return error */
959 }
960
961 return 0; /* success return 0 */
962}
963
979uint8_t mifare_classic_value_init(mifare_classic_handle_t *handle, uint8_t block, int32_t value, uint8_t addr)
980{
981 uint8_t res;
982 uint8_t i;
983 uint8_t input_len;
984 uint8_t input_buf[18];
985 uint8_t output_len;
986 uint8_t output_buf[1];
987 uint32_t v;
988 uint32_t v_r;
989 uint8_t data[16];
990
991 if (handle == NULL) /* check handle */
992 {
993 return 2; /* return error */
994 }
995 if (handle->inited != 1) /* check handle initialization */
996 {
997 return 3; /* return error */
998 }
999
1000 v = (uint32_t)(value); /* convert the value */
1001 v_r = (uint32_t)(~value); /* revert the value */
1002 data[0] = (uint8_t)((v >> 0) & 0xFF); /* set the value */
1003 data[1] = (uint8_t)((v >> 8) & 0xFF); /* set the value */
1004 data[2] = (uint8_t)((v >> 16) & 0xFF); /* set the value */
1005 data[3] = (uint8_t)((v >> 24) & 0xFF); /* set the value */
1006 data[4] = (uint8_t)((v_r >> 0) & 0xFF); /* set the value */
1007 data[5] = (uint8_t)((v_r >> 8) & 0xFF); /* set the value */
1008 data[6] = (uint8_t)((v_r >> 16) & 0xFF); /* set the value */
1009 data[7] = (uint8_t)((v_r >> 24) & 0xFF); /* set the value */
1010 data[8] = (uint8_t)((v >> 0) & 0xFF); /* set the value */
1011 data[9] = (uint8_t)((v >> 8) & 0xFF); /* set the value */
1012 data[10] = (uint8_t)((v >> 16) & 0xFF); /* set the value */
1013 data[11] = (uint8_t)((v >> 24) & 0xFF); /* set the value */
1014 data[12] = addr; /* set the address */
1015 data[13] = (uint8_t)(~addr); /* set the address */
1016 data[14] = addr; /* set the address */
1017 data[15] = (uint8_t)(~addr); /* set the address */
1018
1019 input_len = 4; /* set the input length */
1020 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_WRITE; /* set the command */
1021 input_buf[1] = block; /* set the block */
1022 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
1023 output_len = 1; /* set the output length */
1024 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1025 if (res != 0) /* check the result */
1026 {
1027 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1028
1029 return 1; /* return error */
1030 }
1031 if (output_len != 1) /* check the output_len */
1032 {
1033 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1034
1035 return 4; /* return error */
1036 }
1037 if (output_buf[0] != 0xA) /* check the result */
1038 {
1039 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1040
1041 return 5; /* return error */
1042 }
1043
1044 for (i = 0; i < 16; i ++) /* 16 times */
1045 {
1046 input_buf[i] = data[i]; /* copy data */
1047 }
1048 a_mifare_classic_iso14443a_crc(input_buf, 16, input_buf + 16); /* get the crc */
1049 input_len = 18; /* set the input length */
1050 output_len = 1; /* set the output length */
1051 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1052 if (res != 0) /* check the result */
1053 {
1054 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1055
1056 return 1; /* return error */
1057 }
1058 if (output_buf[0] != 0xA) /* check the result */
1059 {
1060 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1061
1062 return 5; /* return error */
1063 }
1064
1065 return 0; /* success return 0 */
1066}
1067
1083uint8_t mifare_classic_value_write(mifare_classic_handle_t *handle, uint8_t block, int32_t value, uint8_t addr)
1084{
1085 uint8_t res;
1086 uint8_t i;
1087 uint8_t input_len;
1088 uint8_t input_buf[18];
1089 uint8_t output_len;
1090 uint8_t output_buf[1];
1091 uint32_t v;
1092 uint32_t v_r;
1093 uint8_t data[16];
1094
1095 if (handle == NULL) /* check handle */
1096 {
1097 return 2; /* return error */
1098 }
1099 if (handle->inited != 1) /* check handle initialization */
1100 {
1101 return 3; /* return error */
1102 }
1103
1104 v = (uint32_t)(value); /* convert the value */
1105 v_r = (uint32_t)(~value); /* revert the value */
1106 data[0] = (uint8_t)((v >> 0) & 0xFF); /* set the value */
1107 data[1] = (uint8_t)((v >> 8) & 0xFF); /* set the value */
1108 data[2] = (uint8_t)((v >> 16) & 0xFF); /* set the value */
1109 data[3] = (uint8_t)((v >> 24) & 0xFF); /* set the value */
1110 data[4] = (uint8_t)((v_r >> 0) & 0xFF); /* set the value */
1111 data[5] = (uint8_t)((v_r >> 8) & 0xFF); /* set the value */
1112 data[6] = (uint8_t)((v_r >> 16) & 0xFF); /* set the value */
1113 data[7] = (uint8_t)((v_r >> 24) & 0xFF); /* set the value */
1114 data[8] = (uint8_t)((v >> 0) & 0xFF); /* set the value */
1115 data[9] = (uint8_t)((v >> 8) & 0xFF); /* set the value */
1116 data[10] = (uint8_t)((v >> 16) & 0xFF); /* set the value */
1117 data[11] = (uint8_t)((v >> 24) & 0xFF); /* set the value */
1118 data[12] = addr; /* set the address */
1119 data[13] = (uint8_t)(~addr); /* set the address */
1120 data[14] = addr; /* set the address */
1121 data[15] = (uint8_t)(~addr); /* set the address */
1122
1123 input_len = 4; /* set the input length */
1124 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_WRITE; /* set the command */
1125 input_buf[1] = block; /* set the block */
1126 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
1127 output_len = 1; /* set the output length */
1128 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1129 if (res != 0) /* check the result */
1130 {
1131 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1132
1133 return 1; /* return error */
1134 }
1135 if (output_len != 1) /* check the output_len */
1136 {
1137 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1138
1139 return 4; /* return error */
1140 }
1141 if (output_buf[0] != 0xA) /* check the result */
1142 {
1143 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1144
1145 return 5; /* return error */
1146 }
1147
1148 for (i = 0; i < 16; i ++) /* 16 times */
1149 {
1150 input_buf[i] = data[i]; /* copy data */
1151 }
1152 a_mifare_classic_iso14443a_crc(input_buf, 16, input_buf + 16); /* get the crc */
1153 input_len = 18; /* set the input length */
1154 output_len = 1; /* set the output length */
1155 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1156 if (res != 0) /* check the result */
1157 {
1158 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1159
1160 return 1; /* return error */
1161 }
1162 if (output_buf[0] != 0xA) /* check the result */
1163 {
1164 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1165
1166 return 5; /* return error */
1167 }
1168
1169 return 0; /* success return 0 */
1170}
1171
1189uint8_t mifare_classic_value_read(mifare_classic_handle_t *handle, uint8_t block, int32_t *value, uint8_t *addr)
1190{
1191 uint8_t res;
1192 uint8_t input_len;
1193 uint8_t input_buf[4];
1194 uint8_t output_len;
1195 uint8_t output_buf[18];
1196 uint8_t crc_buf[2];
1197 uint8_t data[16];
1198 uint32_t value_0;
1199 uint32_t value_1;
1200 uint32_t value_2;
1201 uint8_t address_0;
1202 uint8_t address_1;
1203 uint8_t address_2;
1204 uint8_t address_3;
1205 uint32_t v;
1206
1207 if (handle == NULL) /* check handle */
1208 {
1209 return 2; /* return error */
1210 }
1211 if (handle->inited != 1) /* check handle initialization */
1212 {
1213 return 3; /* return error */
1214 }
1215
1216 input_len = 4; /* set the input length */
1217 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_READ; /* set the command */
1218 input_buf[1] = block; /* set the block */
1219 a_mifare_classic_iso14443a_crc(input_buf , 2, input_buf + 2); /* get the crc */
1220 output_len = 18; /* set the output length */
1221 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1222 if (res != 0) /* check the result */
1223 {
1224 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1225
1226 return 1; /* return error */
1227 }
1228 if (output_len != 18) /* check the output_len */
1229 {
1230 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1231
1232 return 4; /* return error */
1233 }
1234 a_mifare_classic_iso14443a_crc(output_buf, 16, crc_buf); /* get the crc */
1235 if ((output_buf[16] == crc_buf[0]) && (output_buf[17] == crc_buf[1])) /* check the crc */
1236 {
1237 uint8_t i;
1238
1239 for (i = 0; i < 16; i++) /* 16 times */
1240 {
1241 data[i] = output_buf[i]; /* copy the data */
1242 }
1243 value_0 = ((uint32_t)data[0] << 0) | ((uint32_t)data[1] << 8) |
1244 ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 24); /* get the value 0 */
1245 value_1 = ((uint32_t)data[4] << 0) | ((uint32_t)data[5] << 8) |
1246 ((uint32_t)data[6] << 16) | ((uint32_t)data[7] << 24); /* get the value 1 */
1247 value_2 = ((uint32_t)data[8] << 0) | ((uint32_t)data[9] << 8) |
1248 ((uint32_t)data[10] << 16) | ((uint32_t)data[11] << 24); /* get the value 2 */
1249 address_0 = data[12]; /* get the address 0 */
1250 address_1 = (uint8_t)(~data[13]); /* get the address 1 */
1251 address_2 = data[14]; /* get the address 2 */
1252 address_3 = (uint8_t)(~data[15]); /* get the address 3 */
1253
1254 if ((value_0 != value_2) || (value_0 != (uint32_t)(~value_1))) /* check the value */
1255 {
1256 handle->debug_print("mifare_classic: value is invalid.\n"); /* value is invalid */
1257
1258 return 6; /* return error */
1259 }
1260 if ((address_0 != address_2) ||
1261 (address_1 != address_3) ||
1262 (address_0 != (uint8_t)(address_1)) /* check the address */
1263 )
1264 {
1265 handle->debug_print("mifare_classic: block is invalid.\n"); /* block is invalid */
1266
1267 return 7; /* return error */
1268 }
1269 v = value_0; /* get the value */
1270 *value = (int32_t)(v); /* set the value */
1271 *addr = address_0; /* set the address */
1272
1273 return 0; /* success return 0 */
1274 }
1275 else
1276 {
1277 handle->debug_print("mifare_classic: crc error.\n"); /* crc error */
1278
1279 return 5; /* return error */
1280 }
1281}
1282
1298uint8_t mifare_classic_increment(mifare_classic_handle_t *handle, uint8_t block, uint32_t value)
1299{
1300 uint8_t res;
1301 uint8_t input_len;
1302 uint8_t input_buf[6];
1303 uint8_t output_len;
1304 uint8_t output_buf[1];
1305 uint32_t v;
1306
1307 if (handle == NULL) /* check handle */
1308 {
1309 return 2; /* return error */
1310 }
1311 if (handle->inited != 1) /* check handle initialization */
1312 {
1313 return 3; /* return error */
1314 }
1315
1316 v = value; /* set the value */
1317
1318 input_len = 4; /* set the input length */
1319 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_INCREMENT; /* set the command */
1320 input_buf[1] = block; /* set the block */
1321 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
1322 output_len = 1; /* set the output length */
1323 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1324 if (res != 0) /* check the result */
1325 {
1326 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1327
1328 return 1; /* return error */
1329 }
1330 if (output_len != 1) /* check the output_len */
1331 {
1332 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1333
1334 return 4; /* return error */
1335 }
1336 if (output_buf[0] == 0x4) /* check the result */
1337 {
1338 handle->debug_print("mifare_classic: invalid operation.\n"); /* invalid operation */
1339
1340 return 6; /* return error */
1341 }
1342 if (output_buf[0] != 0xA) /* check the result */
1343 {
1344 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1345
1346 return 5; /* return error */
1347 }
1348
1349 input_len = 6; /* set the input length */
1350 input_buf[0] = (v >> 0) & 0xFF; /* set the data */
1351 input_buf[1] = (v >> 8) & 0xFF; /* set the data */
1352 input_buf[2] = (v >> 16) & 0xFF; /* set the data */
1353 input_buf[3] = (v >> 24) & 0xFF; /* set the data */
1354 a_mifare_classic_iso14443a_crc(input_buf, 4, input_buf + 4); /* get the crc */
1355 output_len = 0; /* set the output length */
1356 (void)handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1357
1358 return 0; /* success return 0 */
1359}
1360
1376uint8_t mifare_classic_decrement(mifare_classic_handle_t *handle, uint8_t block, uint32_t value)
1377{
1378 uint8_t res;
1379 uint8_t input_len;
1380 uint8_t input_buf[6];
1381 uint8_t output_len;
1382 uint8_t output_buf[1];
1383 uint32_t v;
1384
1385 if (handle == NULL) /* check handle */
1386 {
1387 return 2; /* return error */
1388 }
1389 if (handle->inited != 1) /* check handle initialization */
1390 {
1391 return 3; /* return error */
1392 }
1393
1394 v = value; /* set the value */
1395
1396 input_len = 4; /* set the input length */
1397 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_DECREMENT; /* set the command */
1398 input_buf[1] = block; /* set the block */
1399 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
1400 output_len = 1; /* set the output length */
1401 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1402 if (res != 0) /* check the result */
1403 {
1404 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1405
1406 return 1; /* return error */
1407 }
1408 if (output_len != 1) /* check the output_len */
1409 {
1410 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1411
1412 return 4; /* return error */
1413 }
1414 if (output_buf[0] == 0x4) /* check the result */
1415 {
1416 handle->debug_print("mifare_classic: invalid operation.\n"); /* invalid operation */
1417
1418 return 6; /* return error */
1419 }
1420 if (output_buf[0] != 0xA) /* check the result */
1421 {
1422 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1423
1424 return 5; /* return error */
1425 }
1426
1427 input_len = 6; /* set the input length */
1428 input_buf[0] = (v >> 0) & 0xFF; /* set the data */
1429 input_buf[1] = (v >> 8) & 0xFF; /* set the data */
1430 input_buf[2] = (v >> 16) & 0xFF; /* set the data */
1431 input_buf[3] = (v >> 24) & 0xFF; /* set the data */
1432 a_mifare_classic_iso14443a_crc(input_buf, 4, input_buf + 4); /* get the crc */
1433 output_len = 0; /* set the output length */
1434 (void)handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1435
1436 return 0; /* success return 0 */
1437}
1438
1454{
1455 uint8_t res;
1456 uint8_t input_len;
1457 uint8_t input_buf[4];
1458 uint8_t output_len;
1459 uint8_t output_buf[1];
1460
1461 if (handle == NULL) /* check handle */
1462 {
1463 return 2; /* return error */
1464 }
1465 if (handle->inited != 1) /* check handle initialization */
1466 {
1467 return 3; /* return error */
1468 }
1469
1470 input_len = 4; /* set the input length */
1471 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_TRANSFER; /* set the command */
1472 input_buf[1] = block; /* set the block */
1473 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
1474 output_len = 1; /* set the output length */
1475 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1476 if (res != 0) /* check the result */
1477 {
1478 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1479
1480 return 1; /* return error */
1481 }
1482 if (output_len != 1) /* check the output_len */
1483 {
1484 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1485
1486 return 4; /* return error */
1487 }
1488 if (output_buf[0] == 0x4) /* check the result */
1489 {
1490 handle->debug_print("mifare_classic: invalid operation.\n"); /* invalid operation */
1491
1492 return 6; /* return error */
1493 }
1494 if (output_buf[0] != 0xA) /* check the result */
1495 {
1496 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1497
1498 return 5; /* return error */
1499 }
1500
1501 return 0; /* success return 0 */
1502}
1503
1519{
1520 uint8_t res;
1521 uint8_t input_len;
1522 uint8_t input_buf[6];
1523 uint8_t output_len;
1524 uint8_t output_buf[1];
1525
1526 if (handle == NULL) /* check handle */
1527 {
1528 return 2; /* return error */
1529 }
1530 if (handle->inited != 1) /* check handle initialization */
1531 {
1532 return 3; /* return error */
1533 }
1534
1535 input_len = 4; /* set the input length */
1536 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_RESTORE; /* set the command */
1537 input_buf[1] = block; /* set the block */
1538 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
1539 output_len = 1; /* set the output length */
1540 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1541 if (res != 0) /* check the result */
1542 {
1543 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1544
1545 return 1; /* return error */
1546 }
1547 if (output_len != 1) /* check the output_len */
1548 {
1549 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1550
1551 return 4; /* return error */
1552 }
1553 if (output_buf[0] == 0x4) /* check the result */
1554 {
1555 handle->debug_print("mifare_classic: invalid operation.\n"); /* invalid operation */
1556
1557 return 6; /* return error */
1558 }
1559 if (output_buf[0] != 0xA) /* check the result */
1560 {
1561 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1562
1563 return 5; /* return error */
1564 }
1565
1566 input_len = 6; /* set the input length */
1567 input_buf[0] = 0x00; /* set the data */
1568 input_buf[1] = 0x00; /* set the data */
1569 input_buf[2] = 0x00; /* set the data */
1570 input_buf[3] = 0x00; /* set the data */
1571 a_mifare_classic_iso14443a_crc(input_buf, 4, input_buf + 4); /* get the crc */
1572 output_len = 0; /* set the output length */
1573 (void)handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1574
1575 return 0; /* success return 0 */
1576}
1577
1589uint8_t mifare_classic_block_to_sector(mifare_classic_handle_t *handle, uint8_t block, uint8_t *sector)
1590{
1591 if (handle == NULL) /* check handle */
1592 {
1593 return 2; /* return error */
1594 }
1595 if (handle->inited != 1) /* check handle initialization */
1596 {
1597 return 3; /* return error */
1598 }
1599
1600 if (block < 32 * 4) /* check the size*/
1601 {
1602 *sector = block / 4; /* s50 */
1603 }
1604 else
1605 {
1606 *sector = 32 + ((block - (32 * 4)) / 16); /* s70 */
1607 }
1608
1609 return 0; /* success return 0 */
1610}
1611
1623uint8_t mifare_classic_sector_block_count(mifare_classic_handle_t *handle, uint8_t sector, uint8_t *count)
1624{
1625 if (handle == NULL) /* check handle */
1626 {
1627 return 2; /* return error */
1628 }
1629 if (handle->inited != 1) /* check handle initialization */
1630 {
1631 return 3; /* return error */
1632 }
1633
1634 if (sector < 32) /* check the size*/
1635 {
1636 *count = 4; /* s50 */
1637 }
1638 else
1639 {
1640 *count = 16; /* s70 */
1641 }
1642
1643 return 0; /* success return 0 */
1644}
1645
1657uint8_t mifare_classic_sector_first_block(mifare_classic_handle_t *handle, uint8_t sector, uint8_t *block)
1658{
1659 if (handle == NULL) /* check handle */
1660 {
1661 return 2; /* return error */
1662 }
1663 if (handle->inited != 1) /* check handle initialization */
1664 {
1665 return 3; /* return error */
1666 }
1667
1668 if (sector < 32) /* check the size*/
1669 {
1670 *block = sector * 4; /* s50 */
1671 }
1672 else
1673 {
1674 *block = 32 * 4 + (sector - 32) * 16; /* s70 */
1675 }
1676
1677 return 0; /* success return 0 */
1678}
1679
1691uint8_t mifare_classic_sector_last_block(mifare_classic_handle_t *handle, uint8_t sector, uint8_t *block)
1692{
1693 if (handle == NULL) /* check handle */
1694 {
1695 return 2; /* return error */
1696 }
1697 if (handle->inited != 1) /* check handle initialization */
1698 {
1699 return 3; /* return error */
1700 }
1701
1702 if (sector < 32) /* check the size*/
1703 {
1704 *block = sector * 4; /* s50 */
1705 }
1706 else
1707 {
1708 *block = 32 * 4 + (sector - 32) * 16; /* s70 */
1709 }
1710 *block = *block + ((sector < 32) ? 4 : 16) - 1; /* get the last block */
1711
1712 return 0; /* success return 0 */
1713}
1714
1756 uint8_t sector, uint8_t key_a[6],
1757 uint8_t block_0_0_4, uint8_t block_1_5_9,
1758 uint8_t block_2_10_14, uint8_t block_3_15,
1759 uint8_t user_data, uint8_t key_b[6])
1760{
1761 uint8_t res;
1762 uint8_t block;
1763 uint8_t i;
1764 uint8_t part_1, part_2, part_3;
1765 uint8_t input_len;
1766 uint8_t input_buf[18];
1767 uint8_t output_len;
1768 uint8_t output_buf[1];
1769 uint8_t access_bits[4];
1770 uint8_t data[16];
1771
1772 if (handle == NULL) /* check handle */
1773 {
1774 return 2; /* return error */
1775 }
1776 if (handle->inited != 1) /* check handle initialization */
1777 {
1778 return 3; /* return error */
1779 }
1780
1781 part_1 = (((block_3_15 >> 2) & 0x1) << 3) | (((block_2_10_14 >> 2) & 0x1) << 2) |
1782 (((block_1_5_9 >> 2) & 0x1) << 1) | (((block_0_0_4 >> 2) & 0x1) << 0); /* set part 1 */
1783 part_2 = (((block_3_15 >> 1) & 0x1) << 3) | (((block_2_10_14 >> 1) & 0x1) << 2) |
1784 (((block_1_5_9 >> 1) & 0x1) << 1) | (((block_0_0_4 >> 1) & 0x1) << 0); /* set part 2 */
1785 part_3 = (((block_3_15 >> 0) & 0x1) << 3) | (((block_2_10_14 >> 0) & 0x1) << 2) |
1786 (((block_1_5_9 >> 0) & 0x1) << 1) | (((block_0_0_4 >> 0) & 0x1) << 0); /* set part 3 */
1787 access_bits[0] = ((0xF - part_2) << 4) | ((0xF - part_1) << 0); /* set the access bits */
1788 access_bits[1] = ((part_1 & 0xF) << 4) | ((0xF - part_3) << 0); /* set the access bits */
1789 access_bits[2] = ((part_3 & 0xF) << 4) | ((part_2 & 0xF) << 0); /* set the access bits */
1790 access_bits[3] = user_data; /* set the user data */
1791 for (i = 0; i < 6; i++) /* 6 times */
1792 {
1793 data[i] = key_a[i]; /* copy the key a */
1794 }
1795 for (i = 0; i < 4; i++) /* 4 times */
1796 {
1797 data[i + 6] = access_bits[i]; /* copy the access bits */
1798 }
1799 for (i = 0; i < 6; i++) /* 6 times */
1800 {
1801 data[i + 10] = key_b[i]; /* copy the key b */
1802 }
1803
1804 if (sector < 32) /* check the size*/
1805 {
1806 block = sector * 4; /* s50 */
1807 }
1808 else
1809 {
1810 block = 32 * 4 + (sector - 32) * 16; /* s70 */
1811 }
1812 block = block + ((sector < 32) ? 4 : 16) - 1; /* get the last block */
1813
1814 input_len = 4; /* set the input length */
1815 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_WRITE; /* set the command */
1816 input_buf[1] = block; /* set the block */
1817 a_mifare_classic_iso14443a_crc(input_buf, 2, input_buf + 2); /* get the crc */
1818 output_len = 1; /* set the output length */
1819 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1820 if (res != 0) /* check the result */
1821 {
1822 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1823
1824 return 1; /* return error */
1825 }
1826 if (output_len != 1) /* check the output_len */
1827 {
1828 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1829
1830 return 4; /* return error */
1831 }
1832 if (output_buf[0] != 0xA) /* check the result */
1833 {
1834 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1835
1836 return 5; /* return error */
1837 }
1838
1839 for (i = 0; i < 16; i ++) /* 16 times */
1840 {
1841 input_buf[i] = data[i]; /* copy data */
1842 }
1843 a_mifare_classic_iso14443a_crc(input_buf, 16, input_buf + 16); /* get the crc */
1844 input_len = 18; /* set the input length */
1845 output_len = 1; /* set the output length */
1846 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1847 if (res != 0) /* check the result */
1848 {
1849 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1850
1851 return 1; /* return error */
1852 }
1853 if (output_buf[0] != 0xA) /* check the result */
1854 {
1855 handle->debug_print("mifare_classic: ack error.\n"); /* ack error */
1856
1857 return 5; /* return error */
1858 }
1859
1860 return 0; /* success return 0 */
1861}
1862
1884 uint8_t sector, uint8_t *block_0_0_4, uint8_t *block_1_5_9,
1885 uint8_t *block_2_10_14, uint8_t *block_3_15,
1886 uint8_t *user_data, uint8_t key_b[6])
1887{
1888 uint8_t res;
1889 uint8_t i;
1890 uint8_t block;
1891 uint8_t input_len;
1892 uint8_t input_buf[4];
1893 uint8_t output_len;
1894 uint8_t output_buf[18];
1895 uint8_t crc_buf[2];
1896 uint8_t data[16];
1897 uint8_t access_bits[4];
1898
1899 if (handle == NULL) /* check handle */
1900 {
1901 return 2; /* return error */
1902 }
1903 if (handle->inited != 1) /* check handle initialization */
1904 {
1905 return 3; /* return error */
1906 }
1907
1908 if (sector < 32) /* check the size*/
1909 {
1910 block = sector * 4; /* s50 */
1911 }
1912 else
1913 {
1914 block = 32 * 4 + (sector - 32) * 16; /* s70 */
1915 }
1916 block = block + ((sector < 32) ? 4 : 16) - 1; /* get the last block */
1917
1918 input_len = 4; /* set the input length */
1919 input_buf[0] = MIFARE_CLASSIC_COMMAND_MIFARE_READ; /* set the command */
1920 input_buf[1] = block; /* set the block */
1921 a_mifare_classic_iso14443a_crc(input_buf , 2, input_buf + 2); /* get the crc */
1922 output_len = 18; /* set the output length */
1923 res = handle->contactless_transceiver(input_buf, input_len, output_buf, &output_len); /* transceiver */
1924 if (res != 0) /* check the result */
1925 {
1926 handle->debug_print("mifare_classic: contactless transceiver failed.\n"); /* contactless transceiver failed */
1927
1928 return 1; /* return error */
1929 }
1930 if (output_len != 18) /* check the output_len */
1931 {
1932 handle->debug_print("mifare_classic: output_len is invalid.\n"); /* output_len is invalid */
1933
1934 return 4; /* return error */
1935 }
1936 a_mifare_classic_iso14443a_crc(output_buf, 16, crc_buf); /* get the crc */
1937 if ((output_buf[16] == crc_buf[0]) && (output_buf[17] == crc_buf[1])) /* check the crc */
1938 {
1939 uint8_t part_1;
1940 uint8_t part_2;
1941 uint8_t part_3;
1942 uint8_t part_1_r;
1943 uint8_t part_2_r;
1944 uint8_t part_3_r;
1945
1946 memcpy(data, output_buf, 16); /* copy the data */
1947
1948 for (i = 0; i < 6; i++) /* 6 times */
1949 {
1950 key_b[i] = data[10 + i]; /* copy the key b */
1951 }
1952 for (i = 0; i < 4; i++) /* 4 times */
1953 {
1954 access_bits[i] = data[6 + i]; /* copy the access bits */
1955 }
1956 part_2_r = (access_bits[0] >> 4) & 0xF; /* get the part2 revert */
1957 part_1_r = (access_bits[0] >> 0) & 0xF; /* get the part1 revert */
1958 part_1 = (access_bits[1] >> 4) & 0xF; /* get the part1 */
1959 part_3_r = (access_bits[1] >> 0) & 0xF; /* get the part3 revert */
1960 part_3 = (access_bits[2] >> 4) & 0xF; /* get the part3 */
1961 part_2 = (access_bits[2] >> 0) & 0xF; /* get the part2 */
1962 if (((part_1 + part_1_r) != 0xF) ||
1963 ((part_2 + part_2_r) != 0xF) ||
1964 ((part_3 + part_3_r) != 0xF)) /* check the param */
1965 {
1966 handle->debug_print("mifare_classic: data is invalid.\n"); /* data is invalid */
1967
1968 return 6; /* return error */
1969 }
1970 *block_0_0_4 = (((part_1 >> 0) & 0x01) << 2) | (((part_2 >> 0) & 0x01) << 1) |
1971 (((part_3 >> 0) & 0x01) << 0); /* get the block_0_0_4 */
1972 *block_1_5_9 = (((part_1 >> 1) & 0x01) << 2) | (((part_2 >> 1) & 0x01) << 1) |
1973 (((part_3 >> 1) & 0x01) << 0); /* get the block_1_5_9 */
1974 *block_2_10_14 = (((part_1 >> 2) & 0x01) << 2) | (((part_2 >> 2) & 0x01) << 1) |
1975 (((part_3 >> 2) & 0x01) << 0); /* get the block_2_10_14 */
1976 *block_3_15 = (((part_1 >> 3) & 0x01) << 2) | (((part_2 >> 3) & 0x01) << 1) |
1977 (((part_3 >> 3) & 0x01) << 0); /* get the block_3_15 */
1978 *user_data = access_bits[3]; /* get the access bits */
1979
1980 return 0; /* success return 0 */
1981 }
1982 else
1983 {
1984 handle->debug_print("mifare_classic: crc error.\n"); /* crc error */
1985
1986 return 5; /* return error */
1987 }
1988}
1989
2002uint8_t mifare_classic_transceiver(mifare_classic_handle_t *handle, uint8_t *in_buf, uint8_t in_len, uint8_t *out_buf, uint8_t *out_len)
2003{
2004 if (handle == NULL) /* check handle */
2005 {
2006 return 2; /* return error */
2007 }
2008 if (handle->inited != 1) /* check handle initialization */
2009 {
2010 return 3; /* return error */
2011 }
2012
2013 if (handle->contactless_transceiver(in_buf, in_len,
2014 out_buf, out_len) != 0) /* transceiver data */
2015 {
2016 return 1; /* return error */
2017 }
2018 else
2019 {
2020 return 0; /* success return 0 */
2021 }
2022}
2023
2033{
2034 if (info == NULL) /* check handle */
2035 {
2036 return 2; /* return error */
2037 }
2038
2039 memset(info, 0, sizeof(mifare_classic_info_t)); /* initialize mifare_classic info structure */
2040 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
2041 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
2042 strncpy(info->interface, "RF", 8); /* copy interface name */
2043 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
2044 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
2045 info->max_current_ma = MAX_CURRENT; /* set maximum current */
2046 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
2047 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
2048 info->driver_version = DRIVER_VERSION; /* set driver version */
2049
2050 return 0; /* success return 0 */
2051}
#define MIFARE_CLASSIC_COMMAND_PERSONALIZE_UID_USAGE
#define MAX_CURRENT
#define MIFARE_CLASSIC_COMMAND_WAKE_UP
#define MIFARE_CLASSIC_COMMAND_MIFARE_READ
#define MIFARE_CLASSIC_COMMAND_MIFARE_INCREMENT
#define SUPPLY_VOLTAGE_MAX
#define MIFARE_CLASSIC_COMMAND_HALT
#define MIFARE_CLASSIC_COMMAND_MIFARE_RESTORE
#define MIFARE_CLASSIC_COMMAND_SET_MOD_TYPE
#define MIFARE_CLASSIC_COMMAND_REQUEST
chip command definition
#define TEMPERATURE_MAX
#define MIFARE_CLASSIC_COMMAND_AUTHENTICATION_WITH_KEY_B
#define MANUFACTURER_NAME
#define TEMPERATURE_MIN
#define MIFARE_CLASSIC_COMMAND_SELECT_CL1
#define SUPPLY_VOLTAGE_MIN
#define MIFARE_CLASSIC_COMMAND_AUTHENTICATION_WITH_KEY_A
#define MIFARE_CLASSIC_COMMAND_SELECT_CL2
#define MIFARE_CLASSIC_COMMAND_MIFARE_WRITE
#define MIFARE_CLASSIC_COMMAND_MIFARE_DECREMENT
#define MIFARE_CLASSIC_COMMAND_ANTICOLLISION_CL2
#define CHIP_NAME
chip information definition
#define MIFARE_CLASSIC_COMMAND_ANTICOLLISION_CL1
#define DRIVER_VERSION
#define MIFARE_CLASSIC_COMMAND_MIFARE_TRANSFER
driver mifare classic header file
mifare_classic_personalized_uid_t
mifare_classic personalized uid enumeration definition
uint8_t mifare_classic_sector_last_block(mifare_classic_handle_t *handle, uint8_t sector, uint8_t *block)
mifare get the sector's last block
uint8_t mifare_classic_anticollision_cl2(mifare_classic_handle_t *handle, uint8_t id[4])
mifare anti collision cl2
uint8_t mifare_classic_halt(mifare_classic_handle_t *handle)
mifare halt
struct mifare_classic_info_s mifare_classic_info_t
mifare_classic information structure definition
uint8_t mifare_classic_read(mifare_classic_handle_t *handle, uint8_t block, uint8_t data[16])
mifare read
struct mifare_classic_handle_s mifare_classic_handle_t
mifare_classic handle structure definition
uint8_t mifare_classic_set_sector_permission(mifare_classic_handle_t *handle, uint8_t sector, uint8_t key_a[6], uint8_t block_0_0_4, uint8_t block_1_5_9, uint8_t block_2_10_14, uint8_t block_3_15, uint8_t user_data, uint8_t key_b[6])
mifare set the sector permission
uint8_t mifare_classic_block_to_sector(mifare_classic_handle_t *handle, uint8_t block, uint8_t *sector)
mifare block number to sector number
uint8_t mifare_classic_sector_first_block(mifare_classic_handle_t *handle, uint8_t sector, uint8_t *block)
mifare get the sector's first block
uint8_t mifare_classic_set_personalized_uid(mifare_classic_handle_t *handle, mifare_classic_personalized_uid_t type)
mifare set the personalized uid
uint8_t mifare_classic_value_init(mifare_classic_handle_t *handle, uint8_t block, int32_t value, uint8_t addr)
mifare init one block as a value block
uint8_t mifare_classic_authentication(mifare_classic_handle_t *handle, uint8_t id[4], uint8_t block, mifare_classic_authentication_key_t key_type, uint8_t key[6])
mifare authentication
uint8_t mifare_classic_select_cl2(mifare_classic_handle_t *handle, uint8_t id[4])
mifare select cl2
uint8_t mifare_classic_request(mifare_classic_handle_t *handle, mifare_classic_type_t *type)
mifare request
uint8_t mifare_classic_value_write(mifare_classic_handle_t *handle, uint8_t block, int32_t value, uint8_t addr)
mifare value write
uint8_t mifare_classic_decrement(mifare_classic_handle_t *handle, uint8_t block, uint32_t value)
mifare decrement
uint8_t mifare_classic_select_cl1(mifare_classic_handle_t *handle, uint8_t id[4])
mifare select cl1
mifare_classic_load_modulation_t
mifare_classic load modulation enumeration definition
uint8_t mifare_classic_get_sector_permission(mifare_classic_handle_t *handle, uint8_t sector, uint8_t *block_0_0_4, uint8_t *block_1_5_9, uint8_t *block_2_10_14, uint8_t *block_3_15, uint8_t *user_data, uint8_t key_b[6])
mifare get the sector permission
uint8_t mifare_classic_value_read(mifare_classic_handle_t *handle, uint8_t block, int32_t *value, uint8_t *addr)
mifare value read
uint8_t mifare_classic_transfer(mifare_classic_handle_t *handle, uint8_t block)
mifare transfer
uint8_t mifare_classic_write(mifare_classic_handle_t *handle, uint8_t block, uint8_t data[16])
mifare write
uint8_t mifare_classic_increment(mifare_classic_handle_t *handle, uint8_t block, uint32_t value)
mifare increment
uint8_t mifare_classic_set_modulation(mifare_classic_handle_t *handle, mifare_classic_load_modulation_t mod)
mifare set the load modulation
mifare_classic_type_t
mifare_classic type enumeration definition
uint8_t mifare_classic_anticollision_cl1(mifare_classic_handle_t *handle, uint8_t id[4])
mifare anti collision cl1
uint8_t mifare_classic_sector_block_count(mifare_classic_handle_t *handle, uint8_t sector, uint8_t *count)
mifare get the sector's block counter
uint8_t mifare_classic_deinit(mifare_classic_handle_t *handle)
close the chip
uint8_t mifare_classic_wake_up(mifare_classic_handle_t *handle, mifare_classic_type_t *type)
mifare wake up
uint8_t mifare_classic_restore(mifare_classic_handle_t *handle, uint8_t block)
mifare restore
uint8_t mifare_classic_init(mifare_classic_handle_t *handle)
initialize the chip
uint8_t mifare_classic_info(mifare_classic_info_t *info)
get chip information
mifare_classic_authentication_key_t
mifare_classic authentication key enumeration definition
@ MIFARE_CLASSIC_TYPE_S50
@ MIFARE_CLASSIC_TYPE_S70
@ MIFARE_CLASSIC_TYPE_INVALID
@ MIFARE_CLASSIC_AUTHENTICATION_KEY_A
uint8_t mifare_classic_transceiver(mifare_classic_handle_t *handle, uint8_t *in_buf, uint8_t in_len, uint8_t *out_buf, uint8_t *out_len)
transceiver data
void(* delay_ms)(uint32_t ms)
void(* debug_print)(const char *const fmt,...)
uint8_t(* contactless_transceiver)(uint8_t *in_buf, uint8_t in_len, uint8_t *out_buf, uint8_t *out_len)