blob: 91a3887b341f73226d63a73524475bcdfdfbd80e [file] [log] [blame]
Yang Liu19159ee2016-01-14 11:09:28 -08001#!/usr/bin/env python3.4
2#
3# Copyright 2016 - 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"""
17 Basic script for managing a JSON "database" file of SIM cards.
18 It will look at the list of attached devices, and add their SIMs to a
19 database.
20 We expect to add much more functionality in the future.
21"""
22
23import argparse
24import json
25import acts.controllers.android_device as android_device
Xianyuan Jia63751fb2020-11-17 00:07:40 +000026import acts_contrib.test_utils.tel.tel_defines as tel_defines
27import acts_contrib.test_utils.tel.tel_lookup_tables as tel_lookup_tables
28import acts_contrib.test_utils.tel.tel_test_utils as tel_test_utils
Nathan Harold0b9adf12016-09-08 19:36:46 -070029
30
31def get_active_sim_list(verbose_warnings=False):
32 """ Get a dictionary of active sims across phones
33
34 Args: verbose_warnings - print warnings as issues are encountered if True
35
36 Returns:
37 A dictionary with keys equivalent to the ICCIDs of each SIM containing
38 information about that SIM
39 """
40 active_list = {}
41 droid_list = android_device.get_all_instances()
42 for droid_device in droid_list:
43 droid = droid_device.get_droid(False)
44
45 sub_info_list = droid.subscriptionGetActiveSubInfoList()
Betty Zhou57245672016-10-04 17:21:43 -070046 if not sub_info_list:
Nathan Harold0b9adf12016-09-08 19:36:46 -070047 if verbose_warnings:
Betty Zhou57245672016-10-04 17:21:43 -070048 print('No Valid Sim in {} {}! SimState = {}'.format(
49 droid_device.model, droid_device.serial, droid.telephonyGetSimState()))
50 continue
Nathan Harold0b9adf12016-09-08 19:36:46 -070051
52 for sub_info in sub_info_list:
53 print(sub_info)
54 iccid = sub_info['iccId']
55 if not sub_info['iccId']:
56 continue
57
58 active_list[iccid] = {}
59 current = active_list[iccid]
60 current['droid_serial'] = droid_device.serial
61
62 sub_id = sub_info['subscriptionId']
63
64 try:
65 plmn_id = droid.telephonyGetSimOperatorForSubscription(sub_id)
66 current[
67 'operator'] = tel_lookup_tables.operator_name_from_plmn_id(
68 plmn_id)
69 except KeyError:
70 if vebose_warnings:
71 print('Unknown Operator {}'.format(
72 droid.telephonyGetSimOperator()))
73 current['operator'] = ''
74
75 # TODO: add actual capability determination to replace the defaults
76 current['capability'] = ['voice', 'ims', 'volte', 'vt', 'sms',
77 'tethering', 'data']
78
79 phone_num = droid.telephonyGetLine1NumberForSubscription(sub_id)
80 if not phone_num:
81 if verbose_warnings:
82 print('Please manually add a phone number for {}\n'.format(
83 iccid))
84 current['phone_num'] = ''
85 else:
86 current['phone_num'] = tel_test_utils.phone_number_formatter(
87 phone_num, tel_defines.PHONE_NUMBER_STRING_FORMAT_11_DIGIT)
88 return active_list
89
Yang Liu19159ee2016-01-14 11:09:28 -080090
91def add_sims(sim_card_file=None):
92 if not sim_card_file:
Nathan Harold0b9adf12016-09-08 19:36:46 -070093 print('Error: file name is None.')
Yang Liu19159ee2016-01-14 11:09:28 -080094 return False
95 try:
96 f = open(sim_card_file, 'r')
97 simconf = json.load(f)
98 f.close()
99 except FileNotFoundError:
100 simconf = {}
Yang Liu19159ee2016-01-14 11:09:28 -0800101
Nathan Harold0b9adf12016-09-08 19:36:46 -0700102 active_sims = get_active_sim_list(True)
Yang Liu19159ee2016-01-14 11:09:28 -0800103
Nathan Harold0b9adf12016-09-08 19:36:46 -0700104 if not active_sims:
105 print('No active SIMs, exiting')
106 return False
107
108 file_write_required = False
109
110 for iccid in active_sims.keys():
Yang Liu19159ee2016-01-14 11:09:28 -0800111 # Add new entry if not exist
Nathan Harold0b9adf12016-09-08 19:36:46 -0700112 if iccid in simconf:
113 print('Declining to add a duplicate entry: {}'.format(iccid))
Yang Liu19159ee2016-01-14 11:09:28 -0800114 #TODO: Add support for "refreshing" an entry
115 continue
Yang Liu19159ee2016-01-14 11:09:28 -0800116
Nathan Harold0b9adf12016-09-08 19:36:46 -0700117 simconf[iccid] = {}
118 current = simconf[iccid]
119 file_write_required = True
Yang Liu19159ee2016-01-14 11:09:28 -0800120
Nathan Harold0b9adf12016-09-08 19:36:46 -0700121 current['operator'] = active_sims[iccid]['operator']
122 current['capability'] = active_sims[iccid]['capability']
123 current['phone_num'] = active_sims[iccid]['phone_num']
Yang Liu19159ee2016-01-14 11:09:28 -0800124
Nathan Harold0b9adf12016-09-08 19:36:46 -0700125 if file_write_required:
Yang Liu19159ee2016-01-14 11:09:28 -0800126 f = open(sim_card_file, 'w')
127 json.dump(simconf, f, indent=4, sort_keys=True)
128 f.close()
129 return True
130
Yang Liu19159ee2016-01-14 11:09:28 -0800131
Nathan Harold0b9adf12016-09-08 19:36:46 -0700132def prune_sims(sim_card_file=None):
Yang Liu19159ee2016-01-14 11:09:28 -0800133 try:
134 f = open(sim_card_file, 'r')
135 simconf = json.load(f)
136 f.close()
137 except FileNotFoundError:
Nathan Harold0b9adf12016-09-08 19:36:46 -0700138 print('File {} not found.'.format(sim_card_file if sim_card_file else
139 '<UNSPECIFIED>'))
Yang Liu19159ee2016-01-14 11:09:28 -0800140 return False
141
Yang Liu19159ee2016-01-14 11:09:28 -0800142 simconf_list = list(simconf.keys())
Nathan Harold0b9adf12016-09-08 19:36:46 -0700143 active_list = get_active_sim_list().keys()
Yang Liu19159ee2016-01-14 11:09:28 -0800144 delete_list = list(set(simconf_list).difference(set(active_list)))
145
Nathan Harold0b9adf12016-09-08 19:36:46 -0700146 print('active phones: {}'.format(active_list))
147
148 file_write_required = False
Yang Liu19159ee2016-01-14 11:09:28 -0800149
150 if len(delete_list) > 0:
151 for sim in delete_list:
152 # prune
Nathan Harold0b9adf12016-09-08 19:36:46 -0700153 print('Deleting the SIM entry: ', sim)
Yang Liu19159ee2016-01-14 11:09:28 -0800154 del simconf[sim]
Nathan Harold0b9adf12016-09-08 19:36:46 -0700155 file_write_required = True
Yang Liu19159ee2016-01-14 11:09:28 -0800156 else:
Nathan Harold0b9adf12016-09-08 19:36:46 -0700157 print('No entries to prune')
Yang Liu19159ee2016-01-14 11:09:28 -0800158
Nathan Harold0b9adf12016-09-08 19:36:46 -0700159 if file_write_required:
Yang Liu19159ee2016-01-14 11:09:28 -0800160 f = open(sim_card_file, 'w')
161 json.dump(simconf, f, indent=4, sort_keys=True)
162 f.close()
163 return True
164
165
Nathan Harold0b9adf12016-09-08 19:36:46 -0700166def dump_sims():
167 active_list = get_active_sim_list()
168 output_format = '{:32.32}{:20.20}{:12.12}{:10.10}'
169 if not active_list:
170 print('No active devices with sims!')
171 return False
Yang Liu19159ee2016-01-14 11:09:28 -0800172
Nathan Harold0b9adf12016-09-08 19:36:46 -0700173 print(output_format.format('ICCID', 'Android SN', 'Phone #', 'Carrier'))
174 for iccid in active_list.keys():
175 print(
176 output_format.format(
177 str(iccid), str(active_list[iccid]['droid_serial']), str(
178 active_list[iccid]['phone_num']), str(active_list[iccid][
179 'operator'])))
180
181
182if __name__ == '__main__':
183
184 parser = argparse.ArgumentParser(description=(
185 'Script to generate, augment and prune'
186 ' SIM list'))
187 parser.add_argument(
188 '-f',
189 '--file',
190 default='./simcard_list.json',
191 help='json file path',
192 type=str)
Yang Liu19159ee2016-01-14 11:09:28 -0800193 group = parser.add_mutually_exclusive_group()
Nathan Harold0b9adf12016-09-08 19:36:46 -0700194 group.add_argument(
195 '-a',
196 '--append',
197 help='(default) Append to the list of SIM entries',
198 action='store_true')
199 group.add_argument(
200 '-p',
201 '--prune',
202 help='Prune the list of SIM entries',
203 action='store_true')
204 group.add_argument(
205 '-d',
206 '--dump',
207 help='Dump a list of SIMs from devices',
208 action='store_true')
Yang Liu19159ee2016-01-14 11:09:28 -0800209
210 args = parser.parse_args()
211
Nathan Harold0b9adf12016-09-08 19:36:46 -0700212 if args.prune:
213 prune_sims(args.file)
214 elif args.dump:
215 dump_sims()
216 # implies either no arguments or a && !p
217 elif not args.prune and not args.dump:
218 add_sims(args.file)
Yang Liu19159ee2016-01-14 11:09:28 -0800219"""
220Usage Examples
221
222----------------------------------------------------------------
223p3 manage_sim.py -h
224usage: manage_sim.py [-h] [-f F] [-a | -p]
225
226Script to generate, augment and prune SIM list
227
228optional arguments:
229 -h, --help show this help message and exit
230 -f F, --file F name for json file
231 -a append to the list of SIM entries
Nathan Harold0b9adf12016-09-08 19:36:46 -0700232 -d dump a list of SIMs from all devices
Yang Liu19159ee2016-01-14 11:09:28 -0800233 -p prune the list of SIM entries
234
235----------------------------------------------------------------
236p3 manage_sim.py -f ./simcard_list.json -p
237 OR
238p3 manage_sim.py -p
239
240Namespace(a=False, f='./simcard_list.json', p=True)
241add_sims: 8901260222780922759
242Please manually add a phone number for 8901260222780922759
243
244active phones: 1
245 ['8901260222780922759']
246Deleting the SIM entry: 89148000001280331488
247:
248:
249Deleting the SIM entry: 89014103277559059196
250
251----------------------------------------------------------------
252p3 manage_sim.py -f ./simcard_list.json -a
253 OR
254p3 manage_sim.py -a
255
256Namespace(a=True, f='./simcard_list.json', p=False)
257add_sims: 8901260222780922759
258Please manually add a phone number for 8901260222780922759
259
260----------------------------------------------------------------
261"""