first steps towards a reconfigurable sdr source
This commit is contained in:
		@@ -121,7 +121,7 @@ class WebSocketMessageHandler(object):
 | 
				
			|||||||
            if message["type"] == "config":
 | 
					            if message["type"] == "config":
 | 
				
			||||||
                for key, value in message["params"].items():
 | 
					                for key, value in message["params"].items():
 | 
				
			||||||
                    # only the keys in the protected property manager can be overridden from the web
 | 
					                    # only the keys in the protected property manager can be overridden from the web
 | 
				
			||||||
                    protected = pm.collect("samp_rate")
 | 
					                    protected = pm.collect("samp_rate", "center_freq", "rf_gain")
 | 
				
			||||||
                    protected[key] = value
 | 
					                    protected[key] = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        except json.JSONDecodeError:
 | 
					        except json.JSONDecodeError:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,24 +3,10 @@ from owrx.config import PropertyManager, FeatureDetector
 | 
				
			|||||||
import threading
 | 
					import threading
 | 
				
			||||||
import csdr
 | 
					import csdr
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import signal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RtlNmuxSource(threading.Thread):
 | 
					class RtlNmuxSource(object):
 | 
				
			||||||
    def run(self):
 | 
					 | 
				
			||||||
        props = PropertyManager.getSharedInstance().collect(
 | 
					 | 
				
			||||||
            "rtl_type", "samp_rate", "nmux_memory", "iq_server_port", "center_freq", "ppm",
 | 
					 | 
				
			||||||
            "rf_gain", "lna_gain", "rf_amp"
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def restart(name, value):
 | 
					 | 
				
			||||||
            print("would now restart rtl source due to property change: {0} changed to {1}".format(name, value))
 | 
					 | 
				
			||||||
            # TODO not sure how to implement an actual restart... help
 | 
					 | 
				
			||||||
        props.wire(restart)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        featureDetector = FeatureDetector()
 | 
					 | 
				
			||||||
        if not featureDetector.is_available(props["rtl_type"]):
 | 
					 | 
				
			||||||
            print("The RTL source type {0} is not available. please check requirements.".format(props["rtl_type"]))
 | 
					 | 
				
			||||||
            return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    types = {
 | 
					    types = {
 | 
				
			||||||
        "rtl_sdr": {
 | 
					        "rtl_sdr": {
 | 
				
			||||||
            "command": "rtl_sdr -s {samp_rate} -f {center_freq} -p {ppm} -g {rf_gain} -",
 | 
					            "command": "rtl_sdr -s {samp_rate} -f {center_freq} -p {ppm} -g {rf_gain} -",
 | 
				
			||||||
@@ -36,7 +22,30 @@ class RtlNmuxSource(threading.Thread):
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        params = types[props["rtl_type"]]
 | 
					    def setup(self):
 | 
				
			||||||
 | 
					        self.props = props = PropertyManager.getSharedInstance().collect(
 | 
				
			||||||
 | 
					            "rtl_type", "samp_rate", "nmux_memory", "iq_server_port", "center_freq", "ppm",
 | 
				
			||||||
 | 
					            "rf_gain", "lna_gain", "rf_amp"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def restart(name, value):
 | 
				
			||||||
 | 
					            print("would now restart rtl source due to property change: {0} changed to {1}".format(name, value))
 | 
				
			||||||
 | 
					            self.stop()
 | 
				
			||||||
 | 
					            self.start()
 | 
				
			||||||
 | 
					        props.wire(restart)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        featureDetector = FeatureDetector()
 | 
				
			||||||
 | 
					        if not featureDetector.is_available(props["rtl_type"]):
 | 
				
			||||||
 | 
					            print("The RTL source type {0} is not available. please check requirements.".format(props["rtl_type"]))
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def start(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        props = self.props
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = RtlNmuxSource.types[props["rtl_type"]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        start_sdr_command = params["command"].format(
 | 
					        start_sdr_command = params["command"].format(
 | 
				
			||||||
            samp_rate = props["samp_rate"],
 | 
					            samp_rate = props["samp_rate"],
 | 
				
			||||||
@@ -58,10 +67,18 @@ class RtlNmuxSource(threading.Thread):
 | 
				
			|||||||
            return
 | 
					            return
 | 
				
			||||||
        print("[RtlNmuxSource] nmux_bufsize = %d, nmux_bufcnt = %d" % (nmux_bufsize, nmux_bufcnt))
 | 
					        print("[RtlNmuxSource] nmux_bufsize = %d, nmux_bufcnt = %d" % (nmux_bufsize, nmux_bufcnt))
 | 
				
			||||||
        cmd = start_sdr_command + " | nmux --bufsize %d --bufcnt %d --port %d --address 127.0.0.1" % (nmux_bufsize, nmux_bufcnt, props["iq_server_port"])
 | 
					        cmd = start_sdr_command + " | nmux --bufsize %d --bufcnt %d --port %d --address 127.0.0.1" % (nmux_bufsize, nmux_bufcnt, props["iq_server_port"])
 | 
				
			||||||
        self.process = subprocess.Popen(cmd, shell=True)
 | 
					        self.process = subprocess.Popen(cmd, shell=True, preexec_fn=os.setpgrp)
 | 
				
			||||||
        print("[RtlNmuxSource] Started rtl source: " + cmd)
 | 
					        print("[RtlNmuxSource] Started rtl source: " + cmd)
 | 
				
			||||||
        self.process.wait()
 | 
					
 | 
				
			||||||
        print("[RtlNmuxSource] shut down")
 | 
					        # TODO use this to monitor unexpected failures / shutdowns and react accordingly
 | 
				
			||||||
 | 
					        def wait_for_process_to_end():
 | 
				
			||||||
 | 
					            rc = self.process.wait()
 | 
				
			||||||
 | 
					            print("[RtlNmuxSource] shut down with RC={0}".format(rc))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        threading.Thread(target = wait_for_process_to_end).start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def stop(self):
 | 
				
			||||||
 | 
					        os.killpg(os.getpgid(self.process.pid), signal.SIGTERM)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SpectrumThread(threading.Thread):
 | 
					class SpectrumThread(threading.Thread):
 | 
				
			||||||
    sharedInstance = None
 | 
					    sharedInstance = None
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ def main():
 | 
				
			|||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pm.getPropertyValue("start_rtl_thread")):
 | 
					    if (pm.getPropertyValue("start_rtl_thread")):
 | 
				
			||||||
        RtlNmuxSource().start()
 | 
					        RtlNmuxSource().setup()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    server = ThreadedHttpServer(('0.0.0.0', pm.getPropertyValue("web_port")), RequestHandler)
 | 
					    server = ThreadedHttpServer(('0.0.0.0', pm.getPropertyValue("web_port")), RequestHandler)
 | 
				
			||||||
    server.serve_forever()
 | 
					    server.serve_forever()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user