Change in ...osmo-dev[master]: add sysmobts-calib.py

neels gerrit-no-reply at lists.osmocom.org
Thu Aug 8 13:44:47 UTC 2019


neels has submitted this change and it was merged. ( https://gerrit.osmocom.org/c/osmo-dev/+/15074 )

Change subject: add sysmobts-calib.py
......................................................................

add sysmobts-calib.py

Change-Id: I0cb372bddd115246ad1822dc06d318815387e8a4
---
A sysmobts-calib.py
1 file changed, 200 insertions(+), 0 deletions(-)



diff --git a/sysmobts-calib.py b/sysmobts-calib.py
new file mode 100755
index 0000000..d22223c
--- /dev/null
+++ b/sysmobts-calib.py
@@ -0,0 +1,200 @@
+#!/usr/bin/env python3
+doc = '''Remotely do a clock calibration of a sysmoBTS.
+
+You need is ssh root access to the BTS, and an antenna connected to the NWL.
+
+Remotely goes through the steps to obtain a OCXO calibration value from netlisten.
+- Obtain the current calibration value from /etc/osmocom/osmo-bts-sysmo.cfg.
+- Stop the osmo-bts-sysmo.service.
+- Do a scan to get the strongest received ARFCN.
+- Run n passes of sysmobts-calib (default: 7) to obtain an average calibration val.
+- Write this calibration value back to /etc/osmocom/osmo-bts-sysmo.cfg.
+- Start osmo-bts-sysmo.service.
+'''
+
+import sys
+import subprocess
+import re
+import shlex
+import argparse
+
+calib_val_re = re.compile(r'clock-calibration +([0-9]+)')
+result_re = re.compile('The calibration value is: ([0-9]*)')
+
+class Globals:
+    orig_calib_val = None
+    calib_val = None
+    bts = 'bts0'
+    band = '900'
+    arfcn = None
+
+def error(*msgs):
+    sys.stderr.write(''.join(str(m) for m in msgs))
+    sys.stderr.write('\n')
+    exit(1)
+
+def log(*msgs):
+    print(''.join(str(m) for m in msgs))
+
+def cmd_to_str(cmd):
+    return ' '.join(shlex.quote(c) for c in cmd)
+
+def call_output(*cmd):
+    cmd = ('ssh', Globals.bts,) + cmd
+    log('+ %s' % cmd_to_str(cmd))
+    sys.stdout.flush()
+    sys.stderr.flush()
+    p = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
+    o,e = p.communicate()
+    return o.decode('utf-8')
+
+def call(*cmd):
+    o = call_output(*cmd)
+    if o:
+        log(o)
+
+def reload_dsp():
+    #call('/bin/sh', '-c', r"'cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; sleep 3s; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0; sleep 1s'")
+    # systemd service contains the DSP reload commands in the ExecStopPost.
+    # So starting and stopping the service is the easy way to reload the DSP.
+    call('systemctl', 'start', 'osmo-bts-sysmo')
+    call('systemctl', 'stop', 'osmo-bts-sysmo')
+
+def get_cfg_calib_val():
+    o = call_output('grep', 'clock-calibration', '/etc/osmocom/osmo-bts-sysmo.cfg')
+    if not o:
+        return None
+    o = o.strip()
+    m = calib_val_re.match(o)
+    if not m:
+        return None
+    return m.group(1)
+
+def set_cfg_calib_val(calib_val):
+    if get_cfg_calib_val() is None:
+        call('sed', '-i', "'s/^ instance 0$/&\\n  clock-calibration %s/'" % calib_val, '/etc/osmocom/osmo-bts-sysmo.cfg');
+    else:
+        call('sed', '-i', "'s/clock-calibration.*$/clock-calibration %s/'" % calib_val, '/etc/osmocom/osmo-bts-sysmo.cfg');
+
+    now = get_cfg_calib_val()
+    if now != calib_val:
+        print('Failed to set calibration value, set manually in osmo-bts-sysmo.cfg')
+        print('phy 0\n instance 0\n  clock-calibration %s' % calib_val)
+
+
+def ask(*question, valid_answers=('*',)):
+    while True:
+        print('\n' + '\n  '.join(question))
+
+        answer = sys.stdin.readline().strip()
+        for v in valid_answers:
+            if v == answer:
+                return answer
+            if v == '*':
+                return answer
+            if v == '+' and len(answer):
+                return answer
+
+def call_sysmobts_calib(mode, *args):
+    o = call_output('sysmobts-calib', '-c', 'ocxo', '-s', 'netlisten', '-b', Globals.band, '-i', Globals.calib_val, '-m', mode, *args)
+    log(o)
+    reload_dsp()
+    return o
+
+def int_be_one(string):
+    val = int(string)
+    if val < 1:
+        raise argparse.ArgumentTypeError('value must be at least 1')
+    return val
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description=doc)
+    parser.add_argument('-b', '--band', dest='band', default=None,
+                        help='Which GSM band to scan and calibrate to (850, 900, 1800, 1900)')
+    parser.add_argument('-a', '--arfcn', dest='arfcn', default=None,
+                        help="Don't scan, directly use this ARFCN to calibrate to")
+    parser.add_argument('-i', '--initial-clock-correction', dest='calib_val', default=None,
+                        help='Clock calibration value to start out with. If omitted, this is obtained from'
+                        ' /etc/osmocom/osmo-bts-sysmo.cfg from the BTS file system.')
+    parser.add_argument('-I', '--set-clock-correction', dest='set_calib_val', default=None,
+                        help="Don't scan or calibrate, just set the given value in the config file")
+    parser.add_argument('-G', '--get-clock-correction', dest='get_calib_val', default=False, action='store_true',
+                        help="Don't scan or calibrate, just read the given value in the config file")
+    parser.add_argument('-n', '--passes', dest='passes', default=7, type=int_be_one,
+                        help="How many times to run sysmobts-calib to obtain a resulting calibration value average")
+    parser.add_argument('args', nargs=1, help='Hostname (SSH) to reach the BTS at')
+
+    cmdline = parser.parse_args()
+
+    Globals.bts = cmdline.args[0]
+    if cmdline.band:
+        Globals.band = cmdline.band
+
+    if cmdline.set_calib_val:
+        set_cfg_calib_val(cmdline.set_calib_val)
+        exit(0)
+
+    if cmdline.get_calib_val:
+        print(get_cfg_calib_val())
+        exit(0)
+
+    Globals.orig_calib_val = cmdline.calib_val
+    if Globals.orig_calib_val is None:
+        Globals.orig_calib_val = get_cfg_calib_val() or '0'
+    Globals.calib_val = Globals.orig_calib_val
+
+    print('Starting out with clock calibration value %s' % Globals.calib_val)
+
+    #call('systemctl', 'stop', 'osmo-bts-sysmo')
+    reload_dsp()
+
+    if cmdline.arfcn:
+        Globals.arfcn = cmdline.arfcn
+    else:
+        arfcns = call_sysmobts_calib('scan')
+        best_arfcn_line = arfcns.splitlines()[-1]
+        Globals.arfcn = best_arfcn_line.split(':')[0].split(' ')[-1]
+        try:
+            int(Globals.arfcn)
+        except:
+            error('Error while scanning bands')
+
+    print('Using ARFCN %r' % Globals.arfcn)
+
+    collected_values = []
+
+    passes = cmdline.passes
+    if passes < 1:
+        passes = 1
+
+    for i in range(passes):
+        print('\npass %d of %d' % (i+1, passes))
+        o = call_sysmobts_calib('calibrate', '-a', Globals.arfcn)
+        for m in result_re.finditer(o):
+            collected_values.append(int(m.group(1)))
+
+        collected_values = list(sorted(collected_values))
+        print(collected_values)
+        if not collected_values:
+            continue
+
+        best_values = collected_values
+        if len(best_values) > 3:
+            best_values = best_values[1:-1]
+
+        avg = sum(best_values) / len(best_values)
+        Globals.calib_val = str(int(avg))
+        print('clock-calibration: started with %s, current=%s' %
+              (Globals.orig_calib_val, Globals.calib_val))
+
+    print('RESULT:', Globals.calib_val, ' (was %s)' % Globals.orig_calib_val)
+
+    cfg_calib_val = get_cfg_calib_val()
+    if Globals.calib_val != cfg_calib_val:
+        a = ask('osmo-bts-sysmo.cfg currently has %s\nmodify osmo-bts-sysmo.cfg to clock-calibration %s? (ok, no)'
+                % (cfg_calib_val, Globals.calib_val),
+                valid_answers=('ok', 'no', ''))
+        if a == 'ok':
+            set_cfg_calib_val(Globals.calib_val)
+    call('systemctl', 'start', 'osmo-bts-sysmo')
+# vim: shiftwidth=4 expandtab tabstop=4

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-dev/+/15074
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-dev
Gerrit-Branch: master
Gerrit-Change-Id: I0cb372bddd115246ad1822dc06d318815387e8a4
Gerrit-Change-Number: 15074
Gerrit-PatchSet: 2
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: keith <keith at rhizomatica.org>
Gerrit-Reviewer: laforge <laforge at gnumonks.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190808/e4bb65b5/attachment.html>


More information about the gerrit-log mailing list