[PATCH] osmo-gsm-tester[master]: ofono_client: Discover modem path from imsi

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Pau Espin Pedrol gerrit-no-reply at lists.osmocom.org
Mon May 22 14:49:13 UTC 2017


Review at  https://gerrit.osmocom.org/2696

ofono_client: Discover modem path from imsi

Change-Id: I602604d25f51b24d87877bc8ac798525b7be61dd
---
M example/resources.conf
M src/osmo_gsm_tester/ofono_client.py
M src/osmo_gsm_tester/resource.py
M src/osmo_gsm_tester/suite.py
4 files changed, 105 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/96/2696/1

diff --git a/example/resources.conf b/example/resources.conf
index cd0216e..b7ac5a3 100644
--- a/example/resources.conf
+++ b/example/resources.conf
@@ -60,21 +60,17 @@
 
 modem:
 - label: sierra_1
-  path: '/sierra_1'
   imsi: '901700000009031'
   ki: '80A37E6FDEA931EAC92FFA5F671EFEAD'
 
 - label: sierra_2
-  path: '/sierra_2'
   imsi: '901700000009029'
   ki: '00969E283349D354A8239E877F2E0866'
 
 - label: gobi_0
-  path: '/gobi_0'
   imsi: '901700000009030'
   ki: 'BB70807226393CDBAC8DD3439FF54252'
 
 - label: gobi_3
-  path: '/gobi_3'
   imsi: '901700000009032'
   ki: '2F70DCA43C45ACB97E947FDD0C7CA30A'
diff --git a/src/osmo_gsm_tester/ofono_client.py b/src/osmo_gsm_tester/ofono_client.py
index 1ff98a9..8c19dfd 100644
--- a/src/osmo_gsm_tester/ofono_client.py
+++ b/src/osmo_gsm_tester/ofono_client.py
@@ -17,7 +17,7 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from . import log, test, util, event_loop
+from . import log, test, util, event_loop, resource
 
 from pydbus import SystemBus, Variant
 import time
@@ -31,6 +31,7 @@
 I_MODEM = 'org.ofono.Modem'
 I_NETREG = 'org.ofono.NetworkRegistration'
 I_SMS = 'org.ofono.MessageManager'
+I_SIM = 'org.ofono.SimManager'
 
 class DeferredHandling:
     defer_queue = []
@@ -73,6 +74,80 @@
     root = systembus_get('/')
     return sorted(root.GetModems())
 
+def modem_is_powered(dbus_obj, val):
+    modem_prop = dbus_obj[I_MODEM].GetProperties()
+    return modem_prop.get('Powered') == val
+
+def modem_has_val_in_property(dbus_obj, iface, prop_name, val):
+    modem_prop = dbus_obj[iface].GetProperties()
+    return val in modem_prop.get(prop_name)
+
+def modem_set_powered_sync(log_obj, dbus_obj, powered):
+    modem_prop = dbus_obj[I_MODEM].GetProperties()
+    prev_powered = modem_prop.get('Powered')
+    if prev_powered != powered:
+        dbus_obj[I_MODEM].SetProperty('Powered', Variant('b', powered))
+        event_loop.wait(log_obj, modem_is_powered, dbus_obj, powered)
+    return prev_powered
+
+def build_imsi_modem_map(log_obj, reserved):
+    imsi_modem_map = {}
+    event_loop.poll()
+    modems = list_modems()
+    for modem_path, prop in modems:
+        if modem_path in reserved:
+            log_obj.dbg('Modem with path %s is reserved, skipping discovery' % modem_path)
+            continue
+        log_obj.dbg('Discovering imsi for modem %s' % modem_path)
+        dbus_obj = systembus_get(modem_path)
+        prev_powered = modem_set_powered_sync(log_obj, dbus_obj, True)
+
+        has_sim_feature = True
+        try: # wait for 3 seconds to see if the modem has sim feature
+            event_loop.wait(log_obj, modem_has_val_in_property, dbus_obj, I_MODEM, 'Features', 'sim', timeout=3)
+        except RuntimeError:
+            has_sim_feature = False
+            log_obj.dbg('modem %s has no sim feature, skipping' % modem_path)
+        if has_sim_feature:
+            event_loop.wait(log_obj, modem_has_val_in_property, dbus_obj, I_MODEM, 'Interfaces', I_SIM)
+            sim_prop = dbus_obj[I_SIM].GetProperties()
+            imsi = sim_prop.get('SubscriberIdentity')
+            if imsi:
+                imsi_modem_map[imsi] = modem_path
+
+        #Leave in same status as it was:
+        if not prev_powered:
+            modem_set_powered_sync(log_obj, dbus_obj, False)
+    log_obj.dbg('imsi->modem map:', imsi_modem_map)
+    return imsi_modem_map
+
+def reserved_resource_populate_path(log_obj, to_be_reserved, reserved):
+    modem_to_be = to_be_reserved.get(resource.R_MODEM)
+    modem_reserved = reserved.get(resource.R_MODEM)
+
+    # check whether patching is needed or we can avoid it, as it can take some time:
+    if not modem_to_be:
+        return
+    modem_to_be = [d for d in modem_to_be if not d.get('path')]
+    if not modem_to_be:
+         return
+
+    reserved_modem_paths = []
+    if modem_reserved: # otherwise, no modems are previosuly already reserved
+        for reserved_dict in modem_reserved:
+            reserved_modem_paths.append(reserved_dict['path'])
+
+    imsi_map = build_imsi_modem_map(log_obj, reserved_modem_paths)
+
+    for to_be_dict in modem_to_be:
+        imsi = to_be_dict.get('imsi')
+        path = imsi_map.get(imsi)
+        if path:
+            log_obj.dbg('patching modem resource: %s -> %s' % (imsi, path))
+            to_be_dict['path'] = path
+        else:
+            log_obj.raise_exn('No free modem found with IMSI', imsi)
+
 
 class Modem(log.Origin):
     'convenience for ofono Modem interaction'
@@ -82,8 +157,10 @@
     def __init__(self, conf):
         self.conf = conf
         self.path = conf.get('path')
-        self.set_name(self.path)
+        self.set_name(self.label() if self.label() else self.imsi())
         self.set_log_category(log.C_BUS)
+        if not self.imsi():
+            self.raise_exn('No IMSI')
         self._dbus_obj = None
         self._interfaces = set()
         self._connected_signals = util.listdict()
@@ -95,12 +172,11 @@
     def set_msisdn(self, msisdn):
         self.msisdn = msisdn
 
+    def label(self):
+        return self.conf.get('label')
+
     def imsi(self):
-        imsi = self.conf.get('imsi')
-        if not imsi:
-            with self:
-                raise RuntimeError('No IMSI')
-        return imsi
+        return self.conf.get('imsi')
 
     def ki(self):
         return self.conf.get('ki')
diff --git a/src/osmo_gsm_tester/resource.py b/src/osmo_gsm_tester/resource.py
index 2a64772..6483cb6 100644
--- a/src/osmo_gsm_tester/resource.py
+++ b/src/osmo_gsm_tester/resource.py
@@ -27,7 +27,6 @@
 from . import config
 from . import util
 from . import schema
-from . import ofono_client
 from . import osmo_nitb
 from . import bts_sysmo, bts_osmotrx, bts_octphy
 
@@ -85,11 +84,30 @@
         self.config_path = config.get_config_file(RESOURCES_CONF)
         self.state_dir = config.get_state_dir()
         self.set_name(conf=self.config_path, state=self.state_dir.path)
+        self.reserve_cb_list = []
         self.read_conf()
 
     def read_conf(self):
         self.all_resources = Resources(config.read(self.config_path, RESOURCES_SCHEMA))
         self.all_resources.set_hashes()
+
+    def add_on_reserve_cb(self, cb):
+        '''
+        Add a hook to be able to read/modify parameters to resources being
+        reserved while the state lock is being hold.
+
+        cb method will be called as follows: cb(origin, to_be_reserved,
+        reserved)
+
+        'origin' a log.Origin() instance which can be sued to log information.
+
+        'to_be_reserved' A Resources() instance which represents the resources
+        that are being reserved now.
+
+        'reserved' A Resources() instance which represents the resources already
+        previously reserved.
+        '''
+        self.reserve_cb_list.append(cb)
 
     def reserve(self, origin, want):
         '''
@@ -149,7 +167,8 @@
             rrfile_path = self.state_dir.mk_parentdir(RESERVED_RESOURCES_FILE)
             reserved = Resources(config.read(rrfile_path, if_missing_return={}))
             to_be_reserved = self.all_resources.without(reserved).find(origin, want)
-
+            for cb in self.reserve_cb_list:
+                cb(self, to_be_reserved, reserved)
             to_be_reserved.mark_reserved_by(origin_id)
 
             reserved.add(to_be_reserved)
diff --git a/src/osmo_gsm_tester/suite.py b/src/osmo_gsm_tester/suite.py
index ea9ef47..eecea91 100644
--- a/src/osmo_gsm_tester/suite.py
+++ b/src/osmo_gsm_tester/suite.py
@@ -181,6 +181,7 @@
         self.set_name(suite_scenario_str)
         self.set_log_category(log.C_TST)
         self.resources_pool = resource.ResourcesPool()
+        self.resources_pool.add_on_reserve_cb(ofono_client.reserved_resource_populate_path)
 
     def mark_start(self):
         self.tests = []

-- 
To view, visit https://gerrit.osmocom.org/2696
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I602604d25f51b24d87877bc8ac798525b7be61dd
Gerrit-PatchSet: 1
Gerrit-Project: osmo-gsm-tester
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pespin at sysmocom.de>



More information about the gerrit-log mailing list