# osmo_gsm_tester: Base class for Mobile Stations (MS) # # Copyright (C) 2016-2017 by sysmocom - s.f.m.c. GmbH # # Author: Neels Hofmeyr # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from abc import ABCMeta, abstractmethod from ..core import log from ..core import schema def on_register_schemas(): resource_schema = { 'type': schema.STR, 'label': schema.STR, 'path': schema.STR, 'imsi': schema.IMSI, 'ki': schema.KI, 'opc': schema.OPC, 'auth_algo': schema.AUTH_ALGO, 'apn_ipaddr': schema.IPV4, 'ciphers[]': schema.CIPHER, 'features[]': schema.MODEM_FEATURE } schema.register_resource_schema('modem', resource_schema) class MS(log.Origin, metaclass=ABCMeta): """Base for everything about mobile/modem and SIMs.""" ############## # PROTECTED ############## def __init__(self, name, testenv, conf): super().__init__(log.C_TST, name) self.testenv = testenv self._conf = conf self._msisdn = None ######################## # PUBLIC - INTERNAL API ######################## @abstractmethod def cleanup(self): """Cleans up resources allocated.""" pass def get_instance_by_type(testenv, conf): """Allocate a MS child class based on type. Opts are passed to the newly created object.""" ms_type = conf.get('type') if ms_type is None: # Map None to ofono for forward compability ms_type = 'ofono' if ms_type == 'ofono': from .ms_ofono import Modem ms_class = Modem elif ms_type == 'osmo-mobile': from .ms_osmo_mobile import MSOsmoMobile ms_class = MSOsmoMobile elif ms_type == 'srsue': from .ms_srs import srsUE ms_class = srsUE elif ms_type == 'amarisoftue': from .ms_amarisoft import AmarisoftUE ms_class = AmarisoftUE else: raise log.Error('MS type not supported:', ms_type) return ms_class(testenv, conf) @abstractmethod def is_registered(self, mcc_mnc=None): '''Check whether MS is considered registered with the target network. In 2G networks, and MS is registered if it had a successful Location Update in CS. In 4G networks, an UE is considered registered with the core network if it has obtained and IP address. If MCC/MNC are given it tries to manually register against that specific network.''' pass @abstractmethod def get_assigned_addr(self, ipv6=False): ''' Returns last assigned IP address ''' pass ################### # PUBLIC (test API included) ################### def imsi(self): return self._conf.get('imsi') def ki(self): return self._conf.get('ki') def opc(self): return self._conf.get('opc', None) def apn_ipaddr(self): return self._conf.get('apn_ipaddr', 'dynamic') def auth_algo(self): return self._conf.get('auth_algo', None) def set_msisdn(self, msisdn): self._msisdn = msisdn def msisdn(self): # If none was set, allocate next one available: if self._msisdn is None: self.set_msisdn(self.testenv.msisdn()) return self._msisdn def emergency_numbers(self): return ['112'] def get_counter(self, counter_name): raise log.Error('get_counter() not implemented!')