def enable_device(self, enable=True): if enable: logger.info("main.py: model - Enabling device") # Enable is a potentially long operation self.device.Enable(True, dbus_interface=MDM_INTFACE, timeout=ENABLE_TIMEOUT, reply_handler=self._enable_device_cb, error_handler=self._enable_device_eb) # -1 == special value for Initialising self._get_registration_info_cb((-1, '', '')) else: logger.info("main.py: model - Disabling device") self.status = VMB_MODEM_STATE_DISABLING def disable_cb(): logger.info("main.py: model - Device disabled") self.stop_reginfo_tracking() self.stop_rssi_tracking() def disable_eb(e): logger.warn("main.py: model - Device disable failed\n%s" % get_error_msg(e)) self.device.Enable(False, dbus_interface=MDM_INTFACE, reply_handler=disable_cb, error_handler=disable_eb)
def __init__(self): logger.info("VMB %s starting, using %s core" % ( self.get_app_version(), self.get_core_version())) super(MainModel, self).__init__() self.bus = dbus.SystemBus() self.obj = None self.conf = config # we have to break MVC here :P self.ctrl = None # stats stuff self.is_3g_bearer = True # we assume 3G self.prev_rx_bytes = 0 self.prev_tx_bytes = 0 self.start_time = None self.stop_time = None self.rx_bytes = self.tx_bytes = 0 # DialStats SignalMatch self.stats_sm = None self.rssi_sm = None self.reginfo_sm = None self.dialer_manager = None self.dial_path = None self.device_opath = None self._we_dialed = None self.preferences_model = PreferencesModel(lambda: self.device) self.profiles_model = ProfilesModel(self) self.provider = UsageProvider(USAGE_DB) self._init_wader_object() # Per SIM stuff self.imsi = None self.msisdn = None # PIN in keyring stuff self.manage_pin = False self.keyring_available = self.is_keyring_available()
def pin_is_enabled(self, is_enabled_cb, is_enabled_eb): logger.info("Checking if PIN request is enabled") self.device.Get(CRD_INTFACE, 'PinEnabled', dbus_interface=dbus.PROPERTIES_IFACE, reply_handler=is_enabled_cb, error_handler=is_enabled_eb)
def _get_devices_cb(self, opaths): if len(opaths): if self.device_opath: logger.warn("Device %s is already active" % self.device_opath) return self.device_opath = opaths[0] logger.info("main.py: model - Setting up device %s" % self.device_opath) self.device = self.bus.get_object(WADER_SERVICE, self.device_opath) self.sim_auth_required = VMB_SIM_AUTH_NONE self.sim_error = False self.status = VMB_MODEM_STATE_HAVEDEVICE # Get status of device, NM may have already connected it props = self.device.GetAll(MDM_INTFACE) if props.get('State') is not None: self.status = props.get('State') # react to any modem manager property changes self.device.connect_to_signal("MmPropertiesChanged", self.on_mm_props_change_cb) self.enable_device() else: logger.warn("No devices found") # connecting to signals is safe now self._connect_to_signals()
def _get_devices_cb(self, opaths): if len(opaths): if self.device_opath: logger.warn("Device %s is already active" % self.device_opath) return self.device_opath = opaths[0] logger.info( "main.py: model - Setting up device %s" % self.device_opath) self.device = self.bus.get_object(WADER_SERVICE, self.device_opath) self.sim_auth_required = VMB_SIM_AUTH_NONE self.sim_error = False self.status = VMB_MODEM_STATE_HAVEDEVICE # Get status of device, NM may have already connected it props = self.device.GetAll(MDM_INTFACE) if props.get('State') is not None: self.status = props.get('State') # react to any modem manager property changes self.device.connect_to_signal("MmPropertiesChanged", self.on_mm_props_change_cb) self.enable_device() else: logger.warn("No devices found") # connecting to signals is safe now self._connect_to_signals()
def __init__(self): logger.info("VMB %s starting, using %s core" % (self.get_app_version(), self.get_core_version())) super(MainModel, self).__init__() self.bus = dbus.SystemBus() self.obj = None self.conf = config # we have to break MVC here :P self.ctrl = None # stats stuff self.is_3g_bearer = True # we assume 3G self.prev_rx_bytes = 0 self.prev_tx_bytes = 0 self.start_time = None self.stop_time = None self.rx_bytes = self.tx_bytes = 0 # DialStats SignalMatch self.stats_sm = None self.rssi_sm = None self.reginfo_sm = None self.dialer_manager = None self.dial_path = None self.device_opath = None self._we_dialed = None self.preferences_model = PreferencesModel(lambda: self.device) self.profiles_model = ProfilesModel(self) self.provider = UsageProvider(USAGE_DB) self._init_wader_object() # Per SIM stuff self.imsi = None self.msisdn = None # PIN in keyring stuff self.manage_pin = False self.keyring_available = self.is_keyring_available()
def on_registration_info_cb(self, status, operator_code, operator_name): if self.registration != status: logger.info('Registration changed %d' % status) self.registration = status if self.operator != operator_name: logger.info('Operator changed %s' % str(operator_name)) self.operator = operator_name
def get_credit_cb(response): match = re.search(regex, response) if match: credit = format % match.group('value') cb(credit) else: logger.info("PAYT SIM credit '%s' didn't match USSD regex" % response) cb(None)
def _on_delete_profile(self): # check if the active one still exists # popup dialog if not if self.profiles_model.active_profile_just_deleted(): logger.info("Active Profile removed") self.profile_required = False # toggle to tell controller self.profile_required = True else: logger.info("Profile removed")
def ussd_cb(response): match = re.search(regex, response) if match: # success = match.group('success') logger.info("PAYT SIM submit voucher via USSD success") cb(None) else: logger.info("PAYT SIM submit voucher didn't match USSD regex:" " '%s'" % response) cb(response)
def get_msisdn_cb(response): match = re.search(regex, response) if match: msisdn = match.group('number') self.msisdn = msisdn logger.info("MSISDN from network: %s" % msisdn) self.set_sim_conf('msisdn', self.msisdn) cb(self.msisdn) else: logger.info("MSISDN from network: '%s' didn't match regex" % response) cb(None)
def delete(self): if self.profile: logger.info("Removing profile %s" % self.profile) self.manager.remove_profile(self.profile) self.profile_path = None self.uuid = None self.name = "" while self.sm: sm = self.sm.pop() sm.remove() else: raise RuntimeError(_("Trying to remove an unsaved profile"))
def store_pin_in_keyring(self, pin): # XXX: In the future is would be good enhance this to fetch/store in # different keyring paths according to the following preference: # 1/ ICC-ID identifies the SIM uniquely and is available before # PIN auth, but only the latest datacards support its # retrieval. # 2/ IMEI identifies the datacard uniquely, but if the user swaps # SIM to another device it won't be found, or worse it finds # the PIN associated with another SIM # 3/ Store in application specific location, this is effectively a # single PIN for all SIMs used within VMB if not self.keyring_available: return logger.info("Storing PIN in keyring")
def get_imsi_cb(imsi): if imsi: msisdn = self.conf.get("sim/%s" % imsi, 'msisdn') if msisdn: logger.info("MSISDN from gconf: %s" % msisdn) self.msisdn = msisdn cb(self.msisdn) return ussd = get_msisdn_ussd_info(imsi) if ussd: self._get_msisdn_by_ussd(ussd, cb) else: cb(_("Unknown"))
def submit_cb(error): if not error: logger.info("PAYT SIM submit voucher success") # ok we established his voucher code is good, let's cause the # system to update the UI with his new credit. To do that we # need to fire off another request self.get_current_sim_credit() self.model.payt_submit_busy = False self.view.clear_voucher_entry_view() else: logger.error("PAYT SIM submit voucher failed") self.model.payt_submit_busy = False show_warning_dialog(_("PAYT submit voucher"), _("PAYT submit voucher failed\n\'%s\'") % error)
def store_pin_in_keyring(self, pin): # XXX: In the future is would be good enhance this to fetch/store in # different keyring paths according to the following preference: # 1/ ICC-ID identifies the SIM uniquely and is available before # PIN auth, but only the latest datacards support its # retrieval. # 2/ IMEI identifies the datacard uniquely, but if the user swaps # SIM to another device it won't be found, or worse it finds # the PIN associated with another SIM # 3/ Store in application specific location, this is effectively a # single PIN for all SIMs used within GUI if not self.keyring_available: return logger.info("Storing PIN in keyring")
def send_puk(self, puk, pin, cb=None): def _send_puk_cb(*args): if cb is not None: cb() def _send_puk_eb(e): logger.error("SendPuk failed: %s" % get_error_msg(e)) self._check_pin_status() logger.info("Trying authentication with PUK %s, PIN %s" % (puk, pin)) self.device.SendPuk(puk, pin, dbus_interface=CRD_INTFACE, reply_handler=_send_puk_cb, error_handler=_send_puk_eb)
def submit_cb(error): if not error: logger.info("PAYT SIM submit voucher success") # ok we established his voucher code is good, let's cause the # system to update the UI with his new credit. To do that we # need to fire off another request self.get_current_sim_credit() self.model.payt_submit_busy = False self.view.clear_voucher_entry_view() else: logger.error("PAYT SIM submit voucher failed") self.model.payt_submit_busy = False show_warning_dialog( _("PAYT submit voucher"), _("PAYT submit voucher failed\n\'%s\'") % error)
def change_pin(self, oldpin, newpin, change_pin_cb, eb): logger.info("Change PIN request") def change_pin_eb(e): logger.error("ChangePin failed %s" % get_error_msg(e)) eb() if 'SimPukRequired' in get_error_msg(e): self.sim_auth_required = GUI_SIM_AUTH_PUK if 'SimPuk2Required' in get_error_msg(e): self.sim_auth_required = GUI_SIM_AUTH_PUK2 self.device.ChangePin(oldpin, newpin, dbus_interface=CRD_INTFACE, reply_handler=change_pin_cb, error_handler=change_pin_eb)
def change_pin(self, oldpin, newpin, change_pin_cb, eb): logger.info("Change PIN request") def change_pin_eb(e): logger.error("ChangePin failed %s" % get_error_msg(e)) eb() if 'SimPukRequired' in get_error_msg(e): self.sim_auth_required = VMB_SIM_AUTH_PUK if 'SimPuk2Required' in get_error_msg(e): self.sim_auth_required = VMB_SIM_AUTH_PUK2 self.device.ChangePin(oldpin, newpin, dbus_interface=CRD_INTFACE, reply_handler=change_pin_cb, error_handler=change_pin_eb)
def smsc_cb(smsc): logger.info("SMSC: %s" % smsc) status_request = _get_sms_confirmation() msgvp = _get_sms_validity_period() numbers = self.get_numbers_list() for number in numbers: msg = Message(number, text, _datetime=datetime.now(self.tz)) self.model.device.Send(dict(number=number, text=text, status_request=status_request, smsc=smsc, msgvp=msgvp), dbus_interface=SMS_INTFACE, reply_handler=lambda ref: on_sms_sent_cb(msg, ref), error_handler=on_sms_sent_eb) self.state = IDLE
def enable_pin(self, enable, pin, enable_pin_cb, eb): s = "Enabling" if enable else "Disabling" logger.info("%s PIN request" % s) def enable_pin_eb(e): logger.error("EnablePin failed %s" % get_error_msg(e)) eb(enable) if 'SimPukRequired' in get_error_msg(e): self.sim_auth_required = GUI_SIM_AUTH_PUK if 'SimPuk2Required' in get_error_msg(e): self.sim_auth_required = GUI_SIM_AUTH_PUK2 self.device.EnablePin(pin, enable, dbus_interface=CRD_INTFACE, reply_handler=enable_pin_cb, error_handler=enable_pin_eb)
def enable_pin(self, enable, pin, enable_pin_cb, eb): s = "Enabling" if enable else "Disabling" logger.info("%s PIN request" % s) def enable_pin_eb(e): logger.error("EnablePin failed %s" % get_error_msg(e)) eb(enable) if 'SimPukRequired' in get_error_msg(e): self.sim_auth_required = VMB_SIM_AUTH_PUK if 'SimPuk2Required' in get_error_msg(e): self.sim_auth_required = VMB_SIM_AUTH_PUK2 self.device.EnablePin(pin, enable, dbus_interface=CRD_INTFACE, reply_handler=enable_pin_cb, error_handler=enable_pin_eb)
def _enable_device_cb(self): logger.info("main.py: model - Device enabled") self.sim_auth_required = VMB_SIM_AUTH_NONE self.init_dial_stats() if self.rssi_sm is None: self.rssi_sm = self.device.connect_to_signal( S.SIG_RSSI, self.on_rssi_changed_cb) if self.reginfo_sm is None: self.reginfo_sm = self.device.connect_to_signal( S.SIG_REG_INFO, self.on_registration_info_cb) self._start_network_registration() # delay the profile creation till the device is completely enabled self.profile_required = False self._get_config()
def get_cached_sim_credit(self): if self.model.get_sim_conf('payt_available'): credit = self.model.get_sim_conf('payt_credit_balance') utc = self.model.get_sim_conf('payt_credit_date') if credit and utc: now = datetime.fromtimestamp(utc, self.tz) logger.info("payt_controller - get_cached_sim_credit: PAYT " "SIM credit from gconf: %s - %s" % (credit, now.strftime("%c"))) self.model.payt_credit_balance = credit self.model.payt_credit_date = now return self.model.payt_credit_balance = _("Not available") self.model.payt_credit_date = None
def _enable_device_cb(self): logger.info("main.py: model - Device enabled") self.sim_auth_required = VMB_SIM_AUTH_NONE self.init_dial_stats() if self.rssi_sm is None: self.rssi_sm = self.device.connect_to_signal(S.SIG_RSSI, self.on_rssi_changed_cb) if self.reginfo_sm is None: self.reginfo_sm = self.device.connect_to_signal(S.SIG_REG_INFO, self.on_registration_info_cb) self._start_network_registration() # delay the profile creation till the device is completely enabled self.profile_required = False self._get_config()
def get_imsi(self, cb): logger.info("main.py: model - get_imsi called") if self.imsi: logger.info("main.py: model - get_imsi imsi is: " + self.imsi) cb(self.imsi) return def get_imsi_cb(imsi): self.imsi = imsi cb(self.imsi) def get_imsi_eb(failure): msg = "Error while getting IMSI for device %s" logger.error(msg % self.device_opath) cb(None) self.device.GetImsi(dbus_interface=CRD_INTFACE, reply_handler=get_imsi_cb, error_handler=get_imsi_eb)
def _device_removed_cb(self, opath): logger.info('Device with opath %s removed' % opath) if self.device_opath: logger.info('Device path: %s' % self.device_opath) if opath == self.device_opath: self.device = None self.device_opath = None self.dial_path = None self.status = VMB_MODEM_STATE_NODEVICE self.operator = '' self.tech = None self.rssi = None self.registration = -1 self.imsi = None self.msisdn = None self.stop_reginfo_tracking() self.stop_rssi_tracking()
def smsc_cb(smsc): logger.info("SMSC: %s" % smsc) status_request = _get_sms_confirmation() msgvp = _get_sms_validity_period() numbers = self.get_numbers_list() for number in numbers: msg = Message(number, text, _datetime=datetime.now(self.tz)) self.model.device.Send( dict(number=number, text=text, status_request=status_request, smsc=smsc, msgvp=msgvp), dbus_interface=SMS_INTFACE, reply_handler=lambda ref: on_sms_sent_cb(msg, ref), error_handler=on_sms_sent_eb) self.state = IDLE
def send_pin(self, pin, cb=None): logger.info("Trying authentication with PIN %s" % pin) def _send_pin_cb(*args): logger.info("Authentication success") if self.manage_pin: self.store_pin_in_keyring(pin) if cb is not None: cb() def _send_pin_eb(e): logger.error("SendPin failed %s" % get_error_msg(e)) if self.manage_pin: self.delete_pin_from_keyring() self._check_pin_status() self.device.SendPin(pin, timeout=AUTH_TIMEOUT, dbus_interface=CRD_INTFACE, reply_handler=_send_pin_cb, error_handler=_send_pin_eb)
def get_smsc(self, cb, eb): """Get SMSC from preferences, networks DB or device, then callback""" # try to get from preferences if self.model.conf.get('preferences', 'use_alternate_smsc', False): alternate_smsc = self.model.conf.get('preferences', 'smsc_number', None) else: alternate_smsc = None # try to get from networks DB if self.model.imsi: provider = NetworkProvider() attrs = provider.get_network_by_id(self.model.imsi) if attrs: provider_smsc = attrs[0].smsc else: provider_smsc = None provider.close() else: provider_smsc = None # use the one from the best source if alternate_smsc is not None: logger.info("SMSC used from preferences") cb(alternate_smsc) elif provider_smsc is not None: logger.info("SMSC used from networks DB") cb(provider_smsc) else: logger.info("SMSC used from SIM") self.model.device.GetSmsc(dbus_interface=SMS_INTFACE, reply_handler=cb, error_handler=eb)
def on_mm_props_change_cb(self, ifname, ifprops): if ifname == NET_INTFACE and 'AccessTechnology' in ifprops: tech = ifprops['AccessTechnology'] if self.tech != tech: logger.info("AccessTechnology changed %s", tech) self.tech = tech is_3g_bearer = self.tech not in TWOG_TECH # maybe write a Usage DB segment if self.is_connected(): self.write_dial_stats(is_3g_bearer) self.is_3g_bearer = is_3g_bearer if ifname == MDM_INTFACE and 'UnlockRequired' in ifprops: if not ifprops['UnlockRequired']: if self.sim_auth_required != GUI_SIM_AUTH_NONE: self.sim_auth_required = GUI_SIM_AUTH_NONE self.enable_device() if ifname == MDM_INTFACE and 'State' in ifprops: # XXX: With any MM implementation when using the PPP IP_METHOD, # the Connected state change comes at dial time which is too # early to properly represent success. If we initiated the # connection ourselves we can wait for the callback from # Wader's dialer instead. def lazy_update(state): self.status = state return False if ifprops['State'] == GUI_MODEM_STATE_CONNECTED: if self.is_our_dial_attempt(): pass # let our controller's Connect callback set it else: # NM applet probably made it, delay timeout_add_seconds(2, lazy_update, ifprops['State']) else: self.status = ifprops['State']
def on_mm_props_change_cb(self, ifname, ifprops): if ifname == NET_INTFACE and 'AccessTechnology' in ifprops: tech = ifprops['AccessTechnology'] if self.tech != tech: logger.info("AccessTechnology changed %s", tech) self.tech = tech is_3g_bearer = self.tech not in TWOG_TECH # maybe write a Usage DB segment if self.is_connected(): self.write_dial_stats(is_3g_bearer) self.is_3g_bearer = is_3g_bearer if ifname == MDM_INTFACE and 'UnlockRequired' in ifprops: if not ifprops['UnlockRequired']: if self.sim_auth_required != VMB_SIM_AUTH_NONE: self.sim_auth_required = VMB_SIM_AUTH_NONE self.enable_device() if ifname == MDM_INTFACE and 'State' in ifprops: # XXX: With any MM implementation when using the PPP IP_METHOD, # the Connected state change comes at dial time which is too # early to properly represent success. If we initiated the # connection ourselves we can wait for the callback from # Wader's dialer instead. def lazy_update(state): self.status = state return False if ifprops['State'] == VMB_MODEM_STATE_CONNECTED: if self.is_our_dial_attempt(): pass # let our controller's Connect callback set it else: # NM applet probably made it, delay timeout_add_seconds(2, lazy_update, ifprops['State']) else: self.status = ifprops['State']
def credit_cb(credit): if credit: utc = time() now = datetime.fromtimestamp(utc, self.tz) logger.info("PAYT SIM credit: %s on %s" % (credit, now.strftime("%c"))) self.model.payt_credit_balance = credit self.model.set_sim_conf('payt_credit_balance', credit) self.model.payt_credit_date = now self.model.set_sim_conf('payt_credit_date', utc) else: self.model.payt_credit_balance = _("Not available") self.model.payt_credit_date = None # Record SIM as PAYT or not if not isinstance(payt_available, bool): self.model.payt_available = (credit is not None) self.model.set_sim_conf('payt_available', self.model.payt_available) self.model.payt_credit_busy = False
def mdm_info(datacard_info): # ok we don't have a model the data is coming straight from # our core via dbus manufacturer = datacard_info[0] model = datacard_info[1] firmware = datacard_info[2] logger.info("diagnostics mdm_info - manufacturer: " + manufacturer) logger.info("diagnostics mdm_info - model: " + model) logger.info("diagnostics mdm_info - firmware: " + firmware) self.view.set_datacard_info(manufacturer, model, firmware)
def sim_imsi(imsi): logger.info("diagnostics sim_imsi - IMSI number is: " + str(imsi)) self.view.set_imsi_info(imsi) # let's look up what we think this SIM's network is. # so we want to display the country and network operator provider = NetworkProvider() networks_attributes = provider.get_network_by_id(imsi) if networks_attributes: net_attrib = networks_attributes[0] logger.info("diagnostics sim_imsi - country: " + str(net_attrib.country)) logger.info("diagnostics sim_imsi - network operator: " + str(net_attrib.name)) self.view.set_network_info(network=net_attrib.name, country=net_attrib.country) provider.close()
def sim_imei(imei): # ok we don't have a model the data is coming from dbus # from wader core lets tell the view to set the imsi value # in the correct place logger.info("diagnostics: controller - sim_imei - IMEI number is: " + str(imei)) self.view.set_imei_info(imei)
def delete_pin_from_keyring(self): if not self.keyring_available: return logger.info("Deleting PIN from keyring")
def _send_pin_cb(*args): logger.info("Authentication success") if self.manage_pin: self.store_pin_in_keyring(pin) if cb is not None: cb()
def on_rssi_changed_cb(self, rssi): if self.rssi != rssi: logger.info("RSSI changed %d" % rssi) self.rssi = rssi