5 Commits

Author SHA1 Message Date
Holger Hans Peter Freyther
44e4636755 re-program: Instead of specifying the IMSI, read it from the card. 2012-08-15 21:09:01 +02:00
Harald Welte
93315bd466 Introduce a '--dry-run' option to skip actual card access
This can be used for example to batch convert from CSV input to HLR
output without writing cards.
2012-08-15 15:26:30 +02:00
Harald Welte
69c2ce2525 read_params_csv: Make sure we don't end up in endless loop
as a side effect, the first line is now specified with '-j 0'
and not '-j 1'
2012-08-15 15:25:51 +02:00
Harald Welte
8b59a55488 pySim-prog: Add mode where it can re-generate a card from CSV
Rather than just having the capability of writing to CSV, it now
has the capability to (re)write a card based on data from the CSV:

./pySim-prog.py -S csv --read-csv /tmp/sim.csv -i 901701234567890

or in batch mode (from the first line onwards):

./pySim-prog.py -S csv --read-csv /tmp/sim.csv --batch -j 1
2012-08-13 20:19:09 +02:00
Harald Welte
1d5968cfcf split parameter writing for CSV and SQL into separate functions 2012-08-13 16:50:28 +02:00

View File

@@ -67,6 +67,12 @@ def parse_options():
default=False, default=False,
) )
parser.add_option("-S", "--source", dest="source",
help="Data Source[default: %default]",
default="cmdline",
)
# if mode is "cmdline"
parser.add_option("-n", "--name", dest="name", parser.add_option("-n", "--name", dest="name",
help="Operator name [default: %default]", help="Operator name [default: %default]",
default="Magic", default="Magic",
@@ -105,6 +111,9 @@ def parse_options():
parser.add_option("--op", dest="op", parser.add_option("--op", dest="op",
help="Set OP to derive OPC from OP and KI", help="Set OP to derive OPC from OP and KI",
) )
parser.add_option("--read-imsi", dest="read_imsi", action="store_true",
help="Read the IMSI from the CARD", default=False
)
parser.add_option("-z", "--secret", dest="secret", metavar="STR", parser.add_option("-z", "--secret", dest="secret", metavar="STR",
@@ -121,12 +130,20 @@ def parse_options():
help="Optional batch state file", help="Optional batch state file",
) )
# if mode is "csv"
parser.add_option("--read-csv", dest="read_csv", metavar="FILE",
help="Read parameters from CSV file rather than command line")
parser.add_option("--write-csv", dest="write_csv", metavar="FILE", parser.add_option("--write-csv", dest="write_csv", metavar="FILE",
help="Append generated parameters in CSV file", help="Append generated parameters in CSV file",
) )
parser.add_option("--write-hlr", dest="write_hlr", metavar="FILE", parser.add_option("--write-hlr", dest="write_hlr", metavar="FILE",
help="Append generated parameters to OpenBSC HLR sqlite3", help="Append generated parameters to OpenBSC HLR sqlite3",
) )
parser.add_option("--dry-run", dest="dry_run",
help="Perform a 'dry run', don't actually program the card",
default=False, action="store_true")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
@@ -135,6 +152,20 @@ def parse_options():
print kls.name print kls.name
sys.exit(0) sys.exit(0)
if options.source == 'csv':
if (options.imsi is None) and (options.batch_mode is False) and (options.read_imsi is False):
parser.error("CSV mode needs either an IMSI, --read-imsi or batch mode")
if options.read_csv is None:
parser.error("CSV mode requires a CSV input file")
elif options.source == 'cmdline':
if ((options.imsi is None) or (options.iccid is None)) and (options.num is None):
parser.error("If either IMSI or ICCID isn't specified, num is required")
else:
parser.error("Only `cmdline' and `csv' sources supported")
if (options.read_csv is not None) and (options.source != 'csv'):
parser.error("You cannot specify a CSV input file in source != csv")
if (options.batch_mode) and (options.num is None): if (options.batch_mode) and (options.num is None):
options.num = 0 options.num = 0
@@ -142,9 +173,6 @@ def parse_options():
if (options.imsi is not None) or (options.iccid is not None): if (options.imsi is not None) or (options.iccid is not None):
parser.error("Can't give ICCID/IMSI for batch mode, need to use automatic parameters ! see --num and --secret for more informations") parser.error("Can't give ICCID/IMSI for batch mode, need to use automatic parameters ! see --num and --secret for more informations")
if ((options.imsi is None) or (options.iccid is None)) and (options.num is None):
parser.error("If either IMSI or ICCID isn't specified, num is required")
if args: if args:
parser.error("Extraneous arguments") parser.error("Extraneous arguments")
@@ -362,8 +390,8 @@ def print_parameters(params):
""" % params """ % params
def write_parameters(opts, params): def write_params_csv(opts, params):
# CSV # csv
if opts.write_csv: if opts.write_csv:
import csv import csv
row = ['name', 'iccid', 'mcc', 'mnc', 'imsi', 'smsp', 'ki', 'opc'] row = ['name', 'iccid', 'mcc', 'mnc', 'imsi', 'smsp', 'ki', 'opc']
@@ -372,6 +400,34 @@ def write_parameters(opts, params):
cw.writerow([params[x] for x in row]) cw.writerow([params[x] for x in row])
f.close() f.close()
def _read_params_csv(opts, imsi):
import csv
row = ['name', 'iccid', 'mcc', 'mnc', 'imsi', 'smsp', 'ki', 'opc']
f = open(opts.read_csv, 'r')
cr = csv.DictReader(f, row)
i = 0
for row in cr:
if opts.num is not None and opts.read_imsi is False:
if opts.num == i:
f.close()
return row;
i += 1
if row['imsi'] == imsi:
f.close()
return row;
f.close()
return None
def read_params_csv(opts, imsi):
row = _read_params_csv(opts, imsi)
if row is not None:
row['mcc'] = int(row['mcc'])
row['mnc'] = int(row['mnc'])
return row
def write_params_hlr(opts, params):
# SQLite3 OpenBSC HLR # SQLite3 OpenBSC HLR
if opts.write_hlr: if opts.write_hlr:
import sqlite3 import sqlite3
@@ -385,7 +441,7 @@ def write_parameters(opts, params):
[ [
params['imsi'], params['imsi'],
params['name'], params['name'],
'9' + params['iccid'][-5:] '9' + params['iccid'][-5:-1]
], ],
) )
sub_id = c.lastrowid sub_id = c.lastrowid
@@ -402,6 +458,10 @@ def write_parameters(opts, params):
conn.commit() conn.commit()
conn.close() conn.close()
def write_parameters(opts, params):
write_params_csv(opts, params)
write_params_hlr(opts, params)
BATCH_STATE = [ 'name', 'country', 'mcc', 'mnc', 'smsp', 'secret', 'num' ] BATCH_STATE = [ 'name', 'country', 'mcc', 'mnc', 'smsp', 'secret', 'num' ]
BATCH_INCOMPATIBLE = ['iccid', 'imsi', 'ki'] BATCH_INCOMPATIBLE = ['iccid', 'imsi', 'ki']
@@ -499,35 +559,57 @@ if __name__ == '__main__':
card = None card = None
while not done: while not done:
# Connect transport
print "Insert card now (or CTRL-C to cancel)" if opts.dry_run is False:
sl.wait_for_card(newcardonly=not first) # Connect transport
print "Insert card now (or CTRL-C to cancel)"
sl.wait_for_card(newcardonly=not first)
# Not the first anymore ! # Not the first anymore !
first = False first = False
# Get card if opts.dry_run is False:
card = card_detect(opts, scc) # Get card
if card is None: card = card_detect(opts, scc)
if opts.batch_mode: if card is None:
first = False if opts.batch_mode:
continue first = False
else: continue
sys.exit(-1) else:
sys.exit(-1)
# Erase if requested # Erase if requested
if opts.erase: if opts.erase:
print "Formatting ..." print "Formatting ..."
card.erase() card.erase()
card.reset() card.reset()
# Generate parameters # Generate parameters
cp = gen_parameters(opts) if opts.source == 'cmdline':
cp = gen_parameters(opts)
elif opts.source == 'csv':
if opts.read_imsi:
if opts.dry_run:
# Connect transport
print "Insert card now (or CTRL-C to cancel)"
sl.wait_for_card(newcardonly=not first)
(res,_) = scc.read_binary(['3f00', '7f20', '6f07'])
imsi = swap_nibbles(res)[3:]
else:
imsi = opts.imsi
cp = read_params_csv(opts, imsi)
if cp is None:
print "Error reading parameters\n"
sys.exit(2)
print_parameters(cp) print_parameters(cp)
# Program the card if opts.dry_run is False:
print "Programming ..." # Program the card
card.program(cp) print "Programming ..."
if opts.dry_run is not True:
card.program(cp)
else:
print "Dry Run: NOT PROGRAMMING!"
# Write parameters permanently # Write parameters permanently
write_parameters(opts, cp) write_parameters(opts, cp)