-#include "parity.h" // for parity
-#include "util.h" // for param_get8,32
-
-static int CmdHelp(const char *Cmd);
-
-
-/**
- * Packs a "short" (<38-bit) HID ID from component parts.
- *
- * This only works with 26, 34, 35 and 37 bit card IDs.
- *
- * NOTE: Parity calculation is only supported on 26-bit tags. Other card lengths
- * may have invalid parity.
- *
- * Returns false on invalid inputs.
- */
-bool pack_short_hid(/* out */ uint32_t *hi, /* out */ uint32_t *lo, /* in */ const short_hid_info *info) {
- uint32_t high = 0, low = 0;
-
- switch (info->fmtLen) {
- case 26: // HID H10301
- low |= (info->cardnum & 0xffff) << 1;
- low |= (info->fc & 0xff) << 17;
-
- if (info->parityValid) {
- // Calculate parity
- low |= oddparity32((low >> 1) & 0xfff) & 1;
- low |= (evenparity32((low >> 13) & 0xfff) & 1) << 25;
- }
- break;
-
- case 34:
- low |= (info->cardnum & 0xffff) << 1;
- low |= (info->fc & 0x7fff) << 17;
- high |= (info->fc & 0x8000) >> 15;
- // TODO: Calculate parity
- break;
-
- case 35:
- low |= (info->cardnum & 0xfffff) << 1;
- low |= (info->fc & 0x7ff) << 21;
- high |= (info->fc & 0x800) >> 11;
- // TODO: Calculate parity
- break;
-
- case 37:
- low |= (info->cardnum & 0x7ffff) << 1;
- low |= (info->fc & 0xfff) << 20;
- high |= (info->fc & 0xf000) >> 12;
- // TODO: Calculate parity
- break;
-
- default:
- // Invalid / unsupported length
- return false;
- }
-
- // Set the highest bit
- if (info->fmtLen != 37) {
- // Bit 37 is always set
- high |= 0x20;
-
- // Set the bit corresponding to the length.
- if (info->fmtLen < 32) {
- low |= 1 << info->fmtLen;
- } else {
- high |= 1 << (info->fmtLen - 32);
- }
- }
-
- // Return result only if successful.
- *hi = high;
- *lo = low;
- return true;
-}
-
-
-/**
- * Unpacks a "short" (<38-bit) HID ID into its component parts.
- *
- * This only works with 26, 34, 35 and 37 bit card IDs.
- *
- * NOTE: Parity checking is only supported on 26-bit tags.
- *
- * Returns false on invalid inputs.
- */
-bool unpack_short_hid(short_hid_info *out, uint32_t hi, uint32_t lo) {
- memset(out, 0, sizeof(short_hid_info));
-
- if (((hi >> 5) & 1) == 1) {
- // if bit 38 is set then < 37 bit format is used
- uint32_t lo2 = 0;
- // get bits 21-37 to check for format len bit
- lo2 = (((hi & 31) << 12) | (lo >> 20));
- uint8_t idx3 = 1;
- // find last bit set to 1 (format len bit)
- while (lo2 > 1) {
- lo2 = lo2 >> 1;
- idx3++;
- }
-
- out->fmtLen = idx3 + 19;
-
- switch (out->fmtLen) {
- case 26: // HID H10301
- out->cardnum = (lo >> 1) & 0xFFFF;
- out->fc = (lo >> 17) & 0xFF;
-
- if (g_debugMode) {
- PrintAndLog("oddparity : input=%x, calculated=%d, provided=%d",
- (lo >> 1) & 0xFFF, oddparity32((lo >> 1) & 0xFFF), lo & 1);
- PrintAndLog("evenparity: input=%x, calculated=%d, provided=%d",
- (lo >> 13) & 0xFFF, evenparity32((lo >> 13) & 0xFFF) & 1, (lo >> 25) & 1);
- }
-
- out->parityValid =
- (oddparity32((lo >> 1) & 0xFFF) == (lo & 1)) &&
- ((evenparity32((lo >> 13) & 0xFFF) & 1) == ((lo >> 25) & 1));
- break;
-
- case 34:
- out->cardnum = (lo >> 1) & 0xFFFF;
- out->fc = ((hi & 1) << 15) | (lo >> 17);
- // TODO: Calculate parity
- break;
-
- case 35:
- out->cardnum = (lo >> 1) & 0xFFFFF;
- out->fc = ((hi & 1) << 11) | (lo >> 21);
- // TODO: Calculate parity
- break;
-
- default:
- return false;
- }
- } else {
- // If bit 38 is not set, then 37 bit format is used
- out->fmtLen = 37;
- out->cardnum = (lo >> 1) & 0x7FFFF;
- out->fc = ((hi & 0xF) << 12) | (lo >> 20);
- // TODO: Calculate parity
- }
- return true;
-}