1.1.0版本

This commit is contained in:
xinzhu.yin
2026-04-16 16:51:05 +08:00
commit c157e774e5
333 changed files with 70759 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
from .hdcp_tx import HdcpSource, HdcpSourceStatus, HdcpSourceConfig
from .hdcp_rx import HdcpSink, HdcpSinkStatus, HdcpSinkConfig
from .types import HdcpMode, HdcpRxConfig, HdcpTxConfig, HdcpStatus, HdcpSink1XKeys, HdcpSink2XKeys, HdcpSource1XKeys, \
HdcpSource2XKeys

View File

@@ -0,0 +1,246 @@
import warnings
from typing import Optional, Union
from UniTAP.libs.lib_tsi.tsi_io import PortIO, PortProtocol
from .types import *
from UniTAP.libs.lib_tsi.tsi import c_int
class HdcpSinkStatus:
"""
Class `HdcpSinkStatus` contains information about HDCP 1.4 and 2.3 statuses.
If you want to get object of one the status, use function `get`.
"""
def __init__(self, port_io: PortIO, ci_status_control: int, caps_1x: HdcpHwSinkCaps, caps_2x: HdcpHwSinkCaps):
super().__init__()
self.__io = port_io
self.__ci_status_control = ci_status_control
self.__caps_1x = caps_1x
self.__caps_2x = caps_2x
def get(self, hdcp_mode: Type[HdcpStatusType]) -> HdcpStatusType:
"""
Returns one of possible HDCP Status Type:
- Status1x (HDCP 1.4).
- StatusRx2x (HDCP 2.3).
Object contains info about:
- HDCP keys (HdcpSink1XKeys if HDCP type 1.4; HdcpSink2XKeys if HDCP type 2.3).
- Active state (True or False).
- Authenticated state (True or False).
- Capable state (True or False).
Returns:
object of `HdcpStatusType` (`Status1x` or `StatusRx2x`)
"""
if hdcp_mode not in [HdcpStatus.Status1x, HdcpStatus.StatusRx2x]:
raise TypeError(f"Wrong type HDCP status, provided type {hdcp_mode}")
if hdcp_mode == HdcpStatus.Status1x:
if self.__caps_1x.hw_supported:
status_value = self.__read_status(HdcpMode.Mode1_4)
status = HdcpStatus.Status1x()
status.active = status_value & 1
status.keys = HdcpSink1XKeys((status_value >> 1) & 3)
status.capable = ((status_value >> 3) & 1)
status.authenticated = ((status_value >> 4) & 1)
return status
else:
warnings.warn(f"Not supported 'HDCP 1.4'")
elif hdcp_mode == HdcpStatus.StatusRx2x:
if self.__caps_2x.hw_supported:
status_value = self.__read_status(HdcpMode.Mode2_3)
status = HdcpStatus.StatusRx2x()
if self.__io.protocol() == PortProtocol.HDMI:
status.keys = HdcpSink2XKeys.Production if (status_value >> 9) & 1 else HdcpSink2XKeys.Unload
else:
if (status_value >> 11) & 1:
status.keys = HdcpSink2XKeys.TestR1
elif (status_value >> 13) & 1:
status.keys = HdcpSink2XKeys.TestR2
elif (status_value >> 9) & 1:
status.keys = HdcpSink2XKeys.Production
else:
status.keys = HdcpSink2XKeys.Unload
status.active = (status_value >> 8) & 1
status.capable = (status_value >> 10) & 1
status.authenticated = (status_value >> 12) & 1
return status
else:
warnings.warn(f"Not supported 'HDCP 2.3'")
def __read_status(self, mode: HdcpMode) -> int:
if mode == HdcpMode.Mode1_4:
return self.__io.get(TSI_HDCP_1X_STATUS_R, c_int)[1]
else:
return self.__io.get(self.__ci_status_control, c_int)[1]
class HdcpSinkConfig:
"""
Class `HdcpSinkConfig` contains information about HDCP 1.4 and 2.3 configurations.
If you want to set configuration, use function `set`.
If you want to get current config, use function `get`.
"""
def __init__(self, port_io: PortIO, caps_1x: HdcpHwSinkCaps, caps_2x: HdcpHwSinkCaps, status: HdcpSinkStatus):
self.__io = port_io
self.__caps_1x = caps_1x
self.__caps_2x = caps_2x
self.__status = status
def set(self, config: HdcpRxConfigType):
"""
This function is used to set the HDCP on Sink (RX - receiver) side.
Possible to load HDCP keys and enable/disable HDCP.
Args:
config (HdcpRxConfigType) - one of the available HDCP config type: Config1x (HDCP 1.4), Config2x (HDCP 2.3)
"""
if isinstance(config, HdcpRxConfig.Config1x):
if self.__caps_1x.hw_supported:
self.__load_keys(config.keys, HdcpMode.Mode1_4)
self.__set_capable(config.capable, HdcpMode.Mode1_4)
else:
warnings.warn(f"Not supported 'HDCP 1.4'")
elif isinstance(config, HdcpRxConfig.Config2x):
if self.__caps_2x.hw_supported:
self.__load_keys(config.keys, HdcpMode.Mode2_3)
self.__set_capable(config.capable, HdcpMode.Mode2_3)
else:
warnings.warn(f"Not supported 'HDCP 2.3'")
def get(self, hdcp_mode: Type[HdcpRxConfigType]) -> HdcpRxConfigType:
"""
This function is used to get current HDCP configuration on Sink (RX - receiver) side.
Returns:
object of HdcpRxConfigType - one of the available HDCP config type: Config1x (HDCP 1.4), Config2x (HDCP 2.3)
"""
if hdcp_mode == HdcpRxConfig.Config1x:
if self.__caps_1x.hw_supported:
config = HdcpRxConfig.Config1x()
status = self.__status.get(HdcpStatus.Status1x)
config.keys = status.keys
config.capable = status.capable
return config
else:
warnings.warn(f"Not supported 'HDCP 1.4'")
elif hdcp_mode == HdcpRxConfig.Config2x:
if self.__caps_2x.hw_supported:
config = HdcpRxConfig.Config2x()
status = self.__status.get(HdcpStatus.StatusRx2x)
config.keys = status.keys
config.capable = status.capable
return config
else:
warnings.warn(f"Not supported 'HDCP 2.3'")
def __load_keys(self, keys: Optional[Union[HdcpSink1XKeys, HdcpSink2XKeys]], hdcp_mode: HdcpMode):
if keys is None:
return
if not self.__full_check(hdcp_mode):
return
if hdcp_mode == HdcpMode.Mode1_4 and not isinstance(keys, HdcpSink1XKeys):
raise TypeError("Was selected HDCP 1.4 mode. Need to use 'HdcpSink1XKeys' type.")
elif hdcp_mode == HdcpMode.Mode1_4 and isinstance(keys, HdcpSink1XKeys):
if keys == HdcpSink1XKeys.Production and not self.__caps_1x.production_keys_available:
warnings.warn("Production keys is not hw supported. Please, select another keys.")
elif keys == HdcpSink1XKeys.Test and not self.__caps_1x.test_keys_available:
warnings.warn("Test keys is not hw supported. Please, select another keys.")
elif hdcp_mode == HdcpMode.Mode2_3 and not isinstance(keys, HdcpSink2XKeys):
raise TypeError("Was selected HDCP 2.3 mode. Need to use 'HdcpSink2XKeys' type.")
elif hdcp_mode == HdcpMode.Mode2_3 and isinstance(keys, HdcpSink2XKeys):
if keys == HdcpSink2XKeys.Production and not self.__caps_2x.production_keys_available:
warnings.warn("Production keys is not hw supported. Please, select another keys.")
self.__io.set(TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else TSI_HDCP_2X_COMMAND_W, keys.value)
def __set_capable(self, value: Optional[bool], hdcp_mode: HdcpMode):
if value is None:
return
if not self.__full_check(hdcp_mode):
return
self.__io.set(TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else TSI_HDCP_2X_COMMAND_W,
(H1_SINK_SET_CAPABLE if value else H1_SINK_CLEAR_CAPABLE)
if hdcp_mode == HdcpMode.Mode1_4 else (H2_SINK_SET_CAPABLE if value else H2_SINK_CLEAR_CAPABLE))
def __full_check(self, hdcp_mode: HdcpMode) -> bool:
if hdcp_mode == HdcpMode.Unknown:
warnings.warn(f"Did not select HDCP mode. Please, select it from available variants: "
f"{'HDCP 1.4 ' if self.__caps_1x.hw_supported else ''}"
f"{'HDCP 2.3 ' if self.__caps_2x.hw_supported else ''}")
return False
if not self.__availability_mode_check(hdcp_mode):
warnings.warn(f"Selected HDCP mode is not HW supported. Please, select it from available variants: "
f"{'HDCP 1.4 ' if self.__caps_1x.hw_supported else ''}"
f"{'HDCP 2.3 ' if self.__caps_2x.hw_supported else ''}")
return False
return True
def __availability_mode_check(self, hdcp_mode: HdcpMode) -> bool:
if hdcp_mode == HdcpMode.Mode1_4 and self.__caps_1x.hw_supported:
return True
elif hdcp_mode == HdcpMode.Mode2_3 and self.__caps_2x.hw_supported:
return True
else:
return False
class HdcpSink:
"""
Main class contains info of HDCP on Sink (RX - receiver) side.
If you need to configurate HDCP, use `config` for getting object responsible for the configuration.
If you need to read HDCP status, use `status` for getting object responsible for the reading current status.
"""
def __init__(self, port_io: PortIO, ci_caps_control: int, ci_status_control: int):
self.__io = port_io
self.__hw_caps_1x = HdcpHwSinkCaps(self.__read_hw_caps(HdcpMode.Mode1_4), HdcpMode.Mode1_4)
self.__hw_caps_2x = HdcpHwSinkCaps(self.__read_hw_caps(HdcpMode.Mode2_3, ci_caps_control), HdcpMode.Mode2_3)
self.__status = HdcpSinkStatus(port_io, ci_status_control, self.__hw_caps_1x, self.__hw_caps_2x)
self.__config = HdcpSinkConfig(port_io, self.__hw_caps_1x, self.__hw_caps_2x, self.__status)
@property
def config(self) -> HdcpSinkConfig:
"""
Should be used to configure HDCP on Sink (RX - receiver) role.
Returns:
object of `HdcpSinkConfig`.
"""
return self.__config
@property
def status(self) -> HdcpSinkStatus:
"""
Should be used to read HDCP current status on Sink (RX - receiver) role.
Returns:
object of `HdcpSinkStatus`.
"""
return self.__status
def __read_hw_caps(self, mode: HdcpMode, ci_caps_control: int = 0) -> int:
if mode == HdcpMode.Mode1_4:
return self.__io.get(TSI_HDCP_1X_STATUS_R, c_int)[1]
elif mode == HdcpMode.Mode2_3:
return self.__io.get(ci_caps_control, c_int)[1]
else:
return 0

View File

@@ -0,0 +1,288 @@
import warnings
from typing import Optional, Union
from UniTAP.libs.lib_tsi.tsi_io import PortIO, PortProtocol
from .types import *
from UniTAP.libs.lib_tsi.tsi_private_types import *
from ctypes import c_int
class HdcpSourceStatus:
"""
Class `HdcpSourceStatus` contains information about HDCP 1.4 and 2.3 statuses.
If you want to get object of one the status, use function `get`.
"""
def __init__(self, port_io: PortIO, ci_status_control: int, caps_1x: HdcpHwSourceCaps, caps_2x: HdcpHwSourceCaps):
super().__init__()
self.__io = port_io
self.__ci_status_control = ci_status_control
self.__caps_1x = caps_1x
self.__caps_2x = caps_2x
def get(self, hdcp_mode: Type[HdcpStatusType]) -> HdcpStatusType:
"""
Returns one of possible HDCP Status Type:
- Status1x (HDCP 1.4).
- StatusTx2x (HDCP 2.3).
Object contains info about:
- HDCP keys (HdcpSource1XKeys if HDCP type 1.4; HdcpSource2XKeys if HDCP type 2.3).
- Active state (True or False).
- Authenticated state (True or False).
- Capable state (True or False).
If HDCP type is 2.3, then it contains more information:
- KM stored state (True or False).
- Try to authenticate state (True or False).
- Try to encrypt state (True or False).
- Content level.
Returns:
object of `HdcpStatusType` (`Status1x` or `StatusTx2x`)
"""
if hdcp_mode not in [HdcpStatus.Status1x, HdcpStatus.StatusTx2x]:
raise TypeError(f"Wrong type HDCP status, provided type {hdcp_mode}")
if hdcp_mode == HdcpStatus.Status1x:
if self.__caps_1x.hw_supported:
status_value = self.__read_status(HdcpMode.Mode1_4)
status = HdcpStatus.Status1x()
status.active = (status_value >> 8) & 1
status.keys = HdcpSource1XKeys(((status_value >> 9) & 3) + 0x100)
status.capable = ((status_value >> 11) & 1)
status.authenticated = ((status_value >> 12) & 1)
return status
else:
warnings.warn(f"Not supported 'HDCP 1.4'")
elif hdcp_mode == HdcpStatus.StatusTx2x:
if self.__caps_2x.hw_supported:
status_value = self.__read_status(HdcpMode.Mode2_3)
status = HdcpStatus.StatusTx2x()
if self.__io.protocol() == PortProtocol.HDMI:
status.keys = HdcpSource2XKeys.Production if (status_value >> 9) & 1 else HdcpSource2XKeys.Unload
else:
if (status_value >> 14) & 1:
status.keys = HdcpSource2XKeys.TestR1
elif (status_value >> 15) & 1:
status.keys = HdcpSource2XKeys.TestR2
elif (status_value >> 9) & 1:
status.keys = HdcpSource2XKeys.Production
else:
status.keys = HdcpSource2XKeys.Unload
status.km_is_stored = (status_value >> 13) & 1
status.try_authenticate = (status_value >> 18) & 1
status.try_encrypt = (status_value >> 19) & 1
status.content_level = self.__io.get(TSI_HDCP_2X_CFG, c_uint32)[1]
status.active = (status_value >> 8) & 1
status.capable = (status_value >> 10) & 1
status.authenticated = (status_value >> 12) & 1
return status
else:
warnings.warn(f"Not supported 'HDCP 2.3'")
def __read_status(self, mode: HdcpMode):
if mode == HdcpMode.Mode1_4:
return self.__io.get(TSI_HDCP_1X_STATUS_R, c_int)[1]
elif mode == HdcpMode.Mode2_3:
return self.__io.get(self.__ci_status_control, c_int)[1]
else:
return 0
class HdcpSourceConfig:
"""
Class `HdcpSourceConfig` contains information about HDCP 1.4 and 2.3 configurations.
If you want to set configuration, use function `set`.
If you want to get current config, use function `get`.
"""
def __init__(self, port_io: PortIO, caps_1x: HdcpHwSourceCaps, caps_2x: HdcpHwSourceCaps, status: HdcpSourceStatus):
self.__io = port_io
self.__caps_1x = caps_1x
self.__caps_2x = caps_2x
self.__status = status
def set(self, config: HdcpTxConfigType):
"""
This function is used to set the HDCP on Source (TX - transmitter) side.
Possible to load HDCP keys and enable/disable HDCP.
Args:
config (HdcpTxConfigType) - one of the available HDCP config type: Config1x (HDCP 1.4), Config2x (HDCP 2.3)
"""
if isinstance(config, HdcpTxConfig.Config1x):
if self.__caps_1x.hw_supported:
self.__load_keys(config.keys, HdcpMode.Mode1_4)
self.__set_authenticate(config.authenticate, HdcpMode.Mode1_4)
self.__set_encryption(config.encryption, HdcpMode.Mode1_4)
else:
warnings.warn(f"Not supported 'HDCP 1.4'")
elif isinstance(config, HdcpTxConfig.Config2x):
if self.__caps_2x.hw_supported:
self.__load_keys(config.keys, HdcpMode.Mode2_3)
self.__set_content_level(config.content_level)
self.__set_authenticate(config.authenticate, HdcpMode.Mode2_3)
self.__set_store_km(config.store_km)
self.__set_encryption(config.encryption, HdcpMode.Mode2_3)
else:
warnings.warn(f"Not supported 'HDCP 2.3'")
def get(self, hdcp_mode: Type[HdcpTxConfigType]) -> HdcpTxConfigType:
"""
This function is used to get current HDCP configuration on Source (TX - transmitter) side.
Returns:
object of HdcpTxConfigType - one of the available HDCP config type: Config1x (HDCP 1.4), Config2x (HDCP 2.3)
"""
if hdcp_mode == HdcpTxConfig.Config1x:
if self.__caps_1x.hw_supported:
config = HdcpTxConfig.Config1x()
status = self.__status.get(HdcpStatus.Status1x)
config.keys = status.keys
config.encryption = status.active
config.authenticate = status.authenticated
return config
else:
warnings.warn(f"Not supported 'HDCP 1.4'")
elif hdcp_mode == HdcpTxConfig.Config2x:
if self.__caps_2x.hw_supported:
config = HdcpTxConfig.Config2x()
status = self.__status.get(HdcpStatus.StatusTx2x)
config.keys = status.keys
config.encryption = status.try_encrypt
config.authenticate = status.try_authenticate
config.store_km = status.km_is_stored
config.content_level = status.content_level
return config
else:
warnings.warn(f"Not supported 'HDCP 2.3'")
def __set_encryption(self, value: Optional[bool], hdcp_mode: HdcpMode):
if value is None:
return
if hdcp_mode == HdcpMode.Mode1_4:
self.__io.set(TSI_HDCP_1X_COMMAND_W, H1_SOURCE_ENABLE_ENCRYPT if value else H1_SOURCE_DISABLE_ENCRYPT)
elif hdcp_mode == HdcpMode.Mode2_3:
self.__io.set(TSI_HDCP_2X_COMMAND_W, H2_SOURCE_ENABLE_ENCRYPT if value else H2_SOURCE_DISABLE_ENCRYPT)
def __set_authenticate(self, value: Optional[bool], hdcp_mode: HdcpMode):
if value is None:
return
if hdcp_mode == HdcpMode.Mode1_4:
self.__io.set(TSI_HDCP_1X_COMMAND_W, H1_SOURCE_AUTHENTICATE if value else H1_SOURCE_DE_AUTHENTICATE)
elif hdcp_mode == HdcpMode.Mode2_3:
self.__io.set(TSI_HDCP_2X_COMMAND_W, H2_SOURCE_AUTHENTICATE if value else H2_SOURCE_DE_AUTHENTICATE)
def __load_keys(self, keys: Optional[Union[HdcpSource1XKeys, HdcpSource2XKeys]], hdcp_mode: HdcpMode):
if keys is None:
return
if not self.__full_check(hdcp_mode):
return
if hdcp_mode == HdcpMode.Mode1_4 and not isinstance(keys, HdcpSource1XKeys):
raise TypeError("Was selected HDCP 1.4 mode. Need to use 'HdcpSource1XKeys' type.")
elif hdcp_mode == HdcpMode.Mode1_4 and isinstance(keys, HdcpSource1XKeys):
if keys == HdcpSource1XKeys.Production and not self.__caps_1x.production_keys_available:
warnings.warn("Production keys is not hw supported. Please, select another keys.")
elif keys == HdcpSource1XKeys.Test and not self.__caps_1x.test_keys_available:
warnings.warn("Test keys is not hw supported. Please, select another keys.")
elif hdcp_mode == HdcpMode.Mode2_3 and not isinstance(keys, HdcpSource2XKeys):
raise TypeError("Was selected HDCP 2.3 mode. Need to use 'HdcpSource2XKeys' type.")
elif hdcp_mode == HdcpMode.Mode2_3 and isinstance(keys, HdcpSource2XKeys):
if keys == HdcpSource2XKeys.Production and not self.__caps_2x.production_keys_available:
warnings.warn("Production keys is not hw supported. Please, select another keys.")
self.__io.set(TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else TSI_HDCP_2X_COMMAND_W, keys.value)
def __full_check(self, hdcp_mode: HdcpMode) -> bool:
if hdcp_mode == HdcpMode.Unknown:
warnings.warn(f"Did not select HDCP mode. Please, select it from available variants: "
f"{'HDCP 1.4 ' if self.__caps_1x.hw_supported else ''}"
f"{'HDCP 2.3 ' if self.__caps_2x.hw_supported else ''}")
return False
if not self.__availability_mode_check(hdcp_mode):
warnings.warn(f"Selected HDCP mode is not HW supported. Please, select it from available variants: "
f"{'HDCP 1.4 ' if self.__caps_1x.hw_supported else ''}"
f"{'HDCP 2.3 ' if self.__caps_2x.hw_supported else ''}")
return False
return True
def __availability_mode_check(self, hdcp_mode: HdcpMode) -> bool:
if hdcp_mode == HdcpMode.Mode1_4 and self.__caps_1x.hw_supported:
return True
elif hdcp_mode == HdcpMode.Mode2_3 and self.__caps_2x.hw_supported:
return True
else:
return False
def __set_store_km(self, value: Optional[bool]):
if value is None:
return
self.__io.set(TSI_HDCP_2X_COMMAND_W, H2_SOURCE_AUTHENTICATE_STORE_KM if value else H2_SOURCE_CLEAR_STORE_KM)
def __set_content_level(self, value: Optional[int]):
if value is None:
return
if value not in [0, 1]:
raise ValueError(f"Incorrect input value of 'Content level' - {value}. Must be from range: 0-1")
self.__io.set(TSI_HDCP_2X_CFG, value)
class HdcpSource:
"""
Main class contains info of HDCP on Source (TX - transmitter) side.
If you need to configurate HDCP, use `config` for getting object responsible for the configuration.
If you need to read HDCP status, use `status` for getting object responsible for the reading current status.
"""
def __init__(self, port_io: PortIO, ci_caps_control: int, ci_status_control: int):
self.__io = port_io
self.__hw_caps_1x = HdcpHwSourceCaps(self.__read_hw_caps(HdcpMode.Mode1_4), HdcpMode.Mode1_4)
self.__hw_caps_2x = HdcpHwSourceCaps(self.__read_hw_caps(HdcpMode.Mode2_3, ci_caps_control), HdcpMode.Mode2_3)
self.__status = HdcpSourceStatus(port_io, ci_status_control, self.__hw_caps_1x, self.__hw_caps_2x)
self.__config = HdcpSourceConfig(port_io, self.__hw_caps_1x, self.__hw_caps_2x, self.__status)
@property
def config(self) -> HdcpSourceConfig:
"""
Should be used to configure HDCP on Source (TX - transmitter) role.
Returns:
object of `HdcpSourceConfig`.
"""
return self.__config
@property
def status(self) -> HdcpSourceStatus:
"""
Should be used to read HDCP current status onSource (TX - transmitter) role.
Returns:
object of `HdcpSourceStatus`.
"""
return self.__status
def __read_hw_caps(self, mode: HdcpMode, ci_caps_control: int = 0) -> int:
if mode == HdcpMode.Mode1_4:
return self.__io.get(TSI_HDCP_1X_STATUS_R, c_int)[1]
elif mode == HdcpMode.Mode2_3:
return self.__io.get(ci_caps_control, c_int)[1]
else:
return 0

View File

@@ -0,0 +1,221 @@
from typing import TypeVar
from UniTAP.libs.lib_tsi.tsi_types import *
from enum import IntEnum
from typing import Type
class HdcpSink1XKeys(IntEnum):
Unknown = -1
Unload = H1_SINK_UNLOAD_KEYS
Test = H1_SINK_LOAD_TEST_KEYS
Production = H1_SINK_LOAD_PROD_KEYS
class HdcpSink2XKeys(IntEnum):
Unknown = -1
Unload = H2_SINK_UNLOAD_KEYS
Production = H2_SINK_LOAD_PROD_KEYS
TestR1 = H2_SINK_LOAD_TEST_KEYS_R1
TestR2 = H2_SINK_LOAD_TEST_KEYS_R2
class HdcpSource1XKeys(IntEnum):
Unknown = -1
Unload = H1_SOURCE_UNLOAD_KEYS
Test = H1_SOURCE_LOAD_TEST_KEYS
Production = H1_SOURCE_LOAD_PROD_KEYS
class HdcpSource2XKeys(IntEnum):
Unknown = -1
Unload = H2_SOURCE_UNLOAD_KEYS
Production = H2_SOURCE_LOAD_PROD_KEYS
TestR1 = H2_SOURCE_LOAD_TEST_KEYS_R1
TestR2 = H2_SOURCE_LOAD_TEST_KEYS_R2
class HdcpMode(IntEnum):
Unknown = -1
Mode1_4 = 0
Mode2_3 = 1
class HdcpHwCaps:
def __init__(self):
self.hw_supported = False
self.production_keys_available = False
self.test_keys_available = False
def __str__(self):
return f"HW Supported: {self.hw_supported}\n" \
f"Production keys available: {self.production_keys_available}\n" \
f"Test keys available: {self.test_keys_available}\n"
class HdcpHwSinkCaps(HdcpHwCaps):
def __init__(self, caps: int, hdcp_mode: HdcpMode):
super().__init__()
if hdcp_mode == HdcpMode.Mode1_4:
self.hw_supported = ((caps >> 16) & 1) != 0
self.production_keys_available = ((caps >> 17) & 1) != 0
self.test_keys_available = ((caps >> 18) & 1) != 0
else:
self.hw_supported = ((caps >> 8) & 1) != 0
self.production_keys_available = ((caps >> 9) & 1) != 0
self.test_keys_available = ((caps >> 10) & 1) != 0
class HdcpHwSourceCaps(HdcpHwCaps):
def __init__(self, caps: int, hdcp_mode: HdcpMode):
super().__init__()
if hdcp_mode == HdcpMode.Mode1_4:
self.hw_supported = ((caps >> 24) & 1) != 0
self.production_keys_available = ((caps >> 25) & 1) != 0
self.test_keys_available = ((caps >> 26) & 1) != 0
elif hdcp_mode == HdcpMode.Mode2_3:
self.hw_supported = ((caps >> 8) & 1) != 0
self.production_keys_available = ((caps >> 9) & 1) != 0
self.test_keys_available = ((caps >> 10) & 1) != 0
class HdcpStatus:
class Status1x:
def __init__(self):
self.active = False
self.keys = None
self.capable = False
self.authenticated = False
def __str__(self):
return f"Active: {bool(self.active)}\n" \
f"Keys: {self.keys.name}\n" \
f"Capable: {bool(self.capable)}\n" \
f"Authenticated: {bool(self.authenticated)}\n"
def __eq__(self, other):
return self.active == other.active and \
self.keys == other.keys and \
self.capable == other.capable and \
self.authenticated == other.authenticated
class StatusRx2x:
def __init__(self):
self.active = False
self.keys = None
self.capable = False
self.authenticated = False
self.km_is_stored = False
self.content_level = 0
def __str__(self):
return f"Active: {bool(self.active)}\n" \
f"Keys: {self.keys.name}\n" \
f"Capable: {bool(self.capable)}\n" \
f"Authenticated: {bool(self.authenticated)}\n" \
f"Km is stored: {bool(self.km_is_stored)}\n" \
f"Content level: {self.content_level}\n"
def __eq__(self, other):
return self.active == other.active and \
self.keys == other.keys and \
self.capable == other.capable and \
self.authenticated == other.authenticated and \
self.km_is_stored == other.km_is_stored and \
self.content_level == other.content_level
class StatusTx2x:
def __init__(self):
self.active = False
self.keys = None
self.capable = False
self.authenticated = False
self.km_is_stored = False
self.content_level = 0
self.try_authenticate = False
self.try_encrypt = False
def __str__(self):
return f"Active: {bool(self.active)}\n" \
f"Keys: {self.keys.name}\n" \
f"Capable: {bool(self.capable)}\n" \
f"Authenticated: {bool(self.authenticated)}\n" \
f"Km is stored: {bool(self.km_is_stored)}\n" \
f"Content level: {self.content_level}\n"
def __eq__(self, other):
return self.active == other.active and \
self.keys == other.keys and \
self.capable == other.capable and \
self.authenticated == other.authenticated and \
self.km_is_stored == other.km_is_stored and \
self.content_level == other.content_level and \
self.try_authenticate == other.try_authenticate and \
self.try_encrypt == other.try_encrypt
class HdcpRxConfig:
class Config1x:
def __init__(self):
self.keys = None
self.capable = None
class Config2x:
def __init__(self):
self.keys = None
self.capable = None
class HdcpTxConfig:
class Config1x:
def __init__(self):
self.encryption = None
self.authenticate = None
self.keys = None
def __eq__(self, other):
return self.encryption == other.encryption and \
self.authenticate == other.authenticate and \
self.keys == other.keys
class Config2x:
def __init__(self):
self.encryption = None
self.authenticate = None
self.keys = None
self.store_km = None
self.content_level = None
def __eq__(self, other):
return self.encryption == other.encryption and \
self.authenticate == other.authenticate and \
self.keys == other.keys and \
self.store_km == other.store_km and \
self.content_level == other.content_level
HdcpRxConfigType = TypeVar("HdcpRxConfigType",
HdcpRxConfig.Config1x,
HdcpRxConfig.Config2x)
HdcpTxConfigType = TypeVar("HdcpTxConfigType",
HdcpTxConfig.Config1x,
HdcpTxConfig.Config2x)
HdcpStatusType = TypeVar("HdcpStatusType",
HdcpStatus.Status1x,
HdcpStatus.StatusRx2x,
HdcpStatus.StatusTx2x)