- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
1181 lines
40 KiB
Python
1181 lines
40 KiB
Python
"""
|
|
Android Telephony EUICC 组件 — EuiccManager, EuiccCardManager, EuiccInfo, DownloadableSubscription 等
|
|
方法签名完全对齐 Android SDK (android.telephony.euicc 包)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
from ..java.lang import RuntimeException
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccManager
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccManager(Stub):
|
|
"""EuiccManager — eUICC 管理器"""
|
|
|
|
ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS"
|
|
ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION"
|
|
ACTION_RESOLVE_ERROR = "android.telephony.euicc.action.RESOLVE_ERROR"
|
|
ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED"
|
|
ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED"
|
|
ACTION_RENAME_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED"
|
|
ACTION_START_RESOLUTION = "android.telephony.euicc.action.START_RESOLUTION"
|
|
|
|
EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION"
|
|
EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID"
|
|
EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION"
|
|
EXTRA_RESOLUTION_INTENT = "android.telephony.euicc.extra.RESOLUTION_INTENT"
|
|
EXTRA_RESOLUTION_CALLBACK_INTENT = "android.telephony.euicc.extra.RESOLUTION_CALLBACK_INTENT"
|
|
EXTRA_USE_QR_SCANNER = "android.telephony.euicc.extra.USE_QR_SCANNER"
|
|
EXTRA_FORCE_COMMIT = "android.telephony.euicc.extra.FORCE_COMMIT"
|
|
EXTRA_CONSENT = "android.telephony.euicc.extra.CONSENT"
|
|
EXTRA_SUBSCRIPTION_ID_FOR_RESOLVING = "android.telephony.euicc.extra.SUBSCRIPTION_ID_FOR_RESOLVING"
|
|
EXTRA_RESOLVING_ACTION = "android.telephony.euicc.extra.RESOLVING_ACTION"
|
|
EXTRA_ACTIVE_SLOT = "android.telephony.euicc.extra.ACTIVE_SLOT"
|
|
EXTRA_SIM_SLOT_INDEX = "android.telephony.euicc.extra.SIM_SLOT_INDEX"
|
|
EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID"
|
|
|
|
EMBEDDED_SUBSCRIPTION_RESULT_OK = 0
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 1
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_BUSY = 2
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_ACTIVATION_CODE = 3
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_CONFIRMATION_CODE = 4
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_RESPONSE = 5
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_MATCHING_ID = 6
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_SMDP_ADDRESS = 7
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_NETWORK = 8
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_UNSUPPORTED = 9
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_PROFILES_LIMIT_EXCEEDED = 10
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_DOWNLOAD_IN_PROGRESS = 11
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_PORT = 12
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_CARRIER_LOCKED = 13
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_PORT_INDEX = 14
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_ADDRESS = 15
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INTERNAL = 16
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_SIM_NOT_READY = 17
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_CARRIER_PRIVILEGE = 18
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_APDU = 19
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_CONFIRMATION_CODE_MISMATCH = 20
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_OPERATION_BUSY = 21
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_INVALID_SLOT_ID = 22
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_NOT_FOUND = 23
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_DISALLOWED = 24
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_NOT_ENABLED = 25
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_MULTI_SIM_NOT_SUPPORTED = 26
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_SUBSCRIPTION_NOT_FOUND = 27
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_SUBSCRIPTION_ALREADY_EXISTS = 28
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_RENAME_NOT_ALLOWED = 29
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_DELETE_NOT_ALLOWED = 30
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_REFRESH_NOT_ALLOWED = 31
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_OUT_OF_MEMORY = 32
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_REJECTED = 33
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_FRAME_TABLE_FULL = 34
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_APPLICATION_NOT_FOUND = 35
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_MISMATCH = 36
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_VERSION_NOT_SUPPORTED = 37
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_POLICY = 38
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_AUTH = 39
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_KEY = 40
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_SIGNATURE = 41
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_CERTIFICATE = 42
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_CERTIFICATE_EXPIRED = 43
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_CERTIFICATE_REVOKED = 44
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_IDENTITY_MISMATCH = 45
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_PROFILE_NOT_AVAILABLE = 46
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_PROFILE_ALREADY_INSTALLED = 47
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_PROFILE_NOT_INSTALLED = 48
|
|
EMBEDDED_SUBSCRIPTION_RESULT_ERROR_EUICC_PROFILE_INVALID = 49
|
|
|
|
# eUICC 操作
|
|
OPERATION_DOWNLOAD = 0
|
|
OPERATION_DELETE = 1
|
|
OPERATION_SWITCH = 2
|
|
OPERATION_RENAME = 3
|
|
OPERATION_REFRESH = 4
|
|
OPERATION_RESOLVE = 5
|
|
OPERATION_GET_DEFAULT = 6
|
|
OPERATION_GET_EID = 7
|
|
OPERATION_GET_EUICC_INFO = 8
|
|
OPERATION_GET_EUICC_CHALLENGE = 9
|
|
OPERATION_GET_PROFILE = 10
|
|
OPERATION_GET_SUBSCRIPTION = 11
|
|
OPERATION_LIST_SUBSCRIPTIONS = 12
|
|
OPERATION_SET_NICKNAME = 13
|
|
OPERATION_ERASE = 14
|
|
OPERATION_UPDATE = 15
|
|
|
|
def __init__(self, context: Any = None):
|
|
super().__init__()
|
|
self._context = context
|
|
self._eid: str = ""
|
|
self._euicc_info: Optional[EuiccInfo] = None
|
|
self._subscriptions: List[EuiccSubscriptionInfo] = []
|
|
self._enabled: bool = False
|
|
self._slot_index: int = 0
|
|
|
|
def isEnabled(self) -> bool:
|
|
"""检查 eUICC 是否启用"""
|
|
return self._enabled
|
|
|
|
def setEnabled(self, enabled: bool):
|
|
self._enabled = enabled
|
|
|
|
def getEid(self) -> str:
|
|
"""获取 eUICC ID (EID)"""
|
|
return self._eid
|
|
|
|
def setEid(self, eid: str):
|
|
self._eid = eid
|
|
|
|
def getEuiccInfo(self) -> Optional[EuiccInfo]:
|
|
"""获取 eUICC 信息"""
|
|
return self._euicc_info
|
|
|
|
def setEuiccInfo(self, info: EuiccInfo):
|
|
self._euicc_info = info
|
|
|
|
def getEuiccCardManager(self) -> Optional[EuiccCardManager]:
|
|
"""获取 eUICC 卡管理器"""
|
|
return EuiccCardManager(self._context)
|
|
|
|
def getSlotIndex(self) -> int:
|
|
return self._slot_index
|
|
|
|
def setSlotIndex(self, index: int):
|
|
self._slot_index = index
|
|
|
|
def getContext(self) -> Any:
|
|
return self._context
|
|
|
|
def downloadSubscription(self, subscription: DownloadableSubscription,
|
|
switch_to_downloaded: bool = True,
|
|
callback: Any = None) -> int:
|
|
"""下载订阅"""
|
|
return EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK
|
|
|
|
def startResolution(self, result: int, callback_intent: Any,
|
|
resolution_intent: Any):
|
|
"""启动解析流程"""
|
|
pass
|
|
|
|
def listSubscriptions(self) -> List[EuiccSubscriptionInfo]:
|
|
"""列出所有订阅"""
|
|
return list(self._subscriptions)
|
|
|
|
def addSubscription(self, sub: EuiccSubscriptionInfo):
|
|
self._subscriptions.append(sub)
|
|
|
|
def removeSubscription(self, sub_id: int):
|
|
self._subscriptions = [s for s in self._subscriptions if s.getSubscriptionId() != sub_id]
|
|
|
|
def getDefaultDownloadableSubscription(self) -> Optional[DownloadableSubscription]:
|
|
"""获取默认可下载订阅"""
|
|
return None
|
|
|
|
def createForCardId(self, card_id: int) -> EuiccManager:
|
|
"""为指定卡 ID 创建 eUICC 管理器"""
|
|
return self
|
|
|
|
def switchToSubscription(self, sub_id: int, callback: Any = None):
|
|
"""切换到指定订阅"""
|
|
pass
|
|
|
|
def deleteSubscription(self, sub_id: int, callback: Any = None):
|
|
"""删除指定订阅"""
|
|
pass
|
|
|
|
def renameSubscription(self, sub_id: int, new_name: str):
|
|
"""重命名订阅"""
|
|
for s in self._subscriptions:
|
|
if s.getSubscriptionId() == sub_id:
|
|
s.setNickname(new_name)
|
|
break
|
|
|
|
def eraseSubscriptions(self, callback: Any = None):
|
|
"""擦除所有订阅"""
|
|
self._subscriptions.clear()
|
|
|
|
def refreshSubscriptions(self, callback: Any = None):
|
|
"""刷新订阅列表"""
|
|
pass
|
|
|
|
def retainSubscriptionsForFactoryReset(self, callback: Any = None):
|
|
"""保留订阅以备恢复出厂设置"""
|
|
pass
|
|
|
|
def isSimPortAvailable(self, port_index: int) -> bool:
|
|
return True
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccManager(enabled={self._enabled}, eid={self._eid[:8] if self._eid else ''}...)"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccCardManager
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccCardManager(Stub):
|
|
"""EuiccCardManager — eUICC 卡管理器"""
|
|
|
|
RESULT_OK = 0
|
|
RESULT_UNKNOWN_ERROR = 1
|
|
RESULT_INVALID_ARGUMENTS = 2
|
|
RESULT_INTERNAL_ERROR = 3
|
|
RESULT_SESSION_CLOSED = 4
|
|
RESULT_NO_PENDING_COMMANDS = 5
|
|
RESULT_COMMAND_FAILED = 6
|
|
RESULT_APDU_ERROR = 7
|
|
RESULT_CARD_NOT_ACCESSIBLE = 8
|
|
RESULT_CARD_REMOVED = 9
|
|
RESULT_CARD_RESET = 10
|
|
RESULT_TIMEOUT = 11
|
|
RESULT_CARD_IO_ERROR = 12
|
|
RESULT_CARD_AUTH_ERROR = 13
|
|
RESULT_PROFILE_NOT_AVAILABLE = 14
|
|
RESULT_PROFILE_ALREADY_INSTALLED = 15
|
|
RESULT_PROFILE_NOT_INSTALLED = 16
|
|
RESULT_PROFILE_INSTALL_ERROR = 17
|
|
RESULT_PROFILE_DELETE_ERROR = 18
|
|
RESULT_PROFILE_EUICC_MISMATCH = 19
|
|
RESULT_PROFILE_VERSION_MISMATCH = 20
|
|
RESULT_PROFILE_CERTIFICATE_ERROR = 21
|
|
RESULT_PROFILE_SIGNATURE_ERROR = 22
|
|
RESULT_PROFILE_INTEGRITY_ERROR = 23
|
|
RESULT_PROFILE_EXPIRED = 24
|
|
RESULT_PROFILE_REVOKED = 25
|
|
RESULT_PROFILE_POLICY_ERROR = 26
|
|
RESULT_PROFILE_AUTH_ERROR = 27
|
|
RESULT_PROFILE_KEY_ERROR = 28
|
|
RESULT_PROFILE_MEMORY_ERROR = 29
|
|
RESULT_PROFILE_UNSUPPORTED = 30
|
|
RESULT_PROFILE_CONFLICT = 31
|
|
RESULT_RAT_NOT_ALLOWED = 32
|
|
RESULT_POLICY_RULES_NOT_SATISFIED = 33
|
|
RESULT_NOT_ENABLED = 34
|
|
RESULT_MULTISIM_NOT_SUPPORTED = 35
|
|
RESULT_CARRIER_LOCKED = 36
|
|
RESULT_OPERATION_BUSY = 37
|
|
RESULT_CARD_ALREADY_ACTIVE = 38
|
|
RESULT_CARD_INACTIVE = 39
|
|
|
|
class ResultCallback(Stub):
|
|
"""EuiccCardManager.ResultCallback — eUICC 卡操作结果回调"""
|
|
|
|
def onComplete(self, result: int, data: Any = None):
|
|
pass
|
|
|
|
def __init__(self, context: Any = None):
|
|
super().__init__()
|
|
self._context = context
|
|
self._card_id: str = ""
|
|
self._eid: str = ""
|
|
|
|
def getContext(self) -> Any:
|
|
return self._context
|
|
|
|
def getCardId(self) -> str:
|
|
return self._card_id
|
|
|
|
def setCardId(self, card_id: str):
|
|
self._card_id = card_id
|
|
|
|
def getEid(self) -> str:
|
|
return self._eid
|
|
|
|
def setEid(self, eid: str):
|
|
self._eid = eid
|
|
|
|
def requestEvents(self, callback: ResultCallback):
|
|
"""请求 eUICC 事件"""
|
|
pass
|
|
|
|
def requestEvents(self, port_index: int, callback: ResultCallback):
|
|
pass
|
|
|
|
def listNotifications(self, callback: ResultCallback):
|
|
"""列出通知"""
|
|
pass
|
|
|
|
def listNotifications(self, port_index: int, callback: ResultCallback):
|
|
pass
|
|
|
|
def retrieveNotification(self, seq_number: int, callback: ResultCallback):
|
|
"""检索通知"""
|
|
pass
|
|
|
|
def retrieveNotificationList(self, seq_numbers: List[int], callback: ResultCallback):
|
|
"""检索通知列表"""
|
|
pass
|
|
|
|
def prepareDownload(self, subscription: DownloadableSubscription,
|
|
callback: ResultCallback):
|
|
"""准备下载"""
|
|
pass
|
|
|
|
def prepareDownload(self, port_index: int, subscription: DownloadableSubscription,
|
|
callback: ResultCallback):
|
|
pass
|
|
|
|
def loadBoundProfilePackage(self, bound_profile_package: bytes,
|
|
callback: ResultCallback):
|
|
"""加载绑定配置文件包"""
|
|
pass
|
|
|
|
def loadBoundProfilePackage(self, port_index: int, bound_profile_package: bytes,
|
|
callback: ResultCallback):
|
|
pass
|
|
|
|
def getProfile(self, iccid: str, callback: ResultCallback):
|
|
"""获取配置文件"""
|
|
pass
|
|
|
|
def getProfile(self, port_index: int, iccid: str, callback: ResultCallback):
|
|
pass
|
|
|
|
def listProfiles(self, callback: ResultCallback):
|
|
"""列出配置文件"""
|
|
pass
|
|
|
|
def listProfiles(self, port_index: int, callback: ResultCallback):
|
|
pass
|
|
|
|
def setNickname(self, iccid: str, nickname: str, callback: ResultCallback):
|
|
"""设置昵称"""
|
|
pass
|
|
|
|
def setNickname(self, port_index: int, iccid: str, nickname: str, callback: ResultCallback):
|
|
pass
|
|
|
|
def deleteProfile(self, iccid: str, callback: ResultCallback):
|
|
"""删除配置文件"""
|
|
pass
|
|
|
|
def deleteProfile(self, port_index: int, iccid: str, callback: ResultCallback):
|
|
pass
|
|
|
|
def enableProfile(self, iccid: str, callback: ResultCallback):
|
|
"""启用配置文件"""
|
|
pass
|
|
|
|
def enableProfile(self, port_index: int, iccid: str, callback: ResultCallback):
|
|
pass
|
|
|
|
def disableProfile(self, iccid: str, callback: ResultCallback):
|
|
"""禁用配置文件"""
|
|
pass
|
|
|
|
def disableProfile(self, port_index: int, iccid: str, callback: ResultCallback):
|
|
pass
|
|
|
|
def resetMemory(self, reset_options: int, callback: ResultCallback):
|
|
"""重置 eUICC 内存"""
|
|
pass
|
|
|
|
def resetMemory(self, port_index: int, reset_options: int, callback: ResultCallback):
|
|
pass
|
|
|
|
def setTestMode(self, test_mode: bool, callback: ResultCallback):
|
|
"""设置测试模式"""
|
|
pass
|
|
|
|
def getEuiccChallenge(self, callback: ResultCallback):
|
|
"""获取 eUICC 挑战"""
|
|
pass
|
|
|
|
def getEuiccChallenge(self, port_index: int, callback: ResultCallback):
|
|
pass
|
|
|
|
def getEuiccInfo(self, callback: ResultCallback):
|
|
"""获取 eUICC 信息"""
|
|
pass
|
|
|
|
def getEuiccInfo(self, port_index: int, callback: ResultCallback):
|
|
pass
|
|
|
|
def listSubscriptions(self, callback: ResultCallback):
|
|
"""列出订阅"""
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccCardManager(eid={self._eid[:8] if self._eid else ''}...)"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccInfo(Stub):
|
|
"""EuiccInfo — eUICC 信息"""
|
|
|
|
def __init__(self, gsid: str = "", svn: str = "",
|
|
pp_version: str = "",
|
|
global_platform_version: str = ""):
|
|
super().__init__()
|
|
self._gsid = gsid
|
|
self._svn = svn
|
|
self._pp_version = pp_version
|
|
self._global_platform_version = global_platform_version
|
|
self._euicc_firmware_version: str = ""
|
|
self._euicc_hardware_version: str = ""
|
|
self._oid: str = ""
|
|
self._eid: str = ""
|
|
self._profile_version: str = ""
|
|
self._ext_card_resource: str = ""
|
|
self._default_smdp_address: str = ""
|
|
|
|
def getGsid(self) -> str:
|
|
return self._gsid
|
|
|
|
def setGsid(self, gsid: str):
|
|
self._gsid = gsid
|
|
|
|
def getSvn(self) -> str:
|
|
return self._svn
|
|
|
|
def setSvn(self, svn: str):
|
|
self._svn = svn
|
|
|
|
def getPpVersion(self) -> str:
|
|
return self._pp_version
|
|
|
|
def setPpVersion(self, pp_version: str):
|
|
self._pp_version = pp_version
|
|
|
|
def getGlobalPlatformVersion(self) -> str:
|
|
return self._global_platform_version
|
|
|
|
def setGlobalPlatformVersion(self, version: str):
|
|
self._global_platform_version = version
|
|
|
|
def getEuiccFirmwareVersion(self) -> str:
|
|
return self._euicc_firmware_version
|
|
|
|
def setEuiccFirmwareVersion(self, version: str):
|
|
self._euicc_firmware_version = version
|
|
|
|
def getEuiccHardwareVersion(self) -> str:
|
|
return self._euicc_hardware_version
|
|
|
|
def setEuiccHardwareVersion(self, version: str):
|
|
self._euicc_hardware_version = version
|
|
|
|
def getOid(self) -> str:
|
|
return self._oid
|
|
|
|
def setOid(self, oid: str):
|
|
self._oid = oid
|
|
|
|
def getEid(self) -> str:
|
|
return self._eid
|
|
|
|
def setEid(self, eid: str):
|
|
self._eid = eid
|
|
|
|
def getProfileVersion(self) -> str:
|
|
return self._profile_version
|
|
|
|
def setProfileVersion(self, version: str):
|
|
self._profile_version = version
|
|
|
|
def getExtCardResource(self) -> str:
|
|
return self._ext_card_resource
|
|
|
|
def setExtCardResource(self, resource: str):
|
|
self._ext_card_resource = resource
|
|
|
|
def getDefaultSmdpAddress(self) -> str:
|
|
return self._default_smdp_address
|
|
|
|
def setDefaultSmdpAddress(self, address: str):
|
|
self._default_smdp_address = address
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccInfo(gsid={self._gsid}, svn={self._svn})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# DownloadableSubscription
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class DownloadableSubscription(Stub):
|
|
"""DownloadableSubscription — 可下载订阅"""
|
|
|
|
def __init__(self, encoded_activation_code: str = ""):
|
|
super().__init__()
|
|
self._encoded_activation_code = encoded_activation_code
|
|
self._confirmation_code: str = ""
|
|
self._carrier_name: str = ""
|
|
self._access_rule: Optional[EuiccRulesAuthTable] = None
|
|
self._matching_id: str = ""
|
|
self._smdp_address: str = ""
|
|
self._profile_class: int = 0
|
|
self._iccid: str = ""
|
|
self._nickname: str = ""
|
|
|
|
def getEncodedActivationCode(self) -> str:
|
|
return self._encoded_activation_code
|
|
|
|
def setEncodedActivationCode(self, code: str):
|
|
self._encoded_activation_code = code
|
|
|
|
def getConfirmationCode(self) -> str:
|
|
return self._confirmation_code
|
|
|
|
def setConfirmationCode(self, code: str):
|
|
self._confirmation_code = code
|
|
|
|
def getCarrierName(self) -> str:
|
|
return self._carrier_name
|
|
|
|
def setCarrierName(self, name: str):
|
|
self._carrier_name = name
|
|
|
|
def getAccessRule(self) -> Optional[EuiccRulesAuthTable]:
|
|
return self._access_rule
|
|
|
|
def setAccessRule(self, rule: EuiccRulesAuthTable):
|
|
self._access_rule = rule
|
|
|
|
def getMatchingId(self) -> str:
|
|
return self._matching_id
|
|
|
|
def setMatchingId(self, matching_id: str):
|
|
self._matching_id = matching_id
|
|
|
|
def getSmdpAddress(self) -> str:
|
|
return self._smdp_address
|
|
|
|
def setSmdpAddress(self, address: str):
|
|
self._smdp_address = address
|
|
|
|
def getProfileClass(self) -> int:
|
|
return self._profile_class
|
|
|
|
def setProfileClass(self, profile_class: int):
|
|
self._profile_class = profile_class
|
|
|
|
def getIccid(self) -> str:
|
|
return self._iccid
|
|
|
|
def setIccid(self, iccid: str):
|
|
self._iccid = iccid
|
|
|
|
def getNickname(self) -> str:
|
|
return self._nickname
|
|
|
|
def setNickname(self, nickname: str):
|
|
self._nickname = nickname
|
|
|
|
@staticmethod
|
|
def forActivationCode(encoded_activation_code: str) -> DownloadableSubscription:
|
|
return DownloadableSubscription(encoded_activation_code)
|
|
|
|
def toString(self) -> str:
|
|
return f"DownloadableSubscription(carrier={self._carrier_name})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccNotification
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccNotification(Stub):
|
|
"""EuiccNotification — eUICC 通知"""
|
|
|
|
EVENT_INSTALL = 1
|
|
EVENT_DELETE = 2
|
|
EVENT_ENABLE = 4
|
|
EVENT_DISABLE = 8
|
|
EVENT_REFRESH = 16
|
|
EVENT_POLICY_RULES_CHANGE = 32
|
|
EVENT_MEMORY_RESET = 64
|
|
EVENT_PROFILE_METADATA_UPDATED = 128
|
|
EVENT_NOTIFICATIONS_ENABLED = 256
|
|
EVENT_ALL = 511
|
|
|
|
ALL_EVENTS = EVENT_INSTALL | EVENT_DELETE | EVENT_ENABLE | EVENT_DISABLE | EVENT_REFRESH | EVENT_POLICY_RULES_CHANGE | EVENT_MEMORY_RESET | EVENT_PROFILE_METADATA_UPDATED | EVENT_NOTIFICATIONS_ENABLED
|
|
|
|
def __init__(self, seq_number: int = 0, target_address: str = "",
|
|
event: int = 0, timestamp: int = 0):
|
|
super().__init__()
|
|
self._seq_number = seq_number
|
|
self._target_address = target_address
|
|
self._event = event
|
|
self._timestamp = timestamp
|
|
self._iccid: str = ""
|
|
self._displacement: Optional[bytes] = None
|
|
self._notification_data: Optional[bytes] = None
|
|
|
|
def getSeqNumber(self) -> int:
|
|
return self._seq_number
|
|
|
|
def setSeqNumber(self, seq: int):
|
|
self._seq_number = seq
|
|
|
|
def getTargetAddress(self) -> str:
|
|
return self._target_address
|
|
|
|
def setTargetAddress(self, address: str):
|
|
self._target_address = address
|
|
|
|
def getEvent(self) -> int:
|
|
return self._event
|
|
|
|
def setEvent(self, event: int):
|
|
self._event = event
|
|
|
|
def getTimestamp(self) -> int:
|
|
return self._timestamp
|
|
|
|
def setTimestamp(self, ts: int):
|
|
self._timestamp = ts
|
|
|
|
def getIccid(self) -> str:
|
|
return self._iccid
|
|
|
|
def setIccid(self, iccid: str):
|
|
self._iccid = iccid
|
|
|
|
def getDisplacement(self) -> Optional[bytes]:
|
|
return self._displacement
|
|
|
|
def setDisplacement(self, data: bytes):
|
|
self._displacement = data
|
|
|
|
def getNotificationData(self) -> Optional[bytes]:
|
|
return self._notification_data
|
|
|
|
def setNotificationData(self, data: bytes):
|
|
self._notification_data = data
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccNotification(seq={self._seq_number}, event={self._event})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccRulesAuthTable
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccRulesAuthTable(Stub):
|
|
"""EuiccRulesAuthTable — eUICC 规则授权表"""
|
|
|
|
RULE_TYPE_ACCESS_RULES = 0
|
|
RULE_TYPE_POLICY_RULES = 1
|
|
RULE_TYPE_USAGE_RULES = 2
|
|
|
|
POLICY_RULE_FLAG_CONSENT_REQUIRED = 1
|
|
POLICY_RULE_FLAG_NOTIFY_REQUIRED = 2
|
|
POLICY_RULE_FLAG_DELETE_BLOCKED = 4
|
|
POLICY_RULE_FLAG_DISABLE_BLOCKED = 8
|
|
|
|
class RulesAuthTableEntry(Stub):
|
|
"""EuiccRulesAuthTable.RulesAuthTableEntry — 规则授权表条目"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._certificate_hash: str = ""
|
|
self._rule_type: int = 0
|
|
self._flags: int = 0
|
|
self._signature: str = ""
|
|
self._pkid: str = ""
|
|
self._valid_from: int = 0
|
|
self._valid_until: int = 0
|
|
|
|
def getCertificateHash(self) -> str:
|
|
return self._certificate_hash
|
|
|
|
def setCertificateHash(self, hash_val: str):
|
|
self._certificate_hash = hash_val
|
|
|
|
def getRuleType(self) -> int:
|
|
return self._rule_type
|
|
|
|
def setRuleType(self, rule_type: int):
|
|
self._rule_type = rule_type
|
|
|
|
def getFlags(self) -> int:
|
|
return self._flags
|
|
|
|
def setFlags(self, flags: int):
|
|
self._flags = flags
|
|
|
|
def getSignature(self) -> str:
|
|
return self._signature
|
|
|
|
def setSignature(self, sig: str):
|
|
self._signature = sig
|
|
|
|
def getPkid(self) -> str:
|
|
return self._pkid
|
|
|
|
def setPkid(self, pkid: str):
|
|
self._pkid = pkid
|
|
|
|
def hasFlags(self, flag: int) -> bool:
|
|
return bool(self._flags & flag)
|
|
|
|
def isValidFor(self, timestamp: int) -> bool:
|
|
return self._valid_from <= timestamp < self._valid_until
|
|
|
|
def toString(self) -> str:
|
|
return f"RulesAuthTableEntry(type={self._rule_type})"
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._entries: List[EuiccRulesAuthTable.RulesAuthTableEntry] = []
|
|
|
|
def getEntries(self) -> List[RulesAuthTableEntry]:
|
|
return list(self._entries)
|
|
|
|
def addEntry(self, entry: RulesAuthTableEntry):
|
|
self._entries.append(entry)
|
|
|
|
def removeEntry(self, entry: RulesAuthTableEntry):
|
|
self._entries = [e for e in self._entries if e is not entry]
|
|
|
|
def findEntryByCertHash(self, cert_hash: str) -> Optional[RulesAuthTableEntry]:
|
|
for e in self._entries:
|
|
if e.getCertificateHash() == cert_hash:
|
|
return e
|
|
return None
|
|
|
|
def findEntryByPkid(self, pkid: str) -> Optional[RulesAuthTableEntry]:
|
|
for e in self._entries:
|
|
if e.getPkid() == pkid:
|
|
return e
|
|
return None
|
|
|
|
def getSize(self) -> int:
|
|
return len(self._entries)
|
|
|
|
def isEmpty(self) -> bool:
|
|
return len(self._entries) == 0
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccRulesAuthTable(entries={len(self._entries)})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccSubscriptionInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccSubscriptionInfo(Stub):
|
|
"""EuiccSubscriptionInfo — eUICC 订阅信息"""
|
|
|
|
SUBSCRIPTION_TYPE_PROFILE = 0
|
|
SUBSCRIPTION_TYPE_RESERVED = 1
|
|
SUBSCRIPTION_TYPE_OPERATIONAL = 2
|
|
SUBSCRIPTION_TYPE_TEST = 3
|
|
SUBSCRIPTION_TYPE_PROVISIONING = 4
|
|
SUBSCRIPTION_TYPE_UNKNOWN = -1
|
|
|
|
def __init__(self, subscription_id: int = 0, iccid: str = "",
|
|
nickname: str = ""):
|
|
super().__init__()
|
|
self._subscription_id = subscription_id
|
|
self._iccid = iccid
|
|
self._nickname = nickname
|
|
self._carrier_name: str = ""
|
|
self._subscription_type: int = EuiccSubscriptionInfo.SUBSCRIPTION_TYPE_PROFILE
|
|
self._is_embedded: bool = True
|
|
self._is_removable: bool = False
|
|
self._is_active: bool = False
|
|
self._profile_class: int = 0
|
|
self._port_index: int = 0
|
|
self._logical_slot_index: int = 0
|
|
self._eid: str = ""
|
|
self._access_rules: Optional[EuiccRulesAuthTable] = None
|
|
|
|
def getSubscriptionId(self) -> int:
|
|
return self._subscription_id
|
|
|
|
def setSubscriptionId(self, sub_id: int):
|
|
self._subscription_id = sub_id
|
|
|
|
def getIccid(self) -> str:
|
|
return self._iccid
|
|
|
|
def setIccid(self, iccid: str):
|
|
self._iccid = iccid
|
|
|
|
def getNickname(self) -> str:
|
|
return self._nickname
|
|
|
|
def setNickname(self, nickname: str):
|
|
self._nickname = nickname
|
|
|
|
def getCarrierName(self) -> str:
|
|
return self._carrier_name
|
|
|
|
def setCarrierName(self, name: str):
|
|
self._carrier_name = name
|
|
|
|
def getSubscriptionType(self) -> int:
|
|
return self._subscription_type
|
|
|
|
def setSubscriptionType(self, sub_type: int):
|
|
self._subscription_type = sub_type
|
|
|
|
def isEmbedded(self) -> bool:
|
|
return self._is_embedded
|
|
|
|
def setEmbedded(self, embedded: bool):
|
|
self._is_embedded = embedded
|
|
|
|
def isRemovable(self) -> bool:
|
|
return self._is_removable
|
|
|
|
def setRemovable(self, removable: bool):
|
|
self._is_removable = removable
|
|
|
|
def isActive(self) -> bool:
|
|
return self._is_active
|
|
|
|
def setActive(self, active: bool):
|
|
self._is_active = active
|
|
|
|
def getProfileClass(self) -> int:
|
|
return self._profile_class
|
|
|
|
def setProfileClass(self, profile_class: int):
|
|
self._profile_class = profile_class
|
|
|
|
def getPortIndex(self) -> int:
|
|
return self._port_index
|
|
|
|
def setPortIndex(self, port: int):
|
|
self._port_index = port
|
|
|
|
def getLogicalSlotIndex(self) -> int:
|
|
return self._logical_slot_index
|
|
|
|
def setLogicalSlotIndex(self, index: int):
|
|
self._logical_slot_index = index
|
|
|
|
def getEid(self) -> str:
|
|
return self._eid
|
|
|
|
def setEid(self, eid: str):
|
|
self._eid = eid
|
|
|
|
def getAccessRules(self) -> Optional[EuiccRulesAuthTable]:
|
|
return self._access_rules
|
|
|
|
def setAccessRules(self, rules: EuiccRulesAuthTable):
|
|
self._access_rules = rules
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccSubscriptionInfo(id={self._subscription_id}, carrier={self._carrier_name})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccProfileInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccProfileInfo(Stub):
|
|
"""EuiccProfileInfo — eUICC 配置文件信息"""
|
|
|
|
PROFILE_CLASS_OPERATIONAL = 0
|
|
PROFILE_CLASS_TEST = 1
|
|
PROFILE_CLASS_PROVISIONING = 2
|
|
PROFILE_CLASS_OPERATIONAL_V2 = 3
|
|
PROFILE_CLASS_UNKNOWN = -1
|
|
|
|
STATE_DISABLED = 0
|
|
STATE_ENABLED = 1
|
|
|
|
def __init__(self, iccid: str = ""):
|
|
super().__init__()
|
|
self._iccid = iccid
|
|
self._nickname: str = ""
|
|
self._carrier_name: str = ""
|
|
self._profile_class: int = EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL
|
|
self._state: int = EuiccProfileInfo.STATE_DISABLED
|
|
self._service_provider_name: str = ""
|
|
self._profile_name: str = ""
|
|
self._profile_owner: str = ""
|
|
self._carrier_privilege_rules: List[EuiccRulesAuthTable.RulesAuthTableEntry] = []
|
|
self._is_visible: bool = True
|
|
self._policy_rules: Optional[EuiccRulesAuthTable] = None
|
|
self._icon: Optional[bytes] = None
|
|
|
|
def getIccid(self) -> str:
|
|
return self._iccid
|
|
|
|
def setIccid(self, iccid: str):
|
|
self._iccid = iccid
|
|
|
|
def getNickname(self) -> str:
|
|
return self._nickname
|
|
|
|
def setNickname(self, nickname: str):
|
|
self._nickname = nickname
|
|
|
|
def getCarrierName(self) -> str:
|
|
return self._carrier_name
|
|
|
|
def setCarrierName(self, name: str):
|
|
self._carrier_name = name
|
|
|
|
def getProfileClass(self) -> int:
|
|
return self._profile_class
|
|
|
|
def setProfileClass(self, profile_class: int):
|
|
self._profile_class = profile_class
|
|
|
|
def getState(self) -> int:
|
|
return self._state
|
|
|
|
def setState(self, state: int):
|
|
self._state = state
|
|
|
|
def getServiceProviderName(self) -> str:
|
|
return self._service_provider_name
|
|
|
|
def setServiceProviderName(self, name: str):
|
|
self._service_provider_name = name
|
|
|
|
def getProfileName(self) -> str:
|
|
return self._profile_name
|
|
|
|
def setProfileName(self, name: str):
|
|
self._profile_name = name
|
|
|
|
def getCarrierPrivilegeRules(self) -> List[EuiccRulesAuthTable.RulesAuthTableEntry]:
|
|
return list(self._carrier_privilege_rules)
|
|
|
|
def setCarrierPrivilegeRules(self, rules: List[EuiccRulesAuthTable.RulesAuthTableEntry]):
|
|
self._carrier_privilege_rules = list(rules)
|
|
|
|
def isVisible(self) -> bool:
|
|
return self._is_visible
|
|
|
|
def setVisible(self, visible: bool):
|
|
self._is_visible = visible
|
|
|
|
def getPolicyRules(self) -> Optional[EuiccRulesAuthTable]:
|
|
return self._policy_rules
|
|
|
|
def setPolicyRules(self, rules: EuiccRulesAuthTable):
|
|
self._policy_rules = rules
|
|
|
|
def isEnabled(self) -> bool:
|
|
return self._state == EuiccProfileInfo.STATE_ENABLED
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccProfileInfo(iccid={self._iccid}, carrier={self._carrier_name})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccActions (helper)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccActions(Stub):
|
|
"""EuiccActions — eUICC 操作辅助类"""
|
|
|
|
@staticmethod
|
|
def createDownloadAction(subscription: DownloadableSubscription,
|
|
switch_on_download: bool = True) -> Any:
|
|
"""创建下载操作意图"""
|
|
return None
|
|
|
|
@staticmethod
|
|
def createDeleteAction(subscription_id: int) -> Any:
|
|
"""创建删除操作意图"""
|
|
return None
|
|
|
|
@staticmethod
|
|
def createSwitchAction(subscription_id: int) -> Any:
|
|
"""创建切换操作意图"""
|
|
return None
|
|
|
|
@staticmethod
|
|
def createRenameAction(subscription_id: int, new_name: str) -> Any:
|
|
"""创建重命名操作意图"""
|
|
return None
|
|
|
|
@staticmethod
|
|
def createEraseAction() -> Any:
|
|
"""创建擦除操作意图"""
|
|
return None
|
|
|
|
@staticmethod
|
|
def encodeActivationCode(matching_id: str, smdp_address: str) -> str:
|
|
"""编码激活码"""
|
|
return f"1$^{matching_id}${smdp_address}$"
|
|
|
|
@staticmethod
|
|
def decodeActivationCode(activation_code: str) -> Optional[Tuple[str, str]]:
|
|
"""解码激活码"""
|
|
try:
|
|
parts = activation_code.split("$")
|
|
if len(parts) >= 3:
|
|
return parts[1], parts[2]
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
@staticmethod
|
|
def isValidActivationCode(activation_code: str) -> bool:
|
|
"""验证激活码是否有效"""
|
|
return activation_code.startswith("1$") and "$" in activation_code
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccChannel (helper)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccChannel(Stub):
|
|
"""EuiccChannel — eUICC 通道辅助类"""
|
|
|
|
CHANNEL_TYPE_APDU = 0
|
|
CHANNEL_TYPE_HTTP = 1
|
|
CHANNEL_TYPE_HTTPS = 2
|
|
|
|
def __init__(self, channel_type: int = CHANNEL_TYPE_APDU):
|
|
super().__init__()
|
|
self._channel_type = channel_type
|
|
self._is_open: bool = False
|
|
self._buffer: bytes = b""
|
|
|
|
def getChannelType(self) -> int:
|
|
return self._channel_type
|
|
|
|
def isOpen(self) -> bool:
|
|
return self._is_open
|
|
|
|
def open(self):
|
|
self._is_open = True
|
|
|
|
def close(self):
|
|
self._is_open = False
|
|
self._buffer = b""
|
|
|
|
def send(self, data: bytes) -> bytes:
|
|
self._buffer = data
|
|
return b""
|
|
|
|
def receive(self) -> bytes:
|
|
return self._buffer
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccChannel(type={self._channel_type}, open={self._is_open})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccPortIndex (helper)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccPortIndex(Stub):
|
|
"""EuiccPortIndex — eUICC 端口索引"""
|
|
|
|
PORT_INDEX_DEFAULT = 0
|
|
PORT_INDEX_FIRST = 0
|
|
PORT_INDEX_SECOND = 1
|
|
|
|
def __init__(self, port_index: int = PORT_INDEX_DEFAULT):
|
|
super().__init__()
|
|
self._port_index = port_index
|
|
|
|
def getPortIndex(self) -> int:
|
|
return self._port_index
|
|
|
|
def setPortIndex(self, index: int):
|
|
self._port_index = index
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccPortIndex({self._port_index})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccResetOption (helper)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccResetOption(Stub):
|
|
"""EuiccResetOption — eUICC 重置选项"""
|
|
|
|
RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1
|
|
RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2
|
|
RESET_OPTION_RESET_TO_DEFAULT = 3
|
|
RESET_OPTION_DELETE_ALL_PROFILES = 4
|
|
|
|
def __init__(self, option: int = RESET_OPTION_DELETE_OPERATIONAL_PROFILES):
|
|
super().__init__()
|
|
self._option = option
|
|
|
|
def getOption(self) -> int:
|
|
return self._option
|
|
|
|
def setOption(self, option: int):
|
|
self._option = option
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccResetOption({self._option})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccMemorySize (helper)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccMemorySize(Stub):
|
|
"""EuiccMemorySize — eUICC 内存大小"""
|
|
|
|
def __init__(self, free_bytes: int = 0, total_bytes: int = 0):
|
|
super().__init__()
|
|
self._free_bytes = free_bytes
|
|
self._total_bytes = total_bytes
|
|
self._used_bytes = total_bytes - free_bytes
|
|
|
|
def getFreeBytes(self) -> int:
|
|
return self._free_bytes
|
|
|
|
def getTotalBytes(self) -> int:
|
|
return self._total_bytes
|
|
|
|
def getUsedBytes(self) -> int:
|
|
return self._used_bytes
|
|
|
|
def getUsedPercentage(self) -> float:
|
|
if self._total_bytes == 0:
|
|
return 0.0
|
|
return (self._used_bytes / self._total_bytes) * 100.0
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccMemorySize(free={self._free_bytes}, total={self._total_bytes})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# EuiccSmdpAddress (helper)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class EuiccSmdpAddress(Stub):
|
|
"""EuiccSmdpAddress — SMDP 地址辅助类"""
|
|
|
|
def __init__(self, address: str = ""):
|
|
super().__init__()
|
|
self._address = address
|
|
self._is_default: bool = False
|
|
|
|
def getAddress(self) -> str:
|
|
return self._address
|
|
|
|
def setAddress(self, address: str):
|
|
self._address = address
|
|
|
|
def isDefault(self) -> bool:
|
|
return self._is_default
|
|
|
|
def setDefault(self, is_default: bool):
|
|
self._is_default = is_default
|
|
|
|
@staticmethod
|
|
def getDefaultAddress() -> EuiccSmdpAddress:
|
|
return EuiccSmdpAddress("default-smdp.gsma.com")
|
|
|
|
def toString(self) -> str:
|
|
return f"EuiccSmdpAddress({self._address})" |