def get_state(self, *args): """ Respond to an incoming get_state request :param args: not applicable to this command :return: """ log.msg('get_state: %r %d' % (self.connections, self.num_connections)) if len(self.connections) == self.num_connections: return Packet.create('CONNECTED', PacketType.PA_STATUS) return Packet.create('DISCONNECTED', PacketType.PA_STATUS)
def get_config(self, *args): """ Respond to an incoming get_config request :param args: not applicable to this command :return: """ return Packet.create(json.dumps(self.config), PacketType.PA_CONFIG)
def _set_select(self, command, *args): if len(args) == 0: num_sources = self.orb.select('') else: num_sources = self.orb.select(args[0]) msg = 'Orb select(%s) yielded num_sources: %d' % (args[:1], num_sources) return Packet.create(msg + NEWLINE, PacketType.PA_STATUS)
def fileRetrieved(self, write_result): file_obj, file_attributes, file_size = write_result # Remove '.part' from the end of the file name now that the download is complete new_file_path = file_obj.name[:-5] os.rename(file_obj.name, new_file_path) new_filename = os.path.basename(new_file_path) log.msg('File downloaded: ', new_filename) orig_filename = new_filename.split('_')[1] self.retrieved_file_queue.append(orig_filename) file_obj.close() # Send a message to the driver indicating that a new image has been retrieved # The driver will then associate metadata with the image file name packets = Packet.create('New Image:' + str(new_filename), PacketType.FROM_INSTRUMENT) self.router.got_data(packets) reactor.callLater(0, self.fetch_file)
def get_version(self, *args): """ Respond to an incoming get_version request :param args: not applicable to this command :return: """ return Packet.create(ooi_port_agent.__version__, PacketType.PA_CONFIG)
def _notify(self, filename): # Send a message to the driver indicating that a new image has been retrieved # The driver will then associate metadata with the image file name packets = Packet.create('downloaded file:' + str(filename) + '\n', PacketType.FROM_INSTRUMENT) self.factory.port_agent.router.got_data(packets) log.msg('Packet sent to driver: %s' % filename)
def notify_disconnected(self): """ Send a disconnect notification to the instrument driver :return: """ log.msg('Notifying driver we are DISCONNECTED') self.disconnect_notification_id = None self.router.got_data(Packet.create('DISCONNECTED', PacketType.PA_STATUS))
def handle_command(self, command_line): log.msg('handle_command: %s' % command_line) parts = command_line.split() if len(parts) > 0: command = parts[0] args = parts[1:] if command in self.callbacks: packets = yield self.callbacks[command](command, *args) else: packets = Packet.create('Received bad command on command port: %r' % command, PacketType.PA_FAULT) else: packets = Packet.create('Received empty command on command port', PacketType.PA_FAULT) if packets: self.port_agent.router.got_data(packets)
def handle_command(self, command_line): log.msg('handle_command: %s' % command_line) parts = command_line.split() if len(parts) > 0: command = parts[0] args = parts[1:] if command in self.callbacks: packets = self.callbacks[command](command, *args) else: packets = Packet.create('Received bad command on command port: %r' % command, PacketType.PA_FAULT) else: packets = Packet.create('Received empty command on command port', PacketType.PA_FAULT) if packets: self.port_agent.router.got_data(packets)
def _set_seek(self, command, *args): if len(args) == 0: seek = ORBOLDEST else: seek = int(args[0]) self.orb.seek(seek) msg = 'Orb seek set to %s' % seek return Packet.create(msg + NEWLINE, PacketType.PA_STATUS)
def _orb_stop(self, *args): self.keep_going = False if self.orb_thread is not None: self.orb_thread.join() self.orb_thread = None msg = 'Stopped orb thread' else: msg = 'Orb thread not running!' return Packet.create(msg + NEWLINE, PacketType.PA_STATUS)
def notify_disconnected(self): """ Send a disconnect notification to the instrument driver :return: """ log.msg('Notifying driver we are DISCONNECTED') self.disconnect_notification_id = None self.router.got_data( Packet.create('DISCONNECTED', PacketType.PA_STATUS))
def _orb_start(self, *args): self._pause = False if self.orb_thread is None: self.keep_going = True self.orb_thread = OrbThread(self.orb, self) self.orb_thread.start() msg = 'Started orb thread' else: msg = 'Orb already running!' return Packet.create(msg + NEWLINE, PacketType.PA_STATUS)
def _heartbeat(self): packets = Packet.create('HB', PacketType.PA_HEARTBEAT) self.router.got_data(packets) # Set TTL Check Status check_string = self._agent + 'check/pass/service:' for port_id in [self.data_port_id, self.command_port_id, self.sniffer_port_id]: d = get(check_string + port_id) d.addCallback(self.done, caller='TTL check status: %s' % port_id) d.addErrback(log.msg, 'Error sending check: %s' % port_id) reactor.callLater(HEARTBEAT_INTERVAL, self._heartbeat)
def _handle_digi_command(self, command, *args): """ Request a protocol object connected to the DIGI command port, then produce the packets corresponding to a requested digi command :param command: command :param args: arguments :return: List of packets representing this command. """ command = [command] + list(args) command = ' '.join(command) + NEWLINE protocol = yield self._start_inst_command_connection() protocol.write(command) returnValue(Packet.create(command, PacketType.DIGI_CMD))
def _heartbeat(self): """ Send a heartbeat packet and set our Consul status to PASS :return: """ packets = Packet.create('HB', PacketType.PA_HEARTBEAT) self.router.got_data(packets) # Set TTL Check Status check_string = self._agent + 'check/pass/service:' for service in self.config['ports']: name, service_id = self.get_service_name_id(service) yield get(check_string + service_id)
def _heartbeat(self): packets = Packet.create('HB', PacketType.PA_HEARTBEAT) self.router.got_data(packets) # Set TTL Check Status check_string = self._agent + 'check/pass/service:' get(check_string + self.data_port_id).addCallback( self.done, caller='%s TTL check status: ' % self.data_port_id) get(check_string + self.command_port_id).addCallback( self.done, caller='%s TTL check status: ' % self.command_port_id) get(check_string + self.sniffer_port_id).addCallback( self.done, caller='%s TTL check status: ' % self.sniffer_port_id) reactor.callLater(HEARTBEAT_INTERVAL, self._heartbeat)
def create_packets(orb_packet, pktid): packets = [] for channel in orb_packet.channels: d = {'calib': channel.calib, 'calper': channel.calper, 'net': channel.net, 'loc': channel.loc, 'sta': channel.sta, 'chan': channel.chan, 'data': channel.data, 'nsamp': channel.nsamp, 'samprate': channel.samprate, 'time': channel.time, 'type_suffix': orb_packet.type.suffix, 'version': orb_packet.version, 'pktid': pktid, } packets.extend(Packet.create(pickle.dumps(d, protocol=-1), PacketType.PICKLED_FROM_INSTRUMENT)) return packets
def connect(self, address: Tuple[str, int]): # send syn; receive syn, ack; send ack # your code here assert self.state == State.CLOSED conn = Connection(address, self) self.connection = conn def receive(): while conn.receive_data: try: data, addr = self.recvfrom(10 * 1024 * 1024) packet = Packet.from_bytes(data) conn.on_recv_packet(packet) except: pass self.receiver = Thread(target=receive) self.receiver.start() conn.state = State.SYN_SENT conn.send_packet(Packet.create(conn.seq, conn.ack, b'\xAC', SYN=True))
def filesListed(self, results): for img_name in results: file_name = img_name.filename if all([ file_name.endswith('png'), file_name not in self.retrieved_file_queue, file_name not in self.pending_file_queue ]): # Queue up pending files for download self.pending_file_queue.append(file_name) # Send a message to the driver indicating that a new image has been listed # The driver will then associate metadata with the image file name packets = Packet.create('New Image:' + str(file_name), PacketType.FROM_INSTRUMENT) self.router.got_data(packets) reactor.callLater(0, self.fetch_file)
def instrument_connected(self, connection): """ Log a successful instrument connection, notifying the driver if the target number of connections is reached. :param connection: connection object :return: """ log.msg('CONNECTED TO ', connection) self.connections.add(connection) if len(self.connections) == self.num_connections: # We are now CONNECTED # Cancel any pending DISCONNECTED notification if self.disconnect_notification_id is not None: try: self.disconnect_notification_id.cancel() except AlreadyCalled: pass finally: self.disconnect_notification_id = None # Notify driver we are CONNECTED self.router.got_data(Packet.create('CONNECTED', PacketType.PA_STATUS))
def instrument_connected(self, connection): """ Log a successful instrument connection, notifying the driver if the target number of connections is reached. :param connection: connection object :return: """ log.msg('CONNECTED TO ', connection) self.connections.add(connection) if len(self.connections) == self.num_connections: # We are now CONNECTED # Cancel any pending DISCONNECTED notification if self.disconnect_notification_id is not None: try: self.disconnect_notification_id.cancel() except AlreadyCalled: pass finally: self.disconnect_notification_id = None # Notify driver we are CONNECTED self.router.got_data( Packet.create('CONNECTED', PacketType.PA_STATUS))
def create_packets(orb_packet, pktid): packets = [] for channel in orb_packet.channels: d = { 'calib': channel.calib, 'calper': channel.calper, 'net': channel.net, 'loc': channel.loc, 'sta': channel.sta, 'chan': channel.chan, 'data': channel.data, 'nsamp': channel.nsamp, 'samprate': channel.samprate, 'time': channel.time, 'type_suffix': orb_packet.type.suffix, 'version': orb_packet.version, 'pktid': pktid, } packets.extend( Packet.create(pickle.dumps(d, protocol=-1), PacketType.PICKLED_FROM_INSTRUMENT)) return packets
def dataReceived(self, data): """ Called asynchronously when data is received from this connection """ self.port_agent.router.got_data(Packet.create(data, self.packet_type))
def get_state(self, *args): msg = 'CONNECTED' return Packet.create(msg, PacketType.PA_STATUS)
def instrument_disconnected(self, connection): self.connections.remove(connection) log.msg('DISCONNECTED FROM ', connection) self.router.got_data(Packet.create('DISCONNECTED', PacketType.PA_STATUS))
def lineReceived(self, line): packets = Packet.create(line, self.packet_type) self.port_agent.router.got_data(packets) self.handle_command(line)
def _list_channels(self, *args): sources = self.orb.sources() return Packet.create(json.dumps(sources, indent=1) + NEWLINE, PacketType.PA_STATUS)
def get_state(self, *args): log.msg('get_state: %r %d' % (self.connections, self.num_connections)) if len(self.connections) == self.num_connections: return Packet.create('CONNECTED', PacketType.PA_STATUS) return Packet.create('DISCONNECTED', PacketType.PA_STATUS)
def _handle_digi_command(self, command, *args): command = [command] + list(args) return Packet.create(' '.join(command) + NEWLINE, PacketType.DIGI_CMD)
def get_version(self, *args): return Packet.create(ooi_port_agent.__version__, PacketType.PA_CONFIG)
def get_config(self, *args): return Packet.create(json.dumps(self.config), PacketType.PA_CONFIG)
def get_state(self, *args): if self.orb_thread is not None: msg = 'CONNECTED' else: msg = 'DISCONNECTED' return Packet.create(msg + NEWLINE, PacketType.PA_STATUS)
def uart_rx_callback(rx_byte): print(chr(rx_byte), end='') if __name__ == '__main__': ser = UART(port='/dev/ttyUSB0') crc = CRC32() packet = Packet(ser, crc, address=2) thread = threading.Thread(target=read) thread.start() while True: packet.create([0, 0, 0]) packet.tx() packet.create([50, 0, 0]) packet.tx() packet.create([100, 0, 0]) packet.tx() packet.create([150, 0, 0]) packet.tx() packet.create([200, 0, 0]) packet.tx() packet.create([250, 0, 0]) packet.tx() packet.create([200, 0, 0]) packet.tx() packet.create([150, 0, 0]) packet.tx()
def gotMessage(self, message, tag): self.port_agent.router.got_data(Packet.create(tag, self.packet_type)) self.port_agent.router.got_data(Packet.create(message + NEWLINE, self.packet_type))
def _list_channels(self, *args): sources = self.orb.sources() return Packet.create( json.dumps(sources, indent=1) + NEWLINE, PacketType.PA_STATUS)
def close(self) -> None: assert self.state in (State.SYN_RCVD, State.ESTABLISHED) self.sends.put(Packet.create(data=b'\xAF', FIN=True)) self.state = State.FIN_WAIT_1
def instrument_connected(self, connection): log.msg('CONNECTED TO ', connection) self.connections.add(connection) if len(self.connections) == self.num_connections: self.router.got_data(Packet.create('CONNECTED', PacketType.PA_STATUS))
def run(self): conn = self.conn socket = conn.socket no_packet = 0 while self.alive: now = datetime.now().timestamp() sending = conn.sending conn.sending = [] for packet, send_time in sending: if conn.seq >= packet.seq + packet.LEN: continue if now - send_time >= 1.0: print(conn.state, "retransmit ", end='') conn.send_packet(packet) else: conn.sending.append((packet, send_time)) # close if conn.state == State.TIME_WAIT and no_packet >= 6: conn.state = State.CLOSED print(conn.state) conn.close_connection() # send data if len(conn.receive.queue) == 0 and len(conn.sends.queue) != 0 and \ len(conn.sending) == 0 and no_packet >= 3 and conn.state in (State.ESTABLISHED, State.FIN_WAIT_1): data = conn.sends.get() if isinstance(data, Packet): to_send = Packet.create(conn.seq, conn.ack, data.payload, SYN=data.SYN, ACK=data.ACK, FIN=data.FIN) else: to_send = Packet.create(conn.seq, conn.ack, data) print(conn.state, "send ", end='') conn.send_packet(to_send) # receive date packet: Packet try: packet = conn.receive.get(timeout=0.5) no_packet = 0 except: no_packet += 1 continue print(conn.state, "recv", packet) if packet.LEN != 0 and packet.seq < conn.ack: print(conn.state, "resend ", end='') conn.send_packet(Packet.create(conn.seq, conn.ack, ACK=True)) continue if packet.LEN != 0 and packet.seq > conn.ack: print(conn.state, "unordered ", packet) continue if packet.ACK: conn.seq = max(conn.seq, packet.ack) if packet.LEN != 0: conn.ack = max(conn.ack, packet.seq + packet.LEN) not_arrive = [it for (it, send_time) in conn.sending if conn.seq < it.seq + it.LEN] all_packet_arrive = len(conn.sends.queue) == 0 and len(not_arrive) == 0 if conn.state == State.CLOSED and packet.SYN: conn.state = State.SYN_RCVD print(conn.state, "send ", end='') conn.send_packet(Packet.create(conn.seq, conn.ack, b'\xAC', SYN=True, ACK=True)) elif conn.state == State.SYN_SENT and packet.SYN: conn.state = State.ESTABLISHED print(conn.state, "send ", end='') conn.send_packet(Packet.create(conn.seq, conn.ack, ACK=True)) elif conn.state == State.SYN_RCVD and packet.ACK: assert packet.ack == 1 conn.state = State.ESTABLISHED # close elif conn.state == State.ESTABLISHED and packet.FIN: conn.send_packet(Packet.create(conn.seq, conn.ack, ACK=True)) conn.state = State.CLOSE_WAIT if all_packet_arrive: conn.send_packet(Packet.create(conn.seq, conn.ack, b'\xAF', FIN=True, ACK=True)) conn.state = State.LAST_ACK elif conn.state == State.FIN_WAIT_1 and all_packet_arrive: conn.state = State.FIN_WAIT_2 if packet.FIN and packet.ACK: conn.send_packet(Packet.create(conn.seq, conn.ack, ACK=True)) conn.state = State.TIME_WAIT elif conn.state == State.CLOSE_WAIT and all_packet_arrive: conn.send_packet(Packet.create(conn.seq, conn.ack, b'\xAF', FIN=True, ACK=True)) conn.state = State.LAST_ACK elif conn.state in (State.FIN_WAIT_1, State.FIN_WAIT_2) and packet.FIN and packet.ACK: conn.send_packet(Packet.create(conn.seq, conn.ack, ACK=True)) conn.state = State.TIME_WAIT elif conn.state == State.LAST_ACK and packet.ACK: conn.state = State.CLOSED print(conn.state) conn.close_connection() elif packet.LEN != 0: conn.message.put(packet) print(conn.state, "send ", end='') conn.send_packet(Packet.create(conn.seq, conn.ack, ACK=True))