+bool Pack_Kastle(/*in*/hidproxcard_t* card, /*out*/hidproxmessage_t* packed){
+ memset(packed, 0, sizeof(hidproxmessage_t));
+ if (card->FacilityCode > 0x00FF) return false; // Can't encode FC.
+ if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN.
+ if (card->IssueLevel > 0x001F) return false; // IL is only 5 bits.
+ if (card->OEM > 0) return false; // Not used in this format
+ packed->Length = 32; // Set number of bits
+ set_bit_by_position(packed, 1, 1); // Always 1
+ set_linear_field(packed, card->IssueLevel, 2, 5);
+ set_linear_field(packed, card->FacilityCode, 7, 8);
+ set_linear_field(packed, card->CardNumber, 15, 16);
+ set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0);
+ set_bit_by_position(packed, oddparity32(get_linear_field(packed, 14, 17)), 31);
+ return add_HID_header(packed);
+}
+bool Unpack_Kastle(/*in*/hidproxmessage_t* packed, /*out*/hidproxcard_t* card){
+ memset(card, 0, sizeof(hidproxcard_t));
+ if (packed->Length != 32) return false; // Wrong length? Stop here.
+ if (get_bit_by_position(packed, 1) != 1) return false; // Always 1 in this format
+ card->IssueLevel = get_linear_field(packed, 2, 5);
+ card->FacilityCode = get_linear_field(packed, 7, 8);
+ card->CardNumber = get_linear_field(packed, 15, 16);
+ card->ParityValid =
+ (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) &&
+ (get_bit_by_position(packed, 31) == oddparity32(get_linear_field(packed, 14, 17)));
+ return true;
+}
+