poniedziałek, 16 stycznia 2023

STM32H7 - Wiegand - UnitTest

W tym poście chciałbym opisać moje podejście do przeprowadzenia testów jednostkowych interfejsu Wiegand.

[Źródło: https://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-mpu-eval-tools/stm32-mcu-mpu-eval-tools/stm32-nucleo-boards/nucleo-h753zi.html#overview]
Poniżej zaprezentują przykładową implementację testów jednostkowych dla interfejsu Wiegand. Do przygotowania rozwiązania wykorzystałem framework Unity.

Funkcje dekodujące numer karty oraz sprawdzające bity parzystości są w projekcie funkcjami prywatnymi. Preferuję testowanie funkcji prywatnych (zwykle przyjmuje się, że testuje się tylko funkcje publiczne, gdzie przy okazji sprawdzane są również funkcje prywatne), w przypadku gdy te funkcję wykonują bardziej skomplikowane operacje. Według mnie pozwala to na szybsze znalezienie błędu w takich funkcjach.

Test odczytu numeru karty 26 bitowej. Przykładowy sposób przygotowania testowej wartości numeru karty można znaleźć na tej stronie https://www.ccdesignworks.com/wiegand_calc.htm. Jest to kalkulator który pozwoli na wygenerowanie karty w formacie bitowym.

  1. void wiegand_decode26BitCardNumber_WithFacCode(Wiegand_TypeDef* wiegandData) {
  2.     uint64_t tmpData = 0;
  3.     Wiegand_TypeDef **pointer = &wiegandData;
  4.  
  5.     tmpData = (**pointer).readCardData.fullData & 0x1FFFFFE;
  6.  
  7.     (**pointer).readCardData.facilityCode = (tmpData & 0x1FE0000) >> 0x11;
  8.     (**pointer).readCardData.cardNumber = (tmpData & 0x1FFFE) >> 1;
  9. }

Powyższa funkcja oddziela dane odpowiadające za wartość kodu strefy oraz numeru karty. 

Poniżej przykładowa implementacja testu dekodująca wartość 26 bitową. 

  1. void test_wiegand_decode26BitCardNumber_WithFacCode_CheckFacAndCardNumber(void)
  2. {
  3.     Wiegand_TypeDef wiegandData;
  4.     wiegandData.readCardData.bitCounter = 26;
  5.     wiegandData.readCardData.fullData = 0x2F86073;
  6.  
  7.     wiegand_decode26BitCardNumber_WithFacCode(&wiegandData);
  8.  
  9.     TEST_ASSERT_EQUAL(124, wiegandData.readCardData.facilityCode);
  10.     TEST_ASSERT_EQUAL(12345, wiegandData.readCardData.cardNumber);
  11. }

Następna funkcja dekoduje numer karty w innym standardzie, gdzie całość z wyjątkiem bitów parzystości składa się na numer karty:

  1. void wiegand_decode26BitCardNumber(Wiegand_TypeDef* wiegandData) {
  2.     uint64_t tmpData = 0;
  3.     Wiegand_TypeDef **pointer = &wiegandData;
  4.  
  5.     tmpData = (**pointer).readCardData.fullData & 0x1FFFFFE;
  6.     (**pointer).readCardData.facilityCode = 0;
  7.     (**pointer).readCardData.cardNumber = (tmpData) >> 1;
  8. }

W takim przypadku test może wyglądać następująco:

  1. void test_wiegand_decode26BitCardNumber_CheckFacAndCardNumber(void)
  2. {
  3.     Wiegand_TypeDef wiegandData;
  4.     wiegandData.readCardData.bitCounter = 26;
  5.     wiegandData.readCardData.fullData = 0x2F86073;
  6.  
  7.     wiegand_decode26BitCardNumber(&wiegandData);
  8.  
  9.     TEST_ASSERT_EQUAL(0, wiegandData.readCardData.facilityCode);
  10.     TEST_ASSERT_EQUAL(8138809, wiegandData.readCardData.cardNumber);
  11. }

Implementacja rozwiązania dla wartości 37 bitowej, odczytującej dodatkowo kod strefy. W takim przypadku numer karty składa się z 19 bitów, a fc z 16 bitów.

  1. void wiegand_decode37BitCardNumber_FacCode(Wiegand_TypeDef* wiegandData, const uint8_t facCodeStat) {
  2.     uint64_t tmpData = 0;
  3.     Wiegand_TypeDef **pointer = &wiegandData;
  4.  
  5.     tmpData = (**pointer).readCardData.fullData & 0xFFFFFFFFE;
  6.     (**pointer).readCardData.facilityCode = 0;
  7.     (**pointer).readCardData.cardNumber = (tmpData & 0xFFFFE) >> 1;
  8.  
  9.     if(facCodeStat == 1) {
  10.         (**pointer).readCardData.facilityCode = (tmpData & 0xFFFF00000) >> 0x14;
  11.     }
  12. }

Testy w takim przypadku wyglądają następująco:

  1. void test_wiegand_decode37BitCardNumber_FacCode_CheckFacCodeAndCardNumber(void)
  2. {
  3.     Wiegand_TypeDef wiegandData;
  4.  
  5.     wiegandData.readCardData.bitCounter = 37;
  6.     wiegandData.readCardData.fullData = 0x055AE83E63;
  7.  
  8.     wiegand_decode37BitCardNumber_FacCode(&wiegandData, 1);
  9.  
  10.     TEST_ASSERT_EQUAL(21934, wiegandData.readCardData.facilityCode);
  11.     TEST_ASSERT_EQUAL(270129, wiegandData.readCardData.cardNumber);
  12. }
  13.  
  14. void test_wiegand_decode37BitCardNumber_FacCode_OnlyCardNumberFacClear(void)
  15. {
  16.     Wiegand_TypeDef wiegandData;
  17.  
  18.     wiegandData.readCardData.bitCounter = 37;
  19.     wiegandData.readCardData.fullData = 0x055AE83E63;
  20.  
  21.     wiegand_decode37BitCardNumber_FacCode(&wiegandData, 0);
  22.  
  23.     TEST_ASSERT_EQUAL(0, wiegandData.readCardData.facilityCode);
  24.     TEST_ASSERT_EQUAL(270129, wiegandData.readCardData.cardNumber);
  25. }

Funkcja testująca pełny numer dla 37 bitowych kart. Czyli gdy numer karty został zapisany na 35 bitach. 

  1. void wiegand_decode37BitCardNumber(Wiegand_TypeDef* wiegandData)
  2. {
  3.     uint64_t tmpData = 0;
  4.     Wiegand_TypeDef **pointer = &wiegandData;
  5.  
  6.     tmpData = (**pointer).readCardData.fullData & 0xFFFFFFFFE;
  7.     (**pointer).readCardData.cardNumber = tmpData >> 1;
  8.     (**pointer).readCardData.facilityCode = 0;
  9. }

Funkcja testowa:

  1. void test_wiegand_decode37BitCardNumber_NoFacOnlyCardNumber(void)
  2. {
  3.     Wiegand_TypeDef wiegandData;
  4.  
  5.     wiegandData.readCardData.bitCounter = 37;
  6.     wiegandData.readCardData.fullData = 0x055AE83E63;
  7.  
  8.     wiegand_decode37BitCardNumber(&wiegandData);
  9.  
  10.     TEST_ASSERT_EQUAL(0, wiegandData.readCardData.facilityCode);
  11.     TEST_ASSERT_EQUAL(0x2AD741F31, wiegandData.readCardData.cardNumber);
  12. }

Podobnie sytuacja wygląda dla pozostałych standardów kart. Przykładowe opisy standardów wraz z zakresem kart można znaleźć np. tutaj link

Teraz funkcja sprawdzająca poprawność bitów parzystości. 

Poniżej funkcja sprawdzająca bity parzystości i nieparzystości (ang. odd i even parity). 

  1. static uint8_t wiegand_checkParityBitsFor26BitCard_HidFormat(const Wiegand_TypeDef* wiegandData) {
  2.     const Wiegand_TypeDef **pointer = &wiegandData;
  3.  
  4.     uint8_t oddParityFromFrame = 0;
  5.     uint32_t dataForOddParity = 0;
  6.  
  7.     uint8_t evenParityFromFrame = 0;
  8.     uint32_t dataForEvenParity = 0;
  9.  
  10.     uint8_t calculatedOddParity = 0;
  11.     uint8_t calculatedEvenParity = 0;
  12.  
  13.     oddParityFromFrame = (uint8_t)((**pointer).readCardData.fullData & 0x0000001);
  14.     evenParityFromFrame = (uint8_t)(((**pointer).readCardData.fullData) >> 25);
  15.  
  16.     dataForOddParity = (uint32_t)(((**pointer).readCardData.fullData & 0x0000001FFF) >> 1);
  17.     dataForEvenParity = (uint32_t)(((**pointer).readCardData.fullData) >> 13) & 0x0000000FFF;
  18.  
  19.     if((numberOfSetBits(dataForOddParity)%2) != 0) { calculatedOddParity = 0; }
  20.     else { calculatedOddParity = 1; }
  21.  
  22.     if((numberOfSetBits(dataForEvenParity)%2) != 0) { calculatedEvenParity = 1; }
  23.     else { calculatedEvenParity = 0; }
  24.  
  25.     if(calculatedOddParity != oddParityFromFrame) { return (1u); }
  26.     if(calculatedEvenParity != evenParityFromFrame) { return (2u); }
  27.  
  28.     return (0u);
  29. }

Powyższa funkcje zwraca wartość 1 lub 2 w przypadku błędu. Gdy wszystkie dane są poprawne to zwracana jest wartość 0.

W tym przypadku musimy sprawdzić wszystkie warunki wyjścia z funkcji, czyli potrzeba przynajmniej trzech testów.

  1. void test_checkParity26BitCards_propervalue(void)
  2. {
  3.     Wiegand_TypeDef wiegandData;
  4.  
  5.     wiegandData.readCardData.bitCounter = 26;
  6.     wiegandData.readCardData.fullData = 9871416;
  7.     uint8_t operationValue = wiegand_checkPartityBitsFor26BitCard_HidFormat(&wiegandData);
  8.  
  9.     TEST_ASSERT_EQUAL(operationValue, 0);
  10. }
  11.  
  12. void test_checkParity26BitCards_WrongMsbEvenParity(void)
  13. {
  14.     Wiegand_TypeDef wiegandData;
  15.  
  16.     wiegandData.readCardData.bitCounter = 26;
  17.     wiegandData.readCardData.fullData = 43425848;
  18.     uint8_t operationValue = wiegand_checkPartityBitsFor26BitCard_HidFormat(&wiegandData);
  19.  
  20.     TEST_ASSERT_EQUAL(operationValue, 2);
  21. }
  22.  
  23. void test_checkParity26BitCards_WrongLsbOddParity(void)
  24. {
  25.     Wiegand_TypeDef wiegandData;
  26.  
  27.     wiegandData.readCardData.bitCounter = 26;
  28.     wiegandData.readCardData.fullData = 9871417;
  29.     uint8_t operationValue = wiegand_checkPartityBitsFor26BitCard_HidFormat(&wiegandData);
  30.  
  31.     TEST_ASSERT_EQUAL(operationValue, 1);
  32. }

Podobnie sprawa wygląda dla 37 bitów:

  1. void test_checkParity37BitCards_propervalue(void)
  2. {
  3.     Wiegand_TypeDef wiegandData;
  4.  
  5.     wiegandData.readCardData.bitCounter = 37;
  6.     wiegandData.readCardData.fullData = 69410729115;
  7.     uint8_t operationValue = wiegand_checkParityBitsFor37BitCard_HidFormat(&wiegandData);
  8.  
  9.     TEST_ASSERT_EQUAL(0, operationValue);
  10. }
  11.  
  12. void test_checkParity37BitCards_WrongMsbEvenParity(void)
  13. {
  14.     Wiegand_TypeDef wiegandData;
  15.  
  16.     wiegandData.readCardData.bitCounter = 37;
  17.     wiegandData.readCardData.fullData = 691252379;
  18.     uint8_t operationValue = wiegand_checkParityBitsFor37BitCard_HidFormat(&wiegandData);
  19.  
  20.     TEST_ASSERT_EQUAL(2, operationValue);
  21. }
  22.  
  23. void test_checkParity37BitCards_WrongLsbOddParity(void)
  24. {
  25.     Wiegand_TypeDef wiegandData;
  26.  
  27.     wiegandData.readCardData.bitCounter = 37;
  28.     wiegandData.readCardData.fullData = 69410729114;
  29.     uint8_t operationValue = wiegand_checkParityBitsFor37BitCard_HidFormat(&wiegandData);
  30.  
  31.     TEST_ASSERT_EQUAL(1, operationValue);
  32. }

Główna funkcja dekodująca może wyglądać następująco:

  1. uint8_t wiegand_checkReceivedData(Wiegand_TypeDef* wiegandData, const WiegandSettings_t wiegSettings)
  2. {
  3.     if(wiegand_checkIfCardReceive((Wiegand_TypeDef*)wiegandData)) {
  4.         wiegandData->readCardData.flag_startReceivingData = 0;
  5.  
  6.         switch(wiegandData->readCardData.bitCounter)
  7.         {
  8.             case 26:
  9.                 if(wiegand_checkPartityBitsFor26BitCard_HidFormat((Wiegand_TypeDef*)wiegandData) != 0u) {
  10.                     return 2u;
  11.                 }
  12.  
  13.                 if(wiegSettings.DecodeCardNumberWithFacilityCode26 == 1)
  14.                 {
  15.                     wiegand_decode26BitCardNumber_WithFacCode((Wiegand_TypeDef*)wiegandData);
  16.  
  17.                     if(wiegSettings.CheckIfFacilityCode26Matches == 1)
  18.                     {
  19.                         if(wiegandData->readCardData.facilityCode != wiegSettings.FacCode26)
  20.                         {
  21.                             return 3u;
  22.                         }
  23.                     }
  24.                 }
  25.                 else {
  26.                     wiegand_decode26BitCardNumber((Wiegand_TypeDef*)wiegandData);
  27.                 }
  28.             break;
  29.             case 37:
  30.                 if(wiegand_checkParityBitsFor37BitCard_HidFormat((Wiegand_TypeDef*)wiegandData) != 0u) {
  31.                     return 2u;
  32.                 }
  33.  
  34.                 if(wiegSettings.DecodeCardNumberWithFacilityCode37 == 1) {
  35.                     if(wiegSettings.CheckIfFacilityCode37Matches == 1) {
  36.                         wiegand_decode37BitCardNumber_FacCode((Wiegand_TypeDef*)wiegandData, 1);
  37.                         if(wiegandData->readCardData.facilityCode != wiegSettings.FacCode37) {
  38.                             return 3u;
  39.                         }
  40.                     }
  41.                     else{
  42.                         wiegand_decode37BitCardNumber_FacCode((Wiegand_TypeDef*)wiegandData, 0);
  43.                     }
  44.                 }
  45.                 else {
  46.                     wiegand_decode37BitCardNumber((Wiegand_TypeDef*)wiegandData);
  47.                 }
  48.             break;
  49.             default:
  50.             return 3u;
  51.         }
  52.  
  53.         return 1u;
  54.     }
  55.     return 0u;
  56. }

Jest to podstawowa implementacja sprawdzająca tylko dwa rodzaje typów kart. Dosyć szybko można zauważyć pewien problem. Funkcja powyższa odwołuje się do już testowanych funkcji prywatnych. Problem jaki z tego wynika, to zwiększenie ilości testów sprawdzających to samo, oraz otrzymujących te same parametry, tylko w innym scenariuszu. Natomiast w przypadku zmian w funkcji prywatnej które nie będą pozwalały na poprawne wykonanie testów nastąpi wygenerowanie dwóch błędów. Funkcja główna zgłosi błąd oraz funkcja pomocnicza (oczywiście musi być spełniony warunek, że testy nie zależą od siebie). W takim przypadku bo zobaczeniu raportu z testów będzie wiadomo gdzie dokładnie nastąpił błąd, bez głębszej analizy początkowej. Natomiast zwiększy to objętość testów. Najrozsądniej, jak już wspomniałem wcześniej, jest przygotowywanie testów, które faktycznie coś wnoszą. Czyli nie testujemy wszystkich funkcji, czy banalnie działających funkcji, tylko takie, które są dosyć rozbudowane i ryzyko popełnienia błędu jest znacznie wyższe. Ostatecznie gdy przygotowane są już testy dla głównej funkcji, to testy prywatnych można za komentować i korzystać z nich tylko w przypadku późniejszych błędów. 

Wracając do tematu przykładowe testy mogą wyglądać następująco:

  1. void test_wiegand_checkReceivedData_37BitWrongParity_ProperValue(void)
  2. {
  3.     Wiegand_TypeDef wiegandData;
  4.  
  5.     wiegandData.readCardData.flag_startReceivingData = 1;
  6.     wiegandData.readCardData.bitCounter = 37;
  7.     wiegandData.readCardData.fullData = 69410729114;
  8.     wiegandData.readCardData.facilityCode = 0;
  9.     wiegandData.readCardData.cardNumber = 0;
  10.     wiegandData.timeoutCounter = 0;
  11.  
  12.     WiegandSettings_t wiegSettings;
  13.  
  14.     wiegSettings.FacCode37 = 0;
  15.     wiegSettings.CheckIfFacilityCode37Matches = 0;
  16.     wiegSettings.DecodeCardNumberWithFacilityCode37 = 0;
  17.  
  18.     uint8_t retValue = wiegand_checkReceivedData(&wiegandData, &wiegSettings);
  19.     TEST_ASSERT_EQUAL(2, retValue);
  20. }
  21.  
  22. void test_wiegand_checkReceivedData_37BitCardWithFacCode_ProperValue(void)
  23. {
  24.     Wiegand_TypeDef wiegandData;
  25.  
  26.     wiegandData.readCardData.flag_startReceivingData = 1;
  27.     wiegandData.readCardData.bitCounter = 37;
  28.     wiegandData.readCardData.fullData = 0x055AE83E63;
  29.     wiegandData.readCardData.facilityCode = 0;
  30.     wiegandData.readCardData.cardNumber = 0;
  31.     wiegandData.timeoutCounter = 0;
  32.  
  33.     WiegandSettings_t wiegSettings;
  34.  
  35.     wiegSettings.FacCode37 = 21934;
  36.     wiegSettings.CheckIfFacilityCode37Matches = 1;
  37.     wiegSettings.DecodeCardNumberWithFacilityCode37 = 1;
  38.  
  39.     uint8_t retValue = wiegand_checkReceivedData(&wiegandData, &wiegSettings);
  40.     TEST_ASSERT_EQUAL(1, retValue);
  41.     TEST_ASSERT_EQUAL(21934, wiegandData.readCardData.facilityCode);
  42.     TEST_ASSERT_EQUAL(270129, wiegandData.readCardData.cardNumber);
  43. }

Lista testów dla tych funkcji byłaby następująca:

  1. extern void test_wiegand_checkReceivedData_37BitCardWithFacCode_ProperValue(void);
  2. extern void test_wiegand_checkReceivedData_37BitCardNoCheckFacCode_ProperValue(void);
  3. extern void test_wiegand_checkReceivedData_37BitCardNoFacCode_ProperValue(void);
  4. extern void test_wiegand_checkReceivedData_NoCard_ProperValue(void);
  5. extern void test_wiegand_checkReceivedData_37BitWrongParity(void);
  6. extern void test_wiegand_checkReceivedData_37BitCardWithFacCode_WrongFacCode(void);
  7. extern void test_wiegand_checkReceivedData_26BitCardWithFacCode_ProperValue(void);
  8. extern void test_wiegand_checkReceivedData_26BitCardNoCheckFacCode_ProperValue(void);
  9. extern void test_wiegand_checkReceivedData_26BitWrongParity(void);
  10. extern void test_wiegand_checkReceivedData_26BitCardWithoutFC_ProperValue(void);

Główna funkcja wywołująca testy:

  1. int main(void)
  2. {
  3.   UnityBegin("test/WiegandTest_Test.c");
  4.   run_test(test_checkParity26BitCards_propervalue, "test_checkParity26BitCards_propervalue", 33);
  5.   run_test(test_checkParity26BitCards_WrongMsbEvenParity, "test_checkParity26BitCards_WrongMsbEvenParity", 44);
  6.   run_test(test_checkParity26BitCards_WrongLsbOddParity, "test_checkParity26BitCards_WrongLsbOddParity", 55);
  7.   run_test(test_checkParity37BitCards_propervalue, "test_checkParity37BitCards_propervalue", 66);
  8.   run_test(test_checkParity37BitCards_WrongMsbEvenParity, "test_checkParity37BitCards_WrongMsbEvenParity", 77);
  9.   run_test(test_checkParity37BitCards_WrongLsbOddParity, "test_checkParity37BitCards_WrongLsbOddParity", 88);
  10.   run_test(test_wiegand_decode26BitCardNumber_WithFacCode_CheckFacAndCardNumber, "test_wiegand_decode26BitCardNumber_WithFacCode_CheckFacAndCardNumber", 99);
  11.   run_test(test_wiegand_decode26BitCardNumber_CheckFacAndCardNumber, "test_wiegand_decode26BitCardNumber_CheckFacAndCardNumber", 111);
  12.   run_test(test_wiegand_decode37BitCardNumber_FacCode_CheckFacCodeAndCardNumber, "test_wiegand_decode37BitCardNumber_FacCode_CheckFacCodeAndCardNumber", 123);
  13.   run_test(test_wiegand_decode37BitCardNumber_FacCode_OnlyCardNumberFacClear, "test_wiegand_decode37BitCardNumber_FacCode_OnlyCardNumberFacClear", 138);
  14.   run_test(test_wiegand_decode37BitCardNumber_NoFacOnlyCardNumber, "test_wiegand_decode37BitCardNumber_NoFacOnlyCardNumber", 151);
  15.   run_test(test_wiegand_checkReceivedData_37BitCardWithFacCode_ProperValue, "test_wiegand_checkReceivedData_37BitCardWithFacCode_ProperValue", 164);
  16.   run_test(test_wiegand_checkReceivedData_37BitCardNoCheckFacCode_ProperValue, "test_wiegand_checkReceivedData_37BitCardNoCheckFacCode_ProperValue", 187);
  17.   run_test(test_wiegand_checkReceivedData_37BitCardNoFacCode_ProperValue, "test_wiegand_checkReceivedData_37BitCardNoFacCode_ProperValue", 210);
  18.   run_test(test_wiegand_checkReceivedData_NoCard_ProperValue, "test_wiegand_checkReceivedData_NoCard_ProperValue", 233);
  19.   run_test(test_wiegand_checkReceivedData_37BitWrongParity, "test_wiegand_checkReceivedData_37BitWrongParity", 250);
  20.   run_test(test_wiegand_checkReceivedData_37BitCardWithFacCode_WrongFacCode, "test_wiegand_checkReceivedData_37BitCardWithFacCode_WrongFacCode", 271);
  21.   run_test(test_wiegand_checkReceivedData_26BitCardWithFacCode_ProperValue, "test_wiegand_checkReceivedData_26BitCardWithFacCode_ProperValue", 294);
  22.   run_test(test_wiegand_checkReceivedData_26BitCardNoCheckFacCode_ProperValue, "test_wiegand_checkReceivedData_26BitCardNoCheckFacCode_ProperValue", 317);
  23.   run_test(test_wiegand_checkReceivedData_26BitWrongParity, "test_wiegand_checkReceivedData_26BitWrongParity", 340);
  24.   run_test(test_wiegand_checkReceivedData_26BitCardWithoutFC_ProperValue, "test_wiegand_checkReceivedData_26BitCardWithoutFC_ProperValue", 361);
  25.  
  26.   return UnityEnd();
  27. }

Raport z testów wyświetlany w konsoli:

  1. ./test3.exe
  2. test/WiegandTest_Test.c:33:test_checkParity26BitCards_propervalue:PASS
  3. test/WiegandTest_Test.c:44:test_checkParity26BitCards_WrongMsbEvenParity:PASS
  4. test/WiegandTest_Test.c:55:test_checkParity26BitCards_WrongLsbOddParity:PASS
  5. test/WiegandTest_Test.c:66:test_checkParity37BitCards_propervalue:PASS
  6. test/WiegandTest_Test.c:77:test_checkParity37BitCards_WrongMsbEvenParity:PASS
  7. test/WiegandTest_Test.c:88:test_checkParity37BitCards_WrongLsbOddParity:PASS
  8. test/WiegandTest_Test.c:99:test_wiegand_decode26BitCardNumber_WithFacCode_CheckFacAndCardNumber:PASS
  9. test/WiegandTest_Test.c:111:test_wiegand_decode26BitCardNumber_CheckFacAndCardNumber:PASS
  10. test/WiegandTest_Test.c:123:test_wiegand_decode37BitCardNumber_FacCode_CheckFacCodeAndCardNumber:PASS
  11. test/WiegandTest_Test.c:138:test_wiegand_decode37BitCardNumber_FacCode_OnlyCardNumberFacClear:PASS
  12. test/WiegandTest_Test.c:151:test_wiegand_decode37BitCardNumber_NoFacOnlyCardNumber:PASS
  13. test/WiegandTest_Test.c:164:test_wiegand_checkReceivedData_37BitCardWithFacCode_ProperValue:PASS
  14. test/WiegandTest_Test.c:187:test_wiegand_checkReceivedData_37BitCardNoCheckFacCode_ProperValue:PASS
  15. test/WiegandTest_Test.c:210:test_wiegand_checkReceivedData_37BitCardNoFacCode_ProperValue:PASS
  16. test/WiegandTest_Test.c:233:test_wiegand_checkReceivedData_NoCard_ProperValue:PASS
  17. test/WiegandTest_Test.c:250:test_wiegand_checkReceivedData_37BitWrongParity:PASS
  18. test/WiegandTest_Test.c:271:test_wiegand_checkReceivedData_37BitCardWithFacCode_WrongFacCode:PASS
  19. test/WiegandTest_Test.c:294:test_wiegand_checkReceivedData_26BitCardWithFacCode_ProperValue:PASS
  20. test/WiegandTest_Test.c:317:test_wiegand_checkReceivedData_26BitCardNoCheckFacCode_ProperValue:PASS
  21. test/WiegandTest_Test.c:340:test_wiegand_checkReceivedData_26BitWrongParity:PASS
  22. test/WiegandTest_Test.c:361:test_wiegand_checkReceivedData_26BitCardWithoutFC_ProperValue:PASS
  23.  
  24. -----------------------
  25. 21 Tests 0 Failures 0 Ignored
  26. OK