1*9c5db199SXin Li# Lint as: python2, python3 2*9c5db199SXin Li# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 4*9c5db199SXin Li# found in the LICENSE file. 5*9c5db199SXin Li 6*9c5db199SXin Lifrom __future__ import absolute_import 7*9c5db199SXin Lifrom __future__ import division 8*9c5db199SXin Lifrom __future__ import print_function 9*9c5db199SXin Li 10*9c5db199SXin Liimport dbus 11*9c5db199SXin Liimport dbus.service 12*9c5db199SXin Liimport logging 13*9c5db199SXin Li 14*9c5db199SXin Liimport six 15*9c5db199SXin Li 16*9c5db199SXin Lifrom autotest_lib.client.cros.cellular import mm1_constants 17*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import dbus_std_ifaces 18*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import pm_constants 19*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import pm_errors 20*9c5db199SXin Lifrom autotest_lib.client.cros.cellular.pseudomodem import utils 21*9c5db199SXin Li 22*9c5db199SXin Liclass IncorrectPasswordError(pm_errors.MMMobileEquipmentError): 23*9c5db199SXin Li """ Wrapper around MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD. """ 24*9c5db199SXin Li 25*9c5db199SXin Li def __init__(self): 26*9c5db199SXin Li pm_errors.MMMobileEquipmentError.__init__( 27*9c5db199SXin Li self, pm_errors.MMMobileEquipmentError.INCORRECT_PASSWORD, 28*9c5db199SXin Li 'Incorrect password') 29*9c5db199SXin Li 30*9c5db199SXin Liclass SimPukError(pm_errors.MMMobileEquipmentError): 31*9c5db199SXin Li """ Wrapper around MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK. """ 32*9c5db199SXin Li 33*9c5db199SXin Li def __init__(self): 34*9c5db199SXin Li pm_errors.MMMobileEquipmentError.__init__( 35*9c5db199SXin Li self, pm_errors.MMMobileEquipmentError.SIM_PUK, 36*9c5db199SXin Li 'SIM PUK required') 37*9c5db199SXin Li 38*9c5db199SXin Liclass SimFailureError(pm_errors.MMMobileEquipmentError): 39*9c5db199SXin Li """ Wrapper around MM_MOBILE_EQUIPMENT_ERROR_SIM_FAILURE. """ 40*9c5db199SXin Li 41*9c5db199SXin Li def __init__(self): 42*9c5db199SXin Li pm_errors.MMMobileEquipmentError.__init__( 43*9c5db199SXin Li self, pm_errors.MMMobileEquipmentError.SIM_FAILURE, 44*9c5db199SXin Li 'SIM failure') 45*9c5db199SXin Li 46*9c5db199SXin Liclass SIM(dbus_std_ifaces.DBusProperties): 47*9c5db199SXin Li """ 48*9c5db199SXin Li Pseudomodem implementation of the org.freedesktop.ModemManager1.Sim 49*9c5db199SXin Li interface. 50*9c5db199SXin Li 51*9c5db199SXin Li Broadband modems usually need a SIM card to operate. Each Modem object will 52*9c5db199SXin Li therefore expose up to one SIM object, which allows SIM-specific actions 53*9c5db199SXin Li such as PIN unlocking. 54*9c5db199SXin Li 55*9c5db199SXin Li The SIM interface handles communication with SIM, USIM, and RUIM (CDMA SIM) 56*9c5db199SXin Li cards. 57*9c5db199SXin Li 58*9c5db199SXin Li """ 59*9c5db199SXin Li 60*9c5db199SXin Li # Multiple object paths needs to be supported so that the SIM can be 61*9c5db199SXin Li # "reset". This allows the object to reappear on a new path as if it has 62*9c5db199SXin Li # been reset. 63*9c5db199SXin Li SUPPORTS_MULTIPLE_OBJECT_PATHS = True 64*9c5db199SXin Li 65*9c5db199SXin Li DEFAULT_MSIN = '1234567890' 66*9c5db199SXin Li DEFAULT_IMSI = '888999111' 67*9c5db199SXin Li DEFAULT_PIN = '1111' 68*9c5db199SXin Li DEFAULT_PUK = '12345678' 69*9c5db199SXin Li DEFAULT_PIN_RETRIES = 3 70*9c5db199SXin Li DEFAULT_PUK_RETRIES = 10 71*9c5db199SXin Li 72*9c5db199SXin Li class Carrier: 73*9c5db199SXin Li """ 74*9c5db199SXin Li Represents a 3GPP carrier that can be stored by a SIM object. 75*9c5db199SXin Li 76*9c5db199SXin Li """ 77*9c5db199SXin Li MCC_LIST = { 78*9c5db199SXin Li 'test' : '001', 79*9c5db199SXin Li 'us': '310', 80*9c5db199SXin Li 'de': '262', 81*9c5db199SXin Li 'es': '214', 82*9c5db199SXin Li 'fr': '208', 83*9c5db199SXin Li 'gb': '234', 84*9c5db199SXin Li 'it': '222', 85*9c5db199SXin Li 'nl': '204' 86*9c5db199SXin Li } 87*9c5db199SXin Li 88*9c5db199SXin Li CARRIER_LIST = { 89*9c5db199SXin Li 'test' : ('test', '000', pm_constants.DEFAULT_TEST_NETWORK_PREFIX), 90*9c5db199SXin Li 'banana' : ('us', '001', 'Banana-Comm'), 91*9c5db199SXin Li 'att': ('us', '090', 'AT&T'), 92*9c5db199SXin Li 'tmobile': ('us', '026', 'T-Mobile'), 93*9c5db199SXin Li 'simyo': ('de', '03', 'simyo'), 94*9c5db199SXin Li 'movistar': ('es', '07', 'Movistar'), 95*9c5db199SXin Li 'sfr': ('fr', '10', 'SFR'), 96*9c5db199SXin Li 'three': ('gb', '20', '3'), 97*9c5db199SXin Li 'threeita': ('it', '99', '3ITA'), 98*9c5db199SXin Li 'kpn': ('nl', '08', 'KPN') 99*9c5db199SXin Li } 100*9c5db199SXin Li 101*9c5db199SXin Li def __init__(self, carrier='test'): 102*9c5db199SXin Li carrier = self.CARRIER_LIST.get(carrier, self.CARRIER_LIST['test']) 103*9c5db199SXin Li 104*9c5db199SXin Li self.mcc = self.MCC_LIST[carrier[0]] 105*9c5db199SXin Li self.mnc = carrier[1] 106*9c5db199SXin Li self.operator_name = carrier[2] 107*9c5db199SXin Li if self.operator_name != 'Banana-Comm': 108*9c5db199SXin Li self.operator_name = self.operator_name + ' - Fake' 109*9c5db199SXin Li self.operator_id = self.mcc + self.mnc 110*9c5db199SXin Li 111*9c5db199SXin Li 112*9c5db199SXin Li def __init__(self, 113*9c5db199SXin Li carrier, 114*9c5db199SXin Li access_technology, 115*9c5db199SXin Li index=0, 116*9c5db199SXin Li pin=DEFAULT_PIN, 117*9c5db199SXin Li puk=DEFAULT_PUK, 118*9c5db199SXin Li pin_retries=DEFAULT_PIN_RETRIES, 119*9c5db199SXin Li puk_retries=DEFAULT_PUK_RETRIES, 120*9c5db199SXin Li locked=False, 121*9c5db199SXin Li msin=DEFAULT_MSIN, 122*9c5db199SXin Li imsi=DEFAULT_IMSI, 123*9c5db199SXin Li config=None): 124*9c5db199SXin Li if not carrier: 125*9c5db199SXin Li raise TypeError('A carrier is required.') 126*9c5db199SXin Li path = mm1_constants.MM1 + '/SIM/' + str(index) 127*9c5db199SXin Li self.msin = msin 128*9c5db199SXin Li self._carrier = carrier 129*9c5db199SXin Li self.imsi = carrier.operator_id + imsi 130*9c5db199SXin Li self._index = 0 131*9c5db199SXin Li self._total_pin_retries = pin_retries 132*9c5db199SXin Li self._total_puk_retries = puk_retries 133*9c5db199SXin Li self._lock_data = { 134*9c5db199SXin Li mm1_constants.MM_MODEM_LOCK_SIM_PIN : { 135*9c5db199SXin Li 'code' : pin, 136*9c5db199SXin Li 'retries' : pin_retries 137*9c5db199SXin Li }, 138*9c5db199SXin Li mm1_constants.MM_MODEM_LOCK_SIM_PUK : { 139*9c5db199SXin Li 'code' : puk, 140*9c5db199SXin Li 'retries' : puk_retries 141*9c5db199SXin Li } 142*9c5db199SXin Li } 143*9c5db199SXin Li self._lock_enabled = locked 144*9c5db199SXin Li self._show_retries = locked 145*9c5db199SXin Li if locked: 146*9c5db199SXin Li self._lock_type = mm1_constants.MM_MODEM_LOCK_SIM_PIN 147*9c5db199SXin Li else: 148*9c5db199SXin Li self._lock_type = mm1_constants.MM_MODEM_LOCK_NONE 149*9c5db199SXin Li self._modem = None 150*9c5db199SXin Li self.access_technology = access_technology 151*9c5db199SXin Li dbus_std_ifaces.DBusProperties.__init__(self, path, None, config) 152*9c5db199SXin Li 153*9c5db199SXin Li 154*9c5db199SXin Li def IncrementPath(self): 155*9c5db199SXin Li """ 156*9c5db199SXin Li Increments the current index at which this modem is exposed on DBus. 157*9c5db199SXin Li E.g. if the current path is org/freedesktop/ModemManager/Modem/0, the 158*9c5db199SXin Li path will change to org/freedesktop/ModemManager/Modem/1. 159*9c5db199SXin Li 160*9c5db199SXin Li Calling this method does not remove the object from its current path, 161*9c5db199SXin Li which means that it will be available via both the old and the new 162*9c5db199SXin Li paths. This is currently only used by Reset, in conjunction with 163*9c5db199SXin Li dbus_std_ifaces.DBusObjectManager.[Add|Remove]. 164*9c5db199SXin Li 165*9c5db199SXin Li """ 166*9c5db199SXin Li self._index += 1 167*9c5db199SXin Li path = mm1_constants.MM1 + '/SIM/' + str(self._index) 168*9c5db199SXin Li logging.info('SIM coming back as: ' + path) 169*9c5db199SXin Li self.SetPath(path) 170*9c5db199SXin Li 171*9c5db199SXin Li 172*9c5db199SXin Li def Reset(self): 173*9c5db199SXin Li """ Resets the SIM. This will lock the SIM if locks are enabled. """ 174*9c5db199SXin Li self.IncrementPath() 175*9c5db199SXin Li if not self.locked and self._lock_enabled: 176*9c5db199SXin Li self._lock_type = mm1_constants.MM_MODEM_LOCK_SIM_PIN 177*9c5db199SXin Li 178*9c5db199SXin Li 179*9c5db199SXin Li @property 180*9c5db199SXin Li def lock_type(self): 181*9c5db199SXin Li """ 182*9c5db199SXin Li Returns the current lock type of the SIM. Can be used to determine 183*9c5db199SXin Li whether or not the SIM is locked. 184*9c5db199SXin Li 185*9c5db199SXin Li @returns: The lock type, as a MMModemLock value. 186*9c5db199SXin Li 187*9c5db199SXin Li """ 188*9c5db199SXin Li return self._lock_type 189*9c5db199SXin Li 190*9c5db199SXin Li 191*9c5db199SXin Li @property 192*9c5db199SXin Li def unlock_retries(self): 193*9c5db199SXin Li """ 194*9c5db199SXin Li Returns the number of unlock retries left. 195*9c5db199SXin Li 196*9c5db199SXin Li @returns: The number of unlock retries for each lock type the SIM 197*9c5db199SXin Li supports as a dictionary. 198*9c5db199SXin Li 199*9c5db199SXin Li """ 200*9c5db199SXin Li retries = dbus.Dictionary(signature='uu') 201*9c5db199SXin Li if not self._show_retries: 202*9c5db199SXin Li return retries 203*9c5db199SXin Li for k, v in six.iteritems(self._lock_data): 204*9c5db199SXin Li retries[dbus.types.UInt32(k)] = dbus.types.UInt32(v['retries']) 205*9c5db199SXin Li return retries 206*9c5db199SXin Li 207*9c5db199SXin Li 208*9c5db199SXin Li @property 209*9c5db199SXin Li def enabled_locks(self): 210*9c5db199SXin Li """ 211*9c5db199SXin Li Returns the currently enabled facility locks. 212*9c5db199SXin Li 213*9c5db199SXin Li @returns: The currently enabled facility locks, as a MMModem3gppFacility 214*9c5db199SXin Li value. 215*9c5db199SXin Li 216*9c5db199SXin Li """ 217*9c5db199SXin Li if self._lock_enabled: 218*9c5db199SXin Li return mm1_constants.MM_MODEM_3GPP_FACILITY_SIM 219*9c5db199SXin Li return mm1_constants.MM_MODEM_3GPP_FACILITY_NONE 220*9c5db199SXin Li 221*9c5db199SXin Li 222*9c5db199SXin Li @property 223*9c5db199SXin Li def locked(self): 224*9c5db199SXin Li """ @returns: True, if the SIM is locked. False, otherwise. """ 225*9c5db199SXin Li return not (self._lock_type == mm1_constants.MM_MODEM_LOCK_NONE or 226*9c5db199SXin Li self._lock_type == mm1_constants.MM_MODEM_LOCK_UNKNOWN) 227*9c5db199SXin Li 228*9c5db199SXin Li 229*9c5db199SXin Li @property 230*9c5db199SXin Li def modem(self): 231*9c5db199SXin Li """ 232*9c5db199SXin Li @returns: the modem object that this SIM is currently plugged into. 233*9c5db199SXin Li 234*9c5db199SXin Li """ 235*9c5db199SXin Li return self._modem 236*9c5db199SXin Li 237*9c5db199SXin Li 238*9c5db199SXin Li @modem.setter 239*9c5db199SXin Li def modem(self, modem): 240*9c5db199SXin Li """ 241*9c5db199SXin Li Assigns a modem object to this SIM, so that the modem knows about it. 242*9c5db199SXin Li This should only be called directly by a modem object. 243*9c5db199SXin Li 244*9c5db199SXin Li @param modem: The modem to be associated with this SIM. 245*9c5db199SXin Li 246*9c5db199SXin Li """ 247*9c5db199SXin Li self._modem = modem 248*9c5db199SXin Li 249*9c5db199SXin Li 250*9c5db199SXin Li @property 251*9c5db199SXin Li def carrier(self): 252*9c5db199SXin Li """ 253*9c5db199SXin Li @returns: An instance of SIM.Carrier that contains the carrier 254*9c5db199SXin Li information assigned to this SIM. 255*9c5db199SXin Li 256*9c5db199SXin Li """ 257*9c5db199SXin Li return self._carrier 258*9c5db199SXin Li 259*9c5db199SXin Li 260*9c5db199SXin Li def _DBusPropertiesDict(self): 261*9c5db199SXin Li imsi = self.imsi 262*9c5db199SXin Li if self.locked: 263*9c5db199SXin Li msin = '' 264*9c5db199SXin Li op_id = '' 265*9c5db199SXin Li op_name = '' 266*9c5db199SXin Li else: 267*9c5db199SXin Li msin = self.msin 268*9c5db199SXin Li op_id = self._carrier.operator_id 269*9c5db199SXin Li op_name = self._carrier.operator_name 270*9c5db199SXin Li return { 271*9c5db199SXin Li 'SimIdentifier' : msin, 272*9c5db199SXin Li 'Imsi' : imsi, 273*9c5db199SXin Li 'OperatorIdentifier' : op_id, 274*9c5db199SXin Li 'OperatorName' : op_name 275*9c5db199SXin Li } 276*9c5db199SXin Li 277*9c5db199SXin Li 278*9c5db199SXin Li def _InitializeProperties(self): 279*9c5db199SXin Li return { mm1_constants.I_SIM : self._DBusPropertiesDict() } 280*9c5db199SXin Li 281*9c5db199SXin Li 282*9c5db199SXin Li def _UpdateProperties(self): 283*9c5db199SXin Li self.SetAll(mm1_constants.I_SIM, self._DBusPropertiesDict()) 284*9c5db199SXin Li 285*9c5db199SXin Li 286*9c5db199SXin Li def _CheckCode(self, code, lock_data, next_lock, error_to_raise): 287*9c5db199SXin Li # Checks |code| against |lock_data['code']|. If the codes don't match: 288*9c5db199SXin Li # 289*9c5db199SXin Li # - if the number of retries left for |lock_data| drops down to 0, 290*9c5db199SXin Li # the current lock type gets set to |next_lock| and 291*9c5db199SXin Li # |error_to_raise| is raised. 292*9c5db199SXin Li # 293*9c5db199SXin Li # - otherwise, IncorrectPasswordError is raised. 294*9c5db199SXin Li # 295*9c5db199SXin Li # If the codes match, no error is raised. 296*9c5db199SXin Li 297*9c5db199SXin Li if code == lock_data['code']: 298*9c5db199SXin Li # Codes match, nothing to do. 299*9c5db199SXin Li return 300*9c5db199SXin Li 301*9c5db199SXin Li # Codes didn't match. Figure out which error to raise based on 302*9c5db199SXin Li # remaining retries. 303*9c5db199SXin Li lock_data['retries'] -= 1 304*9c5db199SXin Li self._show_retries = True 305*9c5db199SXin Li if lock_data['retries'] == 0: 306*9c5db199SXin Li logging.info('Retries exceeded the allowed number.') 307*9c5db199SXin Li if next_lock: 308*9c5db199SXin Li self._lock_type = next_lock 309*9c5db199SXin Li self._lock_enabled = True 310*9c5db199SXin Li else: 311*9c5db199SXin Li error_to_raise = IncorrectPasswordError() 312*9c5db199SXin Li self._modem.UpdateLockStatus() 313*9c5db199SXin Li raise error_to_raise 314*9c5db199SXin Li 315*9c5db199SXin Li 316*9c5db199SXin Li def _ResetRetries(self, lock_type): 317*9c5db199SXin Li if lock_type == mm1_constants.MM_MODEM_LOCK_SIM_PIN: 318*9c5db199SXin Li value = self._total_pin_retries 319*9c5db199SXin Li elif lock_type == mm1_constants.MM_MODEM_LOCK_SIM_PUK: 320*9c5db199SXin Li value = self._total_puk_retries 321*9c5db199SXin Li else: 322*9c5db199SXin Li raise TypeError('Invalid SIM lock type') 323*9c5db199SXin Li self._lock_data[lock_type]['retries'] = value 324*9c5db199SXin Li 325*9c5db199SXin Li 326*9c5db199SXin Li @utils.log_dbus_method() 327*9c5db199SXin Li @dbus.service.method(mm1_constants.I_SIM, in_signature='s') 328*9c5db199SXin Li def SendPin(self, pin): 329*9c5db199SXin Li """ 330*9c5db199SXin Li Sends the PIN to unlock the SIM card. 331*9c5db199SXin Li 332*9c5db199SXin Li @param pin: A string containing the PIN code. 333*9c5db199SXin Li 334*9c5db199SXin Li """ 335*9c5db199SXin Li if not self.locked: 336*9c5db199SXin Li logging.info('SIM is not locked. Nothing to do.') 337*9c5db199SXin Li return 338*9c5db199SXin Li 339*9c5db199SXin Li if self._lock_type == mm1_constants.MM_MODEM_LOCK_SIM_PUK: 340*9c5db199SXin Li if self._lock_data[self._lock_type]['retries'] == 0: 341*9c5db199SXin Li raise SimFailureError() 342*9c5db199SXin Li else: 343*9c5db199SXin Li raise SimPukError() 344*9c5db199SXin Li 345*9c5db199SXin Li lock_data = self._lock_data.get(self._lock_type, None) 346*9c5db199SXin Li if not lock_data: 347*9c5db199SXin Li raise pm_errors.MMCoreError( 348*9c5db199SXin Li pm_errors.MMCoreError.FAILED, 349*9c5db199SXin Li 'Current lock type does not match the SIM lock capabilities.') 350*9c5db199SXin Li 351*9c5db199SXin Li self._CheckCode(pin, lock_data, mm1_constants.MM_MODEM_LOCK_SIM_PUK, 352*9c5db199SXin Li SimPukError()) 353*9c5db199SXin Li 354*9c5db199SXin Li logging.info('Entered correct PIN.') 355*9c5db199SXin Li self._ResetRetries(mm1_constants.MM_MODEM_LOCK_SIM_PIN) 356*9c5db199SXin Li self._lock_type = mm1_constants.MM_MODEM_LOCK_NONE 357*9c5db199SXin Li self._modem.UpdateLockStatus() 358*9c5db199SXin Li self._modem.Expose3GPPProperties() 359*9c5db199SXin Li self._UpdateProperties() 360*9c5db199SXin Li 361*9c5db199SXin Li 362*9c5db199SXin Li @utils.log_dbus_method() 363*9c5db199SXin Li @dbus.service.method(mm1_constants.I_SIM, in_signature='ss') 364*9c5db199SXin Li def SendPuk(self, puk, pin): 365*9c5db199SXin Li """ 366*9c5db199SXin Li Sends the PUK and a new PIN to unlock the SIM card. 367*9c5db199SXin Li 368*9c5db199SXin Li @param puk: A string containing the PUK code. 369*9c5db199SXin Li @param pin: A string containing the PIN code. 370*9c5db199SXin Li 371*9c5db199SXin Li """ 372*9c5db199SXin Li if self._lock_type != mm1_constants.MM_MODEM_LOCK_SIM_PUK: 373*9c5db199SXin Li logging.info('No PUK lock in place. Nothing to do.') 374*9c5db199SXin Li return 375*9c5db199SXin Li 376*9c5db199SXin Li lock_data = self._lock_data.get(self._lock_type, None) 377*9c5db199SXin Li if not lock_data: 378*9c5db199SXin Li raise pm_errors.MMCoreError( 379*9c5db199SXin Li pm_errors.MMCoreError.FAILED, 380*9c5db199SXin Li 'Current lock type does not match the SIM locks in place.') 381*9c5db199SXin Li 382*9c5db199SXin Li if lock_data['retries'] == 0: 383*9c5db199SXin Li raise SimFailureError() 384*9c5db199SXin Li 385*9c5db199SXin Li self._CheckCode(puk, lock_data, None, SimFailureError()) 386*9c5db199SXin Li 387*9c5db199SXin Li logging.info('Entered correct PUK.') 388*9c5db199SXin Li self._ResetRetries(mm1_constants.MM_MODEM_LOCK_SIM_PIN) 389*9c5db199SXin Li self._ResetRetries(mm1_constants.MM_MODEM_LOCK_SIM_PUK) 390*9c5db199SXin Li self._lock_data[mm1_constants.MM_MODEM_LOCK_SIM_PIN]['code'] = pin 391*9c5db199SXin Li self._lock_type = mm1_constants.MM_MODEM_LOCK_NONE 392*9c5db199SXin Li self._modem.UpdateLockStatus() 393*9c5db199SXin Li self._modem.Expose3GPPProperties() 394*9c5db199SXin Li self._UpdateProperties() 395*9c5db199SXin Li 396*9c5db199SXin Li 397*9c5db199SXin Li @utils.log_dbus_method() 398*9c5db199SXin Li @dbus.service.method(mm1_constants.I_SIM, in_signature='sb') 399*9c5db199SXin Li def EnablePin(self, pin, enabled): 400*9c5db199SXin Li """ 401*9c5db199SXin Li Enables or disables PIN checking. 402*9c5db199SXin Li 403*9c5db199SXin Li @param pin: A string containing the PIN code. 404*9c5db199SXin Li @param enabled: True to enable PIN, False otherwise. 405*9c5db199SXin Li 406*9c5db199SXin Li """ 407*9c5db199SXin Li if enabled: 408*9c5db199SXin Li self._EnablePin(pin) 409*9c5db199SXin Li else: 410*9c5db199SXin Li self._DisablePin(pin) 411*9c5db199SXin Li 412*9c5db199SXin Li 413*9c5db199SXin Li def _EnablePin(self, pin): 414*9c5db199SXin Li # Operation fails if the SIM is locked or PIN lock is already 415*9c5db199SXin Li # enabled. 416*9c5db199SXin Li if self.locked or self._lock_enabled: 417*9c5db199SXin Li raise SimFailureError() 418*9c5db199SXin Li 419*9c5db199SXin Li lock_data = self._lock_data[mm1_constants.MM_MODEM_LOCK_SIM_PIN] 420*9c5db199SXin Li self._CheckCode(pin, lock_data, mm1_constants.MM_MODEM_LOCK_SIM_PUK, 421*9c5db199SXin Li SimPukError()) 422*9c5db199SXin Li self._lock_enabled = True 423*9c5db199SXin Li self._show_retries = True 424*9c5db199SXin Li self._ResetRetries(mm1_constants.MM_MODEM_LOCK_SIM_PIN) 425*9c5db199SXin Li self._UpdateProperties() 426*9c5db199SXin Li self.modem.UpdateLockStatus() 427*9c5db199SXin Li 428*9c5db199SXin Li 429*9c5db199SXin Li def _DisablePin(self, pin): 430*9c5db199SXin Li if not self._lock_enabled: 431*9c5db199SXin Li raise SimFailureError() 432*9c5db199SXin Li 433*9c5db199SXin Li if self.locked: 434*9c5db199SXin Li self.SendPin(pin) 435*9c5db199SXin Li else: 436*9c5db199SXin Li lock_data = self._lock_data[mm1_constants.MM_MODEM_LOCK_SIM_PIN] 437*9c5db199SXin Li self._CheckCode(pin, lock_data, 438*9c5db199SXin Li mm1_constants.MM_MODEM_LOCK_SIM_PUK, SimPukError()) 439*9c5db199SXin Li self._ResetRetries(mm1_constants.MM_MODEM_LOCK_SIM_PIN) 440*9c5db199SXin Li self._lock_enabled = False 441*9c5db199SXin Li self._UpdateProperties() 442*9c5db199SXin Li self.modem.UpdateLockStatus() 443*9c5db199SXin Li 444*9c5db199SXin Li 445*9c5db199SXin Li @utils.log_dbus_method() 446*9c5db199SXin Li @dbus.service.method(mm1_constants.I_SIM, in_signature='ss') 447*9c5db199SXin Li def ChangePin(self, old_pin, new_pin): 448*9c5db199SXin Li """ 449*9c5db199SXin Li Changes the PIN code. 450*9c5db199SXin Li 451*9c5db199SXin Li @param old_pin: A string containing the old PIN code. 452*9c5db199SXin Li @param new_pin: A string containing the new PIN code. 453*9c5db199SXin Li 454*9c5db199SXin Li """ 455*9c5db199SXin Li if not self._lock_enabled or self.locked: 456*9c5db199SXin Li raise SimFailureError() 457*9c5db199SXin Li 458*9c5db199SXin Li lock_data = self._lock_data[mm1_constants.MM_MODEM_LOCK_SIM_PIN] 459*9c5db199SXin Li self._CheckCode(old_pin, lock_data, 460*9c5db199SXin Li mm1_constants.MM_MODEM_LOCK_SIM_PUK, SimPukError()) 461*9c5db199SXin Li self._ResetRetries(mm1_constants.MM_MODEM_LOCK_SIM_PIN) 462*9c5db199SXin Li self._lock_data[mm1_constants.MM_MODEM_LOCK_SIM_PIN]['code'] = new_pin 463*9c5db199SXin Li self._UpdateProperties() 464*9c5db199SXin Li self.modem.UpdateLockStatus() 465