| Index: embios/trunk/tools/embios.py |
| — | — | @@ -1,25 +1,27 @@ |
| | 2 | +#!/usr/bin/env python
|
| 2 | 3 | #
|
| 3 | 4 | #
|
| 4 | | -# Copyright 2010 benedikt93, partially derived from TheSeven's ipod tools
|
| | 5 | +# Copyright 2010 TheSeven, benedikt93
|
| 5 | 6 | #
|
| 6 | 7 | #
|
| 7 | | -# This file is part of the freemyipod.org iPod tools.
|
| | 8 | +# This file is part of emBIOS.
|
| 8 | 9 | #
|
| 9 | | -# FreeMyIPods' emBIOS and related tools are free software: you can redistribute it and/or
|
| | 10 | +# emBIOS is free software: you can redistribute it and/or
|
| 10 | 11 | # modify it under the terms of the GNU General Public License as
|
| 11 | 12 | # published by the Free Software Foundation, either version 2 of the
|
| 12 | 13 | # License, or (at your option) any later version.
|
| 13 | 14 | #
|
| 14 | | -# FreeMyIPods' emBIOS and related tools are distributed in the hope that they will be useful,
|
| | 15 | +# emBIOS is distributed in the hope that it will be useful,
|
| 15 | 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 | 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 | 18 | # See the GNU General Public License for more details.
|
| 18 | 19 | #
|
| 19 | | -# You should have received a copy of the GNU General Public License along
|
| 20 | | -# with FreeMyIPods' emBIOS and related tools. If not, see <http://www.gnu.org/licenses/>.
|
| | 20 | +# You should have received a copy of the GNU General Public License
|
| | 21 | +# along with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | 22 | #
|
| 22 | 23 | #
|
| 23 | 24 |
|
| | 25 | +# note: handles commands 1 to 20
|
| 24 | 26 |
|
| 25 | 27 | import sys
|
| 26 | 28 | import time
|
| — | — | @@ -46,6 +48,38 @@ |
| 47 | 49 | print " If <force> is 1, the poweroff will be forced, otherwise it will be gracefully,"
|
| 48 | 50 | print " which may take some time."
|
| 49 | 51 | print ""
|
| | 52 | + print ""
|
| | 53 | + print " uploadfile <offset> <file> <usedma> <freezescheduler>"
|
| | 54 | + print " Uploads a file to the iPod"
|
| | 55 | + print " <offset>: the address to upload the file to"
|
| | 56 | + print " <file>: the path to the file"
|
| | 57 | + print " <usedma>: if 0, DMA will not be used when uploading the file,"
|
| | 58 | + print " otherwise it will be used. It can be omitted, default is then 1"
|
| | 59 | + print " <freezescheduler>: if not 0, the scheduler will be frozen during DMA access"
|
| | 60 | + print " to prevent non-consistent data after the transfer."
|
| | 61 | + print " It can be omitted, default is then 0"
|
| | 62 | + print ""
|
| | 63 | + print " downloadfile <offset> <size> <file> <usedma> <freezescheduler>"
|
| | 64 | + print " Uploads a file to the iPod"
|
| | 65 | + print " <offset>: the address to upload the file to"
|
| | 66 | + print " <size>: the number of bytes to be read"
|
| | 67 | + print " <file>: the path to the file"
|
| | 68 | + print " <usedma>: if 0, DMA will not be used when downloading the file,"
|
| | 69 | + print " otherwise it will be used. It can be omitted, default is then 1"
|
| | 70 | + print " <freezescheduler>: if not 0, the scheduler will be frozen during DMA access"
|
| | 71 | + print " to prevent non-consistent data after the transfer"
|
| | 72 | + print " It can be omitted, default is then 0"
|
| | 73 | + print ""
|
| | 74 | + print " uploadint <offset> <data>"
|
| | 75 | + print " Uploads a single integer to the iPod"
|
| | 76 | + print " <offset>: the address to upload the integer to"
|
| | 77 | + print " <data>: the integer to upload"
|
| | 78 | + print ""
|
| | 79 | + print " downloadint <offset>"
|
| | 80 | + print " Downloads a single integer from the iPod and prints it to the console window"
|
| | 81 | + print " <offset>: the address to download the integer from"
|
| | 82 | + print ""
|
| | 83 | + print ""
|
| 50 | 84 | print " i2crecv <bus> <slave> <addr> <size>"
|
| 51 | 85 | print " Reads data from an I2C device"
|
| 52 | 86 | print " <bus> the bus index"
|
| — | — | @@ -58,8 +92,49 @@ |
| 59 | 93 | print " <bus> the bus index"
|
| 60 | 94 | print " <slave> the slave address"
|
| 61 | 95 | print " <addr> the start address on the I2C device"
|
| 62 | | - print " <db1> ... <dbN> the data in single bytes, seperated by whitespaces, eg. 0x37 0x56 0x45 0x12"
|
| | 96 | + print " <db1> ... <dbN> the data in single bytes, seperated by whitespaces,"
|
| | 97 | + print " eg. 0x37 0x56 0x45 0x12"
|
| 63 | 98 | print ""
|
| | 99 | + print ""
|
| | 100 | + print " readusbconsole <size> <outtype> <file>"
|
| | 101 | + print " Reads data from the USB console."
|
| | 102 | + print " <size>: the number of bytes to read"
|
| | 103 | + print " <outtype>: defines how to output the result:"
|
| | 104 | + print " 'file': writes the result to file <file>"
|
| | 105 | + print " 'printstring': writes the result as string to the console window"
|
| | 106 | + print " 'printhex': writes the result in hexedit notation to the console window"
|
| | 107 | + print " <file>: the file to write the result to, can be omitted"
|
| | 108 | + print " if <outtype> is not 'file'"
|
| | 109 | + print ""
|
| | 110 | + print " writeusbconsole file <file> <offset> <length>"
|
| | 111 | + print " Writes the file <file> to the USB console."
|
| | 112 | + print " Optional params <offset> <length>: specify the range in <file> to write"
|
| | 113 | + print " writeusbconsole direct <i1> <i2> ... <iN>"
|
| | 114 | + print " Writes the integers <i1> ... <iN> to the USB console."
|
| | 115 | + print ""
|
| | 116 | + print " readdevconsole <bitmask> <size> <outtype> <file>"
|
| | 117 | + print " Reads data from one or more of the device's consoles."
|
| | 118 | + print " <bitmask>: the bitmask of the consoles to read from"
|
| | 119 | + print " <size>: the number of bytes to read"
|
| | 120 | + print " <outtype>: defines how to output the result:"
|
| | 121 | + print " 'file': writes the result to file <file>"
|
| | 122 | + print " 'printstring': writes the result as string to the console window"
|
| | 123 | + print " 'printhex': writes the result in hexedit notation to the console window"
|
| | 124 | + print " <file>: the file to write the result to, can be omitted"
|
| | 125 | + print " if <outtype> is not 'file'"
|
| | 126 | + print ""
|
| | 127 | + print " writedevconsole file <bitmask> <file> <offset> <length>"
|
| | 128 | + print " Writes the file <file> to the device consoles specified by <bitmask>"
|
| | 129 | + print " Optional params <offset> <length>: specify the range in <file> to write"
|
| | 130 | + print " writedevconsole direct <bitmask> <i1> <i2> ... <iN>"
|
| | 131 | + print " Writes the integers <i1> ... <iN> to the device consoles specified"
|
| | 132 | + print " by <bitmask>"
|
| | 133 | + print ""
|
| | 134 | + print " flushconsolebuffers <bitmask>"
|
| | 135 | + print " flushes one or more of the device consoles' buffers."
|
| | 136 | + print " <bitmask>: the bitmask of the consoles to be flushed"
|
| | 137 | + print ""
|
| | 138 | + print ""
|
| 64 | 139 | print " getprocessinformation <offset> <size> / getprocinfo <offset> <size>"
|
| 65 | 140 | print " Fetches data on the currently running processes"
|
| 66 | 141 | print " <offset> the offset in the data field"
|
| — | — | @@ -93,6 +168,7 @@ |
| 94 | 169 | print " <priority> the priority of the thread, from 1 to 255"
|
| 95 | 170 | print " <state> the thread's initial state, valid are: 1 => ready, 0 => suspended"
|
| 96 | 171 | print ""
|
| | 172 | + print ""
|
| 97 | 173 | print " flushcaches"
|
| 98 | 174 | print " Flushes the CPUs data and instruction caches."
|
| 99 | 175 | print ""
|
| — | — | @@ -115,6 +191,42 @@ |
| 116 | 192 | if len(argv) != 3: usage()
|
| 117 | 193 | dev.poweroff(int(argv[2]))
|
| 118 | 194 |
|
| | 195 | +
|
| | 196 | + elif argv[1] == "uploadfile":
|
| | 197 | + if len(argv) < 4 or len(argv) > 6: usage()
|
| | 198 | + if len(argv) > 4:
|
| | 199 | + usedma = argv[4]
|
| | 200 | + if len(argv) > 5:
|
| | 201 | + freezesched = argv[5]
|
| | 202 | + else:
|
| | 203 | + freezesched = 0
|
| | 204 | + else:
|
| | 205 | + freezesched = 0
|
| | 206 | + usedma = 1
|
| | 207 | + dev.uploadfile(int(argv[2]), argv[3], usedma, freezesched)
|
| | 208 | +
|
| | 209 | + elif argv[1] == "downloadfile":
|
| | 210 | + if len(argv) < 5 or len(argv) > 7: usage()
|
| | 211 | + if len(argv) > 5:
|
| | 212 | + usedma = argv[5]
|
| | 213 | + if len(argv) > 6:
|
| | 214 | + freezesched = argv[6]
|
| | 215 | + else:
|
| | 216 | + freezesched = 0
|
| | 217 | + else:
|
| | 218 | + freezesched = 0
|
| | 219 | + usedma = 1
|
| | 220 | + dev.downloadfile(int(argv[2]), int(argv[3]), argv[4], usedma, freezesched)
|
| | 221 | +
|
| | 222 | + elif argv[1] == "uploadint":
|
| | 223 | + if len(argv) != 4: usage()
|
| | 224 | + dev.uploadint(int(argv[2]), int(argv[3]))
|
| | 225 | +
|
| | 226 | + elif argv[1] == "downloadint":
|
| | 227 | + if len(argv) != 3: usage()
|
| | 228 | + dev.downloadint(int(argv[2]))
|
| | 229 | +
|
| | 230 | +
|
| 119 | 231 | elif argv[1] == "i2cread":
|
| 120 | 232 | if len(argv) != 6: usage()
|
| 121 | 233 | dev.i2crecv(int(argv[2]), int(argv[3]), int(argv[4]), int(argv[5]))
|
| — | — | @@ -127,7 +239,77 @@ |
| 128 | 240 | data += struct.pack("<B", int(argv[ptr]))
|
| 129 | 241 | ptr += 1
|
| 130 | 242 | dev.i2csend(int(argv[2]), int(argv[3]), int(argv[4]), data)
|
| | 243 | +
|
| | 244 | +
|
| | 245 | + elif argv[1] == "readusbconsole":
|
| | 246 | + if len(argv) not in [4, 5]: usage()
|
| | 247 | + if len(argv) == 4: argv[4] = ""
|
| | 248 | + dev.readusbcon(int(argv[2]), argv[3], argv[4])
|
| | 249 | +
|
| | 250 | + elif argv[1] == "writeusbconsole":
|
| | 251 | + if len(argv) < 4: usage()
|
| 131 | 252 |
|
| | 253 | + if argv[2] == "file":
|
| | 254 | + f = open(argv[3], "rb")
|
| | 255 | + data = f.read()
|
| | 256 | +
|
| | 257 | + if len(argv) > 4:
|
| | 258 | + offset = int(argv[4])
|
| | 259 | + else:
|
| | 260 | + offset = 0
|
| | 261 | + if len(argv) > 5:
|
| | 262 | + size = int(argv[5])
|
| | 263 | + else:
|
| | 264 | + size = len(data)
|
| | 265 | + if len(argv) > 6: usage()
|
| | 266 | +
|
| | 267 | + dev.writeusbcon(data, 0, offset, size)
|
| | 268 | +
|
| | 269 | + if argv[2] == "direct":
|
| | 270 | + data = ""
|
| | 271 | + ptr = 3
|
| | 272 | + while ptr < len(argv):
|
| | 273 | + data += struct.pack("<I", int(argv[ptr]))
|
| | 274 | + ptr += 1
|
| | 275 | + dev.writeusbcon(data)
|
| | 276 | +
|
| | 277 | + elif argv[1] == "readdevconsole":
|
| | 278 | + if len(argv) not in [5, 6]: usage()
|
| | 279 | + if len(argv) == 5: argv[5] = ""
|
| | 280 | + dev.readusbcon(int(argv[2]), int(argv[3]), argv[4], argv[5])
|
| | 281 | +
|
| | 282 | + elif argv[1] == "writedevconsole":
|
| | 283 | + if len(argv) < 5: usage()
|
| | 284 | +
|
| | 285 | + if argv[2] == "file":
|
| | 286 | + f = open(argv[4], "rb")
|
| | 287 | + data = f.read()
|
| | 288 | +
|
| | 289 | + if len(argv) > 5:
|
| | 290 | + offset = int(argv[5])
|
| | 291 | + else:
|
| | 292 | + offset = 0
|
| | 293 | + if len(argv) > 6:
|
| | 294 | + size = int(argv[6])
|
| | 295 | + else:
|
| | 296 | + size = len(data)
|
| | 297 | + if len(argv) > 7: usage()
|
| | 298 | +
|
| | 299 | + dev.writeusbcon(int(argv[3]), data, 0, offset, size)
|
| | 300 | +
|
| | 301 | + if argv[2] == "direct":
|
| | 302 | + data = ""
|
| | 303 | + ptr = 4
|
| | 304 | + while ptr < len(argv):
|
| | 305 | + data += struct.pack("<I", int(argv[ptr]))
|
| | 306 | + ptr += 1
|
| | 307 | + dev.writeusbcon(int(argv[3]), data)
|
| | 308 | +
|
| | 309 | + elif argv[1] == "flushconsolebuffers":
|
| | 310 | + if len(argv) != 3: usage()
|
| | 311 | + dev.flushconsolebuffers(int(argv[2]))
|
| | 312 | +
|
| | 313 | +
|
| 132 | 314 | elif argv[1] == "getprocessinformation" or argv[1] == "getprocinfo":
|
| 133 | 315 | if len(argv) != 4: usage()
|
| 134 | 316 | dev.getprocinfo(int(argv[2]), int(argv[3]))
|
| — | — | @@ -156,6 +338,7 @@ |
| 157 | 339 | if len(argv) != 9: usage()
|
| 158 | 340 | dev.createthread(int(argv[2]), int(argv[3]), int(argv[4]), int(argv[5]), int(argv[6]), int(argv[7]), int(argv[8]))
|
| 159 | 341 |
|
| | 342 | +
|
| 160 | 343 | elif argv[1] == "flushcaches":
|
| 161 | 344 | if len(argv) != 2: usage()
|
| 162 | 345 | dev.flushcaches()
|
| Index: embios/trunk/tools/libembios.py |
| — | — | @@ -21,7 +21,7 @@ |
| 22 | 22 | #
|
| 23 | 23 | #
|
| 24 | 24 |
|
| 25 | | -# note: handles commands 1,2,3,4,5,6,7,8,9,10,11, ,14,15,16,17,18,19,20
|
| | 25 | +# note: handles commands 1 to 20
|
| 26 | 26 |
|
| 27 | 27 | import sys
|
| 28 | 28 | import math
|
| — | — | @@ -59,7 +59,7 @@ |
| 60 | 60 | self.handle = handle
|
| 61 | 61 | self.dev = dev
|
| 62 | 62 |
|
| 63 | | - self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
|
| | 63 | + self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]
|
| 64 | 64 | self.__myprint("Connected to emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
|
| 65 | 65 | % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
|
| 66 | 66 | self.devtype2name(self.devtype), dev.deviceVersion))
|
| — | — | @@ -80,7 +80,7 @@ |
| 81 | 81 |
|
| 82 | 82 | @staticmethod
|
| 83 | 83 | def __myprint(data, silent = 0):
|
| 84 | | - if (silent == 0):
|
| | 84 | + if not silent:
|
| 85 | 85 | sys.stdout.write(data)
|
| 86 | 86 | sys.stdout.flush()
|
| 87 | 87 |
|
| — | — | @@ -157,7 +157,7 @@ |
| 158 | 158 |
|
| 159 | 159 | i = struct.unpack("<IIBBBBI", response)
|
| 160 | 160 |
|
| 161 | | - self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
|
| | 161 | + self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:]
|
| 162 | 162 |
|
| 163 | 163 | self.__myprint("emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
|
| 164 | 164 | % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
|
| — | — | @@ -459,7 +459,7 @@ |
| 460 | 460 |
|
| 461 | 461 | def readusbcon(self, size, outtype = "", file = "", silent = 0):
|
| 462 | 462 | """ reads from USB console
|
| 463 | | - <size>: number of bytes to be read, cannot be more than the Command In endpoint packet size - 0x10
|
| | 463 | + <size>: number of bytes to be read, if its length exceeds the Command In endpoint packet size - 0x10, it will be read in several steps
|
| 464 | 464 | <outtype>: how the data will be put out
|
| 465 | 465 | "file" => writes data to file <file>
|
| 466 | 466 | "printstring" => prints data as a string to the console window
|
| — | — | @@ -471,51 +471,67 @@ |
| 472 | 472 | [len, buffersize, datainbuffer, data]
|
| 473 | 473 | where len is the length of the data actually read,
|
| 474 | 474 | buffersize is the on-device read buffer size,
|
| 475 | | - datainbuffer is the number of bytes still left in the on_device buffer,
|
| | 475 | + datainbuffer is the number of bytes still left in the on device buffer,
|
| 476 | 476 | data is the actual data
|
| | 477 | +
|
| | 478 | + in case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur
|
| 477 | 479 | """
|
| 478 | | - if size > self.cin_maxsize - 0x10:
|
| 479 | | - size = self.cin_maxsize - 0x10
|
| | 480 | + out_data = ""
|
| | 481 | + readbytes = 0
|
| | 482 | + buffersize = 0
|
| | 483 | + bytesleft = 0
|
| | 484 | + timeoutcounter = 0
|
| 480 | 485 |
|
| 481 | 486 | self.__myprint("Reading 0x%x bytes from USB console..." % (size), silent)
|
| 482 | 487 |
|
| 483 | | - self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 10, size, 0, 0))
|
| 484 | | - response = self.__getbulk(self.handle, self.__cinep, size + 0x10)
|
| 485 | | - self.__checkstatus(response)
|
| | 488 | + while size > 0 and timoutcounter < 50:
|
| | 489 | + blocklen = size
|
| | 490 | +
|
| | 491 | + if size > self.cin_maxsize - 0x10:
|
| | 492 | + blocklen = self.cin_maxsize - 0x10
|
| | 493 | +
|
| | 494 | + self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 10, blocklen, 0, 0))
|
| | 495 | + response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
|
| | 496 | + self.__checkstatus(response)
|
| | 497 | +
|
| | 498 | + readbytes, buffersize, bytesleft = struct.unpack("<III", response[:12])
|
| | 499 | + out_data += response[0x10:0x10+readbytes]
|
| | 500 | + size -= blocklen
|
| | 501 | +
|
| | 502 | + if not bytesleft > 0: # no data left to read => wait a bit and prevent an infinite loop trying to read data when there is none
|
| | 503 | + timeoutcounter += 1
|
| | 504 | + time.sleep(0.1)
|
| | 505 | + else:
|
| | 506 | + timeoutcounter -= 3
|
| | 507 | + if timeoutcounter < 0:
|
| | 508 | + timeoutcounter = 0
|
| | 509 | +
|
| | 510 | + self.__myprint(" done\n", silent)
|
| | 511 | + self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
| | 512 | + % (len(out_data), buffersize, bytesleft)
|
| | 513 | + , silent)
|
| 486 | 514 |
|
| 487 | 515 | if (outtype == "file"):
|
| 488 | 516 | f = open(file, "wb")
|
| 489 | | - f.write(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]])
|
| | 517 | + f.write(out_data)
|
| 490 | 518 |
|
| 491 | 519 | elif (outtype == "printstring"):
|
| 492 | | - self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
| 493 | | - % (struct.unpack("<IIII", response[:0x10])[1],
|
| 494 | | - struct.unpack("<IIII", response[:0x10])[2],
|
| 495 | | - struct.unpack("<IIII", response[:0x10])[3])
|
| 496 | | - , silent)
|
| 497 | | - self.__myprint(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]], silent)
|
| | 520 | + self.__myprint(out_data, silent)
|
| 498 | 521 | self.__myprint("\n\n", silent)
|
| 499 | 522 |
|
| 500 | 523 | elif (outtype == "printhex"):
|
| 501 | | - self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
| 502 | | - % (struct.unpack("<IIII", response[:0x10])[1],
|
| 503 | | - struct.unpack("<IIII", response[:0x10])[2],
|
| 504 | | - struct.unpack("<IIII", response[:0x10])[3])
|
| 505 | | - , silent)
|
| 506 | | - self.__myprint(self.__gethexviewprintout(response[0x10:], "", 1), silent)
|
| | 524 | + self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)
|
| 507 | 525 | self.__myprint("\n\n", silent)
|
| 508 | 526 |
|
| 509 | 527 | elif (outtype == ""):
|
| 510 | 528 | pass # return only
|
| | 529 | +
|
| 511 | 530 | else:
|
| 512 | 531 | raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
|
| 513 | 532 |
|
| 514 | | - self.__myprint(" done\n", silent)
|
| | 533 | + return [len(out_data), buffersize, bytesleft, out_data]
|
| 515 | 534 |
|
| 516 | | - # header data
|
| 517 | | - return struct.unpack("<IIII", response[:0x10]).extend(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]])
|
| 518 | 535 |
|
| 519 | | -
|
| 520 | 536 | def writeusbcon(self, data, silent = 0, *range):
|
| 521 | 537 | """ writes to USB console
|
| 522 | 538 | <data>: the data to be written
|
| — | — | @@ -522,7 +538,7 @@ |
| 523 | 539 | <range>: the range in <data> that should be written, in the from [offset, length]
|
| 524 | 540 | <silent>: if 0, nothing will be written to the console window
|
| 525 | 541 |
|
| 526 | | - the data to be written can't exceed the Command Out endpoint packet size - 0x10
|
| | 542 | + if the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps
|
| 527 | 543 | """
|
| 528 | 544 | size = len(data)
|
| 529 | 545 | boffset = 0
|
| — | — | @@ -532,30 +548,143 @@ |
| 533 | 549 | if len(range) > 1:
|
| 534 | 550 | size = range[1]
|
| 535 | 551 |
|
| 536 | | - if size > self.cout_maxsize - 0x10:
|
| 537 | | - size = self.cout_maxsize - 0x10
|
| 538 | | -
|
| 539 | 552 | self.__myprint("Writing 0x%x bytes to USB console..." % (size), silent)
|
| 540 | 553 |
|
| 541 | 554 | timeoutcounter = 0
|
| 542 | 555 |
|
| 543 | | - while (size != 0) and (timeoutcounter < 10):
|
| 544 | | - self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 11, size, 0, 0) + data[boffset:boffset+size])
|
| | 556 | + while (size > 0) and (timeoutcounter < 50):
|
| | 557 | + blocklen = size
|
| | 558 | + if blocklen > self.cout_maxsize - 0x10:
|
| | 559 | + blocklen = self.cout_maxsize - 0x10
|
| | 560 | +
|
| | 561 | + self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 11, size, 0, 0) + data[boffset:boffset+blocklen])
|
| 545 | 562 | response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
| 546 | 563 | self.__checkstatus(response)
|
| 547 | 564 |
|
| 548 | | - size -= struct.unpack("<I", response[4:8])
|
| 549 | | - boffset += struct.unpack("<I", response[4:8])
|
| | 565 | + sendbytes = struct.unpack("<I", response[4:8])
|
| | 566 | + if sendbytes < blocklen: # not everything has been written, need to resent some stuff but wait a bit before doing so
|
| | 567 | + time.sleep(0.1)
|
| | 568 | + timeoutcounter += 1
|
| | 569 | + elif timeoutcounter > 0: # lower timeoutcounter again
|
| | 570 | + timeoutcounter -= 3
|
| | 571 | + if timeoutcounter < 0:
|
| | 572 | + timeoutcounter = 0
|
| 550 | 573 |
|
| 551 | | - time.sleep(0.1)
|
| 552 | | - timeoutcounter += 1
|
| | 574 | + size -= sendbytes
|
| | 575 | + boffset += sendbytes
|
| | 576 | +
|
| 553 | 577 |
|
| 554 | | - if (timeoutcounter >=10):
|
| 555 | | - raise Exception("0x%x couldn't be send.")
|
| | 578 | + if (timeoutcounter >=50):
|
| | 579 | + raise Exception("Timeout, 0x%x bytes couldn't be send." % size)
|
| 556 | 580 |
|
| 557 | 581 | self.__myprint(" done\n", silent)
|
| 558 | 582 |
|
| | 583 | + return size # number of bytes that have not been sent
|
| | 584 | +
|
| 559 | 585 |
|
| | 586 | + def readdevcon(self, bitmask, size, outtype = "", file = "", silent = 0):
|
| | 587 | + """ reads from one or more of the device's consoles
|
| | 588 | + <bitmask>: bitmask of consoles to be read from
|
| | 589 | + <size>: number of bytes to be read, if its length exceeds the Command In endpoint packet size - 0x10, it will be read in several steps
|
| | 590 | + <outtype>: how the data will be put out
|
| | 591 | + "file" => writes data to file <file>
|
| | 592 | + "printstring" => prints data as a string to the console window
|
| | 593 | + "printhex" => prints a hexview view of the data to the console window
|
| | 594 | + "" => only returns the data
|
| | 595 | + <silent>: if 0, nothing will be written to the console window (even if <outtype> defines something else)
|
| | 596 | +
|
| | 597 | + in every case, the data will be returned
|
| | 598 | +
|
| | 599 | + in case that within 5 secs, it's not possible to read <size> bytes, a timeout will occur
|
| | 600 | + """
|
| | 601 | + out_data = ""
|
| | 602 | + readbytes = 0
|
| | 603 | + timeoutcounter = 0
|
| | 604 | +
|
| | 605 | + self.__myprint("Reading 0x%x bytes from device's console(s)..." % (size), silent)
|
| | 606 | +
|
| | 607 | + while size > 0 and timoutcounter < 50:
|
| | 608 | + blocklen = size
|
| | 609 | +
|
| | 610 | + if size > self.cin_maxsize - 0x10:
|
| | 611 | + blocklen = self.cin_maxsize - 0x10
|
| | 612 | +
|
| | 613 | + self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 13, bitmask, blocklen, 0))
|
| | 614 | + response = self.__getbulk(self.handle, self.__cinep, blocklen + 0x10)
|
| | 615 | + self.__checkstatus(response)
|
| | 616 | +
|
| | 617 | + readbytes = struct.unpack("<III", response[4:8])
|
| | 618 | + out_data += response[0x10:0x10+readbytes]
|
| | 619 | + size -= blocklen
|
| | 620 | +
|
| | 621 | + if not readbytes > 0: # no data read => wait a bit and prevent an infinite loop trying to read data when there is none
|
| | 622 | + timeoutcounter += 1
|
| | 623 | + time.sleep(0.1)
|
| | 624 | + else:
|
| | 625 | + timeoutcounter -= 3
|
| | 626 | + if timeoutcounter < 0:
|
| | 627 | + timeoutcounter = 0
|
| | 628 | +
|
| | 629 | + self.__myprint(" done\n", silent)
|
| | 630 | + self.__myprint("\nBytes read: 0x%x\n\n" % (len(out_data)), silent)
|
| | 631 | +
|
| | 632 | + if (outtype == "file"):
|
| | 633 | + f = open(file, "wb")
|
| | 634 | + f.write(out_data)
|
| | 635 | +
|
| | 636 | + elif (outtype == "printstring"):
|
| | 637 | + self.__myprint(out_data, silent)
|
| | 638 | + self.__myprint("\n\n", silent)
|
| | 639 | +
|
| | 640 | + elif (outtype == "printhex"):
|
| | 641 | + self.__myprint(self.__gethexviewprintout(out_data, "", 1), silent)
|
| | 642 | + self.__myprint("\n\n", silent)
|
| | 643 | +
|
| | 644 | + elif (outtype == ""):
|
| | 645 | + pass # return only
|
| | 646 | +
|
| | 647 | + else:
|
| | 648 | + raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
|
| | 649 | +
|
| | 650 | + return out_data
|
| | 651 | +
|
| | 652 | +
|
| | 653 | + def writedevcon(self, bitmask, data, silent = 0, *range):
|
| | 654 | + """ writes to USB console
|
| | 655 | + <bitmask>: bitmask of consoles to be written to
|
| | 656 | + <data>: the data to be written
|
| | 657 | + <range>: the range in <data> that should be written, in the from [offset, length]
|
| | 658 | + <silent>: if 0, nothing will be written to the console window
|
| | 659 | +
|
| | 660 | + if the data to be written exceeds the Command Out endpoint packet size - 0x10, it will be written in several steps
|
| | 661 | + """
|
| | 662 | + size = len(data)
|
| | 663 | + boffset = 0
|
| | 664 | +
|
| | 665 | + if len(range) > 0:
|
| | 666 | + boffset = range[0]
|
| | 667 | + if len(range) > 1:
|
| | 668 | + size = range[1]
|
| | 669 | +
|
| | 670 | + self.__myprint("Writing 0x%x bytes to device's console(s)..." % (size), silent)
|
| | 671 | +
|
| | 672 | + timeoutcounter = 0
|
| | 673 | +
|
| | 674 | + while size > 0:
|
| | 675 | + blocklen = size
|
| | 676 | + if blocklen > self.cout_maxsize - 0x10:
|
| | 677 | + blocklen = self.cout_maxsize - 0x10
|
| | 678 | +
|
| | 679 | + self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 12, bitmask, size, 0) + data[boffset:boffset+blocklen])
|
| | 680 | + response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
| | 681 | + self.__checkstatus(response)
|
| | 682 | +
|
| | 683 | + size -= blocklen
|
| | 684 | + boffset += blocklen
|
| | 685 | +
|
| | 686 | + self.__myprint(" done\n", silent)
|
| | 687 | +
|
| | 688 | +
|
| 560 | 689 | def flushconsolebuffers(self, bitmask, silent = 0):
|
| 561 | 690 | self.__myprint("Flushing device console('s) buffer('s)...")
|
| 562 | 691 |
|
| — | — | @@ -867,6 +996,8 @@ |
| 868 | 997 | processinfoprint += "priority: 0x%02x " % (out[i+3]['priority'])
|
| 869 | 998 | processinfoprint += "cpu load: 0x%02x\n" % (out[i+3]['cpuload'])
|
| 870 | 999 |
|
| | 1000 | + i += 1
|
| | 1001 | +
|
| 871 | 1002 | except IndexError:
|
| 872 | 1003 | processinfoprint += "--------------------------------------------------------------------------------"
|
| 873 | 1004 |
|
| — | — | @@ -895,7 +1026,7 @@ |
| 896 | 1027 |
|
| 897 | 1028 |
|
| 898 | 1029 | #======================================================================================
|
| 899 | | -#======================================================================================
|
| | 1030 | +# backlight control, remnant from libibugger adjusted to work with libembios ==========
|
| 900 | 1031 |
|
| 901 | 1032 |
|
| 902 | 1033 | def backlighton(self, fade, brightness, silent = 0):
|