def send_qubit(self, receiver_id, q, await_ack=False): """ Send the qubit *q* to the receiver with ID *receiver_id*. Args: receiver_id (string): The receiver ID to send the message to q (Qubit): The qubit to send await_ack (bool): If sender should wait for an ACK. Returns: string, boolean: If await_ack=True, return the ID of the qubit and the status of the ACK """ q.set_blocked_state(True) q_id = q.id seq_num = self._get_sequence_number(receiver_id) packet = protocols.encode(sender=self.host_id, receiver=receiver_id, protocol=protocols.SEND_QUBIT, payload=q, payload_type=protocols.QUANTUM, sequence_num=seq_num, await_ack=await_ack) self.logger.log(self.host_id + " sends QUBIT to " + receiver_id) self._packet_queue.put(packet) if packet.await_ack: self._log_ack('SEND QUBIT', receiver_id, packet.seq_num) return q_id, self.await_ack(packet.seq_num, receiver_id) return q_id
def send_key(self, receiver_id, key_size, await_ack=True): """ Args: receiver_id: key_size: await_ack: Returns: bool """ seq_num = self._get_sequence_number(receiver_host.host_id) packet = protocols.encode(sender=self.host_id, receiver=receiver_id, protocol=protocols.SEND_KEY, payload={'keysize': key_size}, payload_type=protocols.CLASSICAL, sequence_num=seq_num, await_ack=await_ack) self.logger.log(self.host_id + " sends KEY to " + receiver_id) self._packet_queue.put(packet) if packet.await_ack: self._log_ack('EPR', receiver_id, seq_num) return self.await_ack(seq_num, receiver_id)
def send_superdense(self, receiver_id, message, await_ack=False): """ Send the two bit binary (i.e. '00', '01', '10', '11) message via superdense coding to the receiver with receiver ID *receiver_id*. Args: receiver_id (string): The receiver ID to send the message to message (string): The two bit binary message await_ack (bool): If sender should wait for an ACK. Returns: boolean: If await_ack=True, return the status of the ACK """ packet = protocols.encode( sender=self.host_id, receiver=receiver_id, protocol=protocols.SEND_SUPERDENSE, payload=message, payload_type=protocols.CLASSICAL, sequence_num=self._get_sequence_number(receiver_id), await_ack=await_ack) self.logger.log(self.host_id + " sends SUPERDENSE to " + receiver_id) self._packet_queue.put(packet) if packet.await_ack: self._log_ack('SUPERDENSE', receiver_id, packet.seq_num) return self.await_ack(packet.seq_num, receiver_id)
def send_epr(self, receiver_id, q_id=None, await_ack=False, block=False): """ Establish an EPR pair with the receiver and return the qubit ID of pair. Args: receiver_id (string): The receiver ID q_id (string): The ID of the qubit await_ack (bool): If sender should wait for an ACK. block (bool): If the created EPR pair should be blocked or not. Returns: string, boolean: If await_ack=True, return the ID of the EPR pair and the status of the ACK """ if q_id is None: q_id = str(uuid.uuid4()) seq_num = self._get_sequence_number(receiver_id) packet = protocols.encode(sender=self.host_id, receiver=receiver_id, protocol=protocols.SEND_EPR, payload={ 'q_id': q_id, 'blocked': block }, payload_type=protocols.SIGNAL, sequence_num=seq_num, await_ack=await_ack) self.logger.log(self.host_id + " sends EPR to " + receiver_id) self._packet_queue.put(packet) if packet.await_ack: self._log_ack('EPR', receiver_id, seq_num) return q_id, self.await_ack(seq_num, receiver_id) return q_id
def send_classical(self, receiver_id, message, await_ack=False): """ Sends the classical message to the receiver host with ID:receiver Args: receiver_id (string): The ID of the host to send the message. message (string): The classical message to send. await_ack (bool): If sender should wait for an ACK. Returns: boolean: If await_ack=True, return the status of the ACK """ seq_num = self._get_sequence_number(receiver_id) packet = protocols.encode(sender=self.host_id, receiver=receiver_id, protocol=protocols.SEND_CLASSICAL, payload=message, payload_type=protocols.CLASSICAL, sequence_num=seq_num, await_ack=await_ack) self.logger.log(self.host_id + " sends CLASSICAL to " + receiver_id + " with sequence " + str(seq_num)) self._packet_queue.put(packet) if packet.await_ack: self._log_ack('classical', receiver_id, seq_num) return self.await_ack(packet.seq_num, receiver_id)
def send_ack(self, receiver, seq_number): """ Sends the classical message to the receiver host with ID:receiver Args: receiver (string): The ID of the host to send the message. seq_number (int): Sequence number of the acknowleged packet. """ packet = protocols.encode(sender=self.host_id, receiver=receiver, protocol=protocols.SEND_CLASSICAL, payload=protocols.ACK, payload_type=protocols.SIGNAL, sequence_num=seq_number, await_ack=False) if receiver not in self._seq_number_receiver: self._seq_number_receiver[receiver] = [[], 0] expected_seq = self._seq_number_receiver[receiver][1] if expected_seq + self._max_window < seq_number: raise Exception( "Message with seq number %d did not come before the receiver window closed!" % expected_seq) elif expected_seq < seq_number: self._seq_number_receiver[receiver][0].append(seq_number) else: self._seq_number_receiver[receiver][1] += 1 expected_seq = self._seq_number_receiver[receiver][1] while len(self._seq_number_receiver[receiver][0]) > 0 and expected_seq in \ self._seq_number_receiver[receiver][0]: self._seq_number_receiver[receiver][0].remove(expected_seq) self._seq_number_receiver[receiver][1] += 1 expected_seq += 1 self._packet_queue.put(packet)
def send_teleport(self, receiver_id, q, await_ack=False, payload=None, generate_epr_if_none=True): """ Teleports the qubit *q* with the receiver with host ID *receiver* Args: receiver_id (string): The ID of the host to establish the EPR pair with q (Qubit): The qubit to teleport await_ack (bool): If sender should wait for an ACK. payload: generate_epr_if_none: Generate an EPR pair with receiver if one doesn't exist Returns: boolean: If await_ack=True, return the status of the ACK """ packet = protocols.encode( sender=self.host_id, receiver=receiver_id, protocol=protocols.SEND_TELEPORT, payload={ 'q': q, 'generate_epr_if_none': generate_epr_if_none }, payload_type=protocols.CLASSICAL, sequence_num=self._get_sequence_number(receiver_id), await_ack=await_ack) if payload is not None: packet.payload = payload self.logger.log(self.host_id + " sends TELEPORT to " + receiver_id) self._packet_queue.put(packet) if packet.await_ack: self._log_ack('TELEPORT', receiver_id, packet.seq_num) return self.await_ack(packet.seq_num, receiver_id)