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)
def expectedCrc(frame): return utils.makeWord(frame[defs.CRC_HIGH], frame[defs.CRC_LOW])