Subversion Repositories freemyipod

Rev

Rev 174 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 174 Rev 176
Line 65... Line 65...
65
        self.update(state)
65
        self.update(state)
66
        self.__dict__ = self
66
        self.__dict__ = self
67
 
67
 
68
 
68
 
69
class Embios(object):
69
class Embios(object):
-
 
70
    """
-
 
71
        Class for all embios functions.
-
 
72
    """
70
    def __init__(self):
73
    def __init__(self):
71
        self.lib = Lib(self)
74
        self.lib = Lib()
-
 
75
        self.getpacketsizeinfo()
72
    
76
    
73
    @staticmethod
77
    @staticmethod
74
    def _alignsplit(addr, size, blksize, align):
78
    def _alignsplit(addr, size, blksize, align):
75
        end = addr + size
79
        end = addr + size
76
        if addr & (align - 1):
80
        if addr & (align - 1):
Line 119... Line 123...
119
    def read(self, addr, size):
123
    def read(self, addr, size):
120
        """ Reads the memory from location 'addr' with size 'size'
124
        """ Reads the memory from location 'addr' with size 'size'
121
            from the device. This cares about too long packages
125
            from the device. This cares about too long packages
122
            and decides whether to use DMA or not.
126
            and decides whether to use DMA or not.
123
        """
127
        """
124
        if not self.lib.connected:
-
 
125
            self.lib.connect()
-
 
126
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
128
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
127
        din_maxsize = self.lib.dev.packetsizelimit["din"]
129
        din_maxsize = self.lib.dev.packetsizelimit["din"]
128
        data = ""
130
        data = ""
129
        (headsize, bodysize, tailsize) = self._alignsplit(addr, size, cin_maxsize, 16)
131
        (headsize, bodysize, tailsize) = self._alignsplit(addr, size, cin_maxsize, 16)
130
        if headsize != 0:
132
        if headsize != 0:
131
            data += self.readmem(addr, headsize)
133
            data += self.readmem(addr, headsize)
Line 146... Line 148...
146
    def write(self, addr, data):
148
    def write(self, addr, data):
147
        """ Writes the data in 'data' to the location 'addr'
149
        """ Writes the data in 'data' to the location 'addr'
148
            in the memory of the device. This cares about too long packages
150
            in the memory of the device. This cares about too long packages
149
            and decides whether to use DMA or not.
151
            and decides whether to use DMA or not.
150
        """
152
        """
151
        if not self.lib.connected:
-
 
152
            self.lib.connect()
-
 
153
        cout_maxsize = self.lib.dev.packetsizelimit["cout"] - 0x10
153
        cout_maxsize = self.lib.dev.packetsizelimit["cout"] - self.lib.headersize
154
        dout_maxsize = self.lib.dev.packetsizelimit["dout"]
154
        dout_maxsize = self.lib.dev.packetsizelimit["dout"]
155
        (headsize, bodysize, tailsize) = self._alignsplit(addr, len(data), cout_maxsize, 16)
155
        (headsize, bodysize, tailsize) = self._alignsplit(addr, len(data), cout_maxsize, 16)
156
        offset = 0
156
        offset = 0
157
        if headsize != 0:
157
        if headsize != 0:
158
            self.writemem(addr, headsize)
158
            self.writemem(addr, headsize)
Line 201... Line 201...
201
    
201
    
202
    def readstring(self, addr, maxlength = 256):
202
    def readstring(self, addr, maxlength = 256):
203
        """ Reads a zero terminated string from memory 
203
        """ Reads a zero terminated string from memory 
204
            Reads only a maximum of 'maxlength' chars.
204
            Reads only a maximum of 'maxlength' chars.
205
        """
205
        """
206
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
206
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
207
        string = ""
207
        string = ""
208
        while (len(string) < maxlength or maxlength < 0):
208
        while (len(string) < maxlength or maxlength < 0):
209
            data = self.readmem(addr, min(maxlength - len(string), cin_maxsize))
209
            data = self.readmem(addr, min(maxlength - len(string), cin_maxsize))
210
            length = data.find("\0")
210
            length = data.find("\0")
211
            if length >= 0:
211
            if length >= 0:
Line 216... Line 216...
216
            addr += cin_maxsize
216
            addr += cin_maxsize
217
        return string
217
        return string
218
    
218
    
219
    def i2cread(self, index, slaveaddr, startaddr, size):
219
    def i2cread(self, index, slaveaddr, startaddr, size):
220
        """ Reads data from an i2c slave """
220
        """ Reads data from an i2c slave """
-
 
221
        if size > 256 or size < 1:
-
 
222
            raise ValueError("Size must be a number between 1 and 256")
-
 
223
        if size == 256:
-
 
224
            size = 0
-
 
225
        resp = self.lib.monitorcommand(struct.pack("IBBBBII", 8, index, slaveaddr, startaddr, size, 0, 0), "III%ds" % size, (None, None, None, "data"))
-
 
226
        return resp.data
221
    
227
    
222
    def i2cwrite(self, index, slaveaddr, startaddr, data):
228
    def i2cwrite(self, index, slaveaddr, startaddr, data):
223
        """ Writes data to an i2c slave """
229
        """ Writes data to an i2c slave """
-
 
230
        size = len(data)
-
 
231
        if size > 256 or size < 1:
-
 
232
            raise ValueError("Size must be a number between 1 and 256")
-
 
233
        if size == 256:
-
 
234
            size = 0
-
 
235
        return self.lib.monitorcommand(struct.pack("IBBBBII%ds" % size, 9, index, slaveaddr, startaddr, size, 0, 0, data), "III" % size, (None, None, None))
224
    
236
    
225
    def usbcread(self, size):
237
    def usbcread(self):
226
        """ Reads data with size 'size' from the USB console """
238
        """ Reads one packet with the maximal cin size """
-
 
239
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
-
 
240
        resp = self.lib.monitorcommand(struct.pack("IIII", 10, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("validsize", "buffersize", "queuesize", "data"))
-
 
241
        resp.data = resp.data[:resp.validsize]
-
 
242
        resp.maxsize = cin_maxsize
-
 
243
        return resp
227
    
244
    
228
    def usbcwrite(self, data):
245
    def usbcwrite(self, data):
229
        """ Writes data to the USB console """
246
        """ Writes data to the USB console """
-
 
247
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
-
 
248
        size = len(data)
-
 
249
        while len(data) > 0:
-
 
250
            writesize = min(cin_maxsize, len(data))
-
 
251
            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 11, writesize, 0, 0, data[:writesize]), "III", ("validsize", "buffersize", "freesize"))
-
 
252
            data = data[resp.validsize:]
-
 
253
        return size
230
    
254
    
231
    def cread(self, size, bitmask):
255
    def cread(self, bitmask=0x1):
232
        """ Reads data with the specified size from the device consoles
256
        """ Reads one packet with the maximal cin size from the device consoles
233
            identified with the specified bitmask
257
            identified with the specified bitmask
234
        """
258
        """
-
 
259
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
-
 
260
        resp = self.lib.monitorcommand(struct.pack("IIII", 14, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("size", None, None))
-
 
261
        resp.data = resp.data[size:]
-
 
262
        resp.maxsize = cin_maxsize
-
 
263
        return resp
235
 
264
 
236
    def cwrite(self, data):
265
    def cwrite(self, data, bitmask=0x1):
237
        """ Writes data to the device consoles 
266
        """ Writes data to the device consoles 
238
            identified with the specified bitmask.
267
            identified with the specified bitmask.
239
        """
268
        """
-
 
269
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
-
 
270
        size = len(data)
-
 
271
        while len(data) > 0:
-
 
272
            writesize = min(cin_maxsize, len(data))
-
 
273
            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 13, writesize, 0, 0, data[:writesize]), "III", (None, None, None))
-
 
274
            data = data[writesize:]
-
 
275
        return size
240
    
276
    
241
    def cflush(self, bitmask):
277
    def cflush(self, bitmask):
242
        """ Flushes the consoles specified with 'bitmask' """
278
        """ Flushes the consoles specified with 'bitmask' """
243
        return self.lib.monitorcommand(struct.pack("IIII", 14, bitmask, 0, 0), "III", (None, None, None))
279
        return self.lib.monitorcommand(struct.pack("IIII", 14, bitmask, 0, 0), "III", (None, None, None))
244
    
280
    
245
    def getprocinfo(self):
281
    def getprocinfo(self):
246
        """ Gets current state of the scheduler """
282
        """ Gets current state of the scheduler """
247
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
283
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
248
        # Get the size
284
        # Get the size
249
        schedulerstate = self.lockscheduler()
285
        schedulerstate = self.lockscheduler()
250
        resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None))
286
        resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None))
251
        tablesize = resp.tablesize
287
        tablesize = resp.tablesize
252
        size = tablesize
288
        size = tablesize
Line 336... Line 372...
336
        if threadtype == "user":
372
        if threadtype == "user":
337
            threadtype = 0
373
            threadtype = 0
338
        elif threadtype == "system":
374
        elif threadtype == "system":
339
            threadtype = 1
375
            threadtype = 1
340
        else:
376
        else:
341
            raise SyntaxError("Threadtype must be either 'system' or 'user'")
377
            raise ValueError("Threadtype must be either 'system' or 'user'")
342
        if priority > 256 or priority < 0:
378
        if priority > 256 or priority < 0:
343
            raise SyntaxError("Priority must be a number between 0 and 256")
379
            raise ValueError("Priority must be a number between 0 and 256")
344
        if state == "ready":
380
        if state == "ready":
345
            state = 0
381
            state = 0
346
        elif state == "suspended":
382
        elif state == "suspended":
347
            state = 1
383
            state = 1
348
        else:
384
        else:
349
            raise SyntaxError("State must be either 'ready' or 'suspended'")
385
            raise ValueError("State must be either 'ready' or 'suspended'")
350
        resp = self.lib.monitorcommand(struct.pack("IIIIIIII", 19, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state), "III", (id, None, None))
386
        resp = self.lib.monitorcommand(struct.pack("IIIIIIII", 19, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state), "III", (id, None, None))
351
        if resp.id < 0:
387
        if resp.id < 0:
352
            raise DeviceError("The device returned the error code "+str(resp.id))
388
            raise DeviceError("The device returned the error code "+str(resp.id))
353
        return resp
389
        return resp
354
    
390
    
Line 392... Line 428...
392
        """ Generates a HMAC-SHA1 hash of the buffer and saves it to 'destination' """
428
        """ Generates a HMAC-SHA1 hash of the buffer and saves it to 'destination' """
393
        return self.lib.monitorcommand(struct.pack("IIII", 26, addr, size, destination), "III", (None, None, None))
429
        return self.lib.monitorcommand(struct.pack("IIII", 26, addr, size, destination), "III", (None, None, None))
394
 
430
 
395
 
431
 
396
class Lib(object):
432
class Lib(object):
397
    def __init__(self, embios):
433
    def __init__(self):
398
        self.idVendor = 0xFFFF
434
        self.idVendor = 0xFFFF
399
        self.idProduct = 0xE000
435
        self.idProduct = 0xE000
400
 
436
        
401
        self.embios = embios
437
        self.headersize = 0x10
-
 
438
        
402
        self.connected = False
439
        self.connect()
403
    
440
    
404
    def connect(self):
441
    def connect(self):
405
        self.dev = Dev(self.idVendor, self.idProduct)
442
        self.dev = Dev(self.idVendor, self.idProduct)
406
        self.connected = True
443
        self.connected = True
407
        self.embios.getpacketsizeinfo()
-
 
408
    
444
    
409
    def monitorcommand(self, cmd, rcvdatatypes=None, rcvstruct=None):
445
    def monitorcommand(self, cmd, rcvdatatypes=None, rcvstruct=None):
410
        if not self.connected:
-
 
411
            self.connect()
-
 
412
        self.dev.cout(cmd)
446
        self.dev.cout(cmd)
413
        if rcvdatatypes:
447
        if rcvdatatypes:
414
            rcvdatatypes = "I" + rcvdatatypes # add the response
448
            rcvdatatypes = "I" + rcvdatatypes # add the response
415
            data = self.dev.cin(struct.calcsize(rcvdatatypes))
449
            data = self.dev.cin(struct.calcsize(rcvdatatypes))
416
            data = struct.unpack(rcvdatatypes, data)
450
            data = struct.unpack(rcvdatatypes, data)
Line 439... Line 473...
439
        self.idVendor = idVendor
473
        self.idVendor = idVendor
440
        self.idProduct = idProduct
474
        self.idProduct = idProduct
441
        
475
        
442
        self.interface = 0
476
        self.interface = 0
443
        self.timeout = 100
477
        self.timeout = 100
444
        
478
 
445
        self.connect()
479
        self.connect()
446
        self.findEndpoints()
480
        self.findEndpoints()
447
        
481
        
448
        self.packetsizelimit = {}
482
        self.packetsizelimit = {}
449
        self.packetsizelimit['cout'] = None
483
        self.packetsizelimit['cout'] = None
Line 482... Line 516...
482
        pass
516
        pass
483
    
517
    
484
    def send(self, endpoint, data):
518
    def send(self, endpoint, data):
485
        size = self.dev.write(endpoint, data, self.interface, self.timeout)
519
        size = self.dev.write(endpoint, data, self.interface, self.timeout)
486
        if size != len(data):
520
        if size != len(data):
487
            raise SendError
521
            raise SendError("Not all data was written!")
488
        return len
522
        return len
489
    
523
    
490
    def receive(self, endpoint, size):
524
    def receive(self, endpoint, size):
491
        read = self.dev.read(endpoint, size, self.interface, self.timeout)
525
        read = self.dev.read(endpoint, size, self.interface, self.timeout)
492
        if len(read) != size:
526
        if len(read) != size:
493
            raise ReceiveError
527
            raise ReceiveError("Requested size and read size don't match!")
494
        return read
528
        return read
495
    
529
    
496
    def cout(self, data):
530
    def cout(self, data):
497
        if self.packetsizelimit['cout'] and len(data) > self.packetsizelimit['cout']:
531
        if self.packetsizelimit['cout'] and len(data) > self.packetsizelimit['cout']:
498
            raise SendError("Packet too big")
532
            raise SendError("Packet too big")