Пример #1
0
    def setup(self, ipAddrOrHostName, fileBase, dumpTraceFileName):

        # Format of trace binary element
        self.sizeOfTraceBinElem = 5
        self.flags1 = ("..", ".I", "1.", "1I")
        self.flags2 = ("...", "..R", ".W.", ".WR", "M..", "M.R", "MW.", "MWR")

        # Instruction timing
        self.instrCountAtStart = None
        self.curInstructionCount = 0
        self.instructionsSkipped = 0

        # Logging
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)
        consoleLogger = logging.StreamHandler()
        consoleLogger.setLevel(logging.DEBUG)
        consoleLogger.setFormatter(
            logging.Formatter('%(asctime)s: %(message)s'))
        self.logger.addHandler(consoleLogger)

        # Open trace file
        self.dumpTraceFile = None
        try:
            if dumpTraceFileName is not None and len(dumpTraceFileName) > 0:
                self.dumpTraceFile = open(
                    os.path.join(fileBase, dumpTraceFileName), "w")
        except Exception as excp:
            self.logger.warning("Can't open dump trace file " +
                                os.path.join(fileBase, dumpTraceFileName))

        # HDLC port
        self.tcpHdlcPort = 10001

        # Callback to send to TCP
        def sendDataToTCP(dataToSend):
            self.rdpTCP.sendFrame(dataToSend)

        # Frame handler
        def onTCPFrame(fr):
            # Send to HDLC
            self.hdlcHandler.processBytes(fr)

        # TCP Reader
        self.rdpTCP = SimpleTCP(ipAddrOrHostName, self.tcpHdlcPort)
        self.rdpTCP.startReader(onTCPFrame)

        # Setup HDLC
        self.hdlcHandler = HDLC(None, sendDataToTCP, None)
        self.hdlcHandler.setCallbacks(None, self.onHDLCBinFrame)

        # Welcome
        self.logger.info(
            f"UnitTest BusRaider IP {ipAddrOrHostName} port {self.tcpHdlcPort}"
        )
Пример #2
0
        print(f"Sending {numCharsToSend} bytes ...")
        sendblock = bytearray()
        for i in range(numCharsToSend):
            sendblock.append(0xaa)
        ser.write(sendblock)
    except Exception as excp:
        print("ERROR: Serial port?", excp)
        ser.close()
        exit()
else:
    galaxyFrame = bytearray(
        b"{\"cmdName\":\"filetarget\",\"fileType\":\"trs80cmd\"}\0")
    galaxyFrame += bytearray(
        b"TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTEST"
    )
    h = HDLC(ser)
    # def onFrame(fr):
    #     print(fr)
    # h.startReader(onFrame)
    numFrames = 1000
    for i in range(numFrames):
        h.sendFrame(galaxyFrame)
    print("Sent hdlc len", len(galaxyFrame))
    # h.stopReader()

try:
    prevTime = time.time()
    while True:
        bytesToRead = ser.inWaiting()
        if bytesToRead > 0:
            dataRead = ser.read(bytesToRead)
Пример #3
0
from SimpleHDLC import HDLC
import serial
import logging
import os
import time
import keyboard

logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))

def onFrame(frame):
    print(frame)

def onError(err):
    print(err)
          
with serial.Serial('COM5', 115200) as s:
    h = HDLC(s)

    h.startReader(onFrame, onError)

    while True:
        if keyboard.is_pressed(' '):
            break    

    h.stopReader()

    
Пример #4
0
def formFileFrame(fileFolder, fileName):
    fileFrame = bytearray(b"{\"cmdName\":\"FileTarget\",\"fileName\":"
                          ) + bytearray(fileName, "utf-8") + bytearray(b"}\0")
    fileFrame += getFileData(fileFolder, fileName)
    return fileFrame


romFrame = formFileFrame(r"TargetSW/TRS80/ROMS/", r"level1.rom")
programFrame = formFileFrame(r"TargetSW/TRS80/Games/", r"galinv1d.cmd")

clearFrame = b"{\"cmdName\":\"ClearTarget\"}\0"
progFrame = b"{\"cmdName\":\"ProgramAndReset\"}\0"
setMCFrame = b"{\"cmdName\":\"SetMachine=TRS80\"}\0"

with serial.Serial('COM6', 115200) as s:
    h = HDLC(s)
    # h.sendFrame(setMCFrame)
    # print("Sent setmachine=TRS80 len", len(setMCFrame))
    # time.sleep(2.0)
    h.sendFrame(clearFrame)
    print("Clear Target Buffer")
    time.sleep(1.0)
    h.sendFrame(romFrame)
    print("Sent ROM", len(romFrame))
    time.sleep(2.1)
    h.sendFrame(programFrame)
    print("Sent Program", len(romFrame))
    time.sleep(2.1)
    h.sendFrame(progFrame)
    print("Sent Program and Reset")
Пример #5
0
def sendFileSerialHDLC(ser):
    # Frame received
    def onFrame(fr):
        global uploadAck
        msgContent = {'cmdName': ''}
        try:
            msgContent = json.loads(fr)
        except Exception as excp:
            print("Failed to parse Json from", fr, excp)
        if msgContent['cmdName'] == "ufEndAck":
            print("Upload Acknowledged")
            uploadAck = True
        elif msgContent['cmdName'] == "ufEndNotAck":
            print("Upload FAILED")
        elif msgContent['cmdName'] == "log":
            try:
                print(msgContent['lev'] + ":", msgContent['src'],
                      msgContent['msg'])
            except Exception as excp:
                print("LOG CONTENT NOT FOUND IN FRAME", fr, excp)
        else:
            print("Unknown cmd msg", fr)

    # Setup HDLC sender
    hdlcHandler = HDLC(ser)
    hdlcHandler.startReader(onFrame)

    # Upload acknowledged
    uploadAck = False

    # Send new firmware in the bin folder using the CommandHandler protocol
    imageFileName = "/bin/kernel.img"
    with open(baseFolder + imageFileName, "rb") as f:

        # Read firmware
        binaryImage = f.read()
        binaryImageLen = len(binaryImage)
        print(f"File {imageFileName} is {binaryImageLen} bytes long")

        # Frames follow the approach used in the web interface start, block..., end
        startFrame = bytearray(b"{\"cmdName\":\"ufStart\",\"fileName\":\"kernel.img\",\"fileType\":\"firmware\",\"fileLen\":\"" + \
                        bytes(str(binaryImageLen),"ascii") + b"\"}\0")
        hdlcHandler.sendFrame(startFrame)

        # Split the file into blocks
        blockMaxSize = 1024
        numBlocks = binaryImageLen // blockMaxSize + (0 if (
            binaryImageLen % blockMaxSize == 0) else 1)
        for i in range(numBlocks):
            blockStart = i * blockMaxSize
            blockToSend = binaryImage[blockStart:blockStart + blockMaxSize]
            dataFrame = bytearray(b"{\"cmdName\":\"ufBlock\",\"index\":\"" +
                                  bytes(str(blockStart), "ascii") +
                                  b"\"}\0") + blockToSend
            hdlcHandler.sendFrame(dataFrame)

        # End frame
        endFrame = bytearray(b"{\"cmdName\":\"ufEnd\",\"blockCount\":\"" +
                             bytes(str(numBlocks), "ascii") + b"\"}\0")
        hdlcHandler.sendFrame(endFrame)

        # Check for end frame acknowledged
        prevTime = time.time()
        while True:
            if uploadAck:
                break
            if time.time() - prevTime > 2:
                break

    # Remain running for a little while to hoover up diagnostics, etc
    try:
        prevTime = time.time()
        while True:
            if uploadAck:
                break
            if time.time() - prevTime > 1:
                break
        hdlcHandler.stopReader()
    except Exception as excp:
        print("ERROR: Serial port?", excp)
        hdlcHandler.stopReader()

    ser.close()
Пример #6
0
from SimpleHDLC import HDLC
import serial
import logging
import os
import time
import msvcrt

def onFrame(fr):
    print(fr)
    
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))

galaxyFrame = bytearray(b"{\"cmdName\":\"filetarget\",\"fileType\":\"trs80cmd\"}\0")
galaxyFrame += bytearray(b"TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTEST")

with serial.Serial('COM15', 115200) as s:
    h = HDLC(s)
    h.startReader(onFrame)

    while True:
        if msvcrt.kbhit():
            k = msvcrt.getch()
#            print(k[0])
            if k[0] == ord("h"):
                h.sendFrame(galaxyFrame)
                print("Sent cmd len", len(galaxyFrame))
            elif k[0] == ord('\x1b'):
                h.stopReader()
                exit(0)
        
Пример #7
0
class Tracer:

    # Start trace
    def start(self):
        # Setup
        self.setup("192.168.86.103", "./examples/logs", "TraceLong.txt")

        # Stop any previous tracer
        self.sendFrame("tracerStop", b"{\"cmdName\":\"tracerStop\"}\0")

        # Set serial terminal machine (with emulated 6850) - to avoid conflicts with display updates, etc
        mc = "Serial Terminal ANSI"
        self.sendFrame(
            "SetMachine", b"{\"cmdName\":\"setMcJson\"}\0" +
            b"{\"name\":\"Serial Terminal ANSI\",\"hw\":[],\"emulate6850\":{}}\0"
        )
        time.sleep(2)

        # Bus reset
        self.sendFrame("busInit", b"{\"cmdName\":\"busInit\"}\0")
        time.sleep(1)

        # Start tracer with recording (dense binary records) turned on (logging should be off as this creates verbose text log)
        self.sendFrame(
            "tracerStart",
            b"{\"cmdName\":\"tracerStart\",\"logging\":0,\"record\":1}\0")

        # Start message
        timeStart = datetime.datetime.now()
        self.logger.info(f"Execution trace started at {str(timeStart)}")

        # Run the trace
        self.awaitingTraceResponse = False
        for i in range(10):
            j = 0
            while self.awaitingTraceResponse and j < 2000:
                time.sleep(0.001)
                j += 1
            if j >= 2000:
                break
            self.sendFrame("tracerGetLong",
                           b"{\"cmdName\":\"tracerGetBin\"}\0")
            self.awaitingTraceResponse = True
            time.sleep(0.01)

        # Calculate rate
        timeEnd = datetime.datetime.now()
        elapsed = (timeEnd - timeStart).total_seconds()
        if elapsed > 0 and not self.instrCountAtStart is None:
            instrCount = self.curInstructionCount - self.instrCountAtStart
            self.logger.info(
                f"{instrCount} instructions in {elapsed:.2f} secs => {instrCount/elapsed:.1f} per second {self.instructionsSkipped} lost"
            )

        # Stop tracing
        self.cleardown()

    def cleardown(self):
        # Clear down
        try:
            self.rdpTCP.stopReader()
        except Exception as excp:
            self.logger.error(f"{excp}")
        if self.dumpTraceFile:
            self.dumpTraceFile.close()

    # Handle received messages
    def frameCallback(self, msgContent, binContent, logger):
        if (msgContent['cmdName']
                == "tracerGetBinData") and (not self.dumpTraceFile is None):
            # Traced bus access contents
            dataCount = msgContent['dataLen'] // self.sizeOfTraceBinElem
            traceCount = msgContent['traceCount']
            # Check if any bus accesses lost in communication
            if self.curInstructionCount != traceCount:
                self.instructionsSkipped += traceCount - self.curInstructionCount
            # For calculating rate
            if self.instrCountAtStart is None:
                self.instrCountAtStart = traceCount
            self.curInstructionCount = traceCount + dataCount
            elemPos = 0
            # Extract the data, format and write to file
            for i in range(dataCount):
                dataStr = self.formatTraceBinElem(binContent, elemPos,
                                                  traceCount)
                elemPos += self.sizeOfTraceBinElem
                traceCount += 1
                self.dumpTraceFile.write(dataStr + "\n")
            self.awaitingTraceResponse = False

    # Format for trace dumping
    def formatTraceBinElem(self, binContent, contentPos, traceCount):
        addr = binContent[contentPos] + (binContent[contentPos + 1] * 256)
        busData = binContent[contentPos + 2]
        retData = binContent[contentPos + 3]
        flags = binContent[contentPos + 4]
        retData = f"{traceCount:08d} {addr:04x} {busData:02x} {self.formatFlags1(flags)}{self.formatFlags2(flags)}"
        if (flags & 0x80) != 0:
            retData += f"{retData:02x}"
        return retData

    def formatFlags1(self, busFlags):
        return self.flags1[(busFlags >> 3) & 0x03]

    def formatFlags2(self, busFlags):
        return self.flags2[busFlags & 0x07]

    # Send frame to BusRaider
    def sendFrame(self, comment, content):
        frame = bytearray(content)
        self.hdlcHandler.sendFrame(frame)

    # HDLC Frame handler
    def onHDLCBinFrame(self, fr):
        msgContent = {'cmdName': ''}
        try:
            # Split string - the format is a JSON string terminated with NULL then
            # a binary section to the end of the buffer
            nullPos = fr.find(b"\0")
            binContent = b""
            if nullPos >= 0:
                jsonStr = fr[:nullPos].decode('utf-8').rstrip('\0')
                msgContent = json.loads(jsonStr)
                binContent = fr[nullPos + 1:]
            else:
                jsonStr = fr.decode('utf-8').rstrip('\0')
                msgContent = json.loads(jsonStr)
        except Exception as excp:
            self.logger.error(f"Failed to parse Json from {fr}, {excp}")
        try:
            # All messages should contain cmdName to identify message type
            if 'cmdName' in msgContent:
                if msgContent['cmdName'] == "log":
                    # Check for a log message from Pi
                    try:
                        self.logger.info(
                            f"{msgContent['lev']} : {msgContent['src']} {msgContent['msg']}"
                        )
                    except Exception as excp:
                        self.logger.error(
                            f"LOG CONTENT NOT FOUND IN FRAME {fr}, {excp}")
                else:
                    self.frameCallback(msgContent, binContent, self.logger)
        except Exception as excp:
            self.logger.error(f"Failed to extract cmdName {fr}, {excp}")

    # Check for using IP address
    def setup(self, ipAddrOrHostName, fileBase, dumpTraceFileName):

        # Format of trace binary element
        self.sizeOfTraceBinElem = 5
        self.flags1 = ("..", ".I", "1.", "1I")
        self.flags2 = ("...", "..R", ".W.", ".WR", "M..", "M.R", "MW.", "MWR")

        # Instruction timing
        self.instrCountAtStart = None
        self.curInstructionCount = 0
        self.instructionsSkipped = 0

        # Logging
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)
        consoleLogger = logging.StreamHandler()
        consoleLogger.setLevel(logging.DEBUG)
        consoleLogger.setFormatter(
            logging.Formatter('%(asctime)s: %(message)s'))
        self.logger.addHandler(consoleLogger)

        # Open trace file
        self.dumpTraceFile = None
        try:
            if dumpTraceFileName is not None and len(dumpTraceFileName) > 0:
                self.dumpTraceFile = open(
                    os.path.join(fileBase, dumpTraceFileName), "w")
        except Exception as excp:
            self.logger.warning("Can't open dump trace file " +
                                os.path.join(fileBase, dumpTraceFileName))

        # HDLC port
        self.tcpHdlcPort = 10001

        # Callback to send to TCP
        def sendDataToTCP(dataToSend):
            self.rdpTCP.sendFrame(dataToSend)

        # Frame handler
        def onTCPFrame(fr):
            # Send to HDLC
            self.hdlcHandler.processBytes(fr)

        # TCP Reader
        self.rdpTCP = SimpleTCP(ipAddrOrHostName, self.tcpHdlcPort)
        self.rdpTCP.startReader(onTCPFrame)

        # Setup HDLC
        self.hdlcHandler = HDLC(None, sendDataToTCP, None)
        self.hdlcHandler.setCallbacks(None, self.onHDLCBinFrame)

        # Welcome
        self.logger.info(
            f"UnitTest BusRaider IP {ipAddrOrHostName} port {self.tcpHdlcPort}"
        )
Пример #8
0
testData = bytearray()
for i in range(4096):
    testData.append((i + 33) % 256)
#testData[22] = 0
setTestDataFrame = b"{\"cmdName\":\"FileTarget\",,\"fileName\":\"test.bin\",\"baseAddr\":\"4000\"}\0"
setTestDataFrame += testData

clearFrame = b"{\"cmdName\":\"ClearTarget\"}\0"
#resetFrame = b"{\"cmdName\":\"ResetTarget\"}\0"
progFrame = b"{\"cmdName\":\"ProgramAndReset\"}\0"
ioclearFrame = b"{\"cmdName\":\"IOClrTarget\"}\0"
setMCFrame = b"{\"cmdName\":\"SetMachine=Rob's Z80\"}\0"

with serial.Serial('COM6', 115200) as s:
    h = HDLC(s)
    if testSetMcToRobs:
        h.sendFrame(setMCFrame)
        print("Set Machine to RobsZ80")
        time.sleep(2.0)
    h.sendFrame(clearFrame)
    print("Clear Target Buffer")
    time.sleep(1.0)
    h.sendFrame(romFrame)
    print("Sent ROM", len(romFrame))
    time.sleep(0.1)
    h.sendFrame(setTestDataFrame)
    print("Sent Test Data", len(setTestDataFrame))
    time.sleep(0.1)
    h.sendFrame(progFrame)
    print("Sent Program and Reset")
with open(r"../../TRS80SW/galinv1d.cmd", "rb") as galaxyFile:
    galaxyData = galaxyFile.read()

romFrame = bytearray(b"{\"cmdName\":\"filetarget\",\"fileType\":\"trs80bin\"}\0")
romFrame += romData

galaxyFrame = bytearray(b"{\"cmdName\":\"filetarget\",\"fileType\":\"trs80cmd\"}\0")
galaxyFrame += galaxyData

clearFrame = b"{\"cmdName\":\"cleartarget\"}\0"
resetFrame = b"{\"cmdName\":\"resettarget\"}\0"
progFrame = b"{\"cmdName\":\"programtarget\"}\0"
ioclearFrame = b"{\"cmdName\":\"ioclrtarget\"}\0"

with serial.Serial('COM6', 921600) as s:
    h = HDLC(s)
    h.sendFrame(clearFrame)
    print("Sent cleartarget len", len(clearFrame))
    time.sleep(1.0)
    h.sendFrame(ioclearFrame)
    print("Sent ioclear len", len(ioclearFrame))
    time.sleep(1.0)
    h.sendFrame(romFrame)
    print("Sent ROM srcs len", len(romFrame))
    time.sleep(1.0)
    h.sendFrame(progFrame)
    print("Sent progtarget len", len(progFrame))
    time.sleep(2.0)
    h.sendFrame(resetFrame)
    print("Sent resettarget len", len(resetFrame))
    time.sleep(2.0)    
Пример #10
0
import os

logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))

from PyCRC.CRCCCITT import CRCCCITT
import struct

def calcCRC(data):
    crc = CRCCCITT("FFFF").calculate(bytes(data))
    b = bytearray(struct.pack(">H", crc))
    return b

print(calcCRC(b'0'))

with serial.Serial('COM6', 921600) as s:
    h = HDLC(s)
    h.sendFrame(b'0')

POLYNOMIAL = 0x1021
PRESET = 0xffff

def _initial(c):
    crc = 0
    c = c << 8
    for j in range(8):
        if (crc ^ c) & 0x8000:
            crc = (crc << 1) ^ POLYNOMIAL
        else:
            crc = crc << 1
        c = c << 1
    return crc & 0xffff
Пример #11
0
    def setup(self, useIP, serialPort, serialBaud, ipAddrOrHostName, dumpBinFileName, dumpTextFileName, frameCallback, logSends=False):
        
        self.useIP = useIP
        # Logging
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)
        consoleLogger = logging.StreamHandler()
        consoleLogger.setLevel(logging.DEBUG)
        consoleLogger.setFormatter(logging.Formatter('%(asctime)s: %(message)s'))
        self.logger.addHandler(consoleLogger)
        if dumpTextFileName is not None and len(dumpTextFileName) != 0:
            fileLogger = logging.FileHandler(os.path.join("./test/logs/", dumpTextFileName))
            fileLogger.setLevel(logging.DEBUG)
            fileLogger.setFormatter(logging.Formatter('%(asctime)s: %(message)s'))
            self.logger.addHandler(fileLogger)
        self.logSends = logSends
        self.respAwaited = None
        self.respGot = False

        # Open dump file
        try:
            self.dumpBinFile = None
            if dumpBinFileName is not None and len(dumpBinFileName) > 0:
                self.dumpBinFile = open(os.path.join("./test/logs/", dumpBinFileName), "wb")
        except Exception(excp):
            self.logger.warning("Can't open dump binary file " + os.path.join("./test/logs/", dumpBinFileName))

        # HDLC Frame handler
        def onHDLCFrame(fr):
            msgContent = {'cmdName':''}
            try:
                msgContent = json.loads(fr)
            except Exception as excp:
                self.logger.error(f"Failed to parse Json from {fr}, {excp}")
            try:
                # print("rxmsg", msgContent['cmdName'])
                if msgContent['cmdName'] == "log":
                    try:
                        self.logger.info(f"{msgContent['lev']} : {msgContent['src']} {msgContent['msg']}")
                    except Exception as excp:
                        self.logger.error(f"LOG CONTENT NOT FOUND IN FRAME {fr}, {excp}")
                else:
                    # Check for awaited response
                    if "cmdName" in msgContent and self.respAwaited is not None:
                        if msgContent["cmdName"] == self.respAwaited:
                            self.respGot = True
                    # Callback
                    try:
                        frameCallback(msgContent, self.logger)
                    except Exception as excp:
                        self.logger.error(f"Error in frameCallback with content {msgContent}, {excp}")
            except Exception as excp:
                self.logger.error(f"Failed to extract cmdName {fr}, {excp}")

        # Check for using IP address
        if useIP:
            self.tcpHdlcPort = 10001

            def sendDataToTCP(dataToSend):
                self.rdpTCP.sendFrame(dataToSend)

            # Frame handler
            def onTCPFrame(fr):
                # Send to HDLC
                self.hdlcHandler.processBytes(fr)

            # TCP Reader
            self.rdpTCP = SimpleTCP(ipAddrOrHostName, self.tcpHdlcPort)
            self.rdpTCP.startReader(onTCPFrame)

            # Setup HDLC
            self.hdlcHandler = HDLC(None, sendDataToTCP, self.dumpBinFile)
            self.hdlcHandler.setCallbacks(onHDLCFrame)

            self.logger.info(f"UnitTest BusRaider IP {ipAddrOrHostName} port {self.tcpHdlcPort}")

        else:
            # Open the serial connection to the BusRaider
            try:
                self.ser = serial.Serial(
                    port=serialPort,
                    baudrate=serialBaud,
                    parity=serial.PARITY_NONE,
                    stopbits=serial.STOPBITS_ONE,
                    bytesize=serial.EIGHTBITS
                )
            except Exception:
                self.logger.error("Serial Port " + serialPort + " busy or non-existent!")
                return False
            try:
                self.ser.set_buffer_size(20000, None)
            except Exception:
                self.logger.error("Failed to set serial buffer size")

            self.logger.info(f"UnitTest BusRaider port {serialPort} baudrate {serialBaud}")
            sys.stdout.flush()

            # Setup HDLC sender
            self.hdlcHandler = HDLC(self.ser, self.dumpBinFile)
            self.hdlcHandler.startReader(onHDLCFrame)
Пример #12
0
class CommonTest:

    def setup(self, useIP, serialPort, serialBaud, ipAddrOrHostName, dumpBinFileName, dumpTextFileName, frameCallback, logSends=False):
        
        self.useIP = useIP
        # Logging
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)
        consoleLogger = logging.StreamHandler()
        consoleLogger.setLevel(logging.DEBUG)
        consoleLogger.setFormatter(logging.Formatter('%(asctime)s: %(message)s'))
        self.logger.addHandler(consoleLogger)
        if dumpTextFileName is not None and len(dumpTextFileName) != 0:
            fileLogger = logging.FileHandler(os.path.join("./test/logs/", dumpTextFileName))
            fileLogger.setLevel(logging.DEBUG)
            fileLogger.setFormatter(logging.Formatter('%(asctime)s: %(message)s'))
            self.logger.addHandler(fileLogger)
        self.logSends = logSends
        self.respAwaited = None
        self.respGot = False

        # Open dump file
        try:
            self.dumpBinFile = None
            if dumpBinFileName is not None and len(dumpBinFileName) > 0:
                self.dumpBinFile = open(os.path.join("./test/logs/", dumpBinFileName), "wb")
        except Exception(excp):
            self.logger.warning("Can't open dump binary file " + os.path.join("./test/logs/", dumpBinFileName))

        # HDLC Frame handler
        def onHDLCFrame(fr):
            msgContent = {'cmdName':''}
            try:
                msgContent = json.loads(fr)
            except Exception as excp:
                self.logger.error(f"Failed to parse Json from {fr}, {excp}")
            try:
                # print("rxmsg", msgContent['cmdName'])
                if msgContent['cmdName'] == "log":
                    try:
                        self.logger.info(f"{msgContent['lev']} : {msgContent['src']} {msgContent['msg']}")
                    except Exception as excp:
                        self.logger.error(f"LOG CONTENT NOT FOUND IN FRAME {fr}, {excp}")
                else:
                    # Check for awaited response
                    if "cmdName" in msgContent and self.respAwaited is not None:
                        if msgContent["cmdName"] == self.respAwaited:
                            self.respGot = True
                    # Callback
                    try:
                        frameCallback(msgContent, self.logger)
                    except Exception as excp:
                        self.logger.error(f"Error in frameCallback with content {msgContent}, {excp}")
            except Exception as excp:
                self.logger.error(f"Failed to extract cmdName {fr}, {excp}")

        # Check for using IP address
        if useIP:
            self.tcpHdlcPort = 10001

            def sendDataToTCP(dataToSend):
                self.rdpTCP.sendFrame(dataToSend)

            # Frame handler
            def onTCPFrame(fr):
                # Send to HDLC
                self.hdlcHandler.processBytes(fr)

            # TCP Reader
            self.rdpTCP = SimpleTCP(ipAddrOrHostName, self.tcpHdlcPort)
            self.rdpTCP.startReader(onTCPFrame)

            # Setup HDLC
            self.hdlcHandler = HDLC(None, sendDataToTCP, self.dumpBinFile)
            self.hdlcHandler.setCallbacks(onHDLCFrame)

            self.logger.info(f"UnitTest BusRaider IP {ipAddrOrHostName} port {self.tcpHdlcPort}")

        else:
            # Open the serial connection to the BusRaider
            try:
                self.ser = serial.Serial(
                    port=serialPort,
                    baudrate=serialBaud,
                    parity=serial.PARITY_NONE,
                    stopbits=serial.STOPBITS_ONE,
                    bytesize=serial.EIGHTBITS
                )
            except Exception:
                self.logger.error("Serial Port " + serialPort + " busy or non-existent!")
                return False
            try:
                self.ser.set_buffer_size(20000, None)
            except Exception:
                self.logger.error("Failed to set serial buffer size")

            self.logger.info(f"UnitTest BusRaider port {serialPort} baudrate {serialBaud}")
            sys.stdout.flush()

            # Setup HDLC sender
            self.hdlcHandler = HDLC(self.ser, self.dumpBinFile)
            self.hdlcHandler.startReader(onHDLCFrame)

    def sendFrame(self, comment, content, respExpected = None):
        self.respAwaited = respExpected
        self.respGot = False
        frame = bytearray(content)
        # for b in frame:
        #     print(hex(b)+" ",end='')
        # print()
        try:
            self.hdlcHandler.sendFrame(frame)
            if self.logSends and len(comment) > 0: 
                self.logger.debug(f"Sent {comment}")
        except Exception as excp:
            self.logger.error(f"Failed to send frame {comment}, {excp}")

    def awaitResponse(self, maxWaitMs):
        if self.respAwaited is not None:
            # print("Awaiting response", self.respAwaited, "MaxWaitMs", maxWaitMs)
            waitMsCount = 0
            while(waitMsCount < maxWaitMs):
                if self.respGot:
                    # print("Awaiting response GOT", self.respAwaited)
                    return True
                time.sleep(0.001)
                waitMsCount += 1
        return False

    def cleardown(self):
        # Remain running for a little while to hoover up diagnostics, etc
        prevTime = time.time()
        while True:
            if time.time() - prevTime > 1:
                break
        # Close down
        if self.dumpBinFile is not None:
            self.dumpBinFile.close()
        if self.useIP:
            self.logger.info("UnitTest closing socket")
            try:
                self.rdpTCP.stopReader()
            except Exception as excp:
                self.logger.error(f"{excp}")
        else:
            try:
                self.hdlcHandler.stopReader()
            except Exception as excp:
                self.logger.error(f"Serial port? {excp}")

            self.ser.close()

        # Results
        # testOk = (errCount == 0 and loopCount != 0)
        # testResultStr = "OK" if testOk else "FAILED"
        # logger.info(f"\n---------------------------------------\n")
        # logger.info(f"Test results: {testResultStr} loops {loopCount} errors {errCount} isrs {isrCount}\n")
        # logger.info(f"---------------------------------------\n")

    def getFileData(self, fileFolder, fileName):
        inData = []
        try:
            with open(os.path.join(fileFolder, fileName), "rb") as inFile:
                inData = inFile.read()
        except:
            pass
        if len(inData) == 0:
            try:
                with open(os.path.join(fileFolder, fileName), "rb") as inFile:
                    inData = inFile.read()
            except:
                logger.error("Unable to load file ", os.path.join(fileFolder, fileName))
                return None
        return inData

    def formFileFrame(self, fileFolder, fileName):
        fileFrame = bytearray(b"{\"cmdName\":\"FileTarget\",\"fileName\":\"") + bytearray(fileName, "utf-8") + b"\"}\0"
        fileData = self.getFileData(fileFolder, fileName)
        if fileData is None:
            return None
        fileFrame += fileData
        return fileFrame