Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
82 benedikt93 1
#!/usr/bin/env python
64 benedikt93 2
#
3
#
171 farthen 4
#    Copyright 2010 TheSeven, benedikt93, Farthen
64 benedikt93 5
#
6
#
82 benedikt93 7
#    This file is part of emBIOS.
64 benedikt93 8
#
82 benedikt93 9
#    emBIOS is free software: you can redistribute it and/or
64 benedikt93 10
#    modify it under the terms of the GNU General Public License as
11
#    published by the Free Software Foundation, either version 2 of the
12
#    License, or (at your option) any later version.
13
#
82 benedikt93 14
#    emBIOS is distributed in the hope that it will be useful,
64 benedikt93 15
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
#    See the GNU General Public License for more details.
18
#
82 benedikt93 19
#    You should have received a copy of the GNU General Public License
20
#    along with emBIOS.  If not, see <http://www.gnu.org/licenses/>.
64 benedikt93 21
#
22
#
23
 
171 farthen 24
import sys
25
import os
26
import inspect
27
import re
176 farthen 28
import time
64 benedikt93 29
 
176 farthen 30
from functools import wraps
31
 
64 benedikt93 32
import libembios
171 farthen 33
from libembios import Error
34
import libembiosdata
64 benedikt93 35
 
171 farthen 36
class NotImplementedError(Error):
37
    pass
64 benedikt93 38
 
171 farthen 39
class ArgumentError(Error):
40
    pass
64 benedikt93 41
 
171 farthen 42
class ArgumentTypeError(Error):
43
    def __init__(self, expected, seen=False):
44
        self.expected = expected
45
        self.seen = seen
46
    def __str__(self):
47
        if self.seen:
48
            return "Expected " + str(self.expected) + " but saw " + str(self.seen)
49
        else:
50
            return "Expected " + str(self.expected) + ", but saw something else"
64 benedikt93 51
 
52
 
171 farthen 53
def usage(errormsg=None, specific=False):
54
    """
55
        Prints the usage information.
56
        It is auto generated from various places.
57
    """
58
    logger = Logger()
59
    cmddict= Commandline.cmddict
60
    doc = {}
61
    # This sorts the output of various internal functions
62
    # and puts everything in easy readable form
63
    for function in cmddict:
64
        function = cmddict[function].func
65
        docinfo = {}
66
        name = function.__name__
67
        args = inspect.getargspec(function)[0]
68
        docinfo['varargs'] = False
69
        if inspect.getargspec(function)[1]:
70
            docinfo['varargs'] = True
71
        kwargvalues = inspect.getargspec(function)[3]
72
        kwargs = {}
73
        if args:
74
            if kwargvalues:
75
                argnum = len(args) - len(kwargvalues)
76
                kwargnum = len(kwargvalues)
77
                kwargs = dict(zip(args[argnum:], kwargvalues))
78
            else:
79
                argnum = len(args)
80
        else:
81
            argnum = 0
82
        docinfo['args'] = args[1:argnum]
83
        docinfo['kwargs'] = kwargs
84
        if function.__doc__:
85
            # strip unneccessary whitespace
86
            docinfo['documentation'] = re.sub(r'\n        ', '\n', function.__doc__)
87
        else:
88
            docinfo['documentation'] = None
89
        doc[name] = docinfo
64 benedikt93 90
 
171 farthen 91
    if not specific:
92
        logger.log("Please provide a command and (if needed) parameters as command line arguments\n\n")
93
        logger.log("Available commands:\n\n")
82 benedikt93 94
    else:
171 farthen 95
        logger.log("\n")
96
    for function in sorted(doc.items()):
97
        function = function[0]
98
        if specific == False or specific == function:
99
            logger.log("  " + function + " ")
100
            for arg in doc[function]['args']:
101
                logger.log("<" + arg + "> ")
102
            if doc[function]['kwargs']:
103
                for kwarg in doc[function]['kwargs']:
104
                    logger.log("[" + kwarg + "] ")
105
            if doc[function]['varargs']:
106
                logger.log("<db1> ... <dbN>")
107
            if doc[function]['documentation']:
108
                logger.log(doc[function]['documentation']+"\n")
64 benedikt93 109
 
171 farthen 110
    logger.log("\n")
111
 
112
    if errormsg:
113
        logger.error(str(errormsg)+"\n")
114
    exit(2)
115
 
116
 
117
class Logger(object):
118
    """
119
        Simple stdout logger.
120
        Loglevel 4 is most verbose, Loglevel 0 only say something if there is an error.
121
    """
122
    def __init__(self):
123
        # Possible values: 0 (only errors), 1 (warnings), 2 (info, recommended for production use), 3 and more (debug)
124
        self.loglevel = 3
125
 
126
    def log(self, text):
127
        sys.stdout.write(text)
67 benedikt93 128
 
171 farthen 129
    def debug(self, text):
130
        if self.loglevel >= 3:
131
            self.log(text)
119 benedikt93 132
 
171 farthen 133
    def info(self, text):
134
        if self.loglevel >= 2:
135
            self.log(text)
82 benedikt93 136
 
171 farthen 137
    def warning(self, text):
138
        if self.loglevel >= 1:
139
            self.log("WARNING: " + text)
119 benedikt93 140
 
171 farthen 141
    def error(self, text):
142
        self.log("ERROR: " + text)
143
 
144
 
145
def command(func):
146
    """
147
        Decorator for all commands.
148
        The decorated function is called with (self, all, other, arguments, ...)
149
    """
176 farthen 150
    @wraps(func)
172 farthen 151
    def decorator(*args):
171 farthen 152
        return func(args[0], *args[1:])
153
    func._command = True
154
    decorator.func = func
155
    return decorator
156
 
157
 
158
def commandClass(cls):
159
    """
160
        Decorator for the class. Sets the self.cmddict of the class
161
        to all functions decorated with @command
162
    """
163
    cls.cmddict = {}
164
    for attr, value in cls.__dict__.iteritems():
165
        if getattr(value, 'func', False):
166
            if getattr(value.func, '_command', False):
167
                cls.cmddict[value.func.__name__] = value
168
    return cls
169
 
170
 
171
@commandClass
172
class Commandline(object):
173
    """
174
        If you want to create a new commandline function you just need to
175
        create a function with the name of it in this class and decorate
176
        it with the decorator @command. If you don't want to call the desired
177
        function (wrong arguments etc) just raise ArgumentError with or
178
        without an error message or raise ArgumentCountError
179
    """
180
    def __init__(self):
181
        self.logger = Logger()
182
        try:
183
            self.embios = libembios.Embios()
184
        except libembios.DeviceNotFoundError:
185
            self.logger.error("No emBIOS device found!")
176 farthen 186
            exit(1)
187
        self.getinfo("version")
171 farthen 188
 
189
    def _parsecommand(self, func, args):
190
        # adds self to the commandline args.
191
        # this is needed because the functions need access to their class.
192
        args.insert(0, self)
193
        if func in self.cmddict:
194
            try:
172 farthen 195
                self.cmddict[func](*args)
171 farthen 196
            except ArgumentError, e:
176 farthen 197
                usage(e, specific=func)
171 farthen 198
            except ArgumentError:
176 farthen 199
                usage("Syntax Error in function '" + func + "'", specific=func)
171 farthen 200
            except ArgumentTypeError, e:
176 farthen 201
                usage(e, specific=func)
171 farthen 202
            except NotImplementedError:
203
                self.logger.error("This function is not implemented yet!")
204
            except libembios.DeviceError, e:
205
                self.logger.error(str(e))
176 farthen 206
            except ValueError:
207
                usage(specific=func)
171 farthen 208
            except TypeError, e:
209
                if str(e).split(" ", 1)[0] == func + "()":
210
                    self.logger.error(usage("Argument Error in '" + func + "': Wrong argument count", specific=func))
211
                else:
212
                    raise
176 farthen 213
            except libembios.usb.core.USBError:
214
                self.logger.error("Problem with USB connection.")
171 farthen 215
        else:
216
            usage("No such command")
67 benedikt93 217
 
171 farthen 218
    @staticmethod
219
    def _bool(something):
220
        """
221
            Converts quite everything into bool.
222
        """
223
        if type(something) == bool:
224
            return something
225
        elif type(something) == int or type(something) == long:
226
            return bool(something)
227
        elif type(something == str):
228
            truelist = ['true', '1', 't', 'y', 'yes']
229
            falselist = ['false', '0', 'f', 'n', 'no']
230
            if something.lower() in truelist:
231
                return True
232
            elif something.lower() in falselist:
233
                return False
234
        raise ArgumentTypeError("bool", "'"+str(something)+"'")
235
 
236
    @staticmethod
237
    def _hexint(something):
238
        """
239
            Converts quite everything to a hexadecimal represented integer.
240
            This works for default arguments too, because it returns
241
            None when it found that it got a NoneType object.
242
        """
243
        if type(something) == int or type(something) == long:
244
            return something
245
        elif type(something) == str:
246
            try:
247
                return int(something, 16)
248
            except ValueError:
249
                raise ArgumentTypeError("hexadecimal coded integer", "'"+str(something)+"'")
250
        elif type(something) == NoneType:
251
            return None
252
        else:
253
            raise ArgumentTypeError("hexadecimal coded integer", "'"+str(something)+"'")
254
 
255
    @staticmethod
256
    def _strcheck(string, values):
257
        if string in values:
258
            return string
259
        else:
260
            expected = ""
261
            for item in values:
262
                expected += "'" + item + "', "
263
            expected = expected[:-2]
264
            raise ArgumentTypeError("one out of " + expected, "'" + string + "'")
64 benedikt93 265
 
173 farthen 266
    @staticmethod
267
    def _hex(integer):
268
        return "0x%x" % integer
64 benedikt93 269
 
171 farthen 270
    @command
271
    def getinfo(self, infotype):
272
        """
273
            Get info on the running emBIOS.
274
            <infotype> may be either of 'version', 'packetsize', 'usermemrange'.
275
        """
276
        if infotype == "version":
277
            resp = self.embios.getversioninfo()
172 farthen 278
            self.logger.info("Connected to "+libembiosdata.swtypes[resp.swtypeid] + " v" + str(resp.majorv) + "." + str(resp.minorv) +
171 farthen 279
                             "." + str(resp.patchv) + " r" + str(resp.revision) + " running on " + libembiosdata.hwtypes[resp.hwtypeid] + "\n")
280
        elif infotype == "packetsize":
281
            resp = self.embios.getpacketsizeinfo()
282
            self.logger.info("Maximum packet sizes: "+str(resp))
283
        elif infotype == "usermemrange":
284
            resp = self.embios.getusermemrange()
173 farthen 285
            self.logger.info("The user memory range is "+self._hex(resp.lower)+" - "+self._hex(resp.upper-1))
171 farthen 286
        else:
287
            raise ArgumentTypeError("one out of 'version', 'packetsize', 'usermemrange'", infotype)
64 benedikt93 288
 
171 farthen 289
    @command
290
    def reset(self, force=False):
291
        """
292
            Resets the device"
293
            If <force> is 1, the reset will be forced, otherwise it will be gracefully,
294
            which may take some time.
295
        """
296
        force = self._bool(force)
297
        if force: self.logger.info("Resetting forcefully...\n")
298
        else: self.logger.info("Resetting...\n")
299
        self.embios.reset(force)
64 benedikt93 300
 
171 farthen 301
    @command
302
    def poweroff(self, force=False):
303
        """
304
            Powers the device off
305
            If <force> is 1, the poweroff will be forced, otherwise it will be gracefully,
306
            which may take some time.
307
        """
308
        force = self._bool(force)
309
        if force: self.logger.info("Resetting forcefully...\n")
310
        else: self.logger.info("Resetting...\n")
311
        self.embios.reset(force)
64 benedikt93 312
 
171 farthen 313
    @command
314
    def uploadfile(self, addr, filename):
315
        """
316
            Uploads a file to the device
317
            <offset>: the address to upload the file to
318
            <filename>: the path to the file
319
        """
320
        addr = self._hexint(addr)
321
        try:
322
            f = open(filename, 'rb')
323
        except IOError:
324
            raise ArgumentError("File not readable. Does it exist?")
173 farthen 325
        self.logger.info("Writing file '"+filename+"' to memory at "+self._hex(addr)+"...")
171 farthen 326
        with f:
327
            self.embios.write(addr, f.read())
328
        self.logger.info("done\n")
176 farthen 329
 
171 farthen 330
    @command
331
    def downloadfile(self, addr, size, filename):
332
        """
333
            Uploads a file to the device
334
            <offset>: the address to upload the file to
335
            <size>: the number of bytes to be read
336
            <filename>: the path to the file
337
        """
338
        addr = self._hexint(addr)
339
        size = self._hexint(size)
340
        try:
341
            f = open(filename, 'wb')
342
        except IOError:
343
            raise ArgumentError("Can not open file for write!")
173 farthen 344
        self.logger.info("Reading data from address "+self._hex(addr)+" with the size "+self._hex(size)+" to '"+filename+"'...")
171 farthen 345
        with f:
346
            f.write(self.embios.read(addr, size))
347
        self.logger.info("done\n")
348
 
349
    @command
350
    def uploadint(self, addr, integer):
351
        """
352
            Uploads a single integer to the device
353
            <offset>: the address to upload the integer to
354
            <data>: the integer to upload
355
        """
356
        addr = self._hexint(addr)
357
        integer = self._hexint(integer)
358
        if integer > 0xFFFFFFFF:
359
            raise ArgumentError("Specified integer too long")
360
        data = chr(integer)
361
        self.embios.writemem(addr, data)
173 farthen 362
        self.logger.info("Integer '"+self._hex(integer)+"' written successfully to "+self._hex(addr))
171 farthen 363
 
364
    @command
365
    def downloadint(self, addr):
366
        """
367
            Downloads a single integer from the device and prints it to the console window
368
            <offset>: the address to download the integer from
369
        """
370
        addr = self._hexint(addr)
371
        data = self.embios.readmem(addr, 1)
372
        integer = ord(data)
173 farthen 373
        self.logger.info("Integer '"+self._hex(integer)+"' read from address "+self._hex(addr))
171 farthen 374
 
375
    @command
176 farthen 376
    def i2cread(self, bus, slave, addr, size):
171 farthen 377
        """
378
            Reads data from an I2C device
379
            <bus> the bus index
380
            <slave> the slave address
381
            <addr> the start address on the I2C device
382
            <size> the number of bytes to read
383
        """
384
        bus = self._hexint(bus)
385
        slave = self._hexint(slave)
386
        addr = self._hexint(addr)
387
        size = self._hexint(size)
176 farthen 388
        self.embios.i2cread(bus, slave, addr, size)
171 farthen 389
 
390
    @command
176 farthen 391
    def i2cwrite(self, bus, slave, addr, *args):
171 farthen 392
        """
393
            Writes data to an I2C device
394
            <bus> the bus index
395
            <slave> the slave address
396
            <addr> the start address on the I2C device
176 farthen 397
            <db1> ... <dbN> the data in single bytes, encoded in hex,
398
                seperated by whitespaces, eg. 37 56 45 12
171 farthen 399
        """
400
        bus = self._hexint(bus)
401
        slave = self._hexint(slave)
402
        addr = self._hexint(addr)
176 farthen 403
        data = ""
171 farthen 404
        for arg in args:
176 farthen 405
            data += chr(self._hexint(arg))
406
        self.embios.i2cwrite(bus, slave, addr, data)
171 farthen 407
 
408
    @command
176 farthen 409
    def console(self):
171 farthen 410
        """
176 farthen 411
            Reads data from the USB console continuously
171 farthen 412
        """
176 farthen 413
        while True:
414
            resp = self.embios.usbcread()
415
            self.logger.log(resp.data)
416
            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
171 farthen 417
 
418
    @command
176 farthen 419
    def writeusbconsole(self, *args):
171 farthen 420
        """
176 farthen 421
            Writes the string <db1> ... <dbN> to the USB console.
171 farthen 422
        """
176 farthen 423
        text = ""
424
        for word in args:
425
            text += word + " "
426
        text = text[:-1]
427
        self.logger.info("Writing '"+text+"' to the usb console\n")
428
        self.embios.usbcwrite(text)
171 farthen 429
 
430
    @command
176 farthen 431
    def readdevconsole(self, bitmask):
171 farthen 432
        """
176 farthen 433
            Reads data continuously from one or more of the device's consoles.
434
            <bitmask>: the bitmask of the consoles to read from.
171 farthen 435
        """
436
        bitmask = self._hexint(bitmask)
176 farthen 437
        while True:
438
            resp = self.embios.cread()
439
            self.logger.log(resp.data)
440
            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
441
 
171 farthen 442
    @command
176 farthen 443
    def writedevconsole(self, bitmask, *args):
171 farthen 444
        """
176 farthen 445
            Writes the string <db1> ... <dbN> to one or more of the device's consoles.
446
            <bitmask>: the bitmask of the consoles to write to
171 farthen 447
        """
448
        bitmask = self._hexint(bitmask)
176 farthen 449
        text = ""
450
        for word in args:
451
            text += word + " "
452
        text = text[:-1]
453
        self.logger.info("Writing '"+text+"' to the device consoles identified with "+self._hex(bitmask)+"\n")
454
        self.embios.cwrite(text, bitmask)
171 farthen 455
 
456
    @command
457
    def flushconsolebuffers(self, bitmask):
458
        """
459
            flushes one or more of the device consoles' buffers.
460
            <bitmask>: the bitmask of the consoles to be flushed
461
        """
462
        bitmask = self._hexint(bitmask)
463
        raise NotImplementedError
464
 
465
    @command
466
    def getprocinfo(self):
467
        """
468
            Fetches data on the currently running processes
469
        """
173 farthen 470
        import datetime
471
        threads = self.embios.getprocinfo()
472
        self.logger.info("The device has "+str(len(threads))+" running threads:\n\n")
473
        for thread in threads:
474
            self.logger.info("  "+thread.name+":\n")
475
            self.logger.info("    Thread id: "+str(thread.id)+"\n")
476
            self.logger.info("    Thread type: "+thread.type+"\n")
477
            self.logger.info("    Thread state: "+thread.state+"\n")
478
            self.logger.info("    Priority: "+str(thread.priority)+"/256\n")
479
            self.logger.info("    CPU time (total): "+str(datetime.timedelta(microseconds=thread.cputime_total))+"\n")
480
            self.logger.info("    Stack address: "+self._hex(thread.stackaddr)+"\n")
481
            self.logger.info("    Registers:\n")
177 farthen 482
            for registerrange in range(4):
483
                self.logger.info("      ")
484
                for register in range(registerrange, 16, 4):
485
                    registerrepr = "r"+str(register)
486
                    self.logger.info("{:3s}: 0x{:08X}    ".format(registerrepr, thread.regs["r"+str(register)]))
487
                self.logger.info("\n")
488
            self.logger.info("      cpsr: 0x{:08X}".format(thread.regs.cpsr))
173 farthen 489
            self.logger.info("\n")
490
 
171 farthen 491
    @command
492
    def lockscheduler(self):
493
        """
494
            Locks (freezes) the scheduler
495
        """
176 farthen 496
        self.logger.info("Will now lock scheduler\n")
173 farthen 497
        self.embios.lockscheduler()
171 farthen 498
 
499
    @command
500
    def unlockscheduler(self):
501
        """
502
            Unlocks (unfreezes) the scheduler
503
        """
176 farthen 504
        self.logger.info("Will now unlock scheduler\n")
173 farthen 505
        self.embios.unlockscheduler()
171 farthen 506
 
507
    @command
508
    def suspendthread(self, threadid):
509
        """
510
            Suspends/resumes the thread with thread ID <threadid>
511
        """
512
        threadid = self._hexint(threadid)
173 farthen 513
        self.embios.resumethread(threadid)
171 farthen 514
 
515
    @command
516
    def resumethread(self, threadid):
517
        """
518
            Resumes the thread with thread ID <threadid>
519
        """
520
        threadid = self._hexint(threadid)
173 farthen 521
        self.embios.resumethread(threadid)
171 farthen 522
 
523
    @command
524
    def killthread(self, threadid):
525
        """
526
            Kills the thread with thread ID <threadid>
527
        """
528
        threadid = self._hexint(threadid)
173 farthen 529
        self.embios.killthread(threadid)
171 farthen 530
 
531
    @command
532
    def createthread(self, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state):
533
        """
534
            Creates a new thread and returns its thread ID
535
            <namepointer> a pointer to the thread's name
536
            <entrypoint> a pointer to the entrypoint of the thread
537
            <stackpointer> a pointer to the stack of the thread
538
            <stacksize> the size of the thread's stack
539
            <type> the thread type, vaild are: 0 => user thread, 1 => system thread
540
            <priority> the priority of the thread, from 1 to 255
541
            <state> the thread's initial state, valid are: 1 => ready, 0 => suspended
542
        """
543
        nameptr = self._hexint(nameptr)
544
        entrypoint = self._hexint(entrypoint)
545
        stackpointer = self._hexint(stackpointer)
546
        stacksize = self._hexint(stacksize)
547
        priority = self._hexint(priority)
548
        self.embios.createthread(nameptr, entrypoint, stackptr, stacksize, type, priority, state)
172 farthen 549
 
550
    @command
551
    def run(self, filename):
552
        """
173 farthen 553
            Uploads the emBIOS application <filename> to
554
            the beginning of the user memory and executes it
172 farthen 555
        """
176 farthen 556
        #self.execimage(addr)
557
        raise NotImplementedError
171 farthen 558
 
559
    @command
173 farthen 560
    def execimage(self, addr):
171 farthen 561
        """
173 farthen 562
            Executes the emBIOS application at <addr>.
171 farthen 563
        """
172 farthen 564
        addr = self._hexint(addr)
173 farthen 565
        self.logger.info("Starting emBIOS app at "+self._hex(addr)+"\n")
172 farthen 566
        self.embios.execimage(addr)
176 farthen 567
 
171 farthen 568
    @command
176 farthen 569
    def flushcaches(self):
171 farthen 570
        """
176 farthen 571
            Flushes the CPUs data and instruction caches.
572
        """
573
        self.logger.info("Flushing CPU data and instruction caches...")
574
        self.embios.flushcaches()
575
        self.logger.info("done\n")
576
 
577
    @command
578
    def readbootflash(self, addr_flash, addr_mem, size):
579
        """
171 farthen 580
            Reads <size> bytes from bootflash to memory.
581
            <addr_bootflsh>: the address in bootflash to read from
582
            <addr_mem>: the address in memory to copy the data to
583
        """
584
        addr_flash = self._hexint(addr_flash)
585
        addr_mem = self._hexint(addr_mem)
586
        size = self._hexint(size)
174 farthen 587
        self.logger.info("Dumping boot flash addresses "+self._hex(addr_flash)+" - "+
588
                         hex(addr_flash+size)+" to "+self._hex(addr_mem)+" - "+self._hex(addr_mem+size)+"\n")
589
        self.embios.bootflashread(addr_flash, addr_mem, size)
176 farthen 590
 
171 farthen 591
    @command
176 farthen 592
    def writebootflash(self, addr_flash, addr_mem, size, force=False):
171 farthen 593
        """
594
            Writes <size> bytes from memory to bootflash.
595
            ATTENTION: Don't call this unless you really know what you're doing!
596
            This may BRICK your device (unless it has a good recovery option)
597
            <addr_mem>: the address in memory to copy the data from
598
            <addr_bootflsh>: the address in bootflash to write to
174 farthen 599
            <force>: Use this flag to suppress the 5 seconds delay
171 farthen 600
        """
601
        addr_flash = self._hexint(addr_flash)
602
        addr_mem = self._hexint(addr_mem)
603
        size = self._hexint(size)
174 farthen 604
        force = self._bool(force)
605
        self.logger.info("Writing boot flash from the memory in "+self._hex(addr_mem)+" - "+
606
                         hex(addr_mem+size)+" to "+self._hex(addr_flash)+" - "+self._hex(addr_flash+size)+"\n")
607
        if force == False:
608
            self.logger.info("If this was not what you intended press Ctrl-C NOW")
176 farthen 609
            for i in range(10):
174 farthen 610
                self.logger.info(".")
611
                time.sleep(1)
612
            self.logger.info("\n")
613
        self.embios.bootflashwrite(addr_flash, addr_mem, size)
176 farthen 614
 
171 farthen 615
    @command
176 farthen 616
    def runfirmware(self, addr, filename):
171 farthen 617
        """
176 farthen 618
            Uploads the firmware in 'filename' to the beginning of the
619
            user memory and executes it
171 farthen 620
        """
176 farthen 621
        addr = self._hexint(addr)
622
        self.uploadfile(addr, filename)
623
        self.execfirmware(addr)
64 benedikt93 624
 
171 farthen 625
    @command
176 farthen 626
    def execfirmware(self, addr):
627
        """
628
            Executes the firmware at addr
629
        """
630
        addr = self._hexint(addr)
631
        self.logger.info("Running firmware at "+self._hex(addr)+". Bye.")
632
        self.embios.execfirmware(addr)
633
 
634
    @command
171 farthen 635
    def aesencrypt(self, addr, size, keyindex):
636
        """
172 farthen 637
            Encrypts a buffer using a hardware key
171 farthen 638
        """
639
        addr = self._hexint(addr)
640
        size = self._hexint(size)
641
        keyindex = self._hexint(keyindex)
642
        self.embios.aesencrypt(addr, size, keyindex)
82 benedikt93 643
 
171 farthen 644
    @command
645
    def aesdecrypt(self, addr, size, keyindex):
646
        """
172 farthen 647
            Decrypts a buffer using a hardware key
171 farthen 648
        """
649
        addr = self._hexint(addr)
650
        size = self._hexint(size)
651
        keyindex = self._hexint(keyindex)
652
        self.embios.aesdecrypt(addr, size, keyindex)
172 farthen 653
 
654
    @command
655
    def hmac_sha1(self, addr, size, destination):
656
        """
657
            Generates a HMAC-SHA1 hash of the buffer and saves it to 'destination'
658
        """
659
        addr = self._hexint(addr)
660
        size = self._hexint(size)
661
        destination = self._hexint(destination)
662
        sha1size = 0x14
173 farthen 663
        self.logger.info("Generating hmac-sha1 hash from the buffer at "+self._hex(addr)+" with the size "+self._hex(size)+
664
                         " and saving it to "+self._hex(destination)+" - "+self._hex(destination+sha1size)+"...")
172 farthen 665
        self.embios.hmac_sha1(addr, size, destination)
666
        self.logger.info("done\n")
667
        data = self.embios.readmem(destination, sha1size)
668
        hash = ord(data)
173 farthen 669
        self.logger.info("The generated hash is "+self._hex(hash))
64 benedikt93 670
 
171 farthen 671
if __name__ == "__main__":
672
    if len(sys.argv) < 2:
673
        usage("No command specified")
674
    interface = Commandline()
675
    interface._parsecommand(sys.argv[1], sys.argv[2:])