1#!/usr/bin/env python3
2#
3#   Copyright 2022 - Google
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import enum
18import os
19import immutabledict
20
21from acts.controllers.amarisoft_lib import amarisoft_client
22
23TEMPLATE_PATH = os.path.dirname(os.path.abspath(__file__)) + '/config_templates'
24TEMPLATE_PATH_ENB = f'{TEMPLATE_PATH}/enb/'
25TEMPLATE_PATH_MME = f'{TEMPLATE_PATH}/mme/'
26
27_CLIENT_CONFIG_DIR_MAPPING = immutabledict.immutabledict({
28    'enb': '/config/mhtest_enb.cfg',
29    'mme': '/config/mhtest_mme.cfg',
30})
31
32
33class EnbCfg():
34  """MME configuration templates."""
35  ENB_GENERIC = 'enb-single-generic.cfg'
36  GNB_NSA_GENERIC = 'gnb-nsa-lte-ho-generic.cfg'
37  GNB_SA_GENERIC = 'gnb-sa-lte-ho-generic.cfg'
38
39
40class MmeCfg():
41  """MME configuration templates."""
42  MME_GENERIC = 'mme-generic.cfg'
43
44
45class SpecTech(enum.Enum):
46  """Spectrum usage techniques."""
47  FDD = 0
48  TDD = 1
49
50
51class ConfigUtils():
52  """Utilities for set Amarisoft configs.
53
54  Attributes:
55    remote: An amarisoft client.
56  """
57
58  def __init__(self, remote: amarisoft_client.AmariSoftClient):
59    self.remote = remote
60
61  def upload_enb_template(self, cfg: str) -> bool:
62    """Loads ENB configuration.
63
64    Args:
65      cfg: The ENB configuration to be loaded.
66
67    Returns:
68      True if the ENB configuration was loaded successfully, False otherwise.
69    """
70    cfg_template = TEMPLATE_PATH_ENB + cfg
71    if not os.path.isfile(cfg_template):
72      return False
73    cfg_path = self.remote.get_config_dir(
74        'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
75    self.remote.run_cmd('rm -f ' + cfg_path)
76    self.remote.sftp_upload(cfg_template, cfg_path)
77    self.remote.set_config_file('enb', cfg_path)
78    if not self.remote.is_file_exist(cfg_path):
79      return False
80    return True
81
82  def upload_mme_template(self, cfg: str) -> bool:
83    """Loads MME configuration.
84
85    Args:
86      cfg: The MME configuration to be loaded.
87
88    Returns:
89      True if the ENB configuration was loaded successfully, False otherwise.
90    """
91    cfg_template = TEMPLATE_PATH_MME + cfg
92    if not os.path.isfile(cfg_template):
93      return False
94    cfg_path = self.remote.get_config_dir(
95        'mme') + _CLIENT_CONFIG_DIR_MAPPING['mme']
96    self.remote.run_cmd('rm -f ' + cfg_path)
97    self.remote.sftp_upload(cfg_template, cfg_path)
98    self.remote.set_config_file('mme', cfg_path)
99    if not self.remote.is_file_exist(cfg_path):
100      return False
101    return True
102
103  def enb_set_plmn(self, plmn: str) -> bool:
104    """Sets the PLMN in ENB configuration.
105
106    Args:
107      plmn: The PLMN to be set. ex: 311480
108
109    Returns:
110      True if set PLMN successfully, False otherwise.
111    """
112    cfg_path = self.remote.get_config_dir(
113        'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
114    if not self.remote.is_file_exist(cfg_path):
115      return False
116    string_from = '#define PLMN \"00101\"'
117    string_to = f'#define PLMN \"{plmn}\"'
118    self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
119    self.remote.run_cmd(
120        f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
121    return True
122
123  def mme_set_plmn(self, plmn: str) -> bool:
124    """Sets the PLMN in MME configuration.
125
126    Args:
127      plmn: The PLMN to be set. ex:'311480'
128
129    Returns:
130      True if set PLMN successfully, False otherwise.
131    """
132    cfg_path = self.remote.get_config_dir(
133        'mme') + _CLIENT_CONFIG_DIR_MAPPING['mme']
134    if not self.remote.is_file_exist(cfg_path):
135      return False
136    string_from = '#define PLMN \"00101\"'
137    string_to = f'#define PLMN \"{plmn}\"'
138    self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
139    self.remote.run_cmd(
140        f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
141    return True
142
143  def enb_set_fdd_arfcn(self, arfcn: int) -> bool:
144    """Sets the FDD ARFCN in ENB configuration.
145
146    Args:
147      arfcn: The arfcn to be set. ex: 1400
148
149    Returns:
150      True if set FDD ARFCN successfully, False otherwise.
151    """
152    cfg_path = self.remote.get_config_dir(
153        'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
154    if not self.remote.is_file_exist(cfg_path):
155      return False
156    string_from = '#define FDD_CELL_earfcn 1400'
157    string_to = f'#define FDD_CELL_earfcn {arfcn}'
158    self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
159    self.remote.run_cmd(
160        f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
161    return True
162
163  def enb_set_tdd_arfcn(self, arfcn: int) -> bool:
164    """Sets the TDD ARFCN in ENB configuration.
165
166    Args:
167      arfcn: The arfcn to be set. ex: 1400
168
169    Returns:
170      True if set FDD ARFCN successfully, False otherwise.
171    """
172    cfg_path = self.remote.get_config_dir(
173        'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
174    if not self.remote.is_file_exist(cfg_path):
175      return False
176    string_from = '#define TDD_CELL_earfcn 40620'
177    string_to = f'#define TDD_CELL_earfcn {arfcn}'
178    self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
179    self.remote.run_cmd(
180        f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
181    return True
182
183  def enb_set_spectrum_tech(self, tech: int) -> bool:
184    """Sets the spectrum usage techniques in ENB configuration.
185
186    Args:
187      tech: the spectrum usage techniques. ex: SpecTech.FDD.name
188
189    Returns:
190      True if set spectrum usage techniques successfully, False otherwise.
191    """
192    cfg_path = self.remote.get_config_dir(
193        'enb') + _CLIENT_CONFIG_DIR_MAPPING['enb']
194    if not self.remote.is_file_exist(cfg_path):
195      return False
196    string_from = '#define TDD 0'
197    string_to = f'#define TDD {tech}'
198    self.remote.run_cmd(f'sed -i \'s/\\r//g\' {cfg_path}')
199    self.remote.run_cmd(
200        f'sed -i \':a;N;$!ba;s/{string_from}/{string_to}/g\' {cfg_path}')
201    return True
202