Example #1
0
def discover_channels(path, serial_number, callback, cancellation_token,
                      channel_termination_token, logger):
    """
  Tries to connect to a UDP server based on the path spec.
  This function blocks until cancellation_token is set.
  Channels spawned by this function run until channel_termination_token is set.
  """
    try:
        dest_addr = ':'.join(path.split(":")[:-1])
        dest_port = int(path.split(":")[-1])
    except (ValueError, IndexError):
        raise Exception(
            '"{}" is not a valid UDP destination. The format should be something like "localhost:1234".'
            .format(path))

    while not cancellation_token.is_set():
        try:
            udp_transport = fibre.udp_transport.UDPTransport(
                dest_addr, dest_port, logger)
            channel = fibre.protocol.Channel(
                "UDP device {}:{}".format(dest_addr, dest_port), udp_transport,
                udp_transport, channel_termination_token, logger)
        except:
            logger.debug("UDP channel init failed. More info: " +
                         traceback.format_exc())
            pass
        else:
            callback(channel)
            wait_any(None, cancellation_token, channel._channel_broken)
        time.sleep(1)
Example #2
0
def discover_channels(path, serial_number, callback, cancellation_token, channel_termination_token, logger):
  """
  Tries to connect to a UDP server based on the path spec.
  This function blocks until cancellation_token is set.
  Channels spawned by this function run until channel_termination_token is set.
  """
  try:
    dest_addr = ':'.join(path.split(":")[:-1])
    dest_port = int(path.split(":")[-1])
  except (ValueError, IndexError):
    raise Exception('"{}" is not a valid UDP destination. The format should be something like "localhost:1234".'
                    .format(path))

  while not cancellation_token.is_set():
    try:
      udp_transport = fibre.udp_transport.UDPTransport(dest_addr, dest_port, logger)
      channel = fibre.protocol.Channel(
              "UDP device {}:{}".format(dest_addr, dest_port),
              udp_transport, udp_transport,
              channel_termination_token, logger)
    except:
      logger.debug("UDP channel init failed. More info: " + traceback.format_exc())
      pass
    else:
      callback(channel)
      wait_any(None, cancellation_token, channel._channel_broken)
    time.sleep(1)
Example #3
0
    def remote_endpoint_operation(self, endpoint_id, input, expect_ack,
                                  output_length):
        if input is None:
            input = bytearray(0)
        if (len(input) >= 128):
            raise Exception("packet larger than 127 currently not supported")

        if (expect_ack):
            endpoint_id |= 0x8000

        self._my_lock.acquire()
        try:
            self._outbound_seq_no = ((self._outbound_seq_no + 1) & 0x7fff)
            seq_no = self._outbound_seq_no
        finally:
            self._my_lock.release()
        seq_no |= 0x80  # FIXME: we hardwire one bit of the seq-no to 1 to avoid conflicts with the ascii protocol
        packet = struct.pack('<HHH', seq_no, endpoint_id, output_length)
        packet = packet + input

        crc16 = calc_crc16(CRC16_INIT, packet)
        if (endpoint_id & 0x7fff == 0):
            trailer = PROTOCOL_VERSION
        else:
            trailer = self._interface_definition_crc
        #print("append trailer " + trailer)
        packet = packet + struct.pack('<H', trailer)

        if (expect_ack):
            ack_event = Event()
            self._expected_acks[seq_no] = ack_event
            try:
                attempt = 0
                while (attempt < self._send_attempts):
                    self._my_lock.acquire()
                    try:
                        self._output.process_packet(packet)
                    except ChannelDamagedException:
                        attempt += 1
                        continue  # resend
                    finally:
                        self._my_lock.release()
                    # Wait for ACK until the resend timeout is exceeded
                    try:
                        if wait_any(self._resend_timeout, ack_event,
                                    self._channel_broken) != 0:
                            raise ChannelBrokenException()
                    except TimeoutError:
                        attempt += 1
                        continue  # resend
                    return self._responses.pop(seq_no)
                    # TODO: record channel statistics
                raise ChannelBrokenException()  # Too many resend attempts
            finally:
                self._expected_acks.pop(seq_no)
                self._responses.pop(seq_no, None)
        else:
            # fire and forget
            self._output.process_packet(packet)
            return None
Example #4
0
    def remote_endpoint_operation(self, endpoint_id, input, expect_ack, output_length):
        if input is None:
            input = bytearray(0)
        if (len(input) >= 128):
            raise Exception("packet larger than 127 currently not supported")

        if (expect_ack):
            endpoint_id |= 0x8000

        self._my_lock.acquire()
        try:
            self._outbound_seq_no = ((self._outbound_seq_no + 1) & 0x7fff)
            seq_no = self._outbound_seq_no
        finally:
            self._my_lock.release()
        seq_no |= 0x80 # FIXME: we hardwire one bit of the seq-no to 1 to avoid conflicts with the ascii protocol
        packet = struct.pack('<HHH', seq_no, endpoint_id, output_length)
        packet = packet + input

        crc16 = calc_crc16(CRC16_INIT, packet)
        if (endpoint_id & 0x7fff == 0):
            trailer = PROTOCOL_VERSION
        else:
            trailer = self._interface_definition_crc
        #print("append trailer " + trailer)
        packet = packet + struct.pack('<H', trailer)

        if (expect_ack):
            ack_event = Event()
            self._expected_acks[seq_no] = ack_event
            try:
                attempt = 0
                while (attempt < self._send_attempts):
                    self._my_lock.acquire()
                    try:
                        self._output.process_packet(packet)
                    except ChannelDamagedException:
                        attempt += 1
                        continue # resend
                    except TimeoutError:
                        attempt += 1
                        continue # resend
                    finally:
                        self._my_lock.release()
                    # Wait for ACK until the resend timeout is exceeded
                    try:
                        if wait_any(self._resend_timeout, ack_event, self._channel_broken) != 0:
                            raise ChannelBrokenException()
                    except TimeoutError:
                        attempt += 1
                        continue # resend
                    return self._responses.pop(seq_no)
                    # TODO: record channel statistics
                raise ChannelBrokenException() # Too many resend attempts
            finally:
                self._expected_acks.pop(seq_no)
                self._responses.pop(seq_no, None)
        else:
            # fire and forget
            self._output.process_packet(packet)
            return None