protocol_indala26.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #include <furi.h>
  2. #include <toolbox/protocols/protocol.h>
  3. #include <lfrfid/tools/bit_lib.h>
  4. #include "lfrfid_protocols.h"
  5. #define INDALA26_PREAMBLE_BIT_SIZE (33)
  6. #define INDALA26_PREAMBLE_DATA_SIZE (5)
  7. #define INDALA26_ENCODED_BIT_SIZE (64)
  8. #define INDALA26_ENCODED_DATA_SIZE \
  9. (((INDALA26_ENCODED_BIT_SIZE) / 8) + INDALA26_PREAMBLE_DATA_SIZE)
  10. #define INDALA26_ENCODED_DATA_LAST ((INDALA26_ENCODED_BIT_SIZE) / 8)
  11. #define INDALA26_DECODED_BIT_SIZE (28)
  12. #define INDALA26_DECODED_DATA_SIZE (4)
  13. #define INDALA26_US_PER_BIT (255)
  14. #define INDALA26_ENCODER_PULSES_PER_BIT (16)
  15. typedef struct {
  16. uint8_t data_index;
  17. uint8_t bit_clock_index;
  18. bool last_bit;
  19. bool current_polarity;
  20. bool pulse_phase;
  21. } ProtocolIndalaEncoder;
  22. typedef struct {
  23. uint8_t encoded_data[INDALA26_ENCODED_DATA_SIZE];
  24. uint8_t negative_encoded_data[INDALA26_ENCODED_DATA_SIZE];
  25. uint8_t corrupted_encoded_data[INDALA26_ENCODED_DATA_SIZE];
  26. uint8_t corrupted_negative_encoded_data[INDALA26_ENCODED_DATA_SIZE];
  27. uint8_t data[INDALA26_DECODED_DATA_SIZE];
  28. ProtocolIndalaEncoder encoder;
  29. } ProtocolIndala;
  30. ProtocolIndala* protocol_indala26_alloc(void) {
  31. ProtocolIndala* protocol = malloc(sizeof(ProtocolIndala));
  32. return protocol;
  33. };
  34. void protocol_indala26_free(ProtocolIndala* protocol) {
  35. free(protocol);
  36. };
  37. uint8_t* protocol_indala26_get_data(ProtocolIndala* protocol) {
  38. return protocol->data;
  39. };
  40. void protocol_indala26_decoder_start(ProtocolIndala* protocol) {
  41. memset(protocol->encoded_data, 0, INDALA26_ENCODED_DATA_SIZE);
  42. memset(protocol->negative_encoded_data, 0, INDALA26_ENCODED_DATA_SIZE);
  43. memset(protocol->corrupted_encoded_data, 0, INDALA26_ENCODED_DATA_SIZE);
  44. memset(protocol->corrupted_negative_encoded_data, 0, INDALA26_ENCODED_DATA_SIZE);
  45. };
  46. static bool protocol_indala26_check_preamble(uint8_t* data, size_t bit_index) {
  47. // Preamble 10100000 00000000 00000000 00000000 1
  48. if(*(uint32_t*)&data[bit_index / 8] != 0b00000000000000000000000010100000) return false;
  49. if(bit_lib_get_bit(data, bit_index + 32) != 1) return false;
  50. return true;
  51. }
  52. static bool protocol_indala26_can_be_decoded(uint8_t* data) {
  53. if(!protocol_indala26_check_preamble(data, 0)) return false;
  54. if(!protocol_indala26_check_preamble(data, 64)) return false;
  55. if(bit_lib_get_bit(data, 61) != 0) return false;
  56. if(bit_lib_get_bit(data, 60) != 0) return false;
  57. return true;
  58. }
  59. static bool protocol_indala26_decoder_feed_internal(bool polarity, uint32_t time, uint8_t* data) {
  60. time += (INDALA26_US_PER_BIT / 2);
  61. size_t bit_count = (time / INDALA26_US_PER_BIT);
  62. bool result = false;
  63. if(bit_count < INDALA26_ENCODED_BIT_SIZE) {
  64. for(size_t i = 0; i < bit_count; i++) {
  65. bit_lib_push_bit(data, INDALA26_ENCODED_DATA_SIZE, polarity);
  66. if(protocol_indala26_can_be_decoded(data)) {
  67. result = true;
  68. break;
  69. }
  70. }
  71. }
  72. return result;
  73. }
  74. static void protocol_indala26_decoder_save(uint8_t* data_to, const uint8_t* data_from) {
  75. bit_lib_copy_bits(data_to, 0, 22, data_from, 33);
  76. bit_lib_copy_bits(data_to, 22, 5, data_from, 55);
  77. bit_lib_copy_bits(data_to, 27, 2, data_from, 62);
  78. }
  79. bool protocol_indala26_decoder_feed(ProtocolIndala* protocol, bool level, uint32_t duration) {
  80. bool result = false;
  81. if(duration > (INDALA26_US_PER_BIT / 2)) {
  82. if(protocol_indala26_decoder_feed_internal(level, duration, protocol->encoded_data)) {
  83. protocol_indala26_decoder_save(protocol->data, protocol->encoded_data);
  84. FURI_LOG_D("Indala26", "Positive");
  85. result = true;
  86. return result;
  87. }
  88. if(protocol_indala26_decoder_feed_internal(
  89. !level, duration, protocol->negative_encoded_data)) {
  90. protocol_indala26_decoder_save(protocol->data, protocol->negative_encoded_data);
  91. FURI_LOG_D("Indala26", "Negative");
  92. result = true;
  93. return result;
  94. }
  95. }
  96. if(duration > (INDALA26_US_PER_BIT / 4)) {
  97. // Try to decode wrong phase synced data
  98. if(level) {
  99. duration += 120;
  100. } else {
  101. if(duration > 120) {
  102. duration -= 120;
  103. }
  104. }
  105. if(protocol_indala26_decoder_feed_internal(
  106. level, duration, protocol->corrupted_encoded_data)) {
  107. protocol_indala26_decoder_save(protocol->data, protocol->corrupted_encoded_data);
  108. FURI_LOG_D("Indala26", "Positive Corrupted");
  109. result = true;
  110. return result;
  111. }
  112. if(protocol_indala26_decoder_feed_internal(
  113. !level, duration, protocol->corrupted_negative_encoded_data)) {
  114. protocol_indala26_decoder_save(
  115. protocol->data, protocol->corrupted_negative_encoded_data);
  116. FURI_LOG_D("Indala26", "Negative Corrupted");
  117. result = true;
  118. return result;
  119. }
  120. }
  121. return result;
  122. };
  123. bool protocol_indala26_encoder_start(ProtocolIndala* protocol) {
  124. memset(protocol->encoded_data, 0, INDALA26_ENCODED_DATA_SIZE);
  125. *(uint32_t*)&protocol->encoded_data[0] = 0b00000000000000000000000010100000;
  126. bit_lib_set_bit(protocol->encoded_data, 32, 1);
  127. bit_lib_copy_bits(protocol->encoded_data, 33, 22, protocol->data, 0);
  128. bit_lib_copy_bits(protocol->encoded_data, 55, 5, protocol->data, 22);
  129. bit_lib_copy_bits(protocol->encoded_data, 62, 2, protocol->data, 27);
  130. protocol->encoder.last_bit =
  131. bit_lib_get_bit(protocol->encoded_data, INDALA26_ENCODED_BIT_SIZE - 1);
  132. protocol->encoder.data_index = 0;
  133. protocol->encoder.current_polarity = true;
  134. protocol->encoder.pulse_phase = true;
  135. protocol->encoder.bit_clock_index = 0;
  136. return true;
  137. };
  138. LevelDuration protocol_indala26_encoder_yield(ProtocolIndala* protocol) {
  139. LevelDuration level_duration;
  140. ProtocolIndalaEncoder* encoder = &protocol->encoder;
  141. if(encoder->pulse_phase) {
  142. level_duration = level_duration_make(encoder->current_polarity, 1);
  143. encoder->pulse_phase = false;
  144. } else {
  145. level_duration = level_duration_make(!encoder->current_polarity, 1);
  146. encoder->pulse_phase = true;
  147. encoder->bit_clock_index++;
  148. if(encoder->bit_clock_index >= INDALA26_ENCODER_PULSES_PER_BIT) {
  149. encoder->bit_clock_index = 0;
  150. bool current_bit = bit_lib_get_bit(protocol->encoded_data, encoder->data_index);
  151. if(current_bit != encoder->last_bit) {
  152. encoder->current_polarity = !encoder->current_polarity;
  153. }
  154. encoder->last_bit = current_bit;
  155. bit_lib_increment_index(encoder->data_index, INDALA26_ENCODED_BIT_SIZE);
  156. }
  157. }
  158. return level_duration;
  159. };
  160. // factory code
  161. static uint8_t get_fc(const uint8_t* data) {
  162. uint8_t fc = 0;
  163. fc = fc << 1 | bit_lib_get_bit(data, 24);
  164. fc = fc << 1 | bit_lib_get_bit(data, 16);
  165. fc = fc << 1 | bit_lib_get_bit(data, 11);
  166. fc = fc << 1 | bit_lib_get_bit(data, 14);
  167. fc = fc << 1 | bit_lib_get_bit(data, 15);
  168. fc = fc << 1 | bit_lib_get_bit(data, 20);
  169. fc = fc << 1 | bit_lib_get_bit(data, 6);
  170. fc = fc << 1 | bit_lib_get_bit(data, 25);
  171. return fc;
  172. }
  173. // card number
  174. static uint16_t get_cn(const uint8_t* data) {
  175. uint16_t cn = 0;
  176. cn = cn << 1 | bit_lib_get_bit(data, 9);
  177. cn = cn << 1 | bit_lib_get_bit(data, 12);
  178. cn = cn << 1 | bit_lib_get_bit(data, 10);
  179. cn = cn << 1 | bit_lib_get_bit(data, 7);
  180. cn = cn << 1 | bit_lib_get_bit(data, 19);
  181. cn = cn << 1 | bit_lib_get_bit(data, 3);
  182. cn = cn << 1 | bit_lib_get_bit(data, 2);
  183. cn = cn << 1 | bit_lib_get_bit(data, 18);
  184. cn = cn << 1 | bit_lib_get_bit(data, 13);
  185. cn = cn << 1 | bit_lib_get_bit(data, 0);
  186. cn = cn << 1 | bit_lib_get_bit(data, 4);
  187. cn = cn << 1 | bit_lib_get_bit(data, 21);
  188. cn = cn << 1 | bit_lib_get_bit(data, 23);
  189. cn = cn << 1 | bit_lib_get_bit(data, 26);
  190. cn = cn << 1 | bit_lib_get_bit(data, 17);
  191. cn = cn << 1 | bit_lib_get_bit(data, 8);
  192. return cn;
  193. }
  194. void protocol_indala26_render_data_internal(
  195. ProtocolIndala* protocol,
  196. FuriString* result,
  197. bool brief) {
  198. bool wiegand_correct = true;
  199. bool checksum_correct = true;
  200. const uint8_t fc = get_fc(protocol->data);
  201. const uint16_t card = get_cn(protocol->data);
  202. const uint32_t fc_and_card = fc << 16 | card;
  203. const uint8_t checksum = bit_lib_get_bit(protocol->data, 27) << 1 |
  204. bit_lib_get_bit(protocol->data, 28);
  205. const bool even_parity = bit_lib_get_bit(protocol->data, 1);
  206. const bool odd_parity = bit_lib_get_bit(protocol->data, 5);
  207. // indala checksum
  208. uint8_t checksum_sum = 0;
  209. checksum_sum += ((fc_and_card >> 14) & 1);
  210. checksum_sum += ((fc_and_card >> 12) & 1);
  211. checksum_sum += ((fc_and_card >> 9) & 1);
  212. checksum_sum += ((fc_and_card >> 8) & 1);
  213. checksum_sum += ((fc_and_card >> 6) & 1);
  214. checksum_sum += ((fc_and_card >> 5) & 1);
  215. checksum_sum += ((fc_and_card >> 2) & 1);
  216. checksum_sum += ((fc_and_card >> 0) & 1);
  217. checksum_sum = checksum_sum & 0b1;
  218. if(checksum_sum == 1 && checksum == 0b01) {
  219. } else if(checksum_sum == 0 && checksum == 0b10) {
  220. } else {
  221. checksum_correct = false;
  222. }
  223. // wiegand parity
  224. uint8_t even_parity_sum = 0;
  225. for(int8_t i = 12; i < 24; i++) {
  226. if(((fc_and_card >> i) & 1) == 1) {
  227. even_parity_sum++;
  228. }
  229. }
  230. if(even_parity_sum % 2 != even_parity) wiegand_correct = false;
  231. uint8_t odd_parity_sum = 1;
  232. for(int8_t i = 0; i < 12; i++) {
  233. if(((fc_and_card >> i) & 1) == 1) {
  234. odd_parity_sum++;
  235. }
  236. }
  237. if(odd_parity_sum % 2 != odd_parity) wiegand_correct = false;
  238. if(brief) {
  239. furi_string_printf(
  240. result,
  241. "FC: %u\r\nCard: %u, Parity:%s%s",
  242. fc,
  243. card,
  244. (checksum_correct ? "+" : "-"),
  245. (wiegand_correct ? "+" : "-"));
  246. } else {
  247. furi_string_printf(
  248. result,
  249. "FC: %u\r\n"
  250. "Card: %u\r\n"
  251. "Checksum: %s\r\n"
  252. "W26 Parity: %s",
  253. fc,
  254. card,
  255. (checksum_correct ? "+" : "-"),
  256. (wiegand_correct ? "+" : "-"));
  257. }
  258. }
  259. void protocol_indala26_render_data(ProtocolIndala* protocol, FuriString* result) {
  260. protocol_indala26_render_data_internal(protocol, result, false);
  261. }
  262. void protocol_indala26_render_brief_data(ProtocolIndala* protocol, FuriString* result) {
  263. protocol_indala26_render_data_internal(protocol, result, true);
  264. }
  265. bool protocol_indala26_write_data(ProtocolIndala* protocol, void* data) {
  266. LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data;
  267. bool result = false;
  268. protocol_indala26_encoder_start(protocol);
  269. if(request->write_type == LFRFIDWriteTypeT5577) {
  270. request->t5577.block[0] = LFRFID_T5577_BITRATE_RF_32 | LFRFID_T5577_MODULATION_PSK1 |
  271. (2 << LFRFID_T5577_MAXBLOCK_SHIFT);
  272. request->t5577.block[1] = bit_lib_get_bits_32(protocol->encoded_data, 0, 32);
  273. request->t5577.block[2] = bit_lib_get_bits_32(protocol->encoded_data, 32, 32);
  274. request->t5577.blocks_to_write = 3;
  275. result = true;
  276. }
  277. return result;
  278. };
  279. const ProtocolBase protocol_indala26 = {
  280. .name = "Indala26",
  281. .manufacturer = "Motorola",
  282. .data_size = INDALA26_DECODED_DATA_SIZE,
  283. .features = LFRFIDFeaturePSK,
  284. .validate_count = 6,
  285. .alloc = (ProtocolAlloc)protocol_indala26_alloc,
  286. .free = (ProtocolFree)protocol_indala26_free,
  287. .get_data = (ProtocolGetData)protocol_indala26_get_data,
  288. .decoder =
  289. {
  290. .start = (ProtocolDecoderStart)protocol_indala26_decoder_start,
  291. .feed = (ProtocolDecoderFeed)protocol_indala26_decoder_feed,
  292. },
  293. .encoder =
  294. {
  295. .start = (ProtocolEncoderStart)protocol_indala26_encoder_start,
  296. .yield = (ProtocolEncoderYield)protocol_indala26_encoder_yield,
  297. },
  298. .render_data = (ProtocolRenderData)protocol_indala26_render_data,
  299. .render_brief_data = (ProtocolRenderData)protocol_indala26_render_brief_data,
  300. .write_data = (ProtocolWriteData)protocol_indala26_write_data,
  301. };