reader-integration-kit 1.4.2__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reader_integration_kit/__init__.py +12 -0
- reader_integration_kit/enum/__init__.py +28 -0
- reader_integration_kit/enum/beep_duration.py +12 -0
- reader_integration_kit/enum/beep_volume.py +15 -0
- reader_integration_kit/enum/ble_data_type.py +12 -0
- reader_integration_kit/enum/blob_type.py +27 -0
- reader_integration_kit/enum/checkpoint_type.py +13 -0
- reader_integration_kit/enum/data_conversion_type.py +12 -0
- reader_integration_kit/enum/field_definition_type.py +14 -0
- reader_integration_kit/enum/led_color.py +15 -0
- reader_integration_kit/enum/protocol_type.py +14 -0
- reader_integration_kit/enum/proximity_card_type.py +166 -0
- reader_integration_kit/enum/reader_module_id.py +13 -0
- reader_integration_kit/enum/reader_module_state.py +12 -0
- reader_integration_kit/enum/serial_port_baud_rate.py +15 -0
- reader_integration_kit/enum/serial_port_data_bits.py +10 -0
- reader_integration_kit/enum/serial_port_flow_control.py +11 -0
- reader_integration_kit/enum/serial_port_parity.py +10 -0
- reader_integration_kit/enum/serial_port_stop_bits.py +9 -0
- reader_integration_kit/enum/transparent_mode_state.py +11 -0
- reader_integration_kit/enum/transparent_mode_status.py +11 -0
- reader_integration_kit/errors/__init__.py +4 -0
- reader_integration_kit/errors/reader_exception.py +58 -0
- reader_integration_kit/facade/__init__.py +882 -0
- reader_integration_kit/lib/ReaderIntegrationKit.dll +0 -0
- reader_integration_kit/structures/__init__.py +36 -0
- reader_integration_kit/structures/blob_header.py +54 -0
- reader_integration_kit/structures/bluetooth_firmware_version.py +35 -0
- reader_integration_kit/structures/card_data.py +77 -0
- reader_integration_kit/structures/card_type_info.py +51 -0
- reader_integration_kit/structures/device_id.py +12 -0
- reader_integration_kit/structures/extended_configuration.py +32 -0
- reader_integration_kit/structures/felica_sam_firmware_version.py +38 -0
- reader_integration_kit/structures/field_entry.py +120 -0
- reader_integration_kit/structures/field_separator_data_header.py +83 -0
- reader_integration_kit/structures/hash_data.py +55 -0
- reader_integration_kit/structures/hid_se_sam_firmware_version.py +38 -0
- reader_integration_kit/structures/led_configuration.py +13 -0
- reader_integration_kit/structures/library_info.py +74 -0
- reader_integration_kit/structures/luid_response_information.py +44 -0
- reader_integration_kit/structures/microcontroller_firmware_version.py +38 -0
- reader_integration_kit/structures/nxp_sam_firmware_version.py +38 -0
- reader_integration_kit/structures/reader_configuration.py +171 -0
- reader_integration_kit/structures/reader_data.py +49 -0
- reader_integration_kit/structures/reader_definition.py +14 -0
- reader_integration_kit/structures/reader_metadata_struct.py +195 -0
- reader_integration_kit/structures/rik_result.py +71 -0
- reader_integration_kit/structures/separator_character.py +44 -0
- reader_integration_kit/structures/separator_entry.py +73 -0
- reader_integration_kit/structures/serial_port_settings.py +45 -0
- reader_integration_kit/structures/smart_card_configuration.py +34 -0
- reader_integration_kit-1.4.2.dist-info/METADATA +139 -0
- reader_integration_kit-1.4.2.dist-info/RECORD +56 -0
- reader_integration_kit-1.4.2.dist-info/WHEEL +5 -0
- reader_integration_kit-1.4.2.dist-info/licenses/rfIDEAS_EULA.txt +281 -0
- reader_integration_kit-1.4.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Library information structure containing version and build metadata.
|
|
3
|
+
This matches the C LibraryInfo structure.
|
|
4
|
+
"""
|
|
5
|
+
from ctypes import Structure, c_char
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LibraryInfo(Structure):
|
|
9
|
+
"""Library information structure with version and build metadata."""
|
|
10
|
+
|
|
11
|
+
_fields_ = [
|
|
12
|
+
("Name", c_char * 256),
|
|
13
|
+
("InternalName", c_char * 256),
|
|
14
|
+
("Comments", c_char * 512),
|
|
15
|
+
("CompanyName", c_char * 256),
|
|
16
|
+
("CompanyCopyright", c_char * 512),
|
|
17
|
+
("LicenseText", c_char * 1024),
|
|
18
|
+
("FileDescription", c_char * 1024),
|
|
19
|
+
("SemVer", c_char * 256),
|
|
20
|
+
("BuildVer", c_char * 256),
|
|
21
|
+
("BumpType", c_char * 256),
|
|
22
|
+
("BuildNumber", c_char * 256),
|
|
23
|
+
("Branch", c_char * 256),
|
|
24
|
+
("BuildURL", c_char * 1024),
|
|
25
|
+
("BuildType", c_char * 256),
|
|
26
|
+
("BuildDate", c_char * 256),
|
|
27
|
+
("BuildPlatform", c_char * 256),
|
|
28
|
+
("BuildToolchain", c_char * 256),
|
|
29
|
+
("PullRequest", c_char * 256),
|
|
30
|
+
("PullRequestBranch", c_char * 256),
|
|
31
|
+
("PullRequestSlug", c_char * 256),
|
|
32
|
+
("RepoSlug", c_char * 256),
|
|
33
|
+
("Commit", c_char * 256),
|
|
34
|
+
("CommitMessage", c_char * 1024),
|
|
35
|
+
("CommitURL", c_char * 1024),
|
|
36
|
+
("SourceDir", c_char * 1024),
|
|
37
|
+
("IsAlphaBuild", c_char * 256),
|
|
38
|
+
("InformationalVersion", c_char * 512),
|
|
39
|
+
("VersionString", c_char * 256),
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
def to_dict(self) -> dict:
|
|
43
|
+
"""Convert the structure to a dictionary."""
|
|
44
|
+
return {
|
|
45
|
+
"Name": self.Name.decode("utf-8", errors="ignore"),
|
|
46
|
+
"InternalName": self.InternalName.decode("utf-8", errors="ignore"),
|
|
47
|
+
"Comments": self.Comments.decode("utf-8", errors="ignore"),
|
|
48
|
+
"CompanyName": self.CompanyName.decode("utf-8", errors="ignore"),
|
|
49
|
+
"CompanyCopyright": self.CompanyCopyright.decode("utf-8", errors="ignore"),
|
|
50
|
+
"LicenseText": self.LicenseText.decode("utf-8", errors="ignore"),
|
|
51
|
+
"FileDescription": self.FileDescription.decode("utf-8", errors="ignore"),
|
|
52
|
+
"SemVer": self.SemVer.decode("utf-8", errors="ignore"),
|
|
53
|
+
"BuildVer": self.BuildVer.decode("utf-8", errors="ignore"),
|
|
54
|
+
"BumpType": self.BumpType.decode("utf-8", errors="ignore"),
|
|
55
|
+
"BuildNumber": self.BuildNumber.decode("utf-8", errors="ignore"),
|
|
56
|
+
"Branch": self.Branch.decode("utf-8", errors="ignore"),
|
|
57
|
+
"BuildURL": self.BuildURL.decode("utf-8", errors="ignore"),
|
|
58
|
+
"BuildType": self.BuildType.decode("utf-8", errors="ignore"),
|
|
59
|
+
"BuildDate": self.BuildDate.decode("utf-8", errors="ignore"),
|
|
60
|
+
"BuildPlatform": self.BuildPlatform.decode("utf-8", errors="ignore"),
|
|
61
|
+
"BuildToolchain": self.BuildToolchain.decode("utf-8", errors="ignore"),
|
|
62
|
+
"PullRequest": self.PullRequest.decode("utf-8", errors="ignore"),
|
|
63
|
+
"PullRequestBranch": self.PullRequestBranch.decode("utf-8", errors="ignore"),
|
|
64
|
+
"PullRequestSlug": self.PullRequestSlug.decode("utf-8", errors="ignore"),
|
|
65
|
+
"RepoSlug": self.RepoSlug.decode("utf-8", errors="ignore"),
|
|
66
|
+
"Commit": self.Commit.decode("utf-8", errors="ignore"),
|
|
67
|
+
"CommitMessage": self.CommitMessage.decode("utf-8", errors="ignore"),
|
|
68
|
+
"CommitURL": self.CommitURL.decode("utf-8", errors="ignore"),
|
|
69
|
+
"SourceDir": self.SourceDir.decode("utf-8", errors="ignore"),
|
|
70
|
+
"IsAlphaBuild": self.IsAlphaBuild.decode("utf-8", errors="ignore"),
|
|
71
|
+
"InformationalVersion": self.InformationalVersion.decode("utf-8", errors="ignore"),
|
|
72
|
+
"VersionString": self.VersionString.decode("utf-8", errors="ignore"),
|
|
73
|
+
}
|
|
74
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from ctypes import Structure, c_uint16, c_uint32
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
class LuidResponseInformation(Structure):
|
|
5
|
+
"""
|
|
6
|
+
Structure representing LUID response information from the reader.
|
|
7
|
+
"""
|
|
8
|
+
_pack_ = 1
|
|
9
|
+
_fields_ = [
|
|
10
|
+
("Luid", c_uint16),
|
|
11
|
+
("ApplicationVersionPackedBcd", c_uint16),
|
|
12
|
+
("BootloaderVersionUnpackedBcd", c_uint32),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
def __init__(self, *args: Any, **kw: Any):
|
|
16
|
+
super().__init__()
|
|
17
|
+
self.Luid = kw.get("Luid", 0)
|
|
18
|
+
self.ApplicationVersionPackedBcd = kw.get("ApplicationVersionPackedBcd", args[0] if len(args) > 0 else 0)
|
|
19
|
+
self.BootloaderVersionUnpackedBcd = kw.get("BootloaderVersionUnpackedBcd", args[1] if len(args) > 1 else 0)
|
|
20
|
+
|
|
21
|
+
def to_dict(self):
|
|
22
|
+
"""Convert to dictionary."""
|
|
23
|
+
return {
|
|
24
|
+
"Luid": self.Luid,
|
|
25
|
+
"ApplicationVersionPackedBcd": self.ApplicationVersionPackedBcd,
|
|
26
|
+
"BootloaderVersionUnpackedBcd": self.BootloaderVersionUnpackedBcd,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def __str__(self):
|
|
30
|
+
return f"LUID: 0x{self.Luid:04X}, App Version: 0x{self.ApplicationVersionPackedBcd:04X}, Bootloader Version: 0x{self.BootloaderVersionUnpackedBcd:08X}"
|
|
31
|
+
|
|
32
|
+
def __repr__(self):
|
|
33
|
+
return (f"LuidResponseInformation(luid=0x{self.Luid:04X}, "
|
|
34
|
+
f"application_version=0x{self.ApplicationVersionPackedBcd:04X}, "
|
|
35
|
+
f"bootloader_version=0x{self.BootloaderVersionUnpackedBcd:08X})")
|
|
36
|
+
|
|
37
|
+
def __eq__(self, other):
|
|
38
|
+
return (isinstance(other, LuidResponseInformation) and
|
|
39
|
+
self.Luid == other.Luid and
|
|
40
|
+
self.ApplicationVersionPackedBcd == other.ApplicationVersionPackedBcd and
|
|
41
|
+
self.BootloaderVersionUnpackedBcd == other.BootloaderVersionUnpackedBcd)
|
|
42
|
+
|
|
43
|
+
def __ne__(self, other):
|
|
44
|
+
return not self.__eq__(other)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from ctypes import Structure, c_uint8, c_int32
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MicrocontrollerFirmwareVersion(Structure):
|
|
6
|
+
_pack_ = 1 # Ensure no padding between fields for native compatibility
|
|
7
|
+
_fields_ = [
|
|
8
|
+
("MajorHigh", c_uint8),
|
|
9
|
+
("MajorLow", c_uint8),
|
|
10
|
+
("MinorHigh", c_uint8),
|
|
11
|
+
("MinorLow", c_uint8),
|
|
12
|
+
("MicrocontrollerType", c_int32), # enum class in C++ uses int (4 bytes)
|
|
13
|
+
("ModuleType", c_int32), # enum class in C++ uses int (4 bytes)
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
def __init__(self, *args: Any, **kw: Any):
|
|
17
|
+
super().__init__()
|
|
18
|
+
self.MinorHigh = kw.get("MinorHigh", 0)
|
|
19
|
+
self.MinorLow = kw.get("MinorLow", 0)
|
|
20
|
+
self.MajorHigh = kw.get("MajorHigh", 0)
|
|
21
|
+
self.MajorLow = kw.get("MajorLow", 0)
|
|
22
|
+
self.MicrocontrollerType = kw.get("MicrocontrollerType", 0)
|
|
23
|
+
self.ModuleType = kw.get("ModuleType", 0)
|
|
24
|
+
|
|
25
|
+
def to_dict(self):
|
|
26
|
+
"""Convert to dictionary."""
|
|
27
|
+
return {
|
|
28
|
+
"MajorHigh": self.MajorHigh,
|
|
29
|
+
"MajorLow": self.MajorLow,
|
|
30
|
+
"MinorHigh": self.MinorHigh,
|
|
31
|
+
"MinorLow": self.MinorLow,
|
|
32
|
+
"MicrocontrollerType": self.MicrocontrollerType,
|
|
33
|
+
"ModuleType": self.ModuleType,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
def __str__(self):
|
|
37
|
+
return f"{self.MajorHigh}.{self.MajorLow}.{self.MinorHigh}.{self.MinorLow}"
|
|
38
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from ctypes import Structure, c_uint8, c_int32
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class NxpSamFirmwareVersion(Structure):
|
|
6
|
+
_pack_ = 1 # Ensure no padding between fields for native compatibility
|
|
7
|
+
_fields_ = [
|
|
8
|
+
("Major", c_uint8),
|
|
9
|
+
("Minor", c_uint8),
|
|
10
|
+
("Rfu", c_uint8),
|
|
11
|
+
("Mode", c_uint8),
|
|
12
|
+
("MicrocontrollerType", c_int32), # enum class in C++ uses int (4 bytes)
|
|
13
|
+
("SamType", c_int32), # enum class in C++ uses int (4 bytes)
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
def __init__(self, *args: Any, **kw: Any):
|
|
17
|
+
super().__init__()
|
|
18
|
+
self.Mode = kw.get("Mode", 0)
|
|
19
|
+
self.Rfu = kw.get("Rfu", 0)
|
|
20
|
+
self.Minor = kw.get("Minor", 0)
|
|
21
|
+
self.Major = kw.get("Major", 0)
|
|
22
|
+
self.SamType = kw.get("SamType", 0)
|
|
23
|
+
self.MicrocontrollerType = kw.get("MicrocontrollerType", 0)
|
|
24
|
+
|
|
25
|
+
def to_dict(self):
|
|
26
|
+
"""Convert to dictionary."""
|
|
27
|
+
return {
|
|
28
|
+
"Major": self.Major,
|
|
29
|
+
"Minor": self.Minor,
|
|
30
|
+
"Rfu": self.Rfu,
|
|
31
|
+
"Mode": self.Mode,
|
|
32
|
+
"MicrocontrollerType": self.MicrocontrollerType,
|
|
33
|
+
"SamType": self.SamType,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
def __str__(self):
|
|
37
|
+
return f"{self.Major}.{self.Minor} Mode: {self.Mode}"
|
|
38
|
+
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
from ctypes import Structure, c_uint8, c_uint16
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
class ReaderConfigurationStruct(Structure):
|
|
5
|
+
_pack_ = 1 # Ensure no padding between fields for native compatibility
|
|
6
|
+
_fields_ = [
|
|
7
|
+
# ReaderConfigurationBlock1
|
|
8
|
+
("FacDigitCount", c_uint8),
|
|
9
|
+
("IdDigitCount", c_uint8),
|
|
10
|
+
("TotalStripLeadingParityCount", c_uint8),
|
|
11
|
+
("TotalStripTrailingParityCount", c_uint8),
|
|
12
|
+
("IdBitCount", c_uint8),
|
|
13
|
+
("ExpectedBitCount", c_uint8),
|
|
14
|
+
("IdAndFacDelimiter", c_uint8),
|
|
15
|
+
("TerminationCharacter", c_uint8),
|
|
16
|
+
("UseFixedLengthForFacAndId", c_uint8),
|
|
17
|
+
("EnforceExpectedBitCount", c_uint8),
|
|
18
|
+
("StripFacFromId", c_uint8),
|
|
19
|
+
("SendFacAfterStrippingIt", c_uint8),
|
|
20
|
+
("UseIdAndFacDelimiter", c_uint8),
|
|
21
|
+
("DisableKeystrokeTerminationCharacter", c_uint8),
|
|
22
|
+
("EnableContinuousRead", c_uint8),
|
|
23
|
+
("DisableKeystroking", c_uint8),
|
|
24
|
+
|
|
25
|
+
# ReaderConfigurationBlock2
|
|
26
|
+
("LegacyBitStreamTimeOutMs", c_uint16),
|
|
27
|
+
("DataHoldTimeMs", c_uint16),
|
|
28
|
+
("LockOutTimeMs", c_uint16),
|
|
29
|
+
("KeyPressTimeMs", c_uint16),
|
|
30
|
+
("KeyReleaseTimeMs", c_uint16),
|
|
31
|
+
("EnableIdExtendedPrecision", c_uint8),
|
|
32
|
+
("UseLowercaseHex", c_uint8),
|
|
33
|
+
("EnableProxProEmulation", c_uint8),
|
|
34
|
+
("EnableHexadecimalId", c_uint8),
|
|
35
|
+
("EnableHexadecimalFac", c_uint8),
|
|
36
|
+
("UseIndividualIdAndFacNumberFormats", c_uint8),
|
|
37
|
+
("UseNumericKeypad", c_uint8),
|
|
38
|
+
("ReaderSupportsReverseAllBytes", c_uint8),
|
|
39
|
+
("ReaderSupportsAsciiExtended", c_uint8),
|
|
40
|
+
("ReaderSupportsExtendedMode", c_uint8),
|
|
41
|
+
("EnableRoswellMode", c_uint8),
|
|
42
|
+
|
|
43
|
+
# ReaderConfigurationBlock3
|
|
44
|
+
("EnableRedLed", c_uint8),
|
|
45
|
+
("EnableGreenLed", c_uint8),
|
|
46
|
+
("EnableOemRelay", c_uint8),
|
|
47
|
+
("EnableOemBeeper", c_uint8),
|
|
48
|
+
("IsBootDevice", c_uint8),
|
|
49
|
+
("UseLeadingCharacters", c_uint8),
|
|
50
|
+
("EnabledSoftwareControlledLed", c_uint8),
|
|
51
|
+
("UseHexadecimalForBothFacAndId", c_uint8),
|
|
52
|
+
("InvertWiegandBits", c_uint8),
|
|
53
|
+
("EnableBeepOnCardRead", c_uint8),
|
|
54
|
+
("ReverseWiegandBits", c_uint8),
|
|
55
|
+
("ReverseWiegandBytes", c_uint8),
|
|
56
|
+
("UseDataInvert", c_uint8),
|
|
57
|
+
("CardGoneCharacters", c_uint8 * 2),
|
|
58
|
+
("LeadingCharacterCount", c_uint8),
|
|
59
|
+
("TrailingCharacterCount", c_uint8),
|
|
60
|
+
("LeadingTrailingCharacters", c_uint8 * 3),
|
|
61
|
+
|
|
62
|
+
# ReaderConfigurationBlock4
|
|
63
|
+
("UseIndividualIdAndFacFixedLengths", c_uint8),
|
|
64
|
+
("UseFixedLengthFac", c_uint8),
|
|
65
|
+
("UseFixedLengthId", c_uint8),
|
|
66
|
+
("CfgRb3", c_uint8),
|
|
67
|
+
("CfgRb4", c_uint8),
|
|
68
|
+
("EnableFacExtendedPrecision", c_uint8),
|
|
69
|
+
("AzertyKeyboardShift", c_uint8),
|
|
70
|
+
("EnableExtendedMode", c_uint8),
|
|
71
|
+
|
|
72
|
+
# ReaderConfigurationBlock5
|
|
73
|
+
("DisableCardConfiguration", c_uint8),
|
|
74
|
+
("CardType", c_uint16),
|
|
75
|
+
("SetHighPriorityCardType", c_uint8),
|
|
76
|
+
("JetMobileCompatibilityCharacter", c_uint8),
|
|
77
|
+
("JetMobileCharacterCount", c_uint8),
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
def __init__(self, *args: Any, **kw: Any):
|
|
81
|
+
super().__init__()
|
|
82
|
+
for field_name, field_type in self._fields_:
|
|
83
|
+
if field_name in kw:
|
|
84
|
+
setattr(self, field_name, kw[field_name])
|
|
85
|
+
else:
|
|
86
|
+
# Handle array fields differently from scalar fields
|
|
87
|
+
if hasattr(field_type, '_length_'):
|
|
88
|
+
array_instance = field_type()
|
|
89
|
+
for i in range(field_type._length_):
|
|
90
|
+
array_instance[i] = 0
|
|
91
|
+
setattr(self, field_name, array_instance)
|
|
92
|
+
else:
|
|
93
|
+
setattr(self, field_name, 0)
|
|
94
|
+
|
|
95
|
+
def __str__(self):
|
|
96
|
+
field_strings = []
|
|
97
|
+
for field_name, _ in self._fields_:
|
|
98
|
+
field_value = getattr(self, field_name)
|
|
99
|
+
if hasattr(field_value, '__len__') and not isinstance(field_value, str):
|
|
100
|
+
field_strings.append(f"{field_name}: {list(field_value)}")
|
|
101
|
+
else:
|
|
102
|
+
field_strings.append(f"{field_name}: {field_value}")
|
|
103
|
+
return "\n".join(field_strings)
|
|
104
|
+
|
|
105
|
+
def __eq__(self, other):
|
|
106
|
+
if not isinstance(other, type(self)):
|
|
107
|
+
return NotImplemented
|
|
108
|
+
return self.FacDigitCount == other.FacDigitCount and \
|
|
109
|
+
self.IdDigitCount == other.IdDigitCount and \
|
|
110
|
+
self.TotalStripLeadingParityCount == other.TotalStripLeadingParityCount and \
|
|
111
|
+
self.TotalStripTrailingParityCount == other.TotalStripTrailingParityCount and \
|
|
112
|
+
self.IdBitCount == other.IdBitCount and \
|
|
113
|
+
self.ExpectedBitCount == other.ExpectedBitCount and \
|
|
114
|
+
self.IdAndFacDelimiter == other.IdAndFacDelimiter and \
|
|
115
|
+
self.TerminationCharacter == other.TerminationCharacter and \
|
|
116
|
+
self.UseFixedLengthForFacAndId == other.UseFixedLengthForFacAndId and \
|
|
117
|
+
self.EnforceExpectedBitCount == other.EnforceExpectedBitCount and \
|
|
118
|
+
self.StripFacFromId == other.StripFacFromId and \
|
|
119
|
+
self.SendFacAfterStrippingIt == other.SendFacAfterStrippingIt and \
|
|
120
|
+
self.UseIdAndFacDelimiter == other.UseIdAndFacDelimiter and \
|
|
121
|
+
self.DisableKeystrokeTerminationCharacter == other.DisableKeystrokeTerminationCharacter and \
|
|
122
|
+
self.EnableContinuousRead == other.EnableContinuousRead and \
|
|
123
|
+
self.DisableKeystroking == other.DisableKeystroking and \
|
|
124
|
+
self.LegacyBitStreamTimeOutMs == other.LegacyBitStreamTimeOutMs and \
|
|
125
|
+
self.DataHoldTimeMs == other.DataHoldTimeMs and \
|
|
126
|
+
self.LockOutTimeMs == other.LockOutTimeMs and \
|
|
127
|
+
self.KeyPressTimeMs == other.KeyPressTimeMs and \
|
|
128
|
+
self.KeyReleaseTimeMs == other.KeyReleaseTimeMs and \
|
|
129
|
+
self.EnableIdExtendedPrecision == other.EnableIdExtendedPrecision and \
|
|
130
|
+
self.UseLowercaseHex == other.UseLowercaseHex and \
|
|
131
|
+
self.EnableProxProEmulation == other.EnableProxProEmulation and \
|
|
132
|
+
self.EnableHexadecimalId == other.EnableHexadecimalId and \
|
|
133
|
+
self.EnableHexadecimalFac == other.EnableHexadecimalFac and \
|
|
134
|
+
self.UseIndividualIdAndFacNumberFormats == other.UseIndividualIdAndFacNumberFormats and \
|
|
135
|
+
self.UseNumericKeypad == other.UseNumericKeypad and \
|
|
136
|
+
self.EnableRoswellMode == other.EnableRoswellMode and \
|
|
137
|
+
self.EnableRedLed == other.EnableRedLed and \
|
|
138
|
+
self.EnableGreenLed == other.EnableGreenLed and \
|
|
139
|
+
self.EnableOemRelay == other.EnableOemRelay and \
|
|
140
|
+
self.EnableOemBeeper == other.EnableOemBeeper and \
|
|
141
|
+
self.UseLeadingCharacters == other.UseLeadingCharacters and \
|
|
142
|
+
self.EnabledSoftwareControlledLed == other.EnabledSoftwareControlledLed and \
|
|
143
|
+
self.UseHexadecimalForBothFacAndId == other.UseHexadecimalForBothFacAndId and \
|
|
144
|
+
self.InvertWiegandBits == other.InvertWiegandBits and \
|
|
145
|
+
self.EnableBeepOnCardRead == other.EnableBeepOnCardRead and \
|
|
146
|
+
self.ReverseWiegandBits == other.ReverseWiegandBits and \
|
|
147
|
+
self.ReverseWiegandBytes == other.ReverseWiegandBytes and \
|
|
148
|
+
self.UseDataInvert == other.UseDataInvert and \
|
|
149
|
+
list(self.CardGoneCharacters) == list(other.CardGoneCharacters) and \
|
|
150
|
+
self.LeadingCharacterCount == other.LeadingCharacterCount and \
|
|
151
|
+
self.TrailingCharacterCount == other.TrailingCharacterCount and \
|
|
152
|
+
list(self.LeadingTrailingCharacters) == list(other.LeadingTrailingCharacters) and \
|
|
153
|
+
self.UseIndividualIdAndFacFixedLengths == other.UseIndividualIdAndFacFixedLengths and \
|
|
154
|
+
self.UseFixedLengthFac == other.UseFixedLengthFac and \
|
|
155
|
+
self.UseFixedLengthId == other.UseFixedLengthId and \
|
|
156
|
+
self.CfgRb3 == other.CfgRb3 and \
|
|
157
|
+
self.CfgRb4 == other.CfgRb4 and \
|
|
158
|
+
self.EnableFacExtendedPrecision == other.EnableFacExtendedPrecision and \
|
|
159
|
+
self.AzertyKeyboardShift == other.AzertyKeyboardShift and \
|
|
160
|
+
self.EnableExtendedMode == other.EnableExtendedMode and \
|
|
161
|
+
self.DisableCardConfiguration == other.DisableCardConfiguration and \
|
|
162
|
+
self.CardType == other.CardType and \
|
|
163
|
+
self.SetHighPriorityCardType == other.SetHighPriorityCardType and \
|
|
164
|
+
self.JetMobileCompatibilityCharacter == other.JetMobileCompatibilityCharacter and \
|
|
165
|
+
self.JetMobileCharacterCount == other.JetMobileCharacterCount
|
|
166
|
+
|
|
167
|
+
def __ne__(self, other: object) -> bool:
|
|
168
|
+
result = self.__eq__(other)
|
|
169
|
+
if result is NotImplemented:
|
|
170
|
+
return result
|
|
171
|
+
return not result
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from ctypes import Structure, c_uint8
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from reader_integration_kit.enum import FieldDefinitionType
|
|
5
|
+
|
|
6
|
+
class ReaderData(Structure):
|
|
7
|
+
_fields_ = [
|
|
8
|
+
("DefinitionType", c_uint8),
|
|
9
|
+
("EnhanceSecurityFlag", c_uint8),
|
|
10
|
+
("FipsBitCount", c_uint8)
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
def __init__(self, *args: Any, **kw: Any):
|
|
14
|
+
super().__init__()
|
|
15
|
+
self.DefinitionType = kw.get("DefinitionType", args[0] if len(args) > 0 else FieldDefinitionType.USER_FIELDS.value)
|
|
16
|
+
self.EnhanceSecurityFlag = kw.get("EnhanceSecurityFlag", args[1] if len(args) > 1 else 0)
|
|
17
|
+
self.FipsBitCount = kw.get("FipsBitCount", args[2] if len(args) > 2 else 0)
|
|
18
|
+
|
|
19
|
+
def __str__(self):
|
|
20
|
+
return (f"Definition type: {FieldDefinitionType(self.DefinitionType).name}\n"
|
|
21
|
+
f"Enhance security flag: {self.EnhanceSecurityFlag}\n"
|
|
22
|
+
f"Fips bit count: {self.FipsBitCount}\n")
|
|
23
|
+
|
|
24
|
+
def __repr__(self):
|
|
25
|
+
return self.__str__()
|
|
26
|
+
|
|
27
|
+
def __eq__(self, other):
|
|
28
|
+
return self.DefinitionType == other.DefinitionType and self.EnhanceSecurityFlag == other.EnhanceSecurityFlag and self.FipsBitCount == other.FipsBitCount
|
|
29
|
+
|
|
30
|
+
def __ne__(self, other):
|
|
31
|
+
return not self.__eq__(other)
|
|
32
|
+
|
|
33
|
+
def to_dict(self):
|
|
34
|
+
return {
|
|
35
|
+
"DefinitionType": FieldDefinitionType(self.DefinitionType).name,
|
|
36
|
+
"EnhanceSecurityFlag": self.EnhanceSecurityFlag,
|
|
37
|
+
"FipsBitCount": self.FipsBitCount
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
def to_bytes(self):
|
|
41
|
+
return bytes([self.DefinitionType, self.EnhanceSecurityFlag, self.FipsBitCount])
|
|
42
|
+
|
|
43
|
+
@classmethod
|
|
44
|
+
def from_bytes(cls, byte_array):
|
|
45
|
+
return cls(
|
|
46
|
+
DefinitionType=byte_array[0],
|
|
47
|
+
EnhanceSecurityFlag=byte_array[1],
|
|
48
|
+
FipsBitCount=byte_array[2]
|
|
49
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from ctypes import Structure, c_uint8
|
|
2
|
+
|
|
3
|
+
from reader_integration_kit.structures.device_id import DeviceId
|
|
4
|
+
from reader_integration_kit.structures.serial_port_settings import SerialPortSettings
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ReaderDefinition(Structure):
|
|
8
|
+
_pack_ = 1
|
|
9
|
+
_fields_ = [
|
|
10
|
+
("DeviceId", DeviceId),
|
|
11
|
+
("ProtocolType", c_uint8), # ProtocolType enum (byte in C++)
|
|
12
|
+
("SerialPortSettings", SerialPortSettings),
|
|
13
|
+
]
|
|
14
|
+
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
from ctypes import Structure, c_char, c_uint8, c_int
|
|
2
|
+
|
|
3
|
+
from reader_integration_kit.structures.microcontroller_firmware_version import MicrocontrollerFirmwareVersion
|
|
4
|
+
from reader_integration_kit.structures.bluetooth_firmware_version import BluetoothFirmwareVersion
|
|
5
|
+
from reader_integration_kit.structures.hid_se_sam_firmware_version import HidSeSamFirmwareVersion
|
|
6
|
+
from reader_integration_kit.structures.nxp_sam_firmware_version import NxpSamFirmwareVersion
|
|
7
|
+
from reader_integration_kit.structures.felica_sam_firmware_version import FelicaSamFirmwareVersion
|
|
8
|
+
|
|
9
|
+
# Maximum string length for metadata fields (matches METADATA_MAX_STRING_LENGTH = 512)
|
|
10
|
+
METADATA_MAX_STRING_LENGTH = 512
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class _AdvancedAttributes(Structure):
|
|
14
|
+
"""Nested struct for internal Block2 attributes."""
|
|
15
|
+
_pack_ = 1
|
|
16
|
+
_fields_ = [
|
|
17
|
+
("ReverseAllBytesSupported", c_uint8),
|
|
18
|
+
("AsciiExtendedSupported", c_uint8),
|
|
19
|
+
("RoswellModeEnabled", c_uint8),
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ReaderMetadataStruct(Structure):
|
|
24
|
+
"""ReaderMetadataStruct - matches the C struct definition."""
|
|
25
|
+
_pack_ = 1 # Ensure no padding between fields for native compatibility
|
|
26
|
+
_fields_ = [
|
|
27
|
+
("Processor", c_char * METADATA_MAX_STRING_LENGTH),
|
|
28
|
+
("HasProcessor", c_uint8),
|
|
29
|
+
("HardwarePlatform", c_char * METADATA_MAX_STRING_LENGTH),
|
|
30
|
+
("HasHardwarePlatform", c_uint8),
|
|
31
|
+
("Product", c_char * METADATA_MAX_STRING_LENGTH),
|
|
32
|
+
("HasProduct", c_uint8),
|
|
33
|
+
("PartNumber", c_char * METADATA_MAX_STRING_LENGTH),
|
|
34
|
+
("HasPartNumber", c_uint8),
|
|
35
|
+
("ProductLine", c_char * METADATA_MAX_STRING_LENGTH),
|
|
36
|
+
("HasProductLine", c_uint8),
|
|
37
|
+
("ConfigurationCount", c_int),
|
|
38
|
+
("HasConfigurationCount", c_uint8),
|
|
39
|
+
("SerialNumber", c_char * METADATA_MAX_STRING_LENGTH),
|
|
40
|
+
("HasSerialNumber", c_uint8),
|
|
41
|
+
("ESN", c_char * METADATA_MAX_STRING_LENGTH),
|
|
42
|
+
("HasESN", c_uint8),
|
|
43
|
+
("InstalledHardware", c_char * METADATA_MAX_STRING_LENGTH),
|
|
44
|
+
("HasInstalledHardware", c_uint8),
|
|
45
|
+
("SupportedHardware", c_char * METADATA_MAX_STRING_LENGTH),
|
|
46
|
+
("HasSupportedHardware", c_uint8),
|
|
47
|
+
# Raw boolean fields mirroring protocol layer's InstalledHardwareInformation.
|
|
48
|
+
# These provide direct, machine-readable access to hardware capabilities.
|
|
49
|
+
("HwSupportedSamSe", c_uint8),
|
|
50
|
+
("HwSupportedRfAms", c_uint8),
|
|
51
|
+
("HwSupportedRf125", c_uint8),
|
|
52
|
+
("HwSupportedRfLegic", c_uint8),
|
|
53
|
+
("HwSupportedRfBle", c_uint8),
|
|
54
|
+
("HwSupportedNxp", c_uint8),
|
|
55
|
+
("HwSupportedRfHidBle", c_uint8),
|
|
56
|
+
("HwSupportedFelica", c_uint8),
|
|
57
|
+
("HwSupportedBeeper", c_uint8),
|
|
58
|
+
("HwSupportedNano", c_uint8),
|
|
59
|
+
("HwInstalledSamSe", c_uint8),
|
|
60
|
+
("HwInstalledRfAms", c_uint8),
|
|
61
|
+
("HwInstalledRf125", c_uint8),
|
|
62
|
+
("HwInstalledRfLegic", c_uint8),
|
|
63
|
+
("HwInstalledRfBle", c_uint8),
|
|
64
|
+
("HwInstalledNxp", c_uint8),
|
|
65
|
+
("HwInstalledRfHidBle", c_uint8),
|
|
66
|
+
("HwInstalledFelica", c_uint8),
|
|
67
|
+
("HasInstalledHardwareInfo", c_uint8),
|
|
68
|
+
("FirmwareFilename", c_char * METADATA_MAX_STRING_LENGTH),
|
|
69
|
+
("HasFirmwareFilename", c_uint8),
|
|
70
|
+
("FirmwareVersion", c_char * METADATA_MAX_STRING_LENGTH),
|
|
71
|
+
("HasFirmwareVersion", c_uint8),
|
|
72
|
+
("ControllerApplicationVersion", MicrocontrollerFirmwareVersion),
|
|
73
|
+
("HasControllerApplicationVersion", c_uint8),
|
|
74
|
+
("ControllerBootloaderVersion", MicrocontrollerFirmwareVersion),
|
|
75
|
+
("HasControllerBootloaderVersion", c_uint8),
|
|
76
|
+
("ControllerRadioVersion", MicrocontrollerFirmwareVersion),
|
|
77
|
+
("HasControllerRadioVersion", c_uint8),
|
|
78
|
+
("RadioApplicationVersion", MicrocontrollerFirmwareVersion),
|
|
79
|
+
("HasRadioApplicationVersion", c_uint8),
|
|
80
|
+
("RadioBootloaderVersion", MicrocontrollerFirmwareVersion),
|
|
81
|
+
("HasRadioBootloaderVersion", c_uint8),
|
|
82
|
+
("RadioRadioVersion", MicrocontrollerFirmwareVersion),
|
|
83
|
+
("HasRadioRadioVersion", c_uint8),
|
|
84
|
+
("BluetoothVersion", BluetoothFirmwareVersion),
|
|
85
|
+
("HasBluetoothVersion", c_uint8),
|
|
86
|
+
("HidSeSamVersion", HidSeSamFirmwareVersion),
|
|
87
|
+
("HasHidSeSamVersion", c_uint8),
|
|
88
|
+
("NxpSamVersion", NxpSamFirmwareVersion),
|
|
89
|
+
("HasNxpSamVersion", c_uint8),
|
|
90
|
+
("FelicaSamVersion", FelicaSamFirmwareVersion),
|
|
91
|
+
("HasFelicaSamVersion", c_uint8),
|
|
92
|
+
# Protocol type used to communicate with this reader (RikCommon::ProtocolType enum).
|
|
93
|
+
("ProtocolType", c_uint8),
|
|
94
|
+
# Whether this reader supports extended configuration mode.
|
|
95
|
+
("ReaderSupportsExtendedMode", c_uint8),
|
|
96
|
+
# Internal attributes derived from Block2 configuration.
|
|
97
|
+
("AdvancedAttributes", _AdvancedAttributes),
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
def _decode_string(self, field_name: str) -> str:
|
|
101
|
+
"""Helper to decode a string field, handling null termination."""
|
|
102
|
+
field = getattr(self, field_name)
|
|
103
|
+
if field:
|
|
104
|
+
try:
|
|
105
|
+
return bytes(field).decode('utf-8').rstrip('\x00')
|
|
106
|
+
except (UnicodeDecodeError, AttributeError):
|
|
107
|
+
return ""
|
|
108
|
+
return ""
|
|
109
|
+
|
|
110
|
+
def to_dict(self) -> dict:
|
|
111
|
+
"""Convert the struct to a dictionary, only including fields that are present."""
|
|
112
|
+
result = {}
|
|
113
|
+
|
|
114
|
+
# String fields with presence flags
|
|
115
|
+
if self.HasProcessor:
|
|
116
|
+
result["Processor"] = self._decode_string("Processor")
|
|
117
|
+
if self.HasHardwarePlatform:
|
|
118
|
+
result["HardwarePlatform"] = self._decode_string("HardwarePlatform")
|
|
119
|
+
if self.HasProduct:
|
|
120
|
+
result["Product"] = self._decode_string("Product")
|
|
121
|
+
if self.HasPartNumber:
|
|
122
|
+
result["PartNumber"] = self._decode_string("PartNumber")
|
|
123
|
+
if self.HasProductLine:
|
|
124
|
+
result["ProductLine"] = self._decode_string("ProductLine")
|
|
125
|
+
if self.HasConfigurationCount:
|
|
126
|
+
result["ConfigurationCount"] = self.ConfigurationCount
|
|
127
|
+
if self.HasSerialNumber:
|
|
128
|
+
result["SerialNumber"] = self._decode_string("SerialNumber")
|
|
129
|
+
if self.HasESN:
|
|
130
|
+
result["ESN"] = self._decode_string("ESN")
|
|
131
|
+
if self.HasInstalledHardware:
|
|
132
|
+
result["InstalledHardware"] = self._decode_string("InstalledHardware")
|
|
133
|
+
if self.HasSupportedHardware:
|
|
134
|
+
result["SupportedHardware"] = self._decode_string("SupportedHardware")
|
|
135
|
+
|
|
136
|
+
# Hardware capability booleans
|
|
137
|
+
if self.HasInstalledHardwareInfo:
|
|
138
|
+
result["InstalledHardwareInfo"] = {
|
|
139
|
+
"SupportedSamSe": bool(self.HwSupportedSamSe),
|
|
140
|
+
"SupportedRfAms": bool(self.HwSupportedRfAms),
|
|
141
|
+
"SupportedRf125": bool(self.HwSupportedRf125),
|
|
142
|
+
"SupportedRfLegic": bool(self.HwSupportedRfLegic),
|
|
143
|
+
"SupportedRfBle": bool(self.HwSupportedRfBle),
|
|
144
|
+
"SupportedNxp": bool(self.HwSupportedNxp),
|
|
145
|
+
"SupportedRfHidBle": bool(self.HwSupportedRfHidBle),
|
|
146
|
+
"SupportedFelica": bool(self.HwSupportedFelica),
|
|
147
|
+
"SupportedBeeper": bool(self.HwSupportedBeeper),
|
|
148
|
+
"SupportedNano": bool(self.HwSupportedNano),
|
|
149
|
+
"InstalledSamSe": bool(self.HwInstalledSamSe),
|
|
150
|
+
"InstalledRfAms": bool(self.HwInstalledRfAms),
|
|
151
|
+
"InstalledRf125": bool(self.HwInstalledRf125),
|
|
152
|
+
"InstalledRfLegic": bool(self.HwInstalledRfLegic),
|
|
153
|
+
"InstalledRfBle": bool(self.HwInstalledRfBle),
|
|
154
|
+
"InstalledNxp": bool(self.HwInstalledNxp),
|
|
155
|
+
"InstalledRfHidBle": bool(self.HwInstalledRfHidBle),
|
|
156
|
+
"InstalledFelica": bool(self.HwInstalledFelica),
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if self.HasFirmwareFilename:
|
|
160
|
+
result["FirmwareFilename"] = self._decode_string("FirmwareFilename")
|
|
161
|
+
if self.HasFirmwareVersion:
|
|
162
|
+
result["FirmwareVersion"] = self._decode_string("FirmwareVersion")
|
|
163
|
+
|
|
164
|
+
# Firmware version structures
|
|
165
|
+
if self.HasControllerApplicationVersion:
|
|
166
|
+
result["ControllerApplicationVersion"] = self.ControllerApplicationVersion.to_dict()
|
|
167
|
+
if self.HasControllerBootloaderVersion:
|
|
168
|
+
result["ControllerBootloaderVersion"] = self.ControllerBootloaderVersion.to_dict()
|
|
169
|
+
if self.HasControllerRadioVersion:
|
|
170
|
+
result["ControllerRadioVersion"] = self.ControllerRadioVersion.to_dict()
|
|
171
|
+
if self.HasRadioApplicationVersion:
|
|
172
|
+
result["RadioApplicationVersion"] = self.RadioApplicationVersion.to_dict()
|
|
173
|
+
if self.HasRadioBootloaderVersion:
|
|
174
|
+
result["RadioBootloaderVersion"] = self.RadioBootloaderVersion.to_dict()
|
|
175
|
+
if self.HasRadioRadioVersion:
|
|
176
|
+
result["RadioRadioVersion"] = self.RadioRadioVersion.to_dict()
|
|
177
|
+
if self.HasBluetoothVersion:
|
|
178
|
+
result["BluetoothVersion"] = self.BluetoothVersion.to_dict()
|
|
179
|
+
if self.HasHidSeSamVersion:
|
|
180
|
+
result["HidSeSamVersion"] = self.HidSeSamVersion.to_dict()
|
|
181
|
+
if self.HasNxpSamVersion:
|
|
182
|
+
result["NxpSamVersion"] = self.NxpSamVersion.to_dict()
|
|
183
|
+
if self.HasFelicaSamVersion:
|
|
184
|
+
result["FelicaSamVersion"] = self.FelicaSamVersion.to_dict()
|
|
185
|
+
|
|
186
|
+
result["ProtocolType"] = self.ProtocolType
|
|
187
|
+
result["ReaderSupportsExtendedMode"] = bool(self.ReaderSupportsExtendedMode)
|
|
188
|
+
result["AdvancedAttributes"] = {
|
|
189
|
+
"ReverseAllBytesSupported": bool(self.AdvancedAttributes.ReverseAllBytesSupported),
|
|
190
|
+
"AsciiExtendedSupported": bool(self.AdvancedAttributes.AsciiExtendedSupported),
|
|
191
|
+
"RoswellModeEnabled": bool(self.AdvancedAttributes.RoswellModeEnabled),
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return result
|
|
195
|
+
|