Nils Fürste | a8263f4 | 2020-11-23 14:45:15 +0100 | [diff] [blame] | 1 | # osmo_gsm_tester: specifics for setting an APN on an AndroidUE modem |
| 2 | # |
| 3 | # Copyright (C) 2020 by Software Radio Systems Limited |
| 4 | # |
| 5 | # Author: Nils Fürste <nils.fuerste@softwareradiosystems.com> |
| 6 | # Author: Bedran Karakoc <bedran.karakoc@softwareradiosystems.com> |
| 7 | # |
| 8 | # This program is free software: you can redistribute it and/or modify |
| 9 | # it under the terms of the GNU General Public License as |
| 10 | # published by the Free Software Foundation, either version 3 of the |
| 11 | # License, or (at your option) any later version. |
| 12 | # |
| 13 | # This program is distributed in the hope that it will be useful, |
| 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | # GNU General Public License for more details. |
| 17 | # |
| 18 | # You should have received a copy of the GNU General Public License |
| 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 20 | |
| 21 | import re |
| 22 | |
| 23 | from ..core import log |
| 24 | from ..core import schema |
| 25 | from .android_host import AndroidHost |
| 26 | |
| 27 | |
| 28 | class AndroidApn(AndroidHost): |
| 29 | ############## |
| 30 | # PROTECTED |
| 31 | ############## |
| 32 | def __init__(self, apn, mcc, mnc, select=None): |
| 33 | self.logger_name = 'apn_worker_' |
| 34 | super().__init__(self.logger_name) |
| 35 | self._apn_name = apn |
| 36 | self._apn = apn |
| 37 | self._mcc = mcc |
| 38 | self._mnc = mnc |
| 39 | self._select = select |
| 40 | if not self._apn: |
| 41 | raise log.Error('APN name not set') |
| 42 | if not self._mcc: |
| 43 | raise log.Error('MCC not set') |
| 44 | if not self._mnc: |
| 45 | raise log.Error('MNC not set') |
| 46 | |
| 47 | # optional parameters, set with set_additional_params() |
| 48 | self.proxy = None |
| 49 | self.port = None |
| 50 | self.user = None |
| 51 | self.password = None |
| 52 | self.server = None |
| 53 | self.mmsc = None |
| 54 | self.mmsport = None |
| 55 | self.mmsproxy = None |
| 56 | self.auth = None |
| 57 | self.type = None |
| 58 | self.protocol = None |
| 59 | self.mvnoval = None |
| 60 | self.mvnotype = None |
| 61 | |
| 62 | def get_carrier_id(self, carrier_name): |
| 63 | qry_carrier_cmd = "content query --uri \"content://telephony/carriers\"" |
| 64 | proc = self.run_androidue_cmd('get-carrier-id', [qry_carrier_cmd]) |
| 65 | proc.launch_sync() |
| 66 | available_carriers = proc.get_stdout().split('\n') |
| 67 | carr_id = -1 |
| 68 | for carr in available_carriers: |
| 69 | if 'name=' + carrier_name in carr: # found carrier |
| 70 | carr_id = re.findall(r'_id=(\S+),', carr)[0] |
| 71 | break |
| 72 | return carr_id |
| 73 | |
| 74 | def set_new_carrier(self, apn_parameter, carr_id): |
| 75 | # check if carrier was found, delete it if exists |
| 76 | if carr_id != -1: |
| 77 | self.delete_apn(apn_parameter['carrier']) |
| 78 | |
| 79 | set_carrier_cmd = "content insert --uri content://telephony/carriers" \ |
| 80 | + " --bind name:s:\"" + apn_parameter["carrier"] + "\"" \ |
| 81 | + " --bind numeric:s:\"" + apn_parameter["mcc"] + apn_parameter["mnc"] + "\"" \ |
| 82 | + " --bind mcc:s:\"" + apn_parameter["mcc"] + "\"" \ |
| 83 | + " --bind mnc:s:\"" + apn_parameter["mnc"] + "\""\ |
| 84 | + " --bind apn:s:\"" + apn_parameter["apn"] + "\"" \ |
| 85 | + " --bind user:s:\"" + apn_parameter["user"] + "\"" \ |
| 86 | + " --bind password:s:\"" + apn_parameter["password"] + "\"" \ |
| 87 | + " --bind mmsc:s:\"" + apn_parameter["mmsc"] + "\"" \ |
| 88 | + " --bind mmsport:s:\"" + apn_parameter["mmsport"] + "\"" \ |
| 89 | + " --bind mmsproxy:s:\"" + apn_parameter["mmsproxy"] + "\"" \ |
| 90 | + " --bind authtype:s:\"" + apn_parameter["auth"] + "\"" \ |
| 91 | + " --bind type:s:\"" + apn_parameter["type"] + "\"" \ |
| 92 | + " --bind protocol:s:\"" + apn_parameter["protocol"] + "\"" \ |
| 93 | + " --bind mvno_type:s:\"" + apn_parameter["mvnotype"] + "\"" \ |
| 94 | + " --bind mvno_match_data:s:\"" + apn_parameter["mvnoval"] + "\"" |
| 95 | proc = self.run_androidue_cmd("set-new-carrier", [set_carrier_cmd]) |
| 96 | proc.launch_sync() |
| 97 | return self.get_carrier_id(apn_parameter['carrier']) |
| 98 | |
| 99 | def set_preferred_apn(self, carr_id): |
| 100 | if carr_id != -1: |
| 101 | set_apn_cmd = "content insert --uri content://telephony/carriers/preferapn --bind apn_id:s:\"" + str(carr_id) + "\"" |
| 102 | proc = self.run_androidue_cmd('set-preferred-apn', [set_apn_cmd]) |
| 103 | proc.launch_sync() |
| 104 | |
| 105 | def select_apn(self, carr_name): |
| 106 | carr_id = self.get_carrier_id(carr_name) |
| 107 | if carr_id == 0: |
| 108 | return False |
| 109 | |
| 110 | # select carrier by ID |
| 111 | sel_apn_cmd = "content update --uri content://telephony/carriers/preferapn --bind apn_id:s:\"" + str(carr_id) + "\"" |
| 112 | proc = self.run_androidue_cmd('select-apn', [sel_apn_cmd]) |
| 113 | proc.launch_sync() |
| 114 | return True |
| 115 | |
| 116 | def delete_apn(self, carr_name): |
| 117 | set_apn_cmd = "content delete --uri content://telephony/carriers --where \'name=\"" + str(carr_name) + "\" \'" |
| 118 | proc = self.run_androidue_cmd('delete-apn', [set_apn_cmd]) |
| 119 | proc.launch_sync() |
| 120 | |
| 121 | ######################## |
| 122 | # PUBLIC - INTERNAL API |
| 123 | ######################## |
| 124 | @classmethod |
| 125 | def from_conf(cls, conf): |
| 126 | return cls(conf.get('apn', None), conf.get('mcc', None), |
| 127 | conf.get('mnc', None), conf.get('select', None)) |
| 128 | |
| 129 | @classmethod |
| 130 | def schema(cls): |
| 131 | resource_schema = { |
| 132 | 'apn': schema.STR, |
| 133 | 'mcc': schema.STR, |
| 134 | 'mnc': schema.STR, |
| 135 | 'select': schema.BOOL_STR, |
| 136 | } |
| 137 | return resource_schema |
| 138 | |
| 139 | def configure(self, testenv, run_dir, run_node, rem_host): |
| 140 | self.testenv = testenv |
| 141 | self.rem_host = rem_host |
| 142 | self._run_node = run_node |
| 143 | self.run_dir = run_dir |
| 144 | self.logger_name += self._run_node.run_addr() |
| 145 | self.set_name(self.logger_name) |
| 146 | |
| 147 | def set_additional_params(self, proxy=None, port=None, user=None, password=None, server=None, auth=None, apn_type=None, |
| 148 | mmsc=None, mmsport=None, mmsproxy=None, protocol=None, mvnoval=None, mvnotype=None): |
| 149 | self.proxy = proxy |
| 150 | self.port = port |
| 151 | self.user = user |
| 152 | self.password = password |
| 153 | self.server = server |
| 154 | self.auth = auth |
| 155 | self.type = apn_type |
| 156 | self.mmsc = mmsc |
| 157 | self.mmsport = mmsport |
| 158 | self.mmsproxy = mmsproxy |
| 159 | self.protocol = protocol |
| 160 | self.mvnoval = mvnoval |
| 161 | self.mvnotype = mvnotype |
| 162 | |
| 163 | def set_apn(self): |
| 164 | apn_params = { |
| 165 | 'carrier': self._apn_name, |
| 166 | 'apn': self._apn, |
| 167 | 'proxy': self.proxy or '', |
| 168 | 'port': self.port or '', |
| 169 | 'user': self.user or '', |
| 170 | 'password': self.password or '', |
| 171 | 'server': self.server or '', |
| 172 | 'mmsc': self.mmsc or '', |
| 173 | 'mmsport': self.mmsport or '', |
| 174 | 'mmsproxy': self.mmsproxy or '', |
| 175 | 'mcc': self._mcc, |
| 176 | 'mnc': self._mnc, |
| 177 | 'auth': self.auth or '-1', |
| 178 | 'type': self.type or 'default', |
| 179 | 'protocol': self.protocol or '', |
| 180 | 'mvnotype': self.mvnotype or '', |
| 181 | 'mvnoval': self.mvnoval or '', |
| 182 | } |
| 183 | self.dbg('APN parameters: ' + str(apn_params)) |
| 184 | |
| 185 | # search for carrier in database |
| 186 | carrier_id = self.get_carrier_id(apn_params['carrier']) |
| 187 | |
| 188 | # add/update carrier |
| 189 | carrier_id = self.set_new_carrier(apn_params, carrier_id) |
| 190 | |
| 191 | # select as preferred APN |
| 192 | if self.select: |
| 193 | self.set_preferred_apn(carrier_id) |
| 194 | |
| 195 | def __str__(self): |
| 196 | return self.name() |
| 197 | |
| 198 | def apn(self): |
| 199 | return self._apn |
| 200 | |
| 201 | def mcc(self): |
| 202 | return self._mcc |
| 203 | |
| 204 | def mnc(self): |
| 205 | return self._mnc |
| 206 | |
| 207 | def select(self): |
| 208 | return self._select |
| 209 | |
| 210 | # vim: expandtab tabstop=4 shiftwidth=4 |