def _run_job(pipe_to_parent: Connection, job: MountainJob) -> None: result0 = job._execute(print_console_out=False) pipe_to_parent.send(result0.getObject()) # wait for message to return while True: if pipe_to_parent.poll(): pipe_to_parent.recv() return time.sleep(0.1)
def _acquire_handles(conn: Connection) -> List[IO]: log = logging.getLogger('_acquire_handles') log.info('Attempting to acquire file handles.') conn.send(os.getpid()) wrapper = conn.recv() handles = [] while wrapper is not None: handles.append(_acquire_handle(conn, *wrapper)) wrapper = conn.recv() return handles
def _pjh_run_job(pipe_to_parent: Connection, job: Dict[str, Any], kachery_config: dict) -> None: import kachery as ka ka.set_config(**kachery_config) hither._run_job(job) pipe_to_parent.send(job['result'].serialize()) # wait for message to return while True: if pipe_to_parent.poll(): pipe_to_parent.recv() return time.sleep(0.1)
def run(conn: Connection) -> None: """ Static Process Function. When a new Backend process is started, it enters here. Currently, it creates a WorkQueue with a worker thread and communicates with the BQSKit Frontend via conn. Args: conn (Connection): The connection object used to communicate to the frontend. Reads commands from the connection, processes them, and responds in a loop. """ wq = WorkQueue() while True: msg = conn.recv() if msg == 'CLOSE': wq.stop() conn.close() break elif msg == 'SUBMIT': task = conn.recv() if not isinstance(task, CompilationTask): pass # TODO: Handle Error wq.enqueue(task) conn.send('OKAY') elif msg == 'STATUS': task_id = conn.recv() if not isinstance(task_id, uuid.UUID): pass # TODO: Handle Error conn.send(wq.status(task_id)) elif msg == 'RESULT': task_id = conn.recv() if not isinstance(task_id, uuid.UUID): pass # TODO: Handle Error conn.send(wq.result(task_id)) elif msg == 'REMOVE': task_id = conn.recv() if not isinstance(task_id, uuid.UUID): pass # TODO: Handle Error wq.remove(task_id) conn.send('OKAY')
def device_receive(cls, data_connection: Connection, ctrl_connection: Connection, dev_parameters: OrderedDict): if not cls.init_device(ctrl_connection, is_tx=False, parameters=dev_parameters): return False try: cls.adapt_num_read_samples_to_sample_rate(dev_parameters[cls.Command.SET_SAMPLE_RATE.name]) except NotImplementedError: # Many SDRs like HackRF or AirSpy do not need to calculate READ_SAMPLES # as default values are either fine or given by the hardware pass if cls.ASYNCHRONOUS: cls.enter_async_receive_mode(data_connection) else: cls.prepare_sync_receive(ctrl_connection) exit_requested = False while not exit_requested: if cls.ASYNCHRONOUS: time.sleep(0.5) else: cls.receive_sync(data_connection) while ctrl_connection.poll(): result = cls.process_command(ctrl_connection.recv(), ctrl_connection, is_tx=False) if result == cls.Command.STOP.name: exit_requested = True break cls.shutdown_device(ctrl_connection) data_connection.close() ctrl_connection.close()
def relay( sub_id: str, shutdown: threading.Event, channel: connection.Connection, callback: Callable[[Dict[str, Any]], None], ) -> None: while not shutdown.is_set(): try: if channel.poll(timeout=1): ev = channel.recv() if ev['event_name'] == eventNames.SUBSCRIBED: logger.info( 'Subscriber#{0} subscribe ack received'.format( sub_id, ), ) elif ev['event_name'] == eventNames.UNSUBSCRIBED: logger.info( 'Subscriber#{0} unsubscribe ack received'.format( sub_id, ), ) break elif ev['event_name'] == eventNames.DISPATCHER_SHUTDOWN: logger.info( 'Subscriber#{0} received dispatcher shutdown event' .format(sub_id, ), ) break else: callback(ev) except queue.Empty: pass except EOFError: break except KeyboardInterrupt: break logger.debug('bbye!!!')
def _run_user_proc(user: pwd.struct_passwd, pipe: Connection) -> None: os.setgid(user.pw_gid) os.setuid(user.pw_uid) os.environ[ "DBUS_SESSION_BUS_ADDRESS" ] = f"unix:path=/run/user/{user.pw_uid}/bus" log.debug(f"Subprocess created with uid={os.getuid()} and gid={os.getgid()}") try: temp_noti: Notify.Notification = Notify.Notification.new("No message.") while not pipe.closed: log.debug( f"Blocking for new notifications from {pipe} on subprocess for user {user}" ) try: input = pipe.recv() except KeyboardInterrupt: input = "QUIT" if isinstance(input, Notification): temp_noti.update(input.summary, input.body, input.app_icon) temp_noti.set_hint_byte("urgency", input.urgency.value) try: temp_noti.show() except GDBusError as e: log.exception("Failed to show notification.") elif isinstance(input, str) and input == "QUIT": log.debug(f"Quit message received. Shutting down.") pipe.close() break except EOFError: log.debug(f"Pipe closed {pipe} on subprocess for user {user}")
def start_loop(name: str, conn: Connection): processes = [Process] while True: settings: dict = conn.recv() for process in processes: try: if process is not None and process.is_alive(): process.terminate() except Exception as ex: print(f'Failed to terminate loop process: {ex}') collect_process = Process(target=loop_collect, args=( name, settings, )) collect_process.start() processes.append(collect_process) send_process = Process(target=loop_send, args=( name, settings, )) send_process.start() processes.append(send_process)
def _player_process(conn: Connection, player_class: Type[AIPlayer], player_args: Tuple[Any]) -> None: # pragma: no cover """ Used to run an AIPlayer in a separate process. See OutOfProcessComputerPlayer.__init__() for more details. """ logging.info("AIProcess: Started") player = player_class(*player_args) logging.info("AIProcess: Player created successfully: %s", player) conn.send(player.cheater) while True: logging.info( "AIProcess: Waiting for a GameView from the UI process...") try: game_view, game_points = conn.recv() except EOFError: logging.info("AIProcess: The pipe was closed. Exiting.") break logging.info("AIProcess: GameView received. Processing...") action = player.request_next_action(game_view, game_points) logging.info("AIProcess: Sending action (%s) to the UI process", action) try: conn.send(action) except BrokenPipeError: logging.info("AIProcess: The pipe was closed. Exiting.") break
def inject( in_spout: Connection, injection_funnels: Dict[str, Connection], aux_funnel: Optional[Connection] = None, ) -> None: """ Receives data from the client and forwards it to a local process. """ # Exit when SIGTERM is sent, i.e. when we call .terminate(). signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit()) while 1: logging.info("INJECTION: waiting.") bparcel = in_spout.recv() parcel = dill.loads(bparcel) # Handle process signals. if aux_funnel and isinstance(parcel, (_Join, _Terminate, _Kill)): logging.info("INJECTION: got signal.") aux_funnel.send(parcel) continue # If the received object is not a signal, it ought to be a parcel. if not isinstance(parcel, Parcel): logging.info("INJECTION: Error: obj not a Parcel: %s", str(parcel)) continue assert not isinstance(parcel.obj, Parcel) logging.info("INJECTION: parcel: %s for pipe: %s", str(parcel), parcel.pipe_id) injection_funnels[parcel.pipe_id].send(parcel.obj)
def report_progress(conn_out: connection.Connection, prefix: str = '') -> None: """Tell the user how much work has been done. :param prefix: A message to print before the progress prompt, e.g. 'Progress: '. :param conn_out: A multiprocessing ``Connection`` object from which values may be read. Each value emitted by the object should be a float between 0 and 1, inclusive, where 0 indicates 0% complete, and 1 represents 100% complete. When a value of 1 is received, this function will return. :return: Nothing. """ while True: progress = conn_out.recv() # \r is carriage return. The other is an ANSI escape code. See: # https://en.wikipedia.org/wiki/ANSI_escape_code print( '\r\033[K' + prefix + f'{progress * 100:.0f}%', end='', ) sys.stdout.flush() if progress == 1: conn_out.close() print() break
def run_daemon(qa_pipe: Connection): wiki_daemon = WikiDaemon(WIKI_PAGE) wiki_daemon.update_wiki_cache() wiki_daemon.reload_spacy_docs() print("wiki_daemon: Child process started") next_wiki_update = time.time() + UPDATE_PERIOD_SECS while True: now = time.time() if next_wiki_update < now: print("wiki_daemon: Checking Wikipedia for updates") updated = wiki_daemon.update_wiki_cache() if updated: print("wiki_daemon: Got new revision, updating") next_wiki_update = now + UPDATE_PERIOD_SECS if qa_pipe.poll(timeout=next_wiki_update - now): try: question = qa_pipe.recv() qa_pipe.send(wiki_daemon.inquiry(question)) except EOFError: # Pipe was closed on other end, we're done here qa_pipe.close() return except ValueError: print("Answer was too large to send!") # Make sure the caller isn't still waiting for an object try: qa_pipe.send("") except EOFError: qa_pipe.close() return
def update(self, conn: Connection, rtsp_url: str, buffer: bool): """ Runs the rtspcam thread to grab data and keep the buffer empty. :param conn: the Pipe to transmit data :param rtsp_url: the url of the rtspcam. :param buffer: should the client read frame by frame from the buffer or just grab the latest frame? :return: """ self.log.info(f"Starting video capture client for {rtsp_url}") cap = VideoCapture(rtsp_url, CAP_FFMPEG) self.log.info("Started...") run = True while run: if not conn.poll() and not buffer: self.log.debug("clearing buffer frame") cap.grab() continue rec_dat = conn.recv() if rec_dat == self.SEND_FRAME: self.log.debug("Sending next frame to parent process") return_value, frame = cap.read() conn.send(frame) elif rec_dat == self.END_PROCESS: self.log.debug("Closing connection") cap.release() run = False self.log.info("Camera Connection Closed") conn.close()
def device_send(cls, ctrl_connection: Connection, send_config: SendConfig, dev_parameters: OrderedDict): if not cls.init_device(ctrl_connection, is_tx=True, parameters=dev_parameters): return False if cls.ASYNCHRONOUS: cls.enter_async_send_mode(send_config.get_data_to_send) else: cls.prepare_sync_send(ctrl_connection) exit_requested = False buffer_size = cls.CONTINUOUS_SEND_BUFFER_SIZE if send_config.continuous else cls.SEND_BUFFER_SIZE if not cls.ASYNCHRONOUS and buffer_size == 0: logger.warning("Send buffer size is zero!") while not exit_requested and not send_config.sending_is_finished(): if cls.ASYNCHRONOUS: time.sleep(0.5) else: cls.send_sync(send_config.get_data_to_send(buffer_size)) while ctrl_connection.poll(): result = cls.process_command(ctrl_connection.recv(), ctrl_connection, is_tx=True) if result == cls.Command.STOP.name: exit_requested = True break if exit_requested: logger.debug("{}: exit requested. Stopping sending".format(cls.__class__.__name__)) if send_config.sending_is_finished(): logger.debug("{}: sending is finished.".format(cls.__class__.__name__)) cls.shutdown_device(ctrl_connection) ctrl_connection.close()
def worker(opt: AbcOpt, conn: Connection, iterations: int, swap: int): """ Локальный поиск под управлением Поиска с запретами Табу обновляется раз в итерацию, в основном процессе хранится весь табу opt: эвристика conn: для передачи данных iterations: количество возможных перезапусков swap: сколько раз ломать тур за итерацию """ best_length, best_tour = opt.length, opt.tour.copy() length, tour = opt.length, opt.tour try: while iterations > 0: _length, _tour = opt.optimize() if best_length > _length: best_length, best_tour = _length, _tour.copy() assert round(get_length(best_tour, opt.matrix), 2) == round(best_length, 2), \ f'{get_length(best_tour, opt.matrix)} != {best_length}' conn.send(opt.solutions) solutions = conn.recv() mix(tour, swap) length = get_length(tour, opt.matrix) opt.length, opt.tour, opt.solutions = length, tour, solutions iterations -= 1 except Exception as exc: print(f'Exception: {exc}') conn.send(set()) conn.send(best_length) conn.send(best_tour)
def runClassifier(conn: Connection, model_save_file: str): logMessage("Starting model") model = Model() model.load_weights(model_save_file).expect_partial() logMessage("Model loaded") while True: try: img = conn.recv() imgArr = np.array(img).reshape( (1, img.size[1], img.size[0], 2)) / 255 aResult = model.predict(imgArr) iResult = np.amax(aResult) if iResult == 0: conn.send(Action.JUMP) elif iResult == 1: conn.send(Action.DUCK) else: conn.send(Action.DO_NOTHING) logMessage("Result sent") except EOFError: break logMessage("Model stopped")
def lulapy_broker(conn: Connection) -> None: connections.append(conn) funcs: Dict[Text, Callable] = { 'message': message, 'subscribe': subscribe, 'unsubscribe': unsubscribe, 'close': close, 'add_connection': add_connection } while True: if len(connections) == 0: break for conn in connections: if conn.closed: connections.remove(conn) for topic in topics.keys(): topics[topic].remove(conn) elif conn.poll(): data = conn.recv() _type = data['type'] funcs[_type](data, conn)
def worker(parent_conn: Connection, pickled_env_factory: str, worker_id: int): env_factory: Callable[[int], UnityEnvironment] = cloudpickle.loads( pickled_env_factory) env = env_factory(worker_id) def _send_response(cmd_name, payload): parent_conn.send(EnvironmentResponse(cmd_name, worker_id, payload)) try: while True: cmd: EnvironmentCommand = parent_conn.recv() if cmd.name == 'step': vector_action, memory, text_action, value = cmd.payload #all_brain_info = env.step(vector_action, memory, text_action, value) if env.global_done: all_brain_info = env.reset() else: all_brain_info = env.step(vector_action, memory, text_action, value) _send_response('step', all_brain_info) elif cmd.name == 'external_brains': _send_response('external_brains', env.external_brains) elif cmd.name == 'reset_parameters': _send_response('reset_parameters', env.reset_parameters) elif cmd.name == 'reset': all_brain_info = env.reset(cmd.payload[0], cmd.payload[1]) _send_response('reset', all_brain_info) elif cmd.name == 'global_done': _send_response('global_done', env.global_done) elif cmd.name == 'close': break except KeyboardInterrupt: print('UnityEnvironment worker: keyboard interrupt') finally: env.close()
def _grant_handles(conn: Connection, handles: Iterable[IO]) -> None: log = logging.getLogger('_grant_handles') cpid = conn.recv() log.info('Attempting to grant file handles to pid {}.'.format(cpid)) for handle in handles: _grant_handle(conn, handle, cpid) conn.send(None)
def _multiprocess_generator_pool_child(pipe: Connection) -> None: while True: # wait for a message pipe.poll(None) # read the message msg = pipe.recv() if msg == SENTINEL: # received a sentinel message to terminate self break else: # start of a new function invocation func, batchsize, kwargs = msg # start a fresh batch of results batch = [] try: for result in func(**kwargs): batch.append(result) # batch is full, send it and start a new one if len(batch) >= batchsize: pipe.send([kwargs, batch, None]) batch = [] except Exception as e: # if an error happened send it up pipe.send([kwargs, batch, e]) # continue to the next arg else: # no error was thrown # send any leftover lines smaller than a batch pipe.send([kwargs, batch, None]) # send a sentinel to say we've finished an arg pipe.send(SENTINEL)
def Pconsumer_fcn(Pconn: Connection, loopCondition: Value): counter = 0 while loopCondition.value == 1: if Pconn.poll(0.1): _ = Pconn.recv() counter += 1 Pconn.close() print(f"Consumer msg: Received: {counter} messages\n")
def get_last_message(connection: Connection) -> dict: message = {} try: while connection.poll(): message = connection.recv() except EOFError: pass return message
def worker( parent_conn: Connection, step_queue: Queue, pickled_env_factory: str, worker_id: int ) -> None: env_factory: Callable[[int], UnityEnvironment] = cloudpickle.loads( pickled_env_factory ) env = env_factory(worker_id) def _send_response(cmd_name, payload): parent_conn.send(EnvironmentResponse(cmd_name, worker_id, payload)) try: while True: cmd: EnvironmentCommand = parent_conn.recv() if cmd.name == "step": all_action_info = cmd.payload actions = {} memories = {} texts = {} values = {} for brain_name, action_info in all_action_info.items(): actions[brain_name] = action_info.action memories[brain_name] = action_info.memory texts[brain_name] = action_info.text values[brain_name] = action_info.value all_brain_info = env.step(actions, memories, texts, values) # The timers in this process are independent from all the processes and the "main" process # So after we send back the root timer, we can safely clear them. # Note that we could randomly return timers a fraction of the time if we wanted to reduce # the data transferred. # TODO get gauges from the workers and merge them in the main process too. step_response = StepResponse(all_brain_info, get_timer_root()) step_queue.put(EnvironmentResponse("step", worker_id, step_response)) reset_timers() elif cmd.name == "external_brains": _send_response("external_brains", env.external_brains) elif cmd.name == "reset_parameters": _send_response("reset_parameters", env.reset_parameters) elif cmd.name == "reset": all_brain_info = env.reset( cmd.payload[0], cmd.payload[1], cmd.payload[2] ) _send_response("reset", all_brain_info) elif cmd.name == "close": break except (KeyboardInterrupt, UnityCommunicationException): logger.info(f"UnityEnvironment worker {worker_id}: environment stopping.") step_queue.put(EnvironmentResponse("env_close", worker_id, None)) finally: # If this worker has put an item in the step queue that hasn't been processed by the EnvManager, the process # will hang until the item is processed. We avoid this behavior by using Queue.cancel_join_thread() # See https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue.cancel_join_thread for # more info. logger.debug(f"UnityEnvironment worker {worker_id} closing.") step_queue.cancel_join_thread() step_queue.close() env.close() logger.debug(f"UnityEnvironment worker {worker_id} done.")
def show_feed(index: int, pipe: Connection): name = "Cam " + str(index) size = big print("running size:", size) cap = cv2.VideoCapture(index, backend) cap.set(cv2.CAP_PROP_FRAME_WIDTH, size[0]) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, size[1]) save_dir = "C:/users/phill/companion app save folder/" vid_ext = ".avi" codec = "DIVX" frame_size = big fps = 30 writer = cv2.VideoWriter() self.writer = cv2.VideoWriter( save_dir + timestamp + self.name + '_output' + vid_ext, cv2.VideoWriter_fourcc(*codec), fps, frame_size) start = time.time() num_frames = 0 resize = 0 while True: if pipe.poll(): msg = pipe.recv() if msg == "small": resize = 1 elif msg == "big": resize = 2 elif msg == "reset": resize = 0 elif msg == "close": cv2.destroyWindow(name) cap.release() break ret, frame = cap.read() if ret and frame is not None: if resize == 1: frame = imutils.resize(frame, width=small[0]) elif resize == 2: frame = imutils.resize(frame, width=big[0]) cv2.imshow(name, frame) num_frames += 1 else: print("Cam failed") cv2.destroyWindow(name) cap.release() break keypress = cv2.waitKey(1) % 0xFF if keypress == ord('q'): break end = time.time() seconds = end - start if seconds > 0: fps = num_frames / seconds else: fps = 0 print("time taken:", seconds, "fps:", fps, "camera:", index, "frames handled:", num_frames) cap.release()
def _worker( parent: connection.Connection, p: connection.Connection, env_fn_wrapper: CloudpickleWrapper, obs_bufs: Optional[Union[dict, tuple, ShArray]] = None, ) -> None: def _encode_obs( obs: Union[dict, tuple, np.ndarray], buffer: Union[dict, tuple, ShArray] ) -> None: if isinstance(obs, np.ndarray) and isinstance(buffer, ShArray): buffer.save(obs) elif isinstance(obs, tuple) and isinstance(buffer, tuple): for o, b in zip(obs, buffer): _encode_obs(o, b) elif isinstance(obs, dict) and isinstance(buffer, dict): for k in obs.keys(): _encode_obs(obs[k], buffer[k]) return None parent.close() env = env_fn_wrapper.data() try: while True: try: cmd, data = p.recv() except EOFError: # the pipe has been closed p.close() break if cmd == "step": if data is None: # reset obs = env.reset() else: obs, reward, done, info = env.step(data) if obs_bufs is not None: _encode_obs(obs, obs_bufs) obs = None if data is None: p.send(obs) else: p.send((obs, reward, done, info)) elif cmd == "close": p.send(env.close()) p.close() break elif cmd == "render": p.send(env.render(**data) if hasattr(env, "render") else None) elif cmd == "seed": p.send(env.seed(data) if hasattr(env, "seed") else None) elif cmd == "getattr": p.send(getattr(env, data) if hasattr(env, data) else None) elif cmd == "setattr": setattr(env, data["key"], data["value"]) else: p.close() raise NotImplementedError except KeyboardInterrupt: p.close()
def log_data(conn: Connection, cs_logger): print('Starting log...') while True: data = conn.recv() if not data: conn.close() print('Closing...') return cs_logger.info(data)
def log_topic_messages(topic_connection: Connection) -> None: while True: try: message = topic_connection.recv() if message == END_OF_TOPIC_MESSAGE: break logging.info(message) except EOFError: break
def listen(conn: Connection, results: Queue): """ Listener for updates. Runs on separate thread. :param conn: child connection from multiprocessing.Pipe. :param results: thread-safe queue for results. """ while True: game_state = conn.recv() results.put(game_state)
def setup_connection_with_parent(): """Called in the child process to connect to the parent process""" sock_addr = sys.argv[1] sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(sock_addr) conn = Connection(os.dup(sock.fileno()) if PY2 else sock.detach()) conn.send('hello') assert conn.recv() == 'hello' return conn
def worker(parent_conn: Connection, step_queue: Queue, pickled_env_factory: str, worker_id: int): env_factory: Callable[[int], UnityEnvironment] = cloudpickle.loads( pickled_env_factory) env = env_factory(worker_id) def _send_response(cmd_name, payload): parent_conn.send(EnvironmentResponse(cmd_name, worker_id, payload)) try: while True: cmd: EnvironmentCommand = parent_conn.recv() if cmd.name == "step": all_action_info = cmd.payload # When an environment is "global_done" it means automatic agent reset won't occur, so we need # to perform an academy reset. if env.global_done: all_brain_info = env.reset() else: actions = {} memories = {} texts = {} values = {} for brain_name, action_info in all_action_info.items(): actions[brain_name] = action_info.action memories[brain_name] = action_info.memory texts[brain_name] = action_info.text values[brain_name] = action_info.value all_brain_info = env.step(actions, memories, texts, values) # The timers in this process are independent from all the processes and the "main" process # So after we send back the root timer, we can safely clear them. # Note that we could randomly return timers a fraction of the time if we wanted to reduce # the data transferred. # TODO get gauges from the workers and merge them in the main process too. step_response = StepResponse(all_brain_info, get_timer_root()) step_queue.put( EnvironmentResponse("step", worker_id, step_response)) reset_timers() elif cmd.name == "external_brains": _send_response("external_brains", env.external_brains) elif cmd.name == "reset_parameters": _send_response("reset_parameters", env.reset_parameters) elif cmd.name == "reset": all_brain_info = env.reset(cmd.payload[0], cmd.payload[1], cmd.payload[2]) _send_response("reset", all_brain_info) elif cmd.name == "global_done": _send_response("global_done", env.global_done) elif cmd.name == "close": break except (KeyboardInterrupt, UnityCommunicationException): print("UnityEnvironment worker: environment stopping.") step_queue.put(EnvironmentResponse("env_close", worker_id, None)) finally: step_queue.close() env.close()
def device_send(cls, ctrl_connection: Connection, send_config: SendConfig, dev_parameters: OrderedDict): if not cls.init_device(ctrl_connection, is_tx=True, parameters=dev_parameters): ctrl_connection.send("failed to start tx mode") return False if cls.ASYNCHRONOUS: ret = cls.enter_async_send_mode(send_config.get_data_to_send) else: ret = cls.prepare_sync_send(ctrl_connection) if ret != 0: ctrl_connection.send("failed to start tx mode") return False exit_requested = False buffer_size = cls.CONTINUOUS_TX_CHUNK_SIZE if send_config.continuous else cls.SYNC_TX_CHUNK_SIZE if not cls.ASYNCHRONOUS and buffer_size == 0: logger.warning("Send buffer size is zero!") ctrl_connection.send("successfully started tx mode") while not exit_requested and not send_config.sending_is_finished(): if cls.ASYNCHRONOUS: try: time.sleep(0.5) except KeyboardInterrupt: pass else: cls.send_sync(send_config.get_data_to_send(buffer_size)) while ctrl_connection.poll(): result = cls.process_command(ctrl_connection.recv(), ctrl_connection, is_tx=True) if result == cls.Command.STOP.name: exit_requested = True break if not cls.ASYNCHRONOUS: # Some Sync send calls (e.g. USRP) are not blocking, so we wait a bit here to ensure # that the send buffer on the SDR is cleared time.sleep(0.75) if exit_requested: logger.debug("{}: exit requested. Stopping sending".format(cls.__class__.__name__)) if send_config.sending_is_finished(): logger.debug("{}: sending is finished.".format(cls.__class__.__name__)) cls.shutdown_device(ctrl_connection, is_tx=True) ctrl_connection.close()
def device_receive(cls, data_connection: Connection, ctrl_connection: Connection, dev_parameters: OrderedDict): if not cls.init_device(ctrl_connection, is_tx=False, parameters=dev_parameters): ctrl_connection.send("failed to start rx mode") return False try: cls.adapt_num_read_samples_to_sample_rate(dev_parameters[cls.Command.SET_SAMPLE_RATE.name]) except NotImplementedError: # Many SDRs like HackRF or AirSpy do not need to calculate SYNC_RX_CHUNK_SIZE # as default values are either fine or given by the hardware pass if cls.ASYNCHRONOUS: ret = cls.enter_async_receive_mode(data_connection, ctrl_connection) else: ret = cls.prepare_sync_receive(ctrl_connection) if ret != 0: ctrl_connection.send("failed to start rx mode") return False exit_requested = False ctrl_connection.send("successfully started rx mode") while not exit_requested: if cls.ASYNCHRONOUS: try: time.sleep(0.25) except KeyboardInterrupt: pass else: cls.receive_sync(data_connection) while ctrl_connection.poll(): result = cls.process_command(ctrl_connection.recv(), ctrl_connection, is_tx=False) if result == cls.Command.STOP.name: exit_requested = True break cls.shutdown_device(ctrl_connection, is_tx=False) data_connection.close() ctrl_connection.close()