Sylvain Munaut | 487d018 | 2010-12-26 21:31:24 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | # |
| 4 | # Utility to write the cards |
| 5 | # |
| 6 | # |
| 7 | # Copyright (C) 2009 Sylvain Munaut <tnt@246tNt.com> |
| 8 | # Copyright (C) 2010 Harald Welte <laforge@gnumonks.org> |
| 9 | # |
| 10 | # This program is free software: you can redistribute it and/or modify |
| 11 | # it under the terms of the GNU General Public License as published by |
| 12 | # the Free Software Foundation, either version 2 of the License, or |
| 13 | # (at your option) any later version. |
| 14 | # |
| 15 | # This program is distributed in the hope that it will be useful, |
| 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | # GNU General Public License for more details. |
| 19 | # |
| 20 | # You should have received a copy of the GNU General Public License |
| 21 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 22 | # |
| 23 | |
| 24 | from optparse import OptionParser |
| 25 | |
| 26 | from pySim.commands import SimCardCommands |
| 27 | from pySim.cards import _cards_classes |
| 28 | |
| 29 | |
| 30 | |
| 31 | def card_detect(opts, scc): |
| 32 | |
| 33 | # Detect type if needed |
| 34 | card = None |
| 35 | ctypes = dict([(kls.name, kls) for kls in _cards_classes]) |
| 36 | |
| 37 | if opts.type in ("auto", "auto_once"): |
| 38 | for kls in _cards_classes: |
| 39 | card = kls.autodetect(scc) |
| 40 | if card: |
| 41 | print "Autodetected card type %s" % card.name |
| 42 | card.reset() |
| 43 | break |
| 44 | |
| 45 | if card is None: |
| 46 | print "Autodetection failed" |
| 47 | return |
| 48 | |
| 49 | if opts.type == "auto_once": |
| 50 | opts.type = card.name |
| 51 | |
| 52 | elif opts.type in ctypes: |
| 53 | card = ctypes[opts.type](scc) |
| 54 | |
| 55 | else: |
| 56 | raise ValueError("Unknown card type %s" % opts.type) |
| 57 | |
| 58 | return card |
| 59 | |
| 60 | |
| 61 | # |
| 62 | # Main |
| 63 | # |
| 64 | |
| 65 | def parse_options(): |
| 66 | |
| 67 | parser = OptionParser(usage="usage: %prog [options]") |
| 68 | |
| 69 | # Card interface |
| 70 | parser.add_option("-d", "--device", dest="device", metavar="DEV", |
| 71 | help="Serial Device for SIM access [default: %default]", |
| 72 | default="/dev/ttyUSB0", |
| 73 | ) |
| 74 | parser.add_option("-b", "--baud", dest="baudrate", type="int", metavar="BAUD", |
| 75 | help="Baudrate used for SIM access [default: %default]", |
| 76 | default=9600, |
| 77 | ) |
| 78 | parser.add_option("-p", "--pcsc-device", dest="pcsc_dev", type='int', metavar="PCSC", |
| 79 | help="Which PC/SC reader number for SIM access", |
| 80 | default=None, |
| 81 | ) |
| 82 | parser.add_option("-t", "--type", dest="type", |
| 83 | help="Card type (user -t list to view) [default: %default]", |
| 84 | default="auto", |
| 85 | ) |
| 86 | |
| 87 | (options, args) = parser.parse_args() |
| 88 | |
| 89 | if options.type == 'list': |
| 90 | for kls in _cards_classes: |
| 91 | print kls.name |
| 92 | sys.exit(0) |
| 93 | |
| 94 | if args: |
| 95 | parser.error("Extraneous arguments") |
| 96 | |
| 97 | return options |
| 98 | |
| 99 | |
| 100 | def main(): |
| 101 | |
| 102 | # Parse options |
| 103 | opts = parse_options() |
| 104 | |
| 105 | # Connect to the card |
| 106 | if opts.pcsc_dev is None: |
| 107 | from pySim.transport.serial import SerialSimLink |
| 108 | sl = SerialSimLink(device=opts.device, baudrate=opts.baudrate) |
| 109 | else: |
| 110 | from pySim.transport.pcsc import PcscSimLink |
| 111 | sl = PcscSimLink(opts.pcsc_dev) |
| 112 | |
| 113 | # Create command layer |
| 114 | scc = SimCardCommands(transport=sl) |
| 115 | |
| 116 | # Iterate |
| 117 | done = False |
| 118 | first = True |
| 119 | card = None |
| 120 | |
| 121 | while not done: |
| 122 | # Connect transport |
| 123 | print "Insert card now (or CTRL-C to cancel)" |
| 124 | sl.wait_for_card(newcardonly=not first) |
| 125 | |
| 126 | # Not the first anymore ! |
| 127 | first = False |
| 128 | |
| 129 | # Get card |
| 130 | card = card_detect(opts, scc) |
| 131 | if card is None: |
| 132 | if opts.batch_mode: |
| 133 | first = False |
| 134 | continue |
| 135 | else: |
| 136 | sys.exit(-1) |
| 137 | |
| 138 | # Check type |
| 139 | if card.name != 'fakemagicsim': |
| 140 | print "Can't fix this type of card ..." |
| 141 | continue |
| 142 | |
| 143 | # Fix record |
| 144 | data, sw = scc.read_record(['000c'], 1) |
| 145 | data_new = data[0:100] + 'fffffffffffffffffffffffffdffffffffffffffffffffffff0791947106004034ffffffffffffff' |
| 146 | scc.update_record(['000c'], 1, data_new) |
| 147 | |
| 148 | # Done for this card and maybe for everything ? |
| 149 | print "Card should be fixed now !\n" |
| 150 | |
| 151 | |
| 152 | if __name__ == '__main__': |
| 153 | main() |