示例#1
0
    def filter(self, transaction):
        valueIndex = None
        if not transaction.control_match(
                "SEND_H264_TRANSCODER_BITFIELD", wLength=8, write=True):
            return [transaction]  #Filter does not apply

        value = debyteify(transaction.payload[0:4])
        mask = debyteify(transaction.payload[4:8])
        maskMinusLowest = mask & (mask - 1)  #bit trick, clears lowest bit
        #of mask.

        lowBit = mask - maskMinusLowest
        if lowBit == 0:
            #No bits set. This is weird enough I'd like to throw a runtime error.
            raise RuntimeError(
                "NOP SPARAM that processes zero bits found, mind blown.")
        lsb = lowBit.bit_length() - 1
        rightMask = mask >> lsb
        bitCount = rightMask.bit_length()

        originalValue = value >> lsb

        #well now we have lsb and bitcount, now for sanity checks.
        regeneratedMask = ((1 << bitCount) - 1) << lsb

        if (regeneratedMask != mask) or ((value & mask) != value):
            #This is an atypical SETUP_H264_TRANSCODER_BITFIELD write, this is
            #weird enough I want to raise an error
            raise RuntimeError(
                "Non-SPARAM write to SETUP_H264_TRANSCODER_FIELD found, mind blown."
            )
        #Also make sure we don't ever run over a 16 bit boundary...
        wordIndex = lsb // 16
        wordIndexTop = (lsb + bitCount - 1) // 16
        if wordIndex != wordIndexTop:
            raise RuntimeError(
                "SPARAM write runs over 16 bit boundary, mind blown.")
        port = transaction.wIndex
        if (wordIndex == 0):
            port += 2
        else:
            lsb -= 16  #Gotta shift

        #Lookup to see if known
        lookupValues = [port, lsb, bitCount]
        name = transaction.device.reverseTranscoderBitfieldLookup(lookupValues)
        if name == None:
            returnString = "\tsparam( 0x%4.4x, %d, %d, %d );" % (
                port, lsb, bitCount, originalValue)
        else:
            returnString = "\tsparam( %s, %d );" % (name[0], originalValue)

        capInfo = self.capInfo(transaction)
        if capInfo != "":
            returnString += " //%s" % self.capInfo(transaction)
        transaction.filterDecoration = returnString
        return [transaction]
示例#2
0
    def filter(self, transaction):
        valueIndex = None
        if transaction.control_match("MAIL_SEND_ENABLE_REGISTER_STATE", 2):
            valueIndex = 1
            mask = ~0xd080  #d080 gets autoset on HDNew devices for MAIL_SEND_ENABLE_REGISTER_STATE
        elif transaction.control_match("ENABLE_REGISTER", 2):
            valueIndex = 0
            mask = ~0xd080  #d080 gets autoset on HDNew devices for MAIL_SEND_ENABLE_REGISTER_STATE
        else:
            return [transaction]  #No filter.

        newValue = debyteify(transaction.payload)

        value = self.values[valueIndex]
        transaction.noteContext["previous"] = value
        transaction.noteContext["current"] = newValue
        changed = value != newValue
        transaction.noteContext["changed"] = changed

        if transaction.control_direction(read=True):
            if (value != None) and ((newValue & mask) != (value & mask)):
                if valueIndex == 1:
                    raise RuntimeError(
                        "MAIL_SEND_ENABLE_REGISTER_STATE changed on its own, mind blown."
                    )
                else:
                    raise RuntimeError(
                        "ENABLE_REGISTER changed on its own, mind blown.")
            #if valueIndex==1: #Replace actual read text
            #    transaction.filterDecoration="\treadEnableState(); //EXPECTED 0x%4.4x %s" % (newValue, self.capInfo(transaction))
        #else:
        #if not changed and (valueIndex==1):
        #    transaction.filterDecoration="\twriteEnableState(); //EXPECTED WRITE 0x%4.4x %s" % (newValue, self.capInfo(transaction))
        self.values[valueIndex] = newValue
        return [transaction]
示例#3
0
 def typeParameterize( data, typeTuple, bufferPrefix="" ):
     if typeTuple[1]==None:
         return bufferPrefix+"{"+hexdump(data)+"}"
     else:
         byteLength=typeTuple[0]
         format="0x%%%d.%dx" % (byteLength*2, byteLength*2) #each hex digit is one nybble.
         return format % debyteify( data )
示例#4
0
    def filter(self, transaction):
        valueIndex = None
        if not transaction.control_match(
                "SEND_H264_TRANSCODER_WORD", wLength=2, write=True):
            return [transaction]  #Filter does not apply

        value = debyteify(transaction.payload)

        returnString = "\tslsi( 0x%4.4x, %4.4x );" % (transaction.wIndex,
                                                      value)

        capInfo = self.capInfo(transaction)
        if capInfo != "":
            returnString += " //%s" % self.capInfo(transaction)
        transaction.filterDecoration = returnString
        return [transaction]
示例#5
0
    def filter_generator(self):
        #Match first command
        transaction = yield None
        firstTransaction = transaction

        if not transaction.control_match("SCMD_REGISTER", 6, write=True):
            return
        command = transaction.payload[2]
        mode = transaction.payload[3]
        send = debyteify(transaction.payload[4:6])

        fCommand = "0x%2.2x" % command  #formatted command
        fSend = "0x%4.4x" % send  #formatted send
        if command == 1:
            fCommand = "SCMD_IDLE"
        elif command == 4:
            fCommand = "SCMD_RESET"
        elif command == 4:
            fCommand = "SCMD_INIT"
        elif command == 5:
            fCommand = "SCMD_STATE_CHANGE"
            if send == 1:
                fSend = "SCMD_STATE_STOP"
            elif send == 2:
                fSend = "SCMD_STATE_START"
            elif send == 4:
                fSend = "SCMD_STATE_NULL"

        printString = "scmd(%s, 0x%2.2x, %s);" % (fCommand, mode, fSend)

        capInfo = self.capInfo(firstTransaction)
        if capInfo != "":
            printString += " //%s" % capInfo

        newTransaction = USBTransaction.makeCustom("scmd")
        newTransaction.identityContext = {
            "command": command,
            "mode": mode,
            "send": send
        }
        newTransaction.filterDecoration = "\t%s" % printString
        yield [newTransaction]
示例#6
0
    def __init__(self, buffer, format=USBPcap, capCounter=None, capBase=0):
        self.format = format
        self.rawData = buffer
        self.capCounter = capCounter
        if format == USBPcap:
            self.initialFlag = True  #Set when suitable
            #format for first capture buf of a complete USBTransaction.
            #Most buffers types are solo in this format,
            #so defaults to True
            self.endFlag = True  #Set when suitable
            #format for last buffer capture buf of a complete USBTransaction
            #Most buffers types are solo in this format,
            #so defaults to True
            self.controlDataFlag = False

            urbLength = debyteifyLittleEndian(buffer[0:2])
            if (urbLength < 27) or (urbLength > len(buffer)):
                raise CaptureFormatError("Data is in wrong format")

            auxLength = 0
            self.irpID = debyteifyLittleEndian(buffer[2:10])
            self.usbdStatus = debyteifyLittleEndian(buffer[10:14])
            self.busID = buffer[18]
            self.deviceID = debyteifyLittleEndian(buffer[19:21])
            self.endPoint = buffer[21]
            self.direction = (buffer[21] >> 7) != 0

            self.type = buffer[22]
            packetDataLength = debyteifyLittleEndian(buffer[23:27])

            if (packetDataLength + urbLength) != len(buffer):
                if (packetDataLength + urbLength <=
                        65535):  #Capture gets truncated apparently
                    raise CaptureFormatError("Data is in wrong format")

            if self.type == USBTransaction.CONTROL:
                self.initialFlag = False  #Control transactions generate 3 capture events, gotta figure out which
                self.endFlag = False  #Control transactions generate 3 capture, gotta figure out which
                self.controlTransferStage = buffer[
                    27]  #This is unique to USBPcap
                if self.controlTransferStage == CapturePoint.SetupStage:
                    self.initialFlag = True  #Only SetupStage is an initial even for a control transaction
                    auxLength = 8  #Size of setup stuff.
                    controlData = buffer[urbLength:urbLength + 8]
                    self.setupControl(controlData)
                    self.controlDataFlag = True
                if self.controlTransferStage == CapturePoint.StatusStage:
                    self.endFlag = True

                self.mainWriteFlag = (self.direction == USBTransaction.Outbound) and \
                    (self.controlTransferStage==CapturePoint.DataStage)
                self.mainReadFlag = (self.direction == USBTransaction.Inbound) and \
                    (self.controlTransferStage==CapturePoint.DataStage)
            else:
                #Single state command, if we read or write, we do it here.
                self.mainReadFlag = self.direction == USBTransaction.Inbound
                self.mainWriteFlag = self.direction == USBTransaction.Outbound

            trueUrbLength = urbLength + auxLength
            self.payloadLength = packetDataLength - auxLength

            self.urb = buffer[:trueUrbLength]
            self.payload = buffer[trueUrbLength:trueUrbLength +
                                  self.payloadLength]

        elif format == Linux:
            urbLength = 64
            if urbLength > len(buffer):
                raise CaptureFormatError("Data is in wrong format")

            urb = buffer[:urbLength]
            self.urb = urb
            self.irpID = debyteifyLittleEndian(urb[0:8])
            urbType = chr(urb[8])  #This is unique to Linux format.
            #'S' for SUBMIT, 'C' for COMPLETE
            if (urbType != 'S') and (urbType != 'C'):
                raise CaptureFormatError("Data is in wrong format")
            self.urbType = urbType

            self.initialFlag = self.urbType == 'S'
            self.endFlag = self.urbType == 'C'

            self.type = urb[9]
            self.endPoint = urb[10]
            self.direction = (urb[10] >> 7) != 0
            self.deviceID = urb[11]
            self.busID = debyteifyLittleEndian(urb[12:14])
            self.usbdStatus = debyteifyLittleEndian(urb[28:32])
            extraPacketLength = debyteifyLittleEndian(urb[36:40])

            self.controlDataFlag = False
            if self.type == USBTransaction.CONTROL:
                if self.urbType == 'S':
                    controlData = urb[40:48]
                    self.setupControl(controlData)
                    self.controlDataFlag = True

            self.mainWriteFlag = (self.direction == USBTransaction.Outbound) and \
                 (self.urbType == 'S')
            self.mainReadFlag = (self.direction == USBTransaction.Inbound) and \
                 (self.urbType == 'C')

            self.payloadLength = debyteifyLittleEndian(urb[36:40])
            self.payload = buffer[urbLength:urbLength + self.payloadLength]
            if (urbLength + self.payloadLength) != len(buffer):
                raise CaptureFormatError("Data is in wrong format")

        elif format == Vizsla:
            urbLength = 8  #Simulated urb created by DumpVizslaIterator
            #URB definition
            #entry 0 is deviceID
            #entry 1 is endPoint ....bit 7 is set to direction.
            #entry 2 is type..IE USBTransaaction.CONTROL, etc.
            #entry 3 is 0 if SETUP, 1 if anything else.
            #entry 4-7 is 32 bit line number.
            self.capCounter = debyteify(buffer[4:8]) + capBase

            if urbLength > len(buffer):
                raise CaptureFormatError("Data is in wrong format")
            urb = buffer[:urbLength]
            self.urb = urb

            self.busID = None  #Unknown in Vizsla captures.
            self.deviceID = urb[0]
            self.endPoint = urb[1]
            self.type = urb[2]
            self.direction = (self.endPoint >> 7) != 0
            self.urbStage = urb[
                3]  #0 if SETUP, 1 if IN or OUT, 2 if end of SETUP.

            self.controlDataFlag = False
            if self.type == USBTransaction.CONTROL:
                if self.urbStage == 0:
                    self.controlDataFlag = True
                    controlData = buffer[urbLength:]
                    self.setupControl(controlData)
            if self.urbStage != 1:
                self.payloadLength = 0
                self.payload = []
            else:
                self.payload = buffer[urbLength:]
                self.payloadLength = len(self.payload)

            self.initialFlag = True
            self.endFlag = True
            self.mainWriteFlag = (self.direction == USBTransaction.Outbound)
            self.mainReadFlag = (self.direction == USBTransaction.Inbound)

            if self.type == USBTransaction.CONTROL:
                if self.urbStage == 0:
                    self.endFlag = False
                    #Not at main read or write yet.
                    self.mainWriteFlag = False
                    self.mainReadFlag = False
                elif self.urbStage == 1:
                    self.initialFlag = False
                    self.endFlag = False
                else:
                    self.initialFlag = False
                    self.mainWriteFlag = False
                    self.mainReadFlag = False
示例#7
0
    def filter_generator(self):
        oldTransaction = None
        firstTransaction = None

        stateChangeComplete = False
        while (True):
            transaction = yield None
            if not transaction.control_match(
                    "SCMD_STATE_READBACK_REGISTER", 2, read=True):
                return
            if firstTransaction == None:
                firstTransaction = transaction

            olderTransaction = oldTransaction
            oldTransaction = transaction

            transaction = yield None
            if not transaction.control_match(
                    "SCMD_STATE_CHANGE_COMPLETE", 2, read=True):
                if transaction.control_match("SCMD_STATE_READBACK_REGISTER",
                                             2,
                                             read=True):
                    if not stateChangeComplete:
                        raise RuntimeError(
                            "Unexpected behaviour of GetStreamStatusChange, examine behaviour."
                        )
                    break
                else:
                    return
            else:
                if stateChangeComplete:
                    raise RuntimeError(
                        "Unexpected behaviour of GetStreamStatusChange, examine behaviour."
                    )
            stateChangeComplete = (debyteify(transaction.payload) & 0x4 > 0)

            transaction = yield None
            if not transaction.control_match(
                    0xbc, 0x0900, 0x01b0, 2, read=True):
                return

        if olderTransaction == None:
            return  #Fragment, just got two reads from SCMD_STATE_READBACK_REGISTER in a row, didn't
            #go through the loop once

        changeOldest = debyteify(transaction.payload)
        changeOld = debyteify(transaction.payload)
        change = debyteify(transaction.payload)
        if (change != changeOld) or (changeOld != changeOldest):
            raise RuntimeError(
                "Unexpected transient change, examine behaviour.")

        transaction = yield None
        if not transaction.control_match(
                "SCMD_STATE_CHANGE_COMPLETE", 2, write=True):
            return
        if debyteify(transaction.payload) != 4:
            raise RuntimeError("Unexpected write value !=4, mind blown")

        transaction = yield None
        if not transaction.control_match(0xbc, 0x0900, 0x01b0, 2, write=True):
            return
        if debyteify(transaction.payload) != 0:
            raise RuntimeError("Unexpected write value != 0, mind blown.")

        printString = "\tcompleteStateChange(); //EXPECTED 0x%4.4x %s" % (
            change, self.capInfo(firstTransaction))

        newTransaction = USBTransaction.makeCustom("GetStreamStatusChange")
        newTransaction.identityContext = {"change": change}
        newTransaction.filterDecoration = printString

        yield [newTransaction]  #Substitute transactions.
示例#8
0
    def filter_generator(self):
        #Match first command
        transaction = yield None
        firstTransaction = transaction

        if not transaction.control_match("SCMD_REGISTER", 4, write=True):
            return
        command = transaction.payload[0]
        mode = transaction.payload[1]
        send = debyteify(transaction.payload[2:4])

        fCommand = "0x%2.2x" % command  #formatted command
        fSend = "0x%4.4x" % send  #formatted send
        if command == 1:
            fCommand = "SCMD_IDLE"
        elif command == 4:
            fCommand = "SCMD_INIT"
        elif command == 5:
            fCommand = "SCMD_STATE_CHANGE"
            if send == 1:
                fSend = "SCMD_STATE_STOP"
            elif send == 2:
                fSend = "SCMD_STATE_START"
            elif send == 4:
                fSend = "SCMD_STATE_NULL"

        #There are other commands we get...we just haven't identified them
        if (command == 1) or (command
                              == 4) or (command
                                        == 5):  #These on the other hand...
            if (mode & 0xa0) and ((mode & 0xa0) != 0xa0):
                raise RuntimeException(
                    "Here's a chance to figure what mode in scmd bits mean")

            if not (mode &
                    0xa0):  #One of these two bits I think disables interrupts.
                transaction = yield None
                if not (transaction.type == USBTransaction.INTERRUPT):
                    raise RuntimeError("Unexpectedly no interrupt for scmd.")
                    return

                modeChanged = False
                while not modeChanged:
                    transaction = yield None
                    #scmd state readback register
                    if not transaction.control_match(
                            "HDNEW_SCMD_READBACK_REGISTER", 2, read=True):
                        raise RuntimeError("Unexpected exit from scmd.")
                        return
                    if transaction.payload[0] == command:
                        modeChanged = True

        #And now we are done
        printString = "scmd(%s, 0x%2.2x, %s);" % (fCommand, mode, fSend)

        capInfo = self.capInfo(firstTransaction)
        if capInfo != "":
            printString += " //%s" % capInfo

        newTransaction = USBTransaction.makeCustom("scmd")
        newTransaction.identityContext = {
            "command": command,
            "mode": mode,
            "send": send
        }
        newTransaction.filterDecoration = "\t%s" % printString
        yield [newTransaction]