def aes_cbc(self, opts): """ AES CBC command handler """ msg = Message().set_code(Opcodes.AES_CBC) msg.set_data(string_to_bytes('0'*15 + '1' + ' '.join(opts.text))) print(colored("⚠️ The IV is always set to be 0000000000000001 in interactive mode.", 'yellow', attrs=["bold"])) self.comm.write_serial(msg.serialize()) self.print_response()
def stop_listen_thread(self): self._stop_listen.set() # send a nothing message to myself to stop receive from blocking temp_save_send_port = self.send_port self.send_port = self.listen_port self._send_message(Message(self, Message.acknowledge(self._my_robot_id, self._my_robot_id, 0))) self.send_port = temp_save_send_port self._listen_thread.join()
def test_comm(): d = DataRepository(10, 10) # change broadcast address for testing CommunicationManager.DEFAULT_BROADCAST = "127.255.255.255" c = CommunicationManager(d, 1, 1) c.start_listen_thread() c.send_message(Message()) sleep(5) c.send_message(Message())
def _receive_incoming_messages(self): """ thread function open listening socket and handle messages """ listen_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: print("starting listening socket") listen_socket.bind((CommunicationManager.HOST, self.listen_port)) except Exception as e: print("unable to start listening socket", e) print("tried HOST:", CommunicationManager.HOST, " PORT:", self.listen_port) return print("listening socket opened") while not self._stop_listen.is_set(): data, address = listen_socket.recvfrom(1024) string = bytes.decode(data) # decode it to string message = Message(self, string) from_robot_id = message.get_sender() # debug # if not message.is_ack(): # print("incoming connection from", address[0], " robot", from_robot_id) if from_robot_id != self._my_robot_id: # ignore if it's from me # debug # if not message.is_ack(): # print("message:", message.get_data()) # check to see if it's an acknowledgement if message.is_ack(): robot_id, message_id = message.get_ack_info() # check to see if it's an acknowledgement TO ME if robot_id == self._my_robot_id: self._highest_acknowledge_from[from_robot_id] = \ max(message_id, self._highest_acknowledge_from[from_robot_id]) # else ignore it (not for me) else: # not an acknowledgement acknowledge_this = False try: robot_id, message_id = message.extract_from_info() # print("checking message id", message_id) if message_id == self._highest_acknowledge_to[robot_id] + 1: # print("handling", message_id) message.handle(self._data) acknowledge_this = True # if handle raises exception, this line won't run # else it's either already handled or one was skipped, so ignore it except ValueError as e: print("handle message failed:", e) robot_id = 0 message_id = 0 if acknowledge_this: # outgoing thread will make acknowledgement and send it # TODO: do we need a mutex around this and outgoing thread iteration? self._highest_acknowledge_to[robot_id] = message_id
def do_generate_proof(self, opts): """ Command to hash the flash memory """ msg = Message().set_code(Opcodes.MD5_FLASH) if opts.bounds is None: msg.set_data(bytes()) else: msg.set_data(int_to_bytes(opts.bounds[0], 2) + int_to_bytes(opts.bounds[1], 2)) self.comm.write_serial(msg.serialize()) self.print_response()
def _send_message(self, message: Message): """ outgoing thread calls this to send messages """ data = message.get_data().encode("utf-8") # if not message.is_ack(): # print("sending", data) send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) send_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) send_socket.connect((self.broadcast, self.send_port)) send_socket.sendall(data) send_socket.shutdown(socket.SHUT_WR) send_socket.close()
def visit_current_space(self) -> float: """ :returns time taken """ total_time = 0 message = Message(self.communication) # objective reading already_have = self.data.get_objective( self.interface.position) != Knowledge.UNKNOWN data, time_taken = self.interface.read_sensor() total_time += time_taken self.data.set_objective(self.interface.position, data) if not already_have: message.add_objective( self.interface.position, self.data.get_objective(self.interface.position)) # check obstacles for direction in COORDINATE_CHANGE: looking_at = self.interface.position + COORDINATE_CHANGE[direction] if not self.data.out_of_bounds(looking_at): previous = self.data.get_obstacle(looking_at) obstacle_reading, time_taken = self.interface.see_obstacles( direction) total_time += time_taken new = Knowledge.YES if obstacle_reading else Knowledge.NO if new != previous: self.data.set_obstacle(looking_at, new) message.add_obstacle(looking_at, new) self.communication.send_message(message) return total_time
def do_secure_channel(self, opts): """ Command to toggle secure mode """ msg = Message().set_code(Opcodes.CRYPTO_SWITCH) if opts.state == 'on': self.comm.start_decrypting_messages() msg.set_data_from_string('1') else: self.comm.stop_decrypting_messages() msg.set_data_from_string('0') self.comm.write_serial(msg.serialize()) self.print_response()
def _outgoing_thread(self): previous_message_id = 0 # used to put a delay between repeating sends of the same message timer = time.time() while not self._stop_send.is_set(): # print(" ------------------------------------------------ checking ack interval") if time.time() - CommunicationManager.ACK_INTERVAL > timer: # print("sending acknowledgements:", [v for v in self._highest_acknowledge_to.values()]) # send all acknowledgements for robot_id, message_id in self._highest_acknowledge_to.items(): ack = Message(self, Message.acknowledge(self._my_robot_id, robot_id, message_id)) self._send_message(ack) timer = time.time() # send messages from outgoing queue # print("about to pull a message from queue") try: message = self._unacknowledged_messages.get(timeout=CommunicationManager.ACK_INTERVAL) this_message_id = message.extract_from_info()[1] # print("pulled from queue", this_message_id) # check has this id been acknowledged by everyone? acknowledged = True for message_id in self._highest_acknowledge_from.values(): if message_id < this_message_id: acknowledged = False if not acknowledged: if this_message_id <= previous_message_id: time.sleep(CommunicationManager.ACK_INTERVAL) previous_message_id = this_message_id self._send_message(message) self._unacknowledged_messages.put(message) # else this message has been acknowledged by everyone, so drop it else: # debugging # print(this_message_id, "acknowledged, so dropping") pass except Empty: # print("queue empty") pass
def test_message(): print(Message.coord_str(Coordinate(536, 0))) assert Message.coord_str(Coordinate(536, 0)) == "536 0 " print("passed Message.coord_str") Message.set_my_robot_id(1) m = Message() m.add_objective(Coordinate(3, 5), 2.0) print(m.get_data()) assert m.get_data() == Message.BEGIN + "1 1 j3 5 2.0k" + Message.END print("passed add_objective") m._cursor = 10 ov = m.extract_objective_value() print(ov) assert ov == 2.0 print("passed extract_objective_value") m = Message() m.add_obstacle(Coordinate(0, 6), Knowledge.YES) print(m.get_data()) assert m.get_data() == Message.BEGIN + "1 2 s0 6 yt" + Message.END print("passed add_obstacle") m._cursor = 6 co = m.extract_coordinates() print(co) assert co == Coordinate(0, 6) print("passed extract coordinate") d = DataRepository(10, 10) m.add_objective(Coordinate(6, 0), 7.0) m.handle(d) obs = d.get_obstacle(Coordinate(0, 6)) obj = d.get_objective(Coordinate(6, 0)) print(obs, obj) assert obs == Knowledge.YES assert obj == 7.0 print("passed handle")
def aes_ecb(self, opts): """ AES ECB command handler""" msg = Message().set_code(Opcodes.AES_ECB) msg.set_data_from_string(' '.join(opts.text)) self.comm.write_serial(msg.serialize()) self.print_response()
def do_md5(self, opts): """ md5 command """ msg = Message().set_code(Opcodes.MD5) msg.set_data_from_string(' '.join(opts.text)) self.comm.write_serial(msg.serialize()) self.print_response()
def do_sensor_reading(self, _opts): """ Command to get a sensor reading from the Arduino """ msg = Message().set_code(Opcodes.SENSOR_READING) msg.set_data(bytes()) self.comm.write_serial(msg.serialize()) self.print_response()