#!/usr/bin/env python3.4
#
# Copyright 2016 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Basic script for managing a JSON "database" file of SIM cards.
It will look at the list of attached devices, and add their SIMs to a
database.
We expect to add much more functionality in the future.
"""
import argparse
import json
import acts.controllers.android_device as android_device
import acts.test_utils.tel.tel_defines as tel_defines
import acts.test_utils.tel.tel_lookup_tables as tel_lookup_tables
import acts.test_utils.tel.tel_test_utils as tel_test_utils
def get_active_sim_list(verbose_warnings=False):
""" Get a dictionary of active sims across phones
Args: verbose_warnings - print warnings as issues are encountered if True
Returns:
A dictionary with keys equivalent to the ICCIDs of each SIM containing
information about that SIM
"""
active_list = {}
droid_list = android_device.get_all_instances()
for droid_device in droid_list:
droid = droid_device.get_droid(False)
sub_info_list = droid.subscriptionGetActiveSubInfoList()
if not sub_info_list:
if verbose_warnings:
print('No Valid Sim in {} {}! SimState = {}'.format(
droid_device.model, droid_device.serial, droid.telephonyGetSimState()))
continue
for sub_info in sub_info_list:
print(sub_info)
iccid = sub_info['iccId']
if not sub_info['iccId']:
continue
active_list[iccid] = {}
current = active_list[iccid]
current['droid_serial'] = droid_device.serial
sub_id = sub_info['subscriptionId']
try:
plmn_id = droid.telephonyGetSimOperatorForSubscription(sub_id)
current[
'operator'] = tel_lookup_tables.operator_name_from_plmn_id(
plmn_id)
except KeyError:
if vebose_warnings:
print('Unknown Operator {}'.format(
droid.telephonyGetSimOperator()))
current['operator'] = ''
# TODO: add actual capability determination to replace the defaults
current['capability'] = ['voice', 'ims', 'volte', 'vt', 'sms',
'tethering', 'data']
phone_num = droid.telephonyGetLine1NumberForSubscription(sub_id)
if not phone_num:
if verbose_warnings:
print('Please manually add a phone number for {}\n'.format(
iccid))
current['phone_num'] = ''
else:
current['phone_num'] = tel_test_utils.phone_number_formatter(
phone_num, tel_defines.PHONE_NUMBER_STRING_FORMAT_11_DIGIT)
return active_list
def add_sims(sim_card_file=None):
if not sim_card_file:
print('Error: file name is None.')
return False
try:
f = open(sim_card_file, 'r')
simconf = json.load(f)
f.close()
except FileNotFoundError:
simconf = {}
active_sims = get_active_sim_list(True)
if not active_sims:
print('No active SIMs, exiting')
return False
file_write_required = False
for iccid in active_sims.keys():
# Add new entry if not exist
if iccid in simconf:
print('Declining to add a duplicate entry: {}'.format(iccid))
#TODO: Add support for "refreshing" an entry
continue
simconf[iccid] = {}
current = simconf[iccid]
file_write_required = True
current['operator'] = active_sims[iccid]['operator']
current['capability'] = active_sims[iccid]['capability']
current['phone_num'] = active_sims[iccid]['phone_num']
if file_write_required:
f = open(sim_card_file, 'w')
json.dump(simconf, f, indent=4, sort_keys=True)
f.close()
return True
def prune_sims(sim_card_file=None):
try:
f = open(sim_card_file, 'r')
simconf = json.load(f)
f.close()
except FileNotFoundError:
print('File {} not found.'.format(sim_card_file if sim_card_file else
'<UNSPECIFIED>'))
return False
simconf_list = list(simconf.keys())
active_list = get_active_sim_list().keys()
delete_list = list(set(simconf_list).difference(set(active_list)))
print('active phones: {}'.format(active_list))
file_write_required = False
if len(delete_list) > 0:
for sim in delete_list:
# prune
print('Deleting the SIM entry: ', sim)
del simconf[sim]
file_write_required = True
else:
print('No entries to prune')
if file_write_required:
f = open(sim_card_file, 'w')
json.dump(simconf, f, indent=4, sort_keys=True)
f.close()
return True
def dump_sims():
active_list = get_active_sim_list()
output_format = '{:32.32}{:20.20}{:12.12}{:10.10}'
if not active_list:
print('No active devices with sims!')
return False
print(output_format.format('ICCID', 'Android SN', 'Phone #', 'Carrier'))
for iccid in active_list.keys():
print(
output_format.format(
str(iccid), str(active_list[iccid]['droid_serial']), str(
active_list[iccid]['phone_num']), str(active_list[iccid][
'operator'])))
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=(
'Script to generate, augment and prune'
' SIM list'))
parser.add_argument(
'-f',
'--file',
default='./simcard_list.json',
help='json file path',
type=str)
group = parser.add_mutually_exclusive_group()
group.add_argument(
'-a',
'--append',
help='(default) Append to the list of SIM entries',
action='store_true')
group.add_argument(
'-p',
'--prune',
help='Prune the list of SIM entries',
action='store_true')
group.add_argument(
'-d',
'--dump',
help='Dump a list of SIMs from devices',
action='store_true')
args = parser.parse_args()
if args.prune:
prune_sims(args.file)
elif args.dump:
dump_sims()
# implies either no arguments or a && !p
elif not args.prune and not args.dump:
add_sims(args.file)
"""
Usage Examples
----------------------------------------------------------------
p3 manage_sim.py -h
usage: manage_sim.py [-h] [-f F] [-a | -p]
Script to generate, augment and prune SIM list
optional arguments:
-h, --help show this help message and exit
-f F, --file F name for json file
-a append to the list of SIM entries
-d dump a list of SIMs from all devices
-p prune the list of SIM entries
----------------------------------------------------------------
p3 manage_sim.py -f ./simcard_list.json -p
OR
p3 manage_sim.py -p
Namespace(a=False, f='./simcard_list.json', p=True)
add_sims: 8901260222780922759
Please manually add a phone number for 8901260222780922759
active phones: 1
['8901260222780922759']
Deleting the SIM entry: 89148000001280331488
:
:
Deleting the SIM entry: 89014103277559059196
----------------------------------------------------------------
p3 manage_sim.py -f ./simcard_list.json -a
OR
p3 manage_sim.py -a
Namespace(a=True, f='./simcard_list.json', p=False)
add_sims: 8901260222780922759
Please manually add a phone number for 8901260222780922759
----------------------------------------------------------------
"""