예제 #1
0
def dissectResponse(frame):
    buf = utils.makeBuffer(frame)
    arr =  utils.makeArray(buf)

    crc = Crc(0xffff)
    actualValue = 0
    sd = arr[defs.START_DELIMITER]
    length = arr[defs.LENGTH]
    da = arr[defs.DESTINATION_ADRESS]
    sa = arr[defs.SOURCE_ADDRESS]
    crc.update(length)
    crc.update(da)
    crc.update(sa)

    dissectingState = APDU_HEADER0
    numberOfDataBytes = 0
    byteCount = 0
    result = []

    if not (length == len(arr) - 4):
        raise FramingError("Frame length doesn't match length byte.")
    assert(frame == arr)
    for idx in range(defs.PDU_START, length + 2):
        ch = arr[idx]
        crc.update(ch)
        if dissectingState == APDU_HEADER0:
            klass = ch & 0x0f
            if klass not in defs.SUPPORTED_CLASSES:
                # Well, to be precise, these classes are not really documented by the GENIBus spec...
                raise ADPUClassNotSupportedError("APDU class '%u' not supported by GeniControl." % klass)
            dissectingState = APDU_HEADER1
            data = []
        elif dissectingState == APDU_HEADER1:
            numberOfDataBytes = ch & 0x3F
            opAck = (ch & 0xC0) >> 6
            byteCount = numberOfDataBytes
            if byteCount:
                dissectingState = APDU_DATA
            else:
                dissectingState = APDU_HEADER0
                result.append(APDU(klass, opAck, data))
        elif dissectingState == APDU_DATA:
            byteCount -= 1
            if byteCount <= 0:
                dissectingState = APDU_HEADER0
                result.append(APDU(klass, opAck, data))
            else:
                data.append(ch)
    frameCrc = utils.makeWord(arr[defs.CRC_HIGH], arr[defs.CRC_LOW])
    if crc.get() != frameCrc:
        raise CrcError("Frame CRC doesn't match calculated CRC.")
    return DissectionResult(sd, da, sa, result)
예제 #2
0
 def expectedCrc(frame):
     return utils.makeWord(frame[defs.CRC_HIGH], frame[defs.CRC_LOW])