diff --git a/kasa/discover.py b/kasa/discover.py index 911c005c..fa95618c 100755 --- a/kasa/discover.py +++ b/kasa/discover.py @@ -831,6 +831,13 @@ class Discover: # Reuse the login_version attribute to pass the max to transport login_version = max([int(i) for i in et]) + if not encrypt_type and encrypt_schm.is_support_https and login_version == 3: + # Some camera firmwares (C460 1.2.2 for one) leave encrypt_type out + # of mgt_encrypt_schm and send no encrypt_info, only the top level + # encrypt_type list. "3" is the AES login that every other camera + # reports as sym_schm AES. + encrypt_type = DeviceEncryptionType.Aes.value + if not encrypt_type: raise UnsupportedDeviceError( f"Unsupported device {discovery_result.ip} of type {type_} " diff --git a/tests/test_discovery.py b/tests/test_discovery.py index e2b5042a..8ad45b85 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -31,6 +31,8 @@ from kasa.device_factory import ( from kasa.deviceconfig import ( DeviceConfig, DeviceConnectionParameters, + DeviceEncryptionType, + DeviceFamily, ) from kasa.discover import ( DiscoveryResult, @@ -749,3 +751,29 @@ async def test_discovery_device_repr(discovery_mock, mocker): assert "update() needed" not in repr_ else: assert "update() needed" in repr_ + + +async def test_connection_parameters_from_encrypt_type_list_only(): + """Cameras that send only the encrypt_type list are treated as AES login.""" + result = { + "device_type": "SMART.IPCAMERA", + "device_model": "C460", + "device_id": "0000000000000000000000000000000000000000", + "ip": "127.0.0.123", + "mac": "7C-F1-7E-00-00-00", + "mgt_encrypt_schm": {"is_support_https": True}, + "encrypt_type": ["3"], + "firmware_version": "1.2.2 Build 260416 Rel.13928n", + "hardware_version": "1.0", + } + params = Discover._get_connection_parameters(DiscoveryResult.from_dict(result)) + + assert params.device_family is DeviceFamily.SmartIpCamera + assert params.encryption_type is DeviceEncryptionType.Aes + assert params.login_version == 3 + assert params.https is True + + # Without the "3" hint the device is still reported as unsupported + result["encrypt_type"] = ["9"] + with pytest.raises(UnsupportedDeviceError, match="no encryption type"): + Discover._get_connection_parameters(DiscoveryResult.from_dict(result))