picopass_poller_i.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "picopass_poller_i.h"
  2. #include <nfc/helpers/iso14443_crc.h>
  3. #define PICOPASS_POLLER_FWT_FC (100000)
  4. #define TAG "Picopass"
  5. static PicopassError picopass_poller_process_error(NfcError error) {
  6. PicopassError ret = PicopassErrorNone;
  7. switch(error) {
  8. case NfcErrorNone:
  9. ret = PicopassErrorNone;
  10. break;
  11. default:
  12. ret = PicopassErrorTimeout;
  13. break;
  14. }
  15. return ret;
  16. }
  17. static PicopassError picopass_poller_send_frame(
  18. PicopassPoller* instance,
  19. BitBuffer* tx_buffer,
  20. BitBuffer* rx_buffer,
  21. uint32_t fwt_fc) {
  22. PicopassError ret = PicopassErrorNone;
  23. do {
  24. NfcError error = nfc_poller_trx(instance->nfc, tx_buffer, rx_buffer, fwt_fc);
  25. if(error != NfcErrorNone) {
  26. ret = picopass_poller_process_error(error);
  27. break;
  28. }
  29. if(!iso13239_crc_check(Iso13239CrcTypePicopass, rx_buffer)) {
  30. ret = PicopassErrorIncorrectCrc;
  31. break;
  32. }
  33. iso13239_crc_trim(instance->rx_buffer);
  34. } while(false);
  35. return ret;
  36. }
  37. PicopassError picopass_poller_actall(PicopassPoller* instance) {
  38. PicopassError ret = PicopassErrorNone;
  39. bit_buffer_reset(instance->tx_buffer);
  40. bit_buffer_append_byte(instance->tx_buffer, RFAL_PICOPASS_CMD_ACTALL);
  41. NfcError error = nfc_poller_trx(
  42. instance->nfc, instance->tx_buffer, instance->rx_buffer, PICOPASS_POLLER_FWT_FC);
  43. if(error != NfcErrorIncompleteFrame) {
  44. ret = picopass_poller_process_error(error);
  45. }
  46. return ret;
  47. }
  48. PicopassError picopass_poller_identify(
  49. PicopassPoller* instance,
  50. PicopassColResSerialNum* col_res_serial_num) {
  51. PicopassError ret = PicopassErrorNone;
  52. do {
  53. bit_buffer_reset(instance->tx_buffer);
  54. bit_buffer_append_byte(instance->tx_buffer, RFAL_PICOPASS_CMD_READ_OR_IDENTIFY);
  55. ret = picopass_poller_send_frame(
  56. instance, instance->tx_buffer, instance->rx_buffer, PICOPASS_POLLER_FWT_FC);
  57. if(ret != PicopassErrorNone) break;
  58. if(bit_buffer_get_size_bytes(instance->rx_buffer) != sizeof(PicopassColResSerialNum)) {
  59. ret = PicopassErrorProtocol;
  60. break;
  61. }
  62. bit_buffer_write_bytes(
  63. instance->rx_buffer, col_res_serial_num->data, sizeof(PicopassColResSerialNum));
  64. } while(false);
  65. return ret;
  66. }
  67. PicopassError picopass_poller_select(
  68. PicopassPoller* instance,
  69. PicopassColResSerialNum* col_res_serial_num,
  70. PicopassSerialNum* serial_num) {
  71. PicopassError ret = PicopassErrorNone;
  72. do {
  73. bit_buffer_reset(instance->tx_buffer);
  74. bit_buffer_append_byte(instance->tx_buffer, RFAL_PICOPASS_CMD_SELECT);
  75. bit_buffer_append_bytes(
  76. instance->tx_buffer, col_res_serial_num->data, sizeof(PicopassColResSerialNum));
  77. ret = picopass_poller_send_frame(
  78. instance, instance->tx_buffer, instance->rx_buffer, PICOPASS_POLLER_FWT_FC);
  79. if(ret != PicopassErrorNone) break;
  80. if(bit_buffer_get_size_bytes(instance->rx_buffer) != sizeof(PicopassSerialNum)) {
  81. ret = PicopassErrorProtocol;
  82. break;
  83. }
  84. bit_buffer_write_bytes(instance->rx_buffer, serial_num->data, sizeof(PicopassSerialNum));
  85. } while(false);
  86. return ret;
  87. }
  88. PicopassError
  89. picopass_poller_read_block(PicopassPoller* instance, uint8_t block_num, PicopassBlock* block) {
  90. PicopassError ret = PicopassErrorNone;
  91. do {
  92. bit_buffer_reset(instance->tmp_buffer);
  93. bit_buffer_append_byte(instance->tmp_buffer, block_num);
  94. iso13239_crc_append(Iso13239CrcTypePicopass, instance->tmp_buffer);
  95. bit_buffer_reset(instance->tx_buffer);
  96. bit_buffer_append_byte(instance->tx_buffer, RFAL_PICOPASS_CMD_READ_OR_IDENTIFY);
  97. bit_buffer_append(instance->tx_buffer, instance->tmp_buffer);
  98. ret = picopass_poller_send_frame(
  99. instance, instance->tx_buffer, instance->rx_buffer, PICOPASS_POLLER_FWT_FC);
  100. if(ret != PicopassErrorNone) break;
  101. if(bit_buffer_get_size_bytes(instance->rx_buffer) != PICOPASS_BLOCK_LEN) {
  102. ret = PicopassErrorProtocol;
  103. break;
  104. }
  105. bit_buffer_write_bytes(instance->rx_buffer, block->data, PICOPASS_BLOCK_LEN);
  106. } while(false);
  107. return ret;
  108. }
  109. PicopassError
  110. picopass_poller_read_check(PicopassPoller* instance, PicopassReadCheckResp* read_check_resp) {
  111. PicopassError ret = PicopassErrorNone;
  112. do {
  113. bit_buffer_reset(instance->tx_buffer);
  114. bit_buffer_append_byte(instance->tx_buffer, RFAL_PICOPASS_CMD_READCHECK_KD);
  115. bit_buffer_append_byte(instance->tx_buffer, 0x02);
  116. NfcError error = nfc_poller_trx(
  117. instance->nfc, instance->tx_buffer, instance->rx_buffer, PICOPASS_POLLER_FWT_FC);
  118. if(error != NfcErrorNone) {
  119. ret = picopass_poller_process_error(error);
  120. break;
  121. }
  122. if(bit_buffer_get_size_bytes(instance->rx_buffer) != sizeof(PicopassReadCheckResp)) {
  123. ret = PicopassErrorProtocol;
  124. break;
  125. }
  126. bit_buffer_write_bytes(
  127. instance->rx_buffer, read_check_resp->data, sizeof(PicopassReadCheckResp));
  128. } while(false);
  129. return ret;
  130. }
  131. PicopassError picopass_poller_check(
  132. PicopassPoller* instance,
  133. uint8_t* nr,
  134. PicopassMac* mac,
  135. PicopassCheckResp* check_resp) {
  136. PicopassError ret = PicopassErrorNone;
  137. uint8_t null_arr[4] = {};
  138. do {
  139. bit_buffer_reset(instance->tx_buffer);
  140. bit_buffer_append_byte(instance->tx_buffer, RFAL_PICOPASS_CMD_CHECK);
  141. if(nr) {
  142. bit_buffer_append_bytes(instance->tx_buffer, nr, 4);
  143. } else {
  144. bit_buffer_append_bytes(instance->tx_buffer, null_arr, sizeof(null_arr));
  145. }
  146. bit_buffer_append_bytes(instance->tx_buffer, mac->data, sizeof(PicopassMac));
  147. NfcError error = nfc_poller_trx(
  148. instance->nfc, instance->tx_buffer, instance->rx_buffer, PICOPASS_POLLER_FWT_FC);
  149. if(error != NfcErrorNone) {
  150. ret = picopass_poller_process_error(error);
  151. break;
  152. }
  153. if(bit_buffer_get_size_bytes(instance->rx_buffer) != sizeof(PicopassCheckResp)) {
  154. ret = PicopassErrorProtocol;
  155. break;
  156. }
  157. bit_buffer_write_bytes(instance->rx_buffer, check_resp->data, sizeof(PicopassCheckResp));
  158. } while(false);
  159. return ret;
  160. }
  161. PicopassError picopass_poller_write_block(
  162. PicopassPoller* instance,
  163. uint8_t block_num,
  164. const PicopassBlock* block,
  165. const PicopassMac* mac) {
  166. PicopassError ret = PicopassErrorNone;
  167. do {
  168. bit_buffer_reset(instance->tx_buffer);
  169. bit_buffer_append_byte(instance->tx_buffer, RFAL_PICOPASS_CMD_UPDATE);
  170. bit_buffer_append_byte(instance->tx_buffer, block_num);
  171. bit_buffer_append_bytes(instance->tx_buffer, block->data, PICOPASS_BLOCK_LEN);
  172. bit_buffer_append_bytes(instance->tx_buffer, mac->data, sizeof(PicopassMac));
  173. NfcError error = nfc_poller_trx(
  174. instance->nfc, instance->tx_buffer, instance->rx_buffer, PICOPASS_POLLER_FWT_FC);
  175. if(error != NfcErrorNone) {
  176. ret = picopass_poller_process_error(error);
  177. break;
  178. }
  179. } while(false);
  180. return ret;
  181. }