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)
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)
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
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