Skip to content

Commit

Permalink
Incremental refactor to make rssi RPC seperate from record RPC.
Browse files Browse the repository at this point in the history
  • Loading branch information
anarkiwi committed Nov 9, 2023
1 parent 7919f7d commit 7ea671d
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 26 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ For example, make a recording with a sample rate of 20.48e6, for 2 seconds (4096
$ wget -nv -O- localhost:8000/v1/record/100000000/409600000/20480000
```

If the worker is started with `--rssi`, that same ```record``` call will cause the worker to publish RSSI values instead of recording (the duration argument must be present, but is not used).
To stream RSSI values instead, call (note that the duration argument must be present, but is not currently used):

```
$ wget -nv -O- localhost:8000/v1/rssi/100000000/409600000/20480000
```

## Working with worker I/Q recordings

Expand Down
3 changes: 2 additions & 1 deletion gamutrf/sigfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ def on_post(self, req, resp):
signal_hz = int(int(req.media["frequency"]) * 1e6)
record_bps = int(int(req.media["bandwidth"]) * MB)
record_samples = int(record_bps * int(req.media["duration"]))
recorder_args = f"record/{signal_hz}/{record_samples}/{record_bps}"
action = req.media["action"]
recorder_args = f"{action}/{signal_hz}/{record_samples}/{record_bps}"

Check warning on line 85 in gamutrf/sigfinder.py

View check run for this annotation

Codecov / codecov/patch

gamutrf/sigfinder.py#L84-L85

Added lines #L84 - L85 were not covered by tests
timeout = int(req.media["duration"])
response = None
if int(req.media["repeat"]) == -1:
Expand Down
50 changes: 33 additions & 17 deletions gamutrf/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,6 @@ def argument_parser():
action=argparse.BooleanOptionalAction,
help="add sigmf meta file",
)
parser.add_argument(
"--rssi",
dest="enable_rssi",
default=False,
action=argparse.BooleanOptionalAction,
help="get RSSI values",
)
parser.add_argument(
"--use_external_gps",
dest="use_external_gps",
Expand Down Expand Up @@ -206,11 +199,12 @@ def on_get(self, _req, resp):
resp.status = falcon.HTTP_200


class Record:
class Action:
def __init__(self, arguments, q, sdr_recorder):
self.arguments = arguments
self.q = q
self.sdr_recorder = sdr_recorder
self.action = None

def on_get(self, _req, resp, center_freq, sample_count, sample_rate):
# TODO check if chosen SDR can do the supplied sample_count
Expand All @@ -228,6 +222,7 @@ def on_get(self, _req, resp, center_freq, sample_count, sample_rate):
if status is None:
self.q.put(
{
"action": self.action,
"center_freq": int(center_freq),
"sample_count": int(sample_count),
"sample_rate": int(sample_rate),
Expand All @@ -239,6 +234,18 @@ def on_get(self, _req, resp, center_freq, sample_count, sample_rate):
resp.text = json.dumps({"status": status})


class Record(Action):
def __init__(self, arguments, q, sdr_recorder):
super().__init__(arguments, q, sdr_recorder)
self.action = "record"


class Rssi(Action):
def __init__(self, arguments, q, sdr_recorder):
super().__init__(arguments, q, sdr_recorder)
self.action = "record"


class API:
def __init__(self, arguments):
self.arguments = arguments
Expand Down Expand Up @@ -267,10 +274,14 @@ def run_recorder(self, record_func):
logging.info("run recorder")
while True:
logging.info("awaiting request")
if self.arguments.enable_rssi:
self.serve_rssi()
action_args = self.q.get()
action = action_args["action"]
if action == "record":
self.serve_recording(record_func, action_args)
elif action == "rssi":
self.serve_rssi(action_args)

Check warning on line 282 in gamutrf/worker.py

View check run for this annotation

Codecov / codecov/patch

gamutrf/worker.py#L277-L282

Added lines #L277 - L282 were not covered by tests
else:
self.serve_recording(record_func)
logging.error("no such action: %s", action)

Check warning on line 284 in gamutrf/worker.py

View check run for this annotation

Codecov / codecov/patch

gamutrf/worker.py#L284

Added line #L284 was not covered by tests

def record(self, center_freq, sample_count, sample_rate=20e6):
return self.sdr_recorder.run_recording(
Expand All @@ -286,8 +297,7 @@ def record(self, center_freq, sample_count, sample_rate=20e6):
self.arguments.antenna,
)

def serve_recording(self, record_func):
record_args = self.q.get()
def serve_recording(self, record_func, record_args):
logging.info(f"got a request: {record_args}")
record_status = record_func(**record_args)
if record_status == -1:
Expand Down Expand Up @@ -330,8 +340,7 @@ def proxy_rssi(self, rssi_addr, record_args):
sock.bind((rssi_addr, RSSI_UDP_PORT)) # nosec
self.process_rssi(record_args, sock)

def serve_rssi(self):
record_args = self.q.get()
def serve_rssi(self, record_args):
logging.info(f"got request {record_args}")
if self.arguments.rssi_external:
logging.info("proxying external RSSI")
Expand All @@ -340,6 +349,7 @@ def serve_rssi(self):
else:
center_freq = int(record_args["center_freq"])
try:
# TODO: enable duration
rssi_server = BirdsEyeRSSI(
self.arguments,
record_args["sample_rate"],
Expand All @@ -361,7 +371,12 @@ def serve_rssi(self):

@staticmethod
def paths():
return ["", "/info", "/record/{center_freq}/{sample_count}/{sample_rate}"]
return [
"",
"/info",
"/record/{center_freq}/{sample_count}/{sample_rate}",
"/rssi/{center_freq}/{sample_count}/{sample_rate}",
]

@staticmethod
def version():
Expand All @@ -372,7 +387,8 @@ def routes(self):
endpoints = Endpoints()
info = Info(self.arguments)
record = Record(self.arguments, self.q, self.sdr_recorder)
funcs = [endpoints, info, record]
rssi = Rssi(self.arguments, self.q, self.sdr_recorder)
funcs = [endpoints, info, record, rssi]
return dict(zip(p, funcs))

def run(self):
Expand Down
1 change: 1 addition & 0 deletions templates/scanner_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% endfor %}
<p>Make a request to record below:</p>
<p><input type="text" name="worker"/> Worker IP or name</p>
<p><input type="text" name="action"/> Action (e.g. record, rssi</p>
<p><input type="text" name="frequency"/> Frequency</p>
<p><input type="text" name="bandwidth" value="20"/> Bandwidth in Mhz (20 max)</p>
<p><input type="text" name="duration" value="10"/> Duration in seconds</p>
Expand Down
6 changes: 2 additions & 4 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,12 @@ def test_report_rssi():

def test_serve_recording():
app = worker.API(FakeArgs())
app.q.put({"center_freq": 1e6, "sample_count": 1e6})
app.serve_recording(app.record)
app.serve_recording(app.record, {"center_freq": 1e6, "sample_count": 1e6})


def test_serve_rssi():
app = worker.API(FakeArgs())
app.q.put({"center_freq": 1e6, "sample_count": 1e6, "sample_rate": 1e6})
app.serve_rssi()
app.serve_rssi({"center_freq": 1e6, "sample_count": 1e6, "sample_rate": 1e6})


def test_argument_parse():
Expand Down
3 changes: 1 addition & 2 deletions tests/test_birdseye_rssi.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def verify_birdseye_stream(self, gamutdir, freq):
for _ in range(15):
try:
response = requests.get(
f"http://localhost:8000/v1/record/{int(freq)}/1000000/1000000"
f"http://localhost:8000/v1/rssi/{int(freq)}/1000000/1000000"
)
self.assertEqual(200, response.status_code, response)
break
Expand Down Expand Up @@ -76,7 +76,6 @@ def test_birdseye_endtoend_rssi(self):
"60s",
"gamutrf-worker",
"--rssi_threshold=-100",
"--rssi",
f"--sdr=file:{testraw}",
],
ports={"8000/tcp": 8000},
Expand Down
1 change: 0 additions & 1 deletion worker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ services:
- --rxb=62914560
- '--gain=${GAIN}'
- --qsize=5
#- --rssi
#- --rssi_threshold=-110
#- --rssi_throttle=10
#- --use_external_gps
Expand Down

0 comments on commit 7ea671d

Please sign in to comment.