blob: 1ee9ef839d5c0f17b9c0971596cfad6a9abe88a4 [file] [log] [blame]
Holger Hans Peter Freyther48c83a82019-02-27 08:27:46 +00001# osmo_gsm_tester: Base class for Mobile Stations (MS)
2#
3# Copyright (C) 2016-2017 by sysmocom - s.f.m.c. GmbH
4#
5# Author: Neels Hofmeyr <neels@hofmeyr.de>
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20from abc import ABCMeta, abstractmethod
Pau Espin Pedrole1a58bd2020-04-10 20:46:07 +020021from ..core import log
Pau Espin Pedrolea8c3d42020-05-04 12:05:05 +020022from ..core import schema
23
24def on_register_schemas():
25 resource_schema = {
26 'type': schema.STR,
27 'label': schema.STR,
28 'path': schema.STR,
29 'imsi': schema.IMSI,
30 'ki': schema.KI,
Pau Espin Pedrol0f7f2652020-07-13 12:01:10 +020031 'opc': schema.OPC,
Pau Espin Pedrolea8c3d42020-05-04 12:05:05 +020032 'auth_algo': schema.AUTH_ALGO,
33 'apn_ipaddr': schema.IPV4,
Nils Fürstea8180152020-12-03 14:14:31 +010034 'ciphers[]': schema.CIPHER_2G,
Andre Puschmann31ecf592021-03-18 16:53:36 +010035 'features[]': schema.MODEM_FEATURE,
36 'dl_earfcn': schema.UINT,
37 'ul_earfcn': schema.UINT
Pau Espin Pedrolea8c3d42020-05-04 12:05:05 +020038 }
39 schema.register_resource_schema('modem', resource_schema)
Holger Hans Peter Freyther48c83a82019-02-27 08:27:46 +000040
Andre Puschmann65a9e742020-11-20 11:48:38 +010041 config_schema = {
42 'count': schema.UINT
43 }
44 schema.register_config_schema('modem', config_schema)
45
Holger Hans Peter Freyther48c83a82019-02-27 08:27:46 +000046class MS(log.Origin, metaclass=ABCMeta):
47 """Base for everything about mobile/modem and SIMs."""
48
Pau Espin Pedrol1ee5ec52020-05-04 17:16:39 +020049##############
50# PROTECTED
51##############
Pau Espin Pedrol83a2fdc2020-10-15 16:33:47 +020052 def __init__(self, name, testenv, conf):
Nils Fürstea8263f42020-11-23 14:45:15 +010053 log.Origin.__init__(self, log.C_TST, name)
Pau Espin Pedrol83a2fdc2020-10-15 16:33:47 +020054 self.testenv = testenv
Holger Hans Peter Freyther48c83a82019-02-27 08:27:46 +000055 self._conf = conf
Pau Espin Pedrol4b7c5852020-10-14 14:48:21 +020056 self._msisdn = None
Holger Hans Peter Freyther48c83a82019-02-27 08:27:46 +000057
Pau Espin Pedrol1ee5ec52020-05-04 17:16:39 +020058########################
59# PUBLIC - INTERNAL API
60########################
61 @abstractmethod
62 def cleanup(self):
63 """Cleans up resources allocated."""
64 pass
65
Pau Espin Pedrola442cb82020-05-05 12:54:37 +020066 def get_instance_by_type(testenv, conf):
Pau Espin Pedrol1ee5ec52020-05-04 17:16:39 +020067 """Allocate a MS child class based on type. Opts are passed to the newly created object."""
68 ms_type = conf.get('type')
69 if ms_type is None:
70 # Map None to ofono for forward compability
71 ms_type = 'ofono'
72
73 if ms_type == 'ofono':
74 from .ms_ofono import Modem
75 ms_class = Modem
76 elif ms_type == 'osmo-mobile':
77 from .ms_osmo_mobile import MSOsmoMobile
78 ms_class = MSOsmoMobile
79 elif ms_type == 'srsue':
80 from .ms_srs import srsUE
81 ms_class = srsUE
Nils Fürstea8263f42020-11-23 14:45:15 +010082 elif ms_type == 'androidue':
83 from .ms_android import AndroidUE
84 ms_class = AndroidUE
Pau Espin Pedrol1ee5ec52020-05-04 17:16:39 +020085 elif ms_type == 'amarisoftue':
86 from .ms_amarisoft import AmarisoftUE
87 ms_class = AmarisoftUE
88 else:
89 raise log.Error('MS type not supported:', ms_type)
Pau Espin Pedrola442cb82020-05-05 12:54:37 +020090 return ms_class(testenv, conf)
Pau Espin Pedrol1ee5ec52020-05-04 17:16:39 +020091
Andre Puschmann419a6622020-05-27 18:46:12 +020092 @abstractmethod
93 def is_registered(self, mcc_mnc=None):
94 '''Check whether MS is considered registered with the target network. In
95 2G networks, and MS is registered if it had a successful Location Update
96 in CS. In 4G networks, an UE is considered registered with the core
97 network if it has obtained and IP address. If MCC/MNC are given it tries
98 to manually register against that specific network.'''
99 pass
100
101 @abstractmethod
102 def get_assigned_addr(self, ipv6=False):
103 ''' Returns last assigned IP address '''
104 pass
105
Pau Espin Pedrol1ee5ec52020-05-04 17:16:39 +0200106###################
107# PUBLIC (test API included)
108###################
Holger Hans Peter Freyther48c83a82019-02-27 08:27:46 +0000109 def imsi(self):
110 return self._conf.get('imsi')
111
112 def ki(self):
113 return self._conf.get('ki')
114
Pau Espin Pedrol0f7f2652020-07-13 12:01:10 +0200115 def opc(self):
116 return self._conf.get('opc', None)
117
Andre Puschmann22ec00a2020-03-24 09:58:06 +0100118 def apn_ipaddr(self):
119 return self._conf.get('apn_ipaddr', 'dynamic')
120
Holger Hans Peter Freyther48c83a82019-02-27 08:27:46 +0000121 def auth_algo(self):
122 return self._conf.get('auth_algo', None)
123
124 def set_msisdn(self, msisdn):
Pau Espin Pedrol4b7c5852020-10-14 14:48:21 +0200125 self._msisdn = msisdn
Holger Hans Peter Freyther48c83a82019-02-27 08:27:46 +0000126
127 def msisdn(self):
Pau Espin Pedrol83a2fdc2020-10-15 16:33:47 +0200128 # If none was set, allocate next one available:
129 if self._msisdn is None:
130 self.set_msisdn(self.testenv.msisdn())
Pau Espin Pedrol4b7c5852020-10-14 14:48:21 +0200131 return self._msisdn
Pau Espin Pedroleaefe6b2020-04-20 13:29:59 +0200132
Pau Espin Pedrol680ba032020-10-14 14:49:05 +0200133 def emergency_numbers(self):
134 return ['112']
135
Pau Espin Pedroleaefe6b2020-04-20 13:29:59 +0200136 def get_counter(self, counter_name):
137 raise log.Error('get_counter() not implemented!')
Andre Puschmann65a9e742020-11-20 11:48:38 +0100138
139 def features(self):
140 return self._conf.get('features', [])