Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 benedikt93 1
#!/usr/bin/env python
2
#
3
#
171 farthen 4
#    Copyright 2010 TheSeven, benedikt93, Farthen
56 benedikt93 5
#
6
#
7
#    This file is part of emBIOS.
8
#
9
#    emBIOS is free software: you can redistribute it and/or
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
#
14
#    emBIOS is distributed in the hope that it will be useful,
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
#
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/>.
21
#
22
#
23
 
24
import sys
25
import struct
171 farthen 26
import usb.core
27
import libembiosdata
56 benedikt93 28
 
171 farthen 29
class Error(Exception):
30
    def __init__(self, value=None):
31
        self.value = value
32
    def __str__(self):
33
        if self.value != None:
34
            return repr(self.value)
56 benedikt93 35
 
171 farthen 36
class ArgumentError(Error):
37
    pass
56 benedikt93 38
 
171 farthen 39
class DeviceNotFoundError(Error):
40
    pass
56 benedikt93 41
 
171 farthen 42
class DeviceError(Error):
43
    pass
56 benedikt93 44
 
171 farthen 45
class SendError(Error):
46
    pass
56 benedikt93 47
 
171 farthen 48
class ReceiveError(Error):
49
    pass
56 benedikt93 50
 
51
 
171 farthen 52
class Bunch(dict):
56 benedikt93 53
    """
171 farthen 54
        This is a dict whose items can also be accessed with
55
        bunchinstance.something.
56 benedikt93 56
    """
171 farthen 57
    def __init__(self, **kw):
58
        dict.__init__(self, kw)
59
        self.__dict__ = self
56 benedikt93 60
 
171 farthen 61
    def __getstate__(self):
62
        return self
56 benedikt93 63
 
171 farthen 64
    def __setstate__(self, state):
65
        self.update(state)
66
        self.__dict__ = self
56 benedikt93 67
 
68
 
171 farthen 69
class Embios(object):
176 farthen 70
    """
71
        Class for all embios functions.
72
    """
171 farthen 73
    def __init__(self):
176 farthen 74
        self.lib = Lib()
75
        self.getpacketsizeinfo()
56 benedikt93 76
 
171 farthen 77
    @staticmethod
78
    def _alignsplit(addr, size, blksize, align):
177 farthen 79
        if size <= blksize: return (size, 0, 0)
171 farthen 80
        end = addr + size
81
        if addr & (align - 1):
82
            bodyaddr = (addr + min(size, blksize)) & ~(align - 1)
83
        else: bodyaddr = addr
84
        headsize = bodyaddr - addr
85
        if (size - headsize) & (align - 1):
86
            tailaddr = (end - min(end - bodyaddr, blksize) + align - 1) & ~(align - 1)
87
        else: tailaddr = end
88
        tailsize = end - tailaddr
89
        return (headsize, tailaddr - bodyaddr, tailsize)
56 benedikt93 90
 
178 farthen 91
    def _readmem(self, addr, size):
92
        """ Reads the memory from location 'addr' with size 'size'
93
            from the device.
94
        """
95
        resp = self.lib.monitorcommand(struct.pack("IIII", 4, addr, size, 0), "III%ds" % size, (None, None, None, "data"))
96
        return resp.data
97
 
98
    def _writemem(self, addr, data):
99
        """ Writes the data in 'data' to the location 'addr'
100
            in the memory of the device.
101
        """
102
        return self.lib.monitorcommand(struct.pack("IIII%ds" % len(data), 5, addr, len(data), 0, data), "III", (None, None, None))
103
 
104
    def _readdma(self, addr, size):
105
        """ Reads the memory from location 'addr' with size 'size'
106
            from the device. This uses DMA and the data in endpoint.
107
        """
108
        self.lib.monitorcommand(struct.pack("IIII", 6, addr, size, 0), "III", (None, None, None))
109
        return struct.unpack("%ds" % size, self.lib.dev.din(size))[0]
110
 
111
    def _writedma(self, addr, data):
112
        """ Writes the data in 'data' to the location 'addr'
113
            in the memory of the device. This uses DMA and the data out endpoint.
114
        """
115
        self.lib.monitorcommand(struct.pack("IIII", 7, addr, len(data), 0), "III", (None, None, None))
116
        return self.lib.dev.dout(data)
117
 
171 farthen 118
    def getversioninfo(self):
119
        """ This returns the emBIOS version and device information. """
120
        return self.lib.monitorcommand(struct.pack("IIII", 1, 0, 0, 0), "IBBBBI", ("revision", "majorv", "minorv", "patchv", "swtypeid", "hwtypeid"))
56 benedikt93 121
 
171 farthen 122
    def getpacketsizeinfo(self):
123
        """ This returns the emBIOS max packet size information.
124
            It also sets the properties of the device object accordingly.
125
        """
126
        resp = self.lib.monitorcommand(struct.pack("IIII", 1, 1, 0, 0), "HHII", ("coutmax", "cinmax", "doutmax", "dinmax"))
127
        self.lib.dev.packetsizelimit['cout'] = resp.coutmax
128
        self.lib.dev.packetsizelimit['cin'] = resp.cinmax
129
        self.lib.dev.packetsizelimit['din'] = resp.dinmax
130
        self.lib.dev.packetsizelimit['dout'] = resp.doutmax
131
        return resp
56 benedikt93 132
 
171 farthen 133
    def getusermemrange(self):
134
        """ This returns the memory range the user has access to. """
135
        return self.lib.monitorcommand(struct.pack("IIII", 1, 2, 0, 0), "III", ("lower", "upper", None))
56 benedikt93 136
 
171 farthen 137
    def reset(self, force=False):
138
        """ Reboot the device """
139
        if force:
140
            return self.lib.monitorcommand(struct.pack("IIII", 2, 0, 0, 0))
141
        else:
142
            return self.lib.monitorcommand(struct.pack("IIII", 2, 1, 0, 0), "III", (None, None, None))
56 benedikt93 143
 
171 farthen 144
    def poweroff(self, force=False):
145
        """ Powers the device off. """
146
        if force:
147
            return self.lib.monitorcommand(struct.pack("IIII", 3, 0, 0, 0))
148
        else:
149
            return self.lib.monitorcommand(struct.pack("IIII", 3, 1, 0, 0), "III", (None, None, None))
56 benedikt93 150
 
171 farthen 151
    def read(self, addr, size):
152
        """ Reads the memory from location 'addr' with size 'size'
153
            from the device. This cares about too long packages
154
            and decides whether to use DMA or not.
155
        """
176 farthen 156
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
171 farthen 157
        din_maxsize = self.lib.dev.packetsizelimit["din"]
158
        data = ""
159
        (headsize, bodysize, tailsize) = self._alignsplit(addr, size, cin_maxsize, 16)
160
        if headsize != 0:
178 farthen 161
            data += self._readmem(addr, headsize)
171 farthen 162
            addr += headsize
163
        while bodysize > 0:
164
            if bodysize >= 2 * cin_maxsize:
165
                readsize = min(bodysize, din_maxsize)
178 farthen 166
                data += self._readdma(addr, readsize)
171 farthen 167
            else:
168
                readsize = min(bodysize, cin_maxsize)
178 farthen 169
                data += self._readmem(addr, readsize)
171 farthen 170
            addr += readsize
171
            bodysize -= readsize
172
        if tailsize != 0:
178 farthen 173
            data += self._readmem(addr, tailsize)
171 farthen 174
        return data
56 benedikt93 175
 
171 farthen 176
    def write(self, addr, data):
177
        """ Writes the data in 'data' to the location 'addr'
178
            in the memory of the device. This cares about too long packages
179
            and decides whether to use DMA or not.
180
        """
176 farthen 181
        cout_maxsize = self.lib.dev.packetsizelimit["cout"] - self.lib.headersize
171 farthen 182
        dout_maxsize = self.lib.dev.packetsizelimit["dout"]
183
        (headsize, bodysize, tailsize) = self._alignsplit(addr, len(data), cout_maxsize, 16)
184
        offset = 0
185
        if headsize != 0:
178 farthen 186
            self._writemem(addr, data[offset:offset+headsize])
171 farthen 187
            offset += headsize
188
            addr += headsize
189
        while bodysize > 0:
190
            if bodysize >= 2 * cout_maxsize:
191
                writesize = min(bodysize, dout_maxsize)
178 farthen 192
                self._writedma(addr, data[offset:offset+writesize])
171 farthen 193
            else:
194
                writesize = min(bodysize, cout_maxsize)
178 farthen 195
                self._writemem(addr, data[offset:offset+writesize])
171 farthen 196
            offset += writesize
197
            addr += writesize
198
            bodysize -= writesize
199
        if tailsize != 0:
178 farthen 200
            self._writemem(addr, data[offset:offset+tailsize])
171 farthen 201
        return data
56 benedikt93 202
 
173 farthen 203
    def readstring(self, addr, maxlength = 256):
204
        """ Reads a zero terminated string from memory 
205
            Reads only a maximum of 'maxlength' chars.
206
        """
176 farthen 207
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
173 farthen 208
        string = ""
209
        while (len(string) < maxlength or maxlength < 0):
178 farthen 210
            data = self._readmem(addr, min(maxlength - len(string), cin_maxsize))
173 farthen 211
            length = data.find("\0")
212
            if length >= 0:
213
                string += data[:length]
214
                break
215
            else:
216
                string += data
217
            addr += cin_maxsize
218
        return string
219
 
171 farthen 220
    def i2cread(self, index, slaveaddr, startaddr, size):
221
        """ Reads data from an i2c slave """
176 farthen 222
        if size > 256 or size < 1:
223
            raise ValueError("Size must be a number between 1 and 256")
224
        if size == 256:
225
            size = 0
226
        resp = self.lib.monitorcommand(struct.pack("IBBBBII", 8, index, slaveaddr, startaddr, size, 0, 0), "III%ds" % size, (None, None, None, "data"))
227
        return resp.data
56 benedikt93 228
 
171 farthen 229
    def i2cwrite(self, index, slaveaddr, startaddr, data):
230
        """ Writes data to an i2c slave """
176 farthen 231
        size = len(data)
232
        if size > 256 or size < 1:
233
            raise ValueError("Size must be a number between 1 and 256")
234
        if size == 256:
235
            size = 0
236
        return self.lib.monitorcommand(struct.pack("IBBBBII%ds" % size, 9, index, slaveaddr, startaddr, size, 0, 0, data), "III" % size, (None, None, None))
56 benedikt93 237
 
176 farthen 238
    def usbcread(self):
239
        """ Reads one packet with the maximal cin size """
240
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
241
        resp = self.lib.monitorcommand(struct.pack("IIII", 10, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("validsize", "buffersize", "queuesize", "data"))
242
        resp.data = resp.data[:resp.validsize]
243
        resp.maxsize = cin_maxsize
244
        return resp
56 benedikt93 245
 
171 farthen 246
    def usbcwrite(self, data):
247
        """ Writes data to the USB console """
176 farthen 248
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
249
        size = len(data)
250
        while len(data) > 0:
251
            writesize = min(cin_maxsize, len(data))
252
            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 11, writesize, 0, 0, data[:writesize]), "III", ("validsize", "buffersize", "freesize"))
253
            data = data[resp.validsize:]
254
        return size
56 benedikt93 255
 
176 farthen 256
    def cread(self, bitmask=0x1):
257
        """ Reads one packet with the maximal cin size from the device consoles
171 farthen 258
            identified with the specified bitmask
259
        """
176 farthen 260
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
261
        resp = self.lib.monitorcommand(struct.pack("IIII", 14, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("size", None, None))
262
        resp.data = resp.data[size:]
263
        resp.maxsize = cin_maxsize
264
        return resp
56 benedikt93 265
 
176 farthen 266
    def cwrite(self, data, bitmask=0x1):
171 farthen 267
        """ Writes data to the device consoles 
268
            identified with the specified bitmask.
269
        """
176 farthen 270
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
271
        size = len(data)
272
        while len(data) > 0:
273
            writesize = min(cin_maxsize, len(data))
274
            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 13, writesize, 0, 0, data[:writesize]), "III", (None, None, None))
275
            data = data[writesize:]
276
        return size
56 benedikt93 277
 
171 farthen 278
    def cflush(self, bitmask):
279
        """ Flushes the consoles specified with 'bitmask' """
280
        return self.lib.monitorcommand(struct.pack("IIII", 14, bitmask, 0, 0), "III", (None, None, None))
56 benedikt93 281
 
173 farthen 282
    def getprocinfo(self):
171 farthen 283
        """ Gets current state of the scheduler """
176 farthen 284
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
173 farthen 285
        # Get the size
286
        schedulerstate = self.lockscheduler()
287
        resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None))
288
        tablesize = resp.tablesize
289
        size = tablesize
290
        structver = resp.structver
291
        offset = 0
292
        data = ""
293
        while size > 0:
294
            if size > cin_maxsize:
295
                readsize = cin_maxsize
296
            else:
297
                readsize = size
298
            resp = self.lib.monitorcommand(struct.pack("IIII", 15, offset, readsize, 0), "III%ds" % readsize, ("structver", "tablesize", None, "data"))
299
            data += resp.data
300
            offset += readsize
301
            size -= readsize
302
        self.lockscheduler(schedulerstate)
303
        threadstructsize = 120
304
        registersize = 32
305
        if len(data) % threadstructsize != 0:
306
            raise DeviceError("The thread struct is not a multiple of "+str(threadsturcsize)+"!")
307
        threadcount = len(data) / threadstructsize
308
        threads = []
309
        id = 0
310
        for thread in range(threadcount):
311
            offset = threadstructsize * thread
312
            threaddata = struct.unpack("<16IIIIIQIIIIIIIBBBB", data[offset:offset+threadstructsize])
313
            info = Bunch()
314
            info.id = id
315
            state = threaddata[17]
316
            info.state = libembiosdata.thread_state[state]
317
            if info.state == "THREAD_FREE":
318
                id += 1
319
                continue
320
            info.regs = Bunch()
321
            for register in range(16):
322
                info.regs["r"+str(register)] = threaddata[register]
323
            info.regs.cpsr = threaddata[16]
324
            info.nameptr = threaddata[18]
325
            if info.nameptr == 0:
326
                info.name = "Thread %d" % info.id
327
            else:
328
                info.name = self.readstring(info.nameptr)
329
            info.cputime_current = threaddata[19]
330
            info.cputime_total = threaddata[20]
331
            info.startusec = threaddata[21]
332
            info.queue_next_ptr = threaddata[22]
333
            info.timeout = threaddata[23]
334
            info.blocked_since = threaddata[24]
335
            info.blocked_by_ptr = threaddata[25]
336
            info.stackaddr = threaddata[26]
337
            info.err_no = threaddata[27]
338
            info.block_type = libembiosdata.thread_block[threaddata[28]]
339
            info.type = libembiosdata.thread_type[threaddata[29]]
340
            info.priority = threaddata[30]
341
            info.cpuload = threaddata[31]
342
            threads.append(info)
343
            id += 1
344
        return threads
56 benedikt93 345
 
173 farthen 346
    def lockscheduler(self, freeze=True):
171 farthen 347
        """ Freezes/Unfreezes the scheduler """
173 farthen 348
        resp = self.lib.monitorcommand(struct.pack("IIII", 16, 1 if freeze else 0, 0, 0), "III", ("before", None, None))
349
        return True if resp.before == 1 else False
67 benedikt93 350
 
173 farthen 351
    def unlockscheduler(self):
171 farthen 352
        """ Unfreezes the scheduler """
353
        return self.lib.monitorcommand(struct.pack("IIII", 16, 0, 0, 0), "III", ("before", None, None))
56 benedikt93 354
 
171 farthen 355
    def suspendthread(self, id, suspend=True):
356
        """ Suspends the thread with the specified id """
173 farthen 357
        resp = self.lib.monitorcommand(struct.pack("IIII", 17, 1 if suspend else 0, id, 0), "III", ("before", None, None))
358
        return True if resp.before == 1 else False
56 benedikt93 359
 
173 farthen 360
    def resumethread(self, id):
361
        """ Resumes the thread with the specified id """
171 farthen 362
        return self.lib.monitorcommand(struct.pack("IIII", 17, 0, id, 0), "III", ("before", None, None))
56 benedikt93 363
 
171 farthen 364
    def killthread(self, id):
365
        """ Kills the thread with the specified id """
366
        return self.lib.monitorcommand(struct.pack("IIII", 18, id, 0, 0), "III", ("before", None, None))
56 benedikt93 367
 
171 farthen 368
    def createthread(self, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state):
369
        """ Creates a thread with the specified attributes """
370
        if threadtype == "user":
371
            threadtype = 0
372
        elif threadtype == "system":
373
            threadtype = 1
374
        else:
176 farthen 375
            raise ValueError("Threadtype must be either 'system' or 'user'")
171 farthen 376
        if priority > 256 or priority < 0:
176 farthen 377
            raise ValueError("Priority must be a number between 0 and 256")
171 farthen 378
        if state == "ready":
379
            state = 0
380
        elif state == "suspended":
381
            state = 1
382
        else:
176 farthen 383
            raise ValueError("State must be either 'ready' or 'suspended'")
171 farthen 384
        resp = self.lib.monitorcommand(struct.pack("IIIIIIII", 19, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state), "III", (id, None, None))
385
        if resp.id < 0:
386
            raise DeviceError("The device returned the error code "+str(resp.id))
387
        return resp
56 benedikt93 388
 
172 farthen 389
    def flushcaches(self):
171 farthen 390
        """ Flushes the CPU instruction and data cache """
391
        return self.lib.monitorcommand(struct.pack("IIII", 20, 0, 0, 0), "III", (None, None, None))
56 benedikt93 392
 
172 farthen 393
    def execimage(self, addr):
171 farthen 394
        """ Runs the emBIOS app at 'addr' """
395
        return self.lib.monitorcommand(struct.pack("IIII", 21, addr, 0, 0), "III", ("excecimage", None, None))
56 benedikt93 396
 
171 farthen 397
    def bootflashread(self, memaddr, flashaddr, size):
398
        """ Copies the data in the bootflash at 'flashaddr' of the specified size
399
            to the memory at addr 'memaddr'
400
        """
174 farthen 401
        return self.lib.monitorcommand(struct.pack("IIII", 22, memaddr, flashaddr, size), "III", (None, None, None))
82 benedikt93 402
 
171 farthen 403
    def bootflashwrite(self, memaddr, flashaddr, size):
404
        """ Copies the data in the memory at 'memaddr' of the specified size
405
            to the boot flash at addr 'flashaddr'
406
        """
174 farthen 407
        return self.lib.monitorcommand(struct.pack("IIII", 23, memaddr, flashaddr, size), "III", (None, None, None))
56 benedikt93 408
 
171 farthen 409
    def execfirmware(self, addr):
410
        """ Executes the firmware at 'addr' and passes all control to it. """
411
        return self.lib.monitorcommand(struct.pack("IIII", 24, addr, 0, 0), "III", (None, None, None))
56 benedikt93 412
 
171 farthen 413
    def aesencrypt(self, addr, size, keyindex):
414
        """ Encrypts the buffer at 'addr' with the specified size
415
            with the hardware AES key index 'keyindex'
416
        """
417
        return self.lib.monitorcommand(struct.pack("IBBHII", 25, 1, 0, keyindex, addr, size), "III", (None, None, None))
82 benedikt93 418
 
171 farthen 419
    def aesdecrypt(self, addr, size, keyindex):
420
        """ Decrypts the buffer at 'addr' with the specified size
421
            with the hardware AES key index 'keyindex'
422
        """
423
        return self.lib.monitorcommand(struct.pack("IBBHII", 25, 0, 0, keyindex, addr, size), "III", (None, None, None))
82 benedikt93 424
 
171 farthen 425
    def hmac_sha1(self, addr, size, destination):
426
        """ Generates a HMAC-SHA1 hash of the buffer and saves it to 'destination' """
427
        return self.lib.monitorcommand(struct.pack("IIII", 26, addr, size, destination), "III", (None, None, None))
56 benedikt93 428
 
429
 
171 farthen 430
class Lib(object):
176 farthen 431
    def __init__(self):
171 farthen 432
        self.idVendor = 0xFFFF
433
        self.idProduct = 0xE000
176 farthen 434
 
435
        self.headersize = 0x10
436
 
437
        self.connect()
56 benedikt93 438
 
171 farthen 439
    def connect(self):
440
        self.dev = Dev(self.idVendor, self.idProduct)
441
        self.connected = True
56 benedikt93 442
 
171 farthen 443
    def monitorcommand(self, cmd, rcvdatatypes=None, rcvstruct=None):
444
        self.dev.cout(cmd)
445
        if rcvdatatypes:
446
            rcvdatatypes = "I" + rcvdatatypes # add the response
447
            data = self.dev.cin(struct.calcsize(rcvdatatypes))
448
            data = struct.unpack(rcvdatatypes, data)
449
            response = data[0]
450
            if libembiosdata.responsecodes[response] == "ok":
451
                if rcvstruct:
452
                    datadict = Bunch()
453
                    counter = 1 # start with 1, 0 is the id
454
                    for item in rcvstruct:
455
                        if item != None: # else the data is undefined
456
                            datadict[item] = data[counter]
457
                        counter += 1
458
                    return datadict
459
                else:
460
                    return data
461
            elif libembiosdata.responsecodes[response] == "unsupported":
462
                raise DeviceError("The device does not support this command.")
463
            elif libembiosdata.responsecodes[response] == "invalid":
464
                raise DeviceError("Invalid command! This should NOT happen!")
465
            elif libembiosdata.responsecodes[response] == "busy":
466
                raise DeviceError("Device busy")
56 benedikt93 467
 
468
 
171 farthen 469
class Dev(object):
470
    def __init__(self, idVendor, idProduct):
471
        self.idVendor = idVendor
472
        self.idProduct = idProduct
67 benedikt93 473
 
171 farthen 474
        self.interface = 0
475
        self.timeout = 100
176 farthen 476
 
171 farthen 477
        self.connect()
478
        self.findEndpoints()
479
 
480
        self.packetsizelimit = {}
481
        self.packetsizelimit['cout'] = None
482
        self.packetsizelimit['cin'] = None
483
        self.packetsizelimit['dout'] = None
484
        self.packetsizelimit['din'] = None
56 benedikt93 485
 
171 farthen 486
    def __del__(self):
487
        self.disconnect()
56 benedikt93 488
 
171 farthen 489
    def findEndpoints(self):
490
        epcounter = 0
491
        self.endpoint = {}
492
        for cfg in self.dev:
493
            for intf in cfg:
494
                for ep in intf:
495
                    if epcounter == 0:
496
                        self.endpoint['cout'] = ep.bEndpointAddress
497
                    elif epcounter == 1:
498
                        self.endpoint['cin'] = ep.bEndpointAddress
499
                    elif epcounter == 2:
500
                        self.endpoint['dout'] = ep.bEndpointAddress
501
                    elif epcounter == 3:
502
                        self.endpoint['din'] = ep.bEndpointAddress
503
                    epcounter += 1
504
        if epcounter <= 3:
505
            raise DeviceError("Not all endpoints found in the descriptor. Only "+str(epcounter)+" found, we need 4")
56 benedikt93 506
 
171 farthen 507
    def connect(self):
508
        self.dev = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
509
        if self.dev is None:
510
            raise DeviceNotFoundError()
511
        self.dev.set_configuration()
56 benedikt93 512
 
171 farthen 513
    def disconnect(self):
514
        pass
102 benedikt93 515
 
171 farthen 516
    def send(self, endpoint, data):
517
        size = self.dev.write(endpoint, data, self.interface, self.timeout)
518
        if size != len(data):
176 farthen 519
            raise SendError("Not all data was written!")
171 farthen 520
        return len
102 benedikt93 521
 
171 farthen 522
    def receive(self, endpoint, size):
523
        read = self.dev.read(endpoint, size, self.interface, self.timeout)
524
        if len(read) != size:
176 farthen 525
            raise ReceiveError("Requested size and read size don't match!")
171 farthen 526
        return read
56 benedikt93 527
 
171 farthen 528
    def cout(self, data):
529
        if self.packetsizelimit['cout'] and len(data) > self.packetsizelimit['cout']:
530
            raise SendError("Packet too big")
531
        return self.send(self.endpoint['cout'], data)
94 benedikt93 532
 
171 farthen 533
    def cin(self, size):
534
        if self.packetsizelimit['cin'] and size > self.packetsizelimit['cin']:
535
            raise ReceiveError("Packet too big")
536
        return self.receive(self.endpoint['cin'], size)
94 benedikt93 537
 
171 farthen 538
    def dout(self, data):
539
        if self.packetsizelimit['dout'] and len(data) > self.packetsizelimit['dout']:
540
            raise SendError("Packet too big")
541
        return self.send(self.endpoint['dout'], data)
94 benedikt93 542
 
171 farthen 543
    def din(self, size):
544
        if self.packetsizelimit['din'] and size > self.packetsizelimit['din']:
545
            raise ReceiveError("Packet too big")
546
        return self.receive(self.endpoint['din'], size)
56 benedikt93 547
 
96 benedikt93 548
 
171 farthen 549
if __name__ == "__main__":
550
    # Some tests
551
    import sys
552
    embios = Embios()
553
    resp = embios.getversioninfo()
554
    sys.stdout.write("Embios device version information: " + libembiosdata.swtypes[resp.swtypeid] + " v" + str(resp.majorv) + "." + str(resp.minorv) + 
555
                     "." + str(resp.patchv) + " r" + str(resp.revision) + " running on " + libembiosdata.hwtypes[resp.hwtypeid] + "\n")
556
    resp = embios.getusermemrange()
557
    sys.stdout.write("Usermemrange: "+hex(resp.lower)+" - "+hex(resp.upper)+"\n")
558
    memaddr = resp.lower
559
    maxlen = resp.upper - resp.lower
560
    f = open("./embios.py", "rb")
561
    sys.stdout.write("Loading test file (embios.py) to send over USB...\n")
562
    datastr = f.read()[:maxlen]
563
    sys.stdout.write("Sending data...\n")
564
    embios.write(memaddr, datastr)
565
    sys.stdout.write("Encrypting data with the hardware key...\n")
566
    embios.aesencrypt(memaddr, len(datastr), 0)
567
    sys.stdout.write("Reading data back and saving it to 'libembios-test-encrypted.bin'...\n")
568
    f = open("./libembios-test-encrypted.bin", "wb")
569
    f.write(embios.read(memaddr, len(datastr)))
570
    sys.stdout.write("Decrypting the data again...\n")
571
    embios.aesdecrypt(memaddr, len(datastr), 0)
572
    sys.stdout.write("Reading data back from device...\n")
573
    readdata = embios.read(memaddr, len(datastr))
574
    if readdata == datastr:
575
        sys.stdout.write("Data matches!")
576
    else:
577
        sys.stdout.write("Data does NOT match. Something got wrong")