def initialize_process(self): self.started.emit() if not hasattr(sys, 'frozen'): rp = os.path.realpath(os.path.join(os.path.dirname(__file__), "scripts")) else: rp = os.path.realpath(os.path.dirname(sys.executable)) suffix = "_recv.py" if self._receiving else "_send.py" filename = self.device.lower().split(" ")[0] + suffix if not self.python2_interpreter: self.stop("FATAL: Could not find python 2 interpreter. Make sure you have a running gnuradio installation.") return options = [self.python2_interpreter, os.path.join(rp, filename), "--samplerate", str(self.sample_rate), "--freq", str(self.freq), "--gain", str(self.gain), "--bandwidth", str(self.bandwidth), "--port", str(self.gr_port)] if self.device.upper() == "HACKRF": options.extend(["--if-gain", str(self.if_gain), "--baseband-gain", str(self.baseband_gain)]) if self.device.upper() == "RTL-SDR": options.extend(["--freq-correction", str(self.freq_correction), "--direct-sampling", str(self.direct_sampling_mode)]) logger.info("Starting Gnuradio") logger.debug(" ".join(options)) self.tb_process = Popen(options, stdout=PIPE, stderr=PIPE, stdin=PIPE, bufsize=1) logger.info("Started Gnuradio") t = Thread(target=self.enqueue_output, args=(self.tb_process.stderr, self.queue)) t.daemon = True # thread dies with the program t.start()
def test_apply_to_all(self): logger.debug("Test apply to all") tests.utils_testing.short_wait() self.form.add_signalfile(get_path_for_data_file("ask.complex")) logger.debug("added new signal") frame2 = self.form.signal_tab_controller.signal_frames[1] self.frame.ui.spinBoxInfoLen.setValue(42) self.frame.ui.spinBoxInfoLen.editingFinished.emit() self.frame.ui.spinBoxCenterOffset.setValue(0.1) self.frame.ui.spinBoxCenterOffset.editingFinished.emit() self.frame.ui.spinBoxNoiseTreshold.setValue(0.5) self.frame.ui.spinBoxNoiseTreshold.editingFinished.emit() self.frame.ui.spinBoxTolerance.setValue(10) self.frame.ui.spinBoxTolerance.editingFinished.emit() self.frame.apply_to_all_clicked.emit(self.frame.signal) self.assertEqual(42, frame2.ui.spinBoxInfoLen.value()) self.assertEqual(0.1, frame2.ui.spinBoxCenterOffset.value()) self.assertEqual(0.5, frame2.ui.spinBoxNoiseTreshold.value()) self.assertEqual(10, frame2.ui.spinBoxTolerance.value())
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 receive(port, current_index, target_index, elapsed): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) s.bind(("", port)) s.listen(1) conn, addr = s.accept() logger.debug('Receiver got connection from address:'.format(addr)) start = False while True: data = conn.recv(65536 * 8) if not start: start = True t = time.time() if len(data) > 0: while len(data) % 8 != 0: data += conn.recv(len(data) % 8) arr = np.frombuffer(data, dtype=np.complex64) current_index.value += len(arr) if current_index.value == target_index: break conn.close() elapsed.value = 1000 * (time.time() - t) s.close()
def process_command(self, command): logger.debug("RTLSDRTCP: {}".format(command)) if command == "stop": return "stop" tag, value = command.split(":") if tag == "center_freq": logger.info("RTLSDRTCP: Set center freq to {0}".format(int(value))) return self.set_parameter("centerFreq", int(value)) elif tag == "tuner_gain": logger.info("RTLSDRTCP: Set tuner gain to {0}".format(int(value))) return self.set_parameter("tunerGain", int(value)) elif tag == "sample_rate": logger.info("RTLSDRTCP: Set sample_rate to {0}".format(int(value))) return self.set_parameter("sampleRate", int(value)) elif tag == "tuner_bandwidth": logger.info("RTLSDRTCP: Set bandwidth to {0}".format(int(value))) return self.set_parameter("bandwidth", int(value)) elif tag == "freq_correction": logger.info("RTLSDRTCP: Set ppm correction to {0}".format( int(value))) return self.set_parameter("freqCorrection", int(value))
def process_command(command): logger.debug("RTLSDR: {}".format(command)) if command == "stop": return "stop" tag, value = command.split(":") if tag == "center_freq": logger.info("RTLSDR: Set center freq to {0}".format(int(value))) return rtlsdr.set_center_freq(int(value)) elif tag == "rf_gain": logger.info("RTLSDR: Set tuner gain to {0}".format(int(value))) return rtlsdr.set_tuner_gain(10 * int(value)) # calculate *10 for API elif tag == "sample_rate": logger.info("RTLSDR: Set sample_rate to {0}".format(int(value))) return rtlsdr.set_sample_rate(int(value)) elif tag == "tuner_bandwidth": logger.info("RTLSDR: Set bandwidth to {0}".format(int(value))) return rtlsdr.set_tuner_bandwidth(int(value)) elif tag == "freq_correction": logger.info("RTLSDR: Set freq_correction to {0}".format( int(value))) return rtlsdr.set_freq_correction(int(value)) elif tag == "direct_sampling_mode": logger.info("RTLSDR: Set direct_sampling_mode to {0}".format( int(value))) return rtlsdr.set_direct_sampling(int(value))
def receive_sync(data_connection, ctrl_connection, device_number: int, center_freq: int, sample_rate: int, bandwidth: int, gain: int, freq_correction: int, direct_sampling_mode: int, device_ip: str, port: int): # connect and initialize rtl_tcp sdr = RTLSDRTCP(center_freq, gain, sample_rate, bandwidth, device_number) sdr.open(ctrl_connection, device_ip, port) if sdr.socket_is_open: sdr.device_number = device_number sdr.set_parameter("centerFreq", int(center_freq), ctrl_connection) sdr.set_parameter("sampleRate", int(sample_rate), ctrl_connection) sdr.set_parameter("bandwidth", int(bandwidth), ctrl_connection) sdr.set_parameter("freqCorrection", int(freq_correction), ctrl_connection) sdr.set_parameter("directSampling", int(direct_sampling_mode), ctrl_connection) # Gain has to be set last, otherwise it does not get considered by RTL-SDR sdr.set_parameter("tunerGain", 10 * int(gain), ctrl_connection) # gain is multiplied by 10 because of rtlsdr-API exit_requested = False while not exit_requested: while ctrl_connection.poll(): result = sdr.process_command(ctrl_connection.recv(), ctrl_connection) if result == "stop": exit_requested = True break if not exit_requested: data_connection.send_bytes(sdr.read_sync()) logger.debug("RTLSDRTCP: closing device") sdr.close() else: ctrl_connection.send("Could not connect to rtl_tcp:404") ctrl_connection.send("close:0") data_connection.close() ctrl_connection.close()
def process_command(self, command, ctrl_connection, is_tx=False): logger.debug("RTLSDRTCP: {}".format(command)) if command == self.Command.STOP.name: return self.Command.STOP tag, value = command if tag == self.Command.SET_FREQUENCY.name: logger.info("RTLSDRTCP: Set center freq to {0}".format(int(value))) return self.set_parameter("centerFreq", int(value), ctrl_connection) elif tag == self.Command.SET_RF_GAIN.name: logger.info("RTLSDRTCP: Set tuner gain to {0}".format(int(value))) return self.set_parameter("tunerGain", 10 * int(value), ctrl_connection) # calculate *10 for API elif tag == self.Command.SET_IF_GAIN.name: logger.info("RTLSDRTCP: Set if gain to {0}".format(int(value))) return self.set_parameter("tunerIFGain", 10 * int(value), ctrl_connection) # calculate *10 for API elif tag == self.Command.SET_SAMPLE_RATE.name: logger.info("RTLSDRTCP: Set sample_rate to {0}".format(int(value))) return self.set_parameter("sampleRate", int(value), ctrl_connection) elif tag == self.Command.SET_BANDWIDTH.name: logger.info("RTLSDRTCP: Set bandwidth to {0}".format(int(value))) return self.set_parameter("bandwidth", int(value), ctrl_connection) elif tag == self.Command.SET_FREQUENCY_CORRECTION.name: logger.info("RTLSDRTCP: Set ppm correction to {0}".format(int(value))) return self.set_parameter("freqCorrection", int(value), ctrl_connection) elif tag == self.Command.SET_DIRECT_SAMPLING_MODE.name: logger.info("RTLSDRTCP: Set direct sampling mode to {0}".format(int(value))) return self.set_parameter("directSampling", int(value), ctrl_connection)
def read_receiving_queue(self): while self.is_receiving: try: byte_buffer = self.parent_data_conn.recv_bytes() samples = self.unpack_complex(byte_buffer) n_samples = len(samples) if n_samples == 0: continue except OSError as e: logger.exception(e) continue except EOFError: logger.info("EOF Error: Ending receive thread") break if self.current_recv_index + n_samples >= len(self.receive_buffer): if self.resume_on_full_receive_buffer: self.current_recv_index = 0 if n_samples >= len(self.receive_buffer): n_samples = len(self.receive_buffer) - 1 else: self.stop_rx_mode( "Receiving buffer is full {0}/{1}".format(self.current_recv_index + n_samples, len(self.receive_buffer))) return self.receive_buffer[self.current_recv_index:self.current_recv_index + n_samples] = samples[:n_samples] self.current_recv_index += n_samples if self.emit_data_received_signal: self.data_received.emit(samples) logger.debug("Exiting read_receive_queue thread.")
def stop_tcp_server(self): if hasattr(self, "server"): logger.debug("Shutdown TCP server") self.server.shutdown() self.server.server_close() if hasattr(self, "server_thread"): self.server_thread.join()
def stop_tx_mode(self, msg): try: self.parent_ctrl_conn.send(self.Command.STOP.name) except (BrokenPipeError, OSError) as e: logger.debug("Closing parent control connection: " + str(e)) logger.info("{0}: Stopping TX Mode: {1}".format(self.__class__.__name__, msg)) if hasattr(self, "transmit_process") and self.transmit_process.is_alive(): self.transmit_process.join(self.JOIN_TIMEOUT) if self.transmit_process.is_alive(): logger.warning("{0}: Transmit process is still alive, terminating it".format(self.__class__.__name__)) self.transmit_process.terminate() self.transmit_process.join() self.is_transmitting = False try: self.parent_ctrl_conn.close() except OSError as e: logger.exception(e) try: self.child_ctrl_conn.close() except OSError as e: logger.exception(e)
def stop_tx_mode(self, msg): try: self.parent_ctrl_conn.send(self.Command.STOP.name) except (BrokenPipeError, OSError) as e: logger.debug("Closing parent control connection: " + str(e)) logger.info("{0}: Stopping TX Mode: {1}".format( self.__class__.__name__, msg)) if hasattr(self, "transmit_process") and self.transmit_process.is_alive(): self.transmit_process.join(self.JOIN_TIMEOUT) if self.transmit_process.is_alive(): logger.warning( "{0}: Transmit process is still alive, terminating it". format(self.__class__.__name__)) self.transmit_process.terminate() self.transmit_process.join() self.is_transmitting = False try: self.parent_ctrl_conn.close() except OSError as e: logger.exception(e) try: self.child_ctrl_conn.close() except OSError as e: logger.exception(e)
def read_receiving_queue(self): while self.is_receiving: try: byte_buffer = self.parent_data_conn.recv_bytes() samples = self.unpack_complex(byte_buffer) n_samples = len(samples) if n_samples > 0: if self.current_recv_index + n_samples >= len(self.receive_buffer): if self.resume_on_full_receive_buffer: self.current_recv_index = 0 if n_samples >= len(self.receive_buffer): n_samples = len(self.receive_buffer) - 1 else: self.stop_rx_mode( "Receiving buffer is full {0}/{1}".format(self.current_recv_index + n_samples, len(self.receive_buffer))) return self.receive_buffer[self.current_recv_index:self.current_recv_index + n_samples] = samples[:n_samples] old_index = self.current_recv_index self.current_recv_index += n_samples self.rcv_index_changed.emit(old_index, self.current_recv_index) except (BrokenPipeError, OSError): pass except EOFError: logger.info("EOF Error: Ending receive thread") break logger.debug("Exiting read_receive_queue thread.")
def receive(port, current_index, target_index, elapsed): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) s.bind(("", port)) s.listen(1) conn, addr = s.accept() logger.debug('Receiver got connection from address:'.format(addr)) start = False while True: data = conn.recv(65536 * 8) if not start: start = True t = time.time() if len(data) > 0: while len(data) % 8 != 0: data += conn.recv(len(data) % 8) arr = np.frombuffer(data, dtype=np.complex64) current_index.value += len(arr) if current_index.value == target_index: break conn.close() elapsed.value = 1000 * (time.time() - t) s.close()
def create_image(data: np.ndarray, colormap, data_min=None, data_max=None, normalize=True) -> QImage: """ Create QImage from ARGB array. The ARGB must have shape (width, height, 4) and dtype=ubyte. NOTE: The order of values in the 3rd axis must be (blue, green, red, alpha). :return: """ image_data = Spectrogram.apply_bgra_lookup(data, colormap, data_min, data_max, normalize) if not image_data.flags['C_CONTIGUOUS']: logger.debug("Array was not C_CONTIGUOUS. Converting it.") image_data = np.ascontiguousarray(image_data) try: # QImage constructor needs inverted row/column order image = QImage(image_data.ctypes.data, image_data.shape[1], image_data.shape[0], QImage.Format_ARGB32) except Exception as e: logger.error("could not create image " + str(e)) return QImage() image.data = image_data return image
def __get_recv_dialog(self): logger.debug("Creating Receive Dialog") tests.utils_testing.short_wait() receive_dialog = ReceiveDialogController(self.form.project_manager, testing_mode=True, parent=self.form) return receive_dialog
def close_rfcat(self): if self.rfcat_is_open: try: self.process.kill() self.rfcat_is_open = False except Exception as e: logger.debug("Could not close rfcat: {}".format(e))
def __get_spectrum_dialog(self): logger.debug("Creating Spectrum Dialog") tests.utils_testing.short_wait() spectrum_dialog = SpectrumDialogController(self.form.project_manager, testing_mode=True, parent=self.form) return spectrum_dialog
def initialize_process(self): self.started.emit() if not hasattr(sys, 'frozen'): rp = os.path.realpath(os.path.join(os.path.dirname(__file__), "scripts")) else: rp = os.path.realpath(os.path.dirname(sys.executable)) suffix = "_recv.py" if self._receiving else "_send.py" filename = self.device.lower().split(" ")[0] + suffix if not self.python2_interpreter: raise Exception("Could not find python 2 interpreter. Make sure you have a running gnuradio installation.") options = [self.python2_interpreter, os.path.join(rp, filename), "--samplerate", str(self.sample_rate), "--freq", str(self.freq), "--gain", str(self.gain), "--bandwidth", str(self.bandwidth), "--port", str(self.gr_port)] if self.device.upper() == "HACKRF": options.extend(["--if-gain", str(self.if_gain), "--baseband-gain", str(self.baseband_gain)]) if self.device.upper() == "RTL-SDR": options.extend(["--freq-correction", str(self.freq_correction), "--direct-sampling", str(self.direct_sampling_mode)]) logger.info("Starting Gnuradio") logger.debug(" ".join(options)) self.tb_process = Popen(options, stdout=PIPE, stderr=PIPE, stdin=PIPE, bufsize=1) logger.info("Started Gnuradio") t = Thread(target=self.enqueue_output, args=(self.tb_process.stderr, self.queue)) t.daemon = True # thread dies with the program t.start()
def receive_sync(self, data_connection, ctrl_connection, device_number: int, center_freq: int, sample_rate: int, gain: int): # connect and initialize rtl_tcp self.open(self.device_ip, self.port) if self.socket_is_open: self.device_number = device_number self.set_parameter("centerFreq", int(center_freq)) self.set_parameter("sampleRate", int(sample_rate)) self.set_parameter( "bandwidth", int(sample_rate)) # set bandwidth equal to sample_rate self.set_parameter("tunerGain", int(gain)) #self.set_parameter("freqCorrection", int(freq_correction_in_ppm)) # TODO: add ppm value as parameter to this function exit_requested = False while not exit_requested: while ctrl_connection.poll(): result = self.process_command(ctrl_connection.recv()) if result == "stop": exit_requested = True break if not exit_requested: data_connection.send_bytes(self.read_sync()) logger.debug("RTLSDRTCP: closing device") self.close() else: ctrl_connection.send("Could not connect to rtl_tcp:404") ctrl_connection.send("close:0") data_connection.close() ctrl_connection.close()
def close_rfcat(self): if self.rfcat_is_open: try: self.process.kill() self.rfcat_is_open = False except Exception as e: logger.debug("Could not close rfcat: {}".format(e))
def process_command(self, command, ctrl_connection, is_tx=False): logger.debug("RTLSDRTCP: {}".format(command)) if command == self.Command.STOP.name: return self.Command.STOP tag, value = command if tag == self.Command.SET_FREQUENCY.name: logger.info("RTLSDRTCP: Set center freq to {0}".format(int(value))) return self.set_parameter("centerFreq", int(value), ctrl_connection) elif tag == self.Command.SET_RF_GAIN.name: logger.info("RTLSDRTCP: Set tuner gain to {0}".format(int(value))) return self.set_parameter("tunerGain", 10 * int(value), ctrl_connection) # calculate *10 for API elif tag == self.Command.SET_IF_GAIN.name: logger.info("RTLSDRTCP: Set if gain to {0}".format(int(value))) return self.set_parameter("tunerIFGain", 10 * int(value), ctrl_connection) # calculate *10 for API elif tag == self.Command.SET_SAMPLE_RATE.name: logger.info("RTLSDRTCP: Set sample_rate to {0}".format(int(value))) return self.set_parameter("sampleRate", int(value), ctrl_connection) elif tag == self.Command.SET_BANDWIDTH.name: logger.info("RTLSDRTCP: Set bandwidth to {0}".format(int(value))) return self.set_parameter("bandwidth", int(value), ctrl_connection) elif tag == self.Command.SET_FREQUENCY_CORRECTION.name: logger.info("RTLSDRTCP: Set ppm correction to {0}".format(int(value))) return self.set_parameter("freqCorrection", int(value), ctrl_connection) elif tag == self.Command.SET_DIRECT_SAMPLING_MODE.name: logger.info("RTLSDRTCP: Set direct sampling mode to {0}".format(int(value))) return self.set_parameter("directSampling", int(value), ctrl_connection)
def create_context_menu(self): menu = QMenu() menu.setToolTipsVisible(True) self._add_zoom_actions_to_menu(menu) if self.something_is_selected: filter_bw = Filter.read_configured_filter_bw() text = self.tr("Apply bandpass filter (filter bw={0:n})".format(filter_bw)) create_from_frequency_selection = menu.addAction(text) create_from_frequency_selection.triggered.connect(self.on_create_from_frequency_selection_triggered) create_from_frequency_selection.setIcon(QIcon.fromTheme("view-filter")) try: cancel_button = " or ".join(k.toString() for k in QKeySequence.keyBindings(QKeySequence.Cancel)) except Exception as e: logger.debug("Error reading cancel button: " + str(e)) cancel_button = "Esc" create_from_frequency_selection.setToolTip("You can abort filtering with <b>{}</b>.".format(cancel_button)) configure_filter_bw = menu.addAction(self.tr("Configure filter bandwidth...")) configure_filter_bw.triggered.connect(self.on_configure_filter_bw_triggered) configure_filter_bw.setIcon(QIcon.fromTheme("configure")) menu.addSeparator() export_fta_action = menu.addAction("Export spectrogram...") export_fta_action.triggered.connect(self.on_export_fta_action_triggered) return menu
def receive_sync(data_connection, ctrl_connection, device_number: int, center_freq: int, sample_rate: int, gain: int, freq_correction: int, direct_sampling_mode: int, device_ip: str, port: int): # connect and initialize rtl_tcp sdr = RTLSDRTCP(center_freq, gain, sample_rate, device_number) sdr.open(ctrl_connection, device_ip, port) if sdr.socket_is_open: sdr.device_number = device_number sdr.set_parameter("centerFreq", int(center_freq), ctrl_connection) sdr.set_parameter("sampleRate", int(sample_rate), ctrl_connection) sdr.set_parameter("bandwidth", int(sample_rate), ctrl_connection) # set bandwidth equal to sample_rate sdr.set_parameter("tunerGain", 10 * int(gain), ctrl_connection) # gain is multiplied by 10 because of rtlsdr-API sdr.set_parameter("freqCorrection", int(freq_correction), ctrl_connection) sdr.set_parameter("directSampling", int(direct_sampling_mode), ctrl_connection) exit_requested = False while not exit_requested: while ctrl_connection.poll(): result = sdr.process_command(ctrl_connection.recv(), ctrl_connection) if result == "stop": exit_requested = True break if not exit_requested: data_connection.send_bytes(sdr.read_sync()) logger.debug("RTLSDRTCP: closing device") sdr.close() else: ctrl_connection.send("Could not connect to rtl_tcp:404") ctrl_connection.send("close:0") data_connection.close() ctrl_connection.close()
def create_context_menu(self): menu = QMenu() menu.setToolTipsVisible(True) self._add_zoom_actions_to_menu(menu) if self.something_is_selected: filter_bw = Filter.read_configured_filter_bw() text = self.tr( "Apply bandpass filter (filter bw={0:n})".format(filter_bw)) create_from_frequency_selection = menu.addAction(text) create_from_frequency_selection.triggered.connect( self.on_create_from_frequency_selection_triggered) create_from_frequency_selection.setIcon( QIcon.fromTheme("view-filter")) try: cancel_button = " or ".join( k.toString() for k in QKeySequence.keyBindings(QKeySequence.Cancel)) except Exception as e: logger.debug("Error reading cancel button: " + str(e)) cancel_button = "Esc" create_from_frequency_selection.setToolTip( "You can abort filtering with <b>{}</b>.".format( cancel_button)) configure_filter_bw = menu.addAction( self.tr("Configure filter bandwidth...")) configure_filter_bw.triggered.connect( self.on_configure_filter_bw_triggered) configure_filter_bw.setIcon(QIcon.fromTheme("configure")) return menu
def receive_sync(data_connection, ctrl_connection, device_number: int, center_freq: int, sample_rate: int, gain: int): ret = rtlsdr.open(device_number) ctrl_connection.send("open:" + str(ret)) ret = rtlsdr.set_center_freq(center_freq) ctrl_connection.send("set_center_freq:" + str(ret)) ret = rtlsdr.set_sample_rate(sample_rate) ctrl_connection.send("set_sample_rate:" + str(ret)) ret = rtlsdr.set_tuner_gain(gain) ctrl_connection.send("set_tuner_gain:" + str(ret)) ret = rtlsdr.reset_buffer() ctrl_connection.send("reset_buffer:" + str(ret)) exit_requested = False while not exit_requested: while ctrl_connection.poll(): result = RTLSDR.process_command(ctrl_connection.recv()) if result == "stop": exit_requested = True break if not exit_requested: data_connection.send_bytes(rtlsdr.read_sync()) logger.debug("RTLSDR: closing device") ret = rtlsdr.close() ctrl_connection.send("close:" + str(ret)) data_connection.close() ctrl_connection.close()
def read_receiving_queue(self): while self.is_receiving: try: byte_buffer = self.parent_data_conn.recv_bytes() samples = self.unpack_complex(byte_buffer) n_samples = len(samples) if n_samples == 0: continue except OSError as e: logger.exception(e) continue except EOFError: logger.info("EOF Error: Ending receive thread") break if self.current_recv_index + n_samples >= len(self.receive_buffer): if self.resume_on_full_receive_buffer: self.current_recv_index = 0 if n_samples >= len(self.receive_buffer): n_samples = len(self.receive_buffer) - 1 else: self.stop_rx_mode( "Receiving buffer is full {0}/{1}".format( self.current_recv_index + n_samples, len(self.receive_buffer))) return self.receive_buffer[self. current_recv_index:self.current_recv_index + n_samples] = samples[:n_samples] self.current_recv_index += n_samples logger.debug("Exiting read_receive_queue thread.")
def start(self): self.abort.value = 0 try: self.process = Process(target=self.modulate_continuously) self.process.daemon = True self.process.start() except RuntimeError as e: logger.debug(str(e))
def file_can_be_opened(filename: str): try: open(filename, "r").close() return True except Exception as e: if not isinstance(e, FileNotFoundError): logger.debug(str(e)) return False
def shutdown_device(cls, ctrl_connection, is_tx: bool): logger.debug("SDRPLAY: closing device") ret = sdrplay.close_stream() ctrl_connection.send("CLOSE STREAM:" + str(ret)) if cls.sdrplay_device_index is not None: ret = sdrplay.release_device_index() ctrl_connection.send("RELEASE DEVICE:" + str(ret))
def enable_or_disable_send_button(self, rfcat_executable): if self.is_rfcat_executable(rfcat_executable): self.settings_frame.info.setText("Info: Executable can be opened.") else: self.settings_frame.info.setText( "Info: Executable cannot be opened! Disabling send button.") logger.debug( "RfCat executable cannot be opened! Disabling send button.")
def file_can_be_opened(filename: str): try: open(filename, "r").close() return True except Exception as e: if not isinstance(e, FileNotFoundError): logger.debug(str(e)) return False
def start(self): self.abort.value = 0 try: self.process = Process(target=self.modulate_continuously) self.process.daemon = True self.process.start() except RuntimeError as e: logger.debug(str(e))
def shutdown_airspy(ctrl_conn): logger.debug("AirSpy: closing device") ret = airspy.stop_rx() ctrl_conn.send("Stop RX:" + str(ret)) ret = airspy.close() ctrl_conn.send("EXIT:" + str(ret)) return True
def shutdown_hackrf(ctrl_conn): logger.debug("HackRF: closing device") ret = hackrf.close() ctrl_conn.send("close:" + str(ret)) ret = hackrf.exit() ctrl_conn.send("exit:" + str(ret)) return True
def prepare_modulation_buffer(self, total_samples: int, show_error=True) -> np.ndarray: memory_size_for_buffer = total_samples * 8 logger.debug("Allocating {0:.2f}MB for modulated samples".format(memory_size_for_buffer / (1024 ** 2))) try: return np.zeros(total_samples, dtype=np.complex64) except MemoryError: if show_error: Errors.not_enough_ram_for_sending_precache(memory_size_for_buffer) return None
def shutdown_device(cls, ctrl_connection): logger.debug("AirSpy: closing device") ret = airspy.stop_rx() ctrl_connection.send("Stop RX:" + str(ret)) ret = airspy.close() ctrl_connection.send("EXIT:" + str(ret)) return True
def prepare_modulation_buffer(self, total_samples: int, show_error=True) -> np.ndarray: memory_size_for_buffer = total_samples * 8 logger.debug("Allocating {0:.2f}MB for modulated samples".format(memory_size_for_buffer / (1024 ** 2))) try: return np.zeros(total_samples, dtype=np.complex64) except MemoryError: if show_error: Errors.not_enough_ram_for_sending_precache(memory_size_for_buffer) return None
def shutdown_device(cls, ctrl_conn: Connection): logger.debug("HackRF: closing device") ret = hackrf.close() ctrl_conn.send("CLOSE:" + str(ret)) ret = hackrf.exit() ctrl_conn.send("EXIT:" + str(ret)) return True
def __get_send_dialog(self): logger.debug("Creating Send Dialog") tests.utils_testing.short_wait() send_dialog = SendDialogController(self.form.project_manager, modulated_data=self.signal.data, testing_mode=True, parent=self.form) send_dialog.graphics_view.show_full_scene(reinitialize=True) return send_dialog
def setUp(self): constants.SETTINGS.setValue("NetworkSDRInterface", True) tests.utils_testing.short_wait() logger.debug("init form") self.form = MainController() self.signal = Signal(get_path_for_data_file("esaver.complex"), "testsignal") self.form.ui.tabWidget.setCurrentIndex(2)
def shutdown_device(cls, ctrl_conn: Connection): logger.debug("HackRF: closing device") ret = hackrf.close() ctrl_conn.send("CLOSE:" + str(ret)) ret = hackrf.exit() ctrl_conn.send("EXIT:" + str(ret)) return True
def shutdown_device(cls, ctrl_connection, is_tx=False): logger.debug("AirSpy: closing device") ret = airspy.stop_rx() ctrl_connection.send("Stop RX:" + str(ret)) ret = airspy.close() ctrl_connection.send("EXIT:" + str(ret)) return True
def log_message(self, message): timestamp = '{0:%b} {0.day} {0:%H}:{0:%M}:{0:%S}.{0:%f}'.format(datetime.datetime.now()) if isinstance(message, list) and len(message) > 0: self.log_messages.append(timestamp + ": " + message[0]) self.log_messages.extend(message[1:]) logger.debug("\n".join(message)) else: self.log_messages.append(timestamp + ": " + message) logger.debug(message)
def set_parameter(self, param: str, log=True): # returns error (True/False) try: self.write_to_rfcat(param) self.ready = False if log: logger.debug(param) except OSError as e: logger.info("Could not set parameter {0}:{1} ({2})".format(param, e)) return True return False
def open_rfcat(self): if not self.rfcat_is_open: try: self.process = Popen([self.rfcat_executable, '-r'], stdin=PIPE, stdout=PIPE, stderr=PIPE) self.rfcat_is_open = True logger.debug("Successfully opened RfCat ({})".format(self.rfcat_executable)) return True except Exception as e: logger.debug("Could not open RfCat! ({})".format(e)) return False else: return True
def shutdown_device(cls, ctrl_connection, is_tx: bool): logger.debug("shutting down pyaudio...") try: if cls.pyaudio_stream: cls.pyaudio_stream.stop_stream() cls.pyaudio_stream.close() if cls.pyaudio_handle: cls.pyaudio_handle.terminate() ctrl_connection.send("CLOSE:0") except Exception as e: logger.exception(e) ctrl_connection.send("Failed to shut down pyaudio")
def prepare_modulation_buffer(self, total_samples: int, show_error=True) -> np.ndarray: memory_size_for_buffer = total_samples * 8 logger.debug("Allocating {0:.2f}MB for modulated samples".format(memory_size_for_buffer / (1024 ** 2))) try: # allocate it three times as we need the same amount for the sending process np.zeros(3*total_samples, dtype=np.complex64) except MemoryError: # will go into continuous mode in this case if show_error: Errors.not_enough_ram_for_sending_precache(3*memory_size_for_buffer) return None return np.zeros(total_samples, dtype=np.complex64)
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 start_tcp_server_for_receiving(self): self.server = socketserver.TCPServer((self.server_ip, self.server_port), self.MyTCPHandler) self.server.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if self.raw_mode: self.server.receive_buffer = self.receive_buffer self.server.current_receive_index = 0 else: self.server.received_bits = self.received_bits self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.daemon = True self.server_thread.start() logger.debug("Started TCP server for receiving") self.receive_server_started.emit()
def __init__(self, raw_mode=False, resume_on_full_receive_buffer=False, spectrum=False, sending=False): """ :param raw_mode: If true, sending and receiving raw samples if false bits are received/sent """ super().__init__(name="NetworkSDRInterface") self.client_ip = self.qsettings.value("client_ip", defaultValue="127.0.0.1", type=str) self.server_ip = "" self.samples_to_send = None # set in virtual device constructor self.client_port = self.qsettings.value("client_port", defaultValue=2222, type=int) self.server_port = self.qsettings.value("server_port", defaultValue=4444, type=int) self.is_in_spectrum_mode = spectrum self.resume_on_full_receive_buffer = resume_on_full_receive_buffer self.__is_sending = False self.__sending_interrupt_requested = False self.sending_repeats = 1 # only used in raw mode self.current_sent_sample = 0 self.current_sending_repeat = 0 self.sending_is_continuous = False self.continuous_send_ring_buffer = None self.num_samples_to_send = None # Only used for continuous send mode self.raw_mode = raw_mode if not sending: if self.raw_mode: num_samples = SettingsProxy.get_receive_buffer_size(self.resume_on_full_receive_buffer, self.is_in_spectrum_mode) try: self.receive_buffer = np.zeros(num_samples, dtype=np.complex64, order='C') except MemoryError: logger.warning("Could not allocate buffer with {0:d} samples, trying less...") i = 0 while True: try: i += 2 self.receive_buffer = np.zeros(num_samples // i, dtype=np.complex64, order='C') logger.debug("Using buffer with {0:d} samples instead.".format(num_samples // i)) break except MemoryError: continue else: self.received_bits = []
def read_device_messages(self): while self.is_receiving or self.is_transmitting: try: message = self.parent_ctrl_conn.recv() try: splitted = message.split(":") action = ":".join(splitted[:-1]) return_code = splitted[-1] self.log_retcode(int(return_code), action) except ValueError: self.device_messages.append("{0}: {1}".format(self.__class__.__name__, message)) except (EOFError, UnpicklingError, OSError, ConnectionResetError) as e: logger.info("Exiting read device message thread due to " + str(e)) break self.is_transmitting = False self.is_receiving = False logger.debug("Exiting read device errors thread")
def apply_bandpass_filter(data, f_low, f_high, filter_bw=0.08): if f_low > f_high: f_low, f_high = f_high, f_low f_low = util.clip(f_low, -0.5, 0.5) f_high = util.clip(f_high, -0.5, 0.5) h = Filter.design_windowed_sinc_bandpass(f_low, f_high, filter_bw) # Choose normal or FFT convolution based on heuristic described in # https://softwareengineering.stackexchange.com/questions/171757/computational-complexity-of-correlation-in-time-vs-multiplication-in-frequency-s/ if len(h) < 8 * math.log(math.sqrt(len(data))): logger.debug("Use normal convolve") return np.convolve(data, h, 'same') else: logger.debug("Use FFT convolve") return Filter.fft_convolve_1d(data, h)
def stop(self, clear_buffer=True): self.abort.value = 1 if clear_buffer: self.ring_buffer.clear() if not self.process.is_alive(): return try: self.process.join(0.1) except RuntimeError as e: logger.debug(str(e)) if self.process.is_alive(): self.process.terminate() self.process.join() logger.debug("Stopped continuous modulation")
def test_create_context_menu(self): self.add_signal_to_form("esaver.complex") self.form.signal_tab_controller.signal_frames[0].ui.cbProtoView.setCurrentIndex(2) logger.debug("Get text edit") text_edit = self.form.signal_tab_controller.signal_frames[0].ui.txtEdProto menu = text_edit.create_context_menu() QApplication.instance().processEvents() line_wrap_action = next(action for action in menu.actions() if action.text().startswith("Linewrap")) checked = line_wrap_action.isChecked() line_wrap_action.trigger() menu = text_edit.create_context_menu() QApplication.instance().processEvents() line_wrap_action = next(action for action in menu.actions() if action.text().startswith("Linewrap")) self.assertNotEqual(checked, line_wrap_action.isChecked())
def closeEvent(self, event: QCloseEvent): if self.device.backend is not Backends.none: self.emit_editing_finished_signals() self.timer.stop() self.device.stop("Dialog closed. Killing recording process.") logger.debug("Device stopped successfully.") if not self.testing_mode: if not self.save_before_close(): event.ignore() return time.sleep(0.1) if self.device.backend not in (Backends.none, Backends.network): # Backend none is selected, when no device is available logger.debug("Cleaning up device") self.device.cleanup() logger.debug("Successfully cleaned up device") self.device_settings_widget.emit_device_parameters_changed() constants.SETTINGS.setValue("{}/geometry".format(self.__class__.__name__), self.saveGeometry()) if self.device is not None: self.device.free_data() self.scene_manager.eliminate() self._eliminate_graphic_view() super().closeEvent(event)
def __send_messages(self, messages, sample_rates): if len(messages): self.is_sending = True else: return False # Open and configure RfCat if not self.open_rfcat(): return False modulation = self.modulators[messages[0].modulator_index].modulation_type if modulation == 0: # ASK modulation = "MOD_ASK_OOK" elif modulation == 1: # FSK modulation = "MOD_2FSK" elif modulation == 2: # GFSK modulation = "MOD_GFSK" elif modulation == 3: # PSK modulation = "MOD_MSK" else: # Fallback modulation = "MOD_ASK_OOK" self.configure_rfcat(modulation=modulation, freq=self.project_manager.device_conf["frequency"], sample_rate=sample_rates[0], bit_len=messages[0].bit_len) repeats_from_settings = constants.SETTINGS.value('num_sending_repeats', type=int) repeats = repeats_from_settings if repeats_from_settings > 0 else -1 while (repeats > 0 or repeats == -1) and self.__sending_interrupt_requested == False: logger.debug("Start iteration ({} left)".format(repeats if repeats > 0 else "infinite")) for i, msg in enumerate(messages): if self.__sending_interrupt_requested: break assert isinstance(msg, Message) wait_time = msg.pause / sample_rates[i] self.current_send_message_changed.emit(i) error = self.send_data(self.bit_str_to_bytearray(msg.encoded_bits_str)) if not error: logger.debug("Sent message {0}/{1}".format(i+1, len(messages))) logger.debug("Waiting message pause: {0:.2f}s".format(wait_time)) if self.__sending_interrupt_requested: break time.sleep(wait_time) else: self.is_sending = False Errors.generic_error("Could not connect to {0}:{1}".format(self.client_ip, self.client_port), msg=error) break if repeats > 0: repeats -= 1 logger.debug("Sending finished") self.is_sending = False
def create_image(data: np.ndarray, colormap, data_min=None, data_max=None, normalize=True) -> QImage: """ Create QImage from ARGB array. The ARGB must have shape (width, height, 4) and dtype=ubyte. NOTE: The order of values in the 3rd axis must be (blue, green, red, alpha). :return: """ image_data = Spectrogram.apply_bgra_lookup(data, colormap, data_min, data_max, normalize) if not image_data.flags['C_CONTIGUOUS']: logger.debug("Array was not C_CONTIGUOUS. Converting it.") image_data = np.ascontiguousarray(image_data) try: # QImage constructor needs inverted row/column order image = QImage(image_data.ctypes.data, image_data.shape[1], image_data.shape[0], QImage.Format_ARGB32) except Exception as e: logger.error("could not create image " + str(e)) return QImage() image.data = image_data return image
def closeEvent(self, event: QCloseEvent): self.timer.stop() if self.device.backend is not Backends.none: self.emit_editing_finished_signals() self.device.stop("Dialog closed. Killing recording process.") logger.debug("Device stopped successfully.") if not self.testing_mode: if not self.save_before_close(): event.ignore() return time.sleep(0.1) if self.device.backend not in (Backends.none, Backends.network): # Backend none is selected, when no device is available logger.debug("Cleaning up device") try: # For Protocol Sniffer self.device.index_changed.disconnect() except TypeError: pass self.device.cleanup() logger.debug("Successfully cleaned up device") self.recording_parameters.emit(str(self.device.name), dict(frequency=self.device.frequency, sample_rate=self.device.sample_rate, bandwidth=self.device.bandwidth, gain=self.device.gain, if_gain=self.device.if_gain, baseband_gain=self.device.baseband_gain, freq_correction=self.device.freq_correction )) constants.SETTINGS.setValue("{}/geometry".format(self.__class__.__name__), self.saveGeometry()) if self.device is not None: self.device.free_data() self.scene_manager.eliminate() if self.graphics_view is not None: self.graphics_view.eliminate() self.graphics_view = None super().closeEvent(event)