Beispiel #1
0
class Emulator():
    def __init__(self, port, address, event_handler=None, timeout=1, rcv_chunk_size=256):
        debug("Init of {}".format(Emulator.__name__))
        #TODO: add procedure in main window to estiamte best rcv_chunksize in loop
        self.__rcv_chunk_size = rcv_chunk_size
        self.__lock = False
        self.connected = False
        self.event_handler = event_handler
        self.emu_timeout = timeout

        self.port = port
        self.address = address
        self.init_rxbuffers()
        #self.__dump_file = open(os.path.join(LOG_PATH, 'rx_dump.dmp'), 'w')


    def set_rcv_chunk_size(self, value):
        self.__rcv_chunk_size = value

    def get_rcv_chunk_size(self):
        return self.__rcv_chunk_size

    def init_rxbuffers(self):
        self.raw_buffer = CircIoBuffer(byte_size=256 * 16 + 2)

    def lock(self):
        #get remaining data first
        time.sleep(self.emu_timeout)
        if self.rx_buffer.available():
            self.event_handler.get_emu_rx_buffer_slot()
        self.__lock = True

    def is_locked(self):
        return self.__lock

    def unlock(self):
        info("Unlock emu buffer")
        self.__lock = False

    def receive_data_amount(self, amount=1, timeout=2, rcv_ready_signal=None, failed_signal=None, period=0.5, unlock_emu=True):
        if not rcv_ready_signal:
            rcv_ready_signal = self.event_handler.get_emu_rx_buffer_slot()
        tstamp = time.time()
        while self.rx_buffer.available() < amount:
            time.sleep(period)
            if time.time() - tstamp > timeout:
                if failed_signal:
                    failed_signal()
                return False
        rcv_ready_signal()
        return True

    def set_event_handler(self, event_handler):
        self.event_handler = event_handler

    def connect(self, port, address):
        self.address = address
        self.port = port
        if not self.connected:
            self._connect()
        else:
            self.event_handler.message("Already connected")

    def disconnect(self):
        try:
            if self.bt_connection:
                self.bt_connection.close()
                self.bt_connection = False
                self.connected = False
                self.event_handler.message("disconnected from emu device")
        except AttributeError as A:
            if A.message != "Emulator instance has no attribute 'bt_connection'":
                raise AttributeError(A)

    def _connect(self):
        msg = "Connecting to bt device addr: {}, port: {}".format(self.address, self.port)
        self.event_handler.message(msg)
        try_num = 0
        num_of_tries = 3
        while try_num < num_of_tries:
            try:
                emu = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
                #emu.connect((self.address, int(self.port)))
                emu.connect((self.address, int(self.port)))
                self.bt_connection = emu
                #emu.settimeout((float(self.__rcv_chunk_size) * 9)/115200)
                emu.settimeout(0)
                self.event_handler.message("connected to emu device")
                self.connected = True
                return
            except (bluetooth.btcommon.BluetoothError, IOError) as err:
                try_num += 1
                self.event_handler.message(err)
                self.event_handler.message("Connection fail. Try: {}".format(try_num))
        self.event_handler.message("Could not connect")


    def set_timeout(self, value):
        self.bt_connection.settimeout(value)

    def get_connection_status(self):
        return self.connected

    def flush(self):
        #self.bt_connection.recv(256*16)
        self.raw_buffer.flush()
        self.rx_buffer.flush()

    def __try_get_data(self):
        try:
            rcv = self.bt_connection.recv(self.__rcv_chunk_size)
            rx_debug("Received data amount: {}".format(len(rcv)))
            rx_debug("rcv: {} ..".format(rcv[0:50]))
            #self.__dump_file.write(rcv)
            return rcv
        except (bluetooth.btcommon.BluetoothError, IOError) as e:
            #Linux and Windows support different exceptions here
            #print e
            return None

    def __get_data(self):
        try:
            rx_data = self.bt_connection.recv(self.__rcv_chunk_size)
            rx_debug("Received data amount: {}".format(len(rx_data)))
            rx_debug("rcv: {} ..".format(rx_data[0:50]))
            return rx_data
        except (bluetooth.btcommon.BluetoothError, IOError) as e:
            pass

    def receive_data(self):
        """
        :param rx_buffer:
        :param rx_buffer_ready_slot:
        :return:
        """
        rx_data = self.__get_data()
        while rx_data:
            self.raw_buffer.write(rx_data)
            rx_data = self.__get_data()
        if self.raw_buffer.available():
            self.event_handler.get_raw_rx_buffer_slot()

    def send(self, data):
        if not self.__lock:
            if self.bt_connection:
                try:
                    self.bt_connection.send(data)
                except bluetooth.btcommon.BluetoothError as e:
                    error("LOST BT CONNECTION")
                    self.event_handler.lost_connection_slot()
                    raise e
            else:
                error("No bt_connection established")
        else:
            debug("Trying send: '{}', but emulator locked".format(data))
def test_flush_unit_sequence_not_present():
    cb = CircIoBuffer('this is test buffer', byte_size=20)
    cb.flush_until('xxx')
    assert cb.available() == 0