rfid_decoder.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (c) 2019 Clementine Computing LLC.
  3. *
  4. * This file is part of PopuFare.
  5. *
  6. * PopuFare is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * PopuFare is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
  18. *
  19. */
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include "../common/common_defs.h"
  24. typedef struct rfid_decode_pattern_struct
  25. {
  26. unsigned int bits;
  27. unsigned int shift;
  28. unsigned long long mask;
  29. unsigned long long match;
  30. unsigned int site_shift;
  31. unsigned long long site_mask;
  32. unsigned int id_shift;
  33. unsigned long long id_mask;
  34. } rfid_decode_pattern;
  35. static rfid_decode_pattern rfid_pattern_buffer[NUM_RFID_PATTERNS] = {{0}};
  36. static int rfid_pattern_used = -1;
  37. int rfid_pattern_loaded()
  38. {
  39. return rfid_pattern_used;
  40. }
  41. int load_rfid_decode_patterns(char *filename)
  42. {
  43. char line[LINE_BUFFER_SIZE];
  44. int i, retval;
  45. FILE *f;
  46. char *c;
  47. if(!filename)
  48. {
  49. fprintf(stderr, "Cannot open RFID Pattern Match file %s", "(null)");
  50. rfid_pattern_used = -1;
  51. return -1;
  52. }
  53. i = 0;
  54. f = fopen(filename, "rb");
  55. if(!f)
  56. {
  57. fprintf(stderr, "Cannot open RFID Pattern Match file %s", filename);
  58. rfid_pattern_used = -1;
  59. return -1;
  60. }
  61. while(i < NUM_RFID_PATTERNS)
  62. {
  63. fgets(line, LINE_BUFFER_SIZE, f);
  64. if(feof(f))
  65. {
  66. break;
  67. }
  68. c = line;
  69. //skip any blank lines, or comment lines starting with a # as their first non-whitespace character
  70. while( (*c == ' ') || (*c == '\t') || (*c == '\r') || (*c == '\n') ) c++;
  71. if( (*c == '#') || (*c == '\0') ) continue;
  72. retval = sscanf(c, "%x %x %llx %llx %x %llx %x %llx", &rfid_pattern_buffer[i].bits, &rfid_pattern_buffer[i].shift,
  73. &rfid_pattern_buffer[i].mask, &rfid_pattern_buffer[i].match,
  74. &rfid_pattern_buffer[i].site_shift, &rfid_pattern_buffer[i].site_mask,
  75. &rfid_pattern_buffer[i].id_shift, &rfid_pattern_buffer[i].id_mask
  76. );
  77. if(retval == 8)
  78. {
  79. i++;
  80. }
  81. else
  82. {
  83. memset(&rfid_pattern_buffer[i], 0, sizeof(rfid_decode_pattern));
  84. fprintf(stderr, "Cannot parse RFID Pattern Match line \"%s\"\n", line);
  85. }
  86. }
  87. fclose(f);
  88. if(i >= NUM_RFID_PATTERNS)
  89. {
  90. fprintf(stderr, "RFID Pattern Match file %s contains more than %d records!", filename, NUM_RFID_PATTERNS);
  91. rfid_pattern_used = -1;
  92. return -1;
  93. }
  94. memset(&rfid_pattern_buffer[i], 0, sizeof(rfid_decode_pattern));
  95. rfid_pattern_used = i;
  96. return i;
  97. }
  98. int decode_rfid_string(char *raw_rfid, unsigned long long *site, unsigned long long *id, unsigned int *bits)
  99. {
  100. unsigned long long raw;
  101. unsigned int nbits;
  102. char *rest;
  103. int i;
  104. if(!raw_rfid)
  105. {
  106. fprintf(stderr, "NULL RFID String!\n");
  107. return -1;
  108. }
  109. if(rfid_pattern_used < 1)
  110. {
  111. fprintf(stderr, "rfid_pattern_used < 1!\n");
  112. }
  113. nbits = strtol(raw_rfid, &rest, 16);
  114. if(*rest++ != '|')
  115. {
  116. fprintf(stderr, "Malformed RFID String!\n");
  117. return -1;
  118. }
  119. raw = strtoll(rest, NULL, 16);
  120. for(i = 0; i < rfid_pattern_used; i++)
  121. {
  122. //If this RFID string has the right number of bits AND matches our shift-and-mask criteria
  123. if( (nbits == rfid_pattern_buffer[i].bits) &&
  124. (((raw >> rfid_pattern_buffer[i].shift) & rfid_pattern_buffer[i].mask) == rfid_pattern_buffer[i].match)
  125. )
  126. {
  127. if(bits)
  128. {
  129. *bits = nbits;
  130. }
  131. if(site)
  132. {
  133. *site = (raw >> rfid_pattern_buffer[i].site_shift) & rfid_pattern_buffer[i].site_mask;
  134. }
  135. if(id)
  136. {
  137. *id = (raw >> rfid_pattern_buffer[i].id_shift) & rfid_pattern_buffer[i].id_mask;
  138. }
  139. return 0;
  140. }
  141. }
  142. return -1;
  143. }