From 10c9ea5f84cafce196d36cd2779a43b5c0259817 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 27 Apr 2021 15:19:34 +0200 Subject: [PATCH] more wiegand formats, and if binary is user supplied use that length, and ignore parity faults is removed since we wanna see all decodings anyway --- client/src/cmdhficlass.c | 8 +- client/src/cmdlfhid.c | 8 +- client/src/cmdwiegand.c | 17 +- client/src/wiegand_formats.c | 285 +++++++++++++++++++++---------- client/src/wiegand_formats.h | 2 +- client/src/wiegand_formatutils.c | 7 +- client/src/wiegand_formatutils.h | 2 +- 7 files changed, 213 insertions(+), 116 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index dcffce616..aad535214 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1309,8 +1309,8 @@ static int CmdHFiClassDecrypt(const char *Cmd) { PrintAndLogEx(SUCCESS, "Binary..................... " _GREEN_("%s"), binstr + i); PrintAndLogEx(INFO, "Wiegand decode"); - wiegand_message_t packed = initialize_message_object(top, mid, bot); - HIDTryUnpack(&packed, true); + wiegand_message_t packed = initialize_message_object(top, mid, bot, strlen(binstr + i)); + HIDTryUnpack(&packed); } else { PrintAndLogEx(INFO, "No credential found"); @@ -2335,8 +2335,8 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { PrintAndLogEx(SUCCESS, " bin : %s", binstr + i); PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "------------------------------ " _CYAN_("wiegand") " -------------------------------"); - wiegand_message_t packed = initialize_message_object(top, mid, bot); - HIDTryUnpack(&packed, true); + wiegand_message_t packed = initialize_message_object(top, mid, bot, strlen(binstr + i)); + HIDTryUnpack(&packed); } else { PrintAndLogEx(INFO, "no credential found"); } diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 882be2da5..c985ecbc0 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -140,8 +140,8 @@ int demodHID(bool verbose) { return PM3_ESOFT; } - wiegand_message_t packed = initialize_message_object(hi2, hi, lo); - if (HIDTryUnpack(&packed, false) == false) { + wiegand_message_t packed = initialize_message_object(hi2, hi, lo, 0); + if (HIDTryUnpack(&packed) == false) { printDemodBuff(0, false, false, true); } PrintAndLogEx(INFO, "raw: " _GREEN_("%08x%08x%08x"), hi2, hi, lo); @@ -292,7 +292,7 @@ static int CmdHIDSim(const char *Cmd) { if (raw_len == 0) { PrintAndLogEx(INFO, "Simulating HID tag"); - HIDTryUnpack(&packed, false); + HIDTryUnpack(&packed); } else { PrintAndLogEx(INFO, "Simulating HID tag using raw " _GREEN_("%s"), raw); } @@ -416,7 +416,7 @@ static int CmdHIDClone(const char *Cmd) { if (raw_len == 0) { PrintAndLogEx(INFO, "Preparing to clone HID tag"); - HIDTryUnpack(&packed, false); + HIDTryUnpack(&packed); } else { PrintAndLogEx(INFO, "Preparing to clone HID tag using raw " _YELLOW_("%s"), raw); } diff --git a/client/src/cmdwiegand.c b/client/src/cmdwiegand.c index c0c32abd8..e29db6a7b 100644 --- a/client/src/cmdwiegand.c +++ b/client/src/cmdwiegand.c @@ -107,27 +107,24 @@ int CmdWiegandDecode(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "wiegand decode", - "Decode raw hex to wiegand format", + "Decode raw hex or binary to wiegand format", "wiegand decode --raw 2006f623ae" ); void *argtable[] = { arg_param_begin, - arg_lit0("p", "parity", "ignore invalid parity"), arg_strx0("r", "raw", "", "raw hex to be decoded"), arg_str0("b", "bin", "", "binary string to be decoded"), arg_param_end }; - CLIExecWithReturn(ctx, Cmd, argtable, false); - - bool ignore_parity = arg_get_lit(ctx, 1); + CLIExecWithReturn(ctx, Cmd, argtable, true); int hlen = 0; char hex[40] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)hex, sizeof(hex), &hlen); + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)hex, sizeof(hex), &hlen); int blen = 0; uint8_t binarr[100] = {0x00}; - int res = CLIParamBinToBuf(arg_get_str(ctx, 3), binarr, sizeof(binarr), &blen); + int res = CLIParamBinToBuf(arg_get_str(ctx, 2), binarr, sizeof(binarr), &blen); CLIParserFree(ctx); if (res) { @@ -144,7 +141,7 @@ int CmdWiegandDecode(const char *Cmd) { return PM3_EINVARG; } } else if (blen) { - uint16_t n = binarray_to_u96(&top, &mid, &bot, binarr, blen); + int n = binarray_to_u96(&top, &mid, &bot, binarr, blen); if (n != blen) { PrintAndLogEx(ERR, "Binary string contains none <0|1> chars"); return PM3_EINVARG; @@ -153,8 +150,8 @@ int CmdWiegandDecode(const char *Cmd) { PrintAndLogEx(ERR, "empty input"); return PM3_EINVARG; } - wiegand_message_t packed = initialize_message_object(top, mid, bot); - HIDTryUnpack(&packed, ignore_parity); + wiegand_message_t packed = initialize_message_object(top, mid, bot, blen); + HIDTryUnpack(&packed); return PM3_SUCCESS; } diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index 711a50230..d4af63a69 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -163,7 +163,6 @@ static bool Unpack_indasc27(wiegand_message_t *packed, wiegand_card_t *card) { return true; } - static bool Pack_2804W(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) { memset(packed, 0, sizeof(wiegand_message_t)); @@ -293,6 +292,91 @@ static bool Unpack_ADT31(wiegand_message_t *packed, wiegand_card_t *card) { return true; } +static bool Pack_hcp32(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) { + + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0) return false; // Not used + if (card->CardNumber > 0x3FFF) return false; // 24 bits + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used + + packed->Length = 32; // Set number of bits + + set_linear_field(packed, card->CardNumber, 1, 24); + + if (preamble) + return add_HID_header(packed); + return true; +} + +static bool Unpack_hcp32(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 32) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 1, 24); + return true; +} + +static bool Pack_hpp32(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) { + + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) return false; // 12 bits + if (card->CardNumber > 0x1FFFFFFF) return false; // 29 bits + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used + + packed->Length = 32; // Set number of bits + + set_linear_field(packed, card->FacilityCode, 1, 12); + set_linear_field(packed, card->CardNumber, 13, 29); + + if (preamble) + return add_HID_header(packed); + return true; +} + +static bool Unpack_hpp32(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 32) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 12); + card->CardNumber = get_linear_field(packed, 13, 29); + return true; +} + +static bool Pack_wie32(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) { + + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) return false; // 12 bits + if (card->CardNumber > 0xFFFF) return false; // 16 bits + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0) return false; // Not used + + packed->Length = 32; // Set number of bits + + set_linear_field(packed, card->FacilityCode, 4, 12); + set_linear_field(packed, card->CardNumber, 16, 16); + + if (preamble) + return add_HID_header(packed); + return true; +} + +static bool Unpack_wie32(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 32) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 4, 12); + card->CardNumber = get_linear_field(packed, 16, 16); + return true; +} + static bool Pack_Kastle(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) { memset(packed, 0, sizeof(wiegand_message_t)); @@ -1109,6 +1193,88 @@ static bool Unpack_pw39(wiegand_message_t *packed, wiegand_card_t *card) { return true; } +// --------------------------------------------------------------------------------------------------- + +void print_desc_wiegand(cardformat_t *fmt, wiegand_message_t *packed) { + + char *s = calloc(128, sizeof(uint8_t)); + sprintf(s, _YELLOW_("%-10s")" %-30s", fmt->Name, fmt->Descrp); + + if (packed->Top != 0) { + PrintAndLogEx(SUCCESS, "%s -> " _GREEN_("%X%08X%08X"), + s, + (uint32_t)packed->Top, + (uint32_t)packed->Mid, + (uint32_t)packed->Bot + ); + } else { + PrintAndLogEx(SUCCESS, "%s -> " _YELLOW_("%X%08X"), + s, + (uint32_t)packed->Mid, + (uint32_t)packed->Bot + ); + } + free(s); +} + +void print_wiegand_code(wiegand_message_t *packed) { + const char *s = "Wiegand: "; + if (packed->Top != 0) { + PrintAndLogEx(SUCCESS, "%s" _GREEN_("%X%08X%08X"), + s, + (uint32_t)packed->Top, + (uint32_t)packed->Mid, + (uint32_t)packed->Bot + ); + } else { + PrintAndLogEx(SUCCESS, "%s" _YELLOW_("%X%08X"), + s, + (uint32_t)packed->Mid, + (uint32_t)packed->Bot + ); + } +} + +static void hid_print_card(wiegand_card_t *card, const cardformat_t format) { + + /* + PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); + + if (format.Fields.hasFacilityCode) + PrintAndLogEx(SUCCESS, "Facility Code: %d",card->FacilityCode); + + if (format.Fields.hasCardNumber) + PrintAndLogEx(SUCCESS, " Card Number: %d",card->CardNumber); + + if (format.Fields.hasIssueLevel) + PrintAndLogEx(SUCCESS, " Issue Level: %d",card->IssueLevel); + + if (format.Fields.hasOEMCode) + PrintAndLogEx(SUCCESS, " OEM Code: %d",card->OEM); + + if (format.Fields.hasParity) + PrintAndLogEx(SUCCESS, " Parity: %s",card->ParityValid ? "Valid" : "Invalid"); + */ + + char s[110] = {0}; + if (format.Fields.hasFacilityCode) + snprintf(s, sizeof(s), "FC: " _GREEN_("%u"), card->FacilityCode); + + if (format.Fields.hasCardNumber) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " CN: " _GREEN_("%"PRIu64), card->CardNumber); + + if (format.Fields.hasIssueLevel) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue: " _GREEN_("%u"), card->IssueLevel); + + if (format.Fields.hasOEMCode) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: " _GREEN_("%u"), card->OEM); + + if (format.Fields.hasParity) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity ( %s )", card->ParityValid ? _GREEN_("ok") : _RED_("fail")); + + PrintAndLogEx(SUCCESS, "[%-8s] %-30s %s", format.Name, format.Descrp, s); +} + static const cardformat_t FormatTable[] = { {"H10301", Pack_H10301, Unpack_H10301, "HID H10301 26-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack {"ind26", Pack_ind26, Unpack_ind26, "Indala 26-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au @@ -1119,13 +1285,16 @@ static const cardformat_t FormatTable[] = { {"ind29", Pack_ind29, Unpack_ind29, "Indala 29-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"ATSW30", Pack_ATSW30, Unpack_ATSW30, "ATS Wiegand 30-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"ADT31", Pack_ADT31, Unpack_ADT31, "HID ADT 31-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au + {"HCP32", Pack_hcp32, Unpack_hcp32, "HID Check Point 32-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au + {"HPP32", Pack_hpp32, Unpack_hpp32, "HID Hewlett-Packard 32-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"Kastle", Pack_Kastle, Unpack_Kastle, "Kastle 32-bit", {1, 1, 1, 0, 1}}, // from @xilni; PR #23 on RfidResearchGroup/proxmark3 {"Kantech", Pack_Kantech, Unpack_Kantech, "Indala/Kantech KFS 32-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au + {"WIE32", Pack_wie32, Unpack_wie32, "Wiegand 32-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"D10202", Pack_D10202, Unpack_D10202, "HID D10202 33-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"H10306", Pack_H10306, Unpack_H10306, "HID H10306 34-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack {"N10002", Pack_N10002, Unpack_N10002, "HID N10002 34-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au {"Optus34", Pack_Optus, Unpack_Optus, "Indala Optus 34-bit", {1, 1, 0, 0, 0}}, // from cardinfo.barkweb.com.au - {"Smartpass", Pack_Smartpass, Unpack_Smartpass, "Cardkey Smartpass 34-bit", {1, 1, 1, 0, 0}}, // from cardinfo.barkweb.com.au + {"SMP34", Pack_Smartpass, Unpack_Smartpass, "Cardkey Smartpass 34-bit", {1, 1, 1, 0, 0}}, // from cardinfo.barkweb.com.au {"BQT34", Pack_bqt34, Unpack_bqt34, "BQT 34-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"C1k35s", Pack_C1k35s, Unpack_C1k35s, "HID Corporate 1000 35-bit std", {1, 1, 0, 0, 1}}, // imported from old pack/unpack {"C15001", Pack_C15001, Unpack_C15001, "HID KeyScan 36-bit", {1, 1, 0, 1, 1}}, // from Proxmark forums @@ -1134,7 +1303,7 @@ static const cardformat_t FormatTable[] = { {"H10320", Pack_H10320, Unpack_H10320, "HID H10320 36-bit BCD", {1, 0, 0, 0, 1}}, // from Proxmark forums {"H10302", Pack_H10302, Unpack_H10302, "HID H10302 37-bit huge ID", {1, 0, 0, 0, 1}}, // from Proxmark forums {"H10304", Pack_H10304, Unpack_H10304, "HID H10304 37-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au - {"HGeneric37", Pack_HGeneric37, Unpack_HGeneric37, "HID Generic 37-bit", {1, 0, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"HGen37", Pack_HGeneric37, Unpack_HGeneric37, "HID Generic 37-bit", {1, 0, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"MDI37", Pack_MDI37, Unpack_MDI37, "PointGuard MDI 37-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au {"BQT38", Pack_bqt38, Unpack_bqt38, "BQT 38-bit", {1, 1, 1, 0, 1}}, // from cardinfo.barkweb.com.au {"ISCS", Pack_iscs38, Unpack_iscs38, "ISCS 38-bit", {1, 1, 0, 1, 1}}, // from cardinfo.barkweb.com.au @@ -1158,50 +1327,12 @@ void HIDListFormats(void) { PrintAndLogEx(INFO, _YELLOW_("%-10s")" %-30s", FormatTable[i].Name, FormatTable[i].Descrp); ++i; } + PrintAndLogEx(INFO, "------------------------------------------------------------"); + PrintAndLogEx(INFO, "Available card formats: " _YELLOW_("%u"), ARRAYLEN(FormatTable)); PrintAndLogEx(NORMAL, ""); return; } -void print_desc_wiegand(cardformat_t *fmt, wiegand_message_t *packed) { - - char *s = calloc(128, sizeof(uint8_t)); - sprintf(s, _YELLOW_("%-10s")" %-30s", fmt->Name, fmt->Descrp); - - if (packed->Top != 0) { - PrintAndLogEx(SUCCESS, "%s --> " _GREEN_("%X%08X%08X"), - s, - (uint32_t)packed->Top, - (uint32_t)packed->Mid, - (uint32_t)packed->Bot - ); - } else { - PrintAndLogEx(SUCCESS, "%s --> " _YELLOW_("%X%08X"), - s, - (uint32_t)packed->Mid, - (uint32_t)packed->Bot - ); - } - free(s); -} - -void print_wiegand_code(wiegand_message_t *packed) { - const char *s = "Encoded wiegand: "; - if (packed->Top != 0) { - PrintAndLogEx(SUCCESS, "%s" _GREEN_("%X%08X%08X"), - s, - (uint32_t)packed->Top, - (uint32_t)packed->Mid, - (uint32_t)packed->Bot - ); - } else { - PrintAndLogEx(SUCCESS, "%s" _YELLOW_("%X%08X"), - s, - (uint32_t)packed->Mid, - (uint32_t)packed->Bot - ); - } -} - cardformat_t HIDGetCardFormat(int idx) { return FormatTable[idx]; } @@ -1237,7 +1368,7 @@ bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed, bo void HIDPackTryAll(wiegand_card_t *card, bool preamble) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "%-10s %-30s --> Encoded wiegand", "Name", "Description"); + PrintAndLogEx(INFO, "%-10s %-30s -> wiegand", "Name", "Description"); PrintAndLogEx(INFO, "----------------------------------------------------------------------"); wiegand_message_t packed; @@ -1254,69 +1385,35 @@ void HIDPackTryAll(wiegand_card_t *card, bool preamble) { PrintAndLogEx(NORMAL, ""); } -static void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) { - - /* - PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); - - if (format.Fields.hasFacilityCode) - PrintAndLogEx(SUCCESS, "Facility Code: %d",card->FacilityCode); - - if (format.Fields.hasCardNumber) - PrintAndLogEx(SUCCESS, " Card Number: %d",card->CardNumber); - - if (format.Fields.hasIssueLevel) - PrintAndLogEx(SUCCESS, " Issue Level: %d",card->IssueLevel); - - if (format.Fields.hasOEMCode) - PrintAndLogEx(SUCCESS, " OEM Code: %d",card->OEM); - - if (format.Fields.hasParity) - PrintAndLogEx(SUCCESS, " Parity: %s",card->ParityValid ? "Valid" : "Invalid"); - */ - - char s[110] = {0}; - if (format.Fields.hasFacilityCode) - snprintf(s, sizeof(s), "FC: " _GREEN_("%u"), card->FacilityCode); - - if (format.Fields.hasCardNumber) - snprintf(s + strlen(s), sizeof(s) - strlen(s), " CN: " _GREEN_("%"PRIu64), card->CardNumber); - - if (format.Fields.hasIssueLevel) - snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue: " _GREEN_("%u"), card->IssueLevel); - - if (format.Fields.hasOEMCode) - snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: " _GREEN_("%u"), card->OEM); - - if (format.Fields.hasParity) - snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? _GREEN_("valid") : _RED_("invalid")); - - PrintAndLogEx(SUCCESS, "[%s] - %s %s", format.Name, format.Descrp, s); -} - -bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity) { +bool HIDTryUnpack(wiegand_message_t *packed) { if (FormatTable[0].Name == NULL) return false; - bool result = false; int i = 0; wiegand_card_t card; memset(&card, 0, sizeof(wiegand_card_t)); + uint8_t found_cnt = 0, found_invalid_par = 0; while (FormatTable[i].Name) { if (FormatTable[i].Unpack(packed, &card)) { - if (ignore_parity || !FormatTable[i].Fields.hasParity || card.ParityValid) { - result = true; - HIDDisplayUnpackedCard(&card, FormatTable[i]); - } + + found_cnt++; + hid_print_card(&card, FormatTable[i]); + + if (FormatTable[i].Fields.hasParity || card.ParityValid == false) + found_invalid_par++; } ++i; } - if (result == false && packed->Length) { - PrintAndLogEx(SUCCESS, "(wiegand unpack) unknown bit len %d", packed->Length); + + if (found_cnt) { + PrintAndLogEx(INFO, "found %u matching format%c", found_cnt, (found_cnt > 1) ? 's' : ' '); + } + + if (packed->Length && found_invalid_par == 0) { + PrintAndLogEx(WARNING, "Wiegand unknown bit len %d", packed->Length); PrintAndLogEx(HINT, "Try 0xFFFF's http://cardinfo.barkweb.com.au/"); } - return result; + return ((found_cnt - found_invalid_par) > 0); } - diff --git a/client/src/wiegand_formats.h b/client/src/wiegand_formats.h index 921b1840a..080784ae2 100644 --- a/client/src/wiegand_formats.h +++ b/client/src/wiegand_formats.h @@ -43,7 +43,7 @@ void HIDListFormats(void); int HIDFindCardFormat(const char *format); cardformat_t HIDGetCardFormat(int idx); bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed, bool preamble); -bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity); +bool HIDTryUnpack(wiegand_message_t *packed); void HIDPackTryAll(wiegand_card_t *card, bool preamble); void print_wiegand_code(wiegand_message_t *packed); void print_desc_wiegand(cardformat_t *fmt, wiegand_message_t *packed); diff --git a/client/src/wiegand_formatutils.c b/client/src/wiegand_formatutils.c index b4ca8065f..9c167f50a 100644 --- a/client/src/wiegand_formatutils.c +++ b/client/src/wiegand_formatutils.c @@ -156,14 +156,17 @@ static uint8_t get_length_from_header(wiegand_message_t *data) { return len; } -wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot) { +wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot, int n) { wiegand_message_t result; memset(&result, 0, sizeof(wiegand_message_t)); result.Top = top; result.Mid = mid; result.Bot = bot; - result.Length = get_length_from_header(&result); + if (n > 0) + result.Length = n; + else + result.Length = get_length_from_header(&result); return result; } diff --git a/client/src/wiegand_formatutils.h b/client/src/wiegand_formatutils.h index 4631b602d..3709f2e00 100644 --- a/client/src/wiegand_formatutils.h +++ b/client/src/wiegand_formatutils.h @@ -42,7 +42,7 @@ bool set_linear_field(wiegand_message_t *data, uint64_t value, uint8_t firstBit, uint64_t get_nonlinear_field(wiegand_message_t *data, uint8_t numBits, uint8_t *bits); bool set_nonlinear_field(wiegand_message_t *data, uint64_t value, uint8_t numBits, uint8_t *bits); -wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot); +wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot, int n); bool add_HID_header(wiegand_message_t *data);