aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/easydabv3.ini37
-rw-r--r--doc/example.ini21
-rwxr-xr-xdoc/receive_events.py59
-rwxr-xr-xdoc/zmq-ctrl/json_remote_server.py131
-rwxr-xr-xdoc/zmq-ctrl/zmq_remote.py22
5 files changed, 216 insertions, 54 deletions
diff --git a/doc/easydabv3.ini b/doc/easydabv3.ini
deleted file mode 100644
index 5f0103f..0000000
--- a/doc/easydabv3.ini
+++ /dev/null
@@ -1,37 +0,0 @@
-; This sample configuration is useful if ODR-DabMod is compiled
-; with --enable-easydabv3
-
-[remotecontrol]
-zmqctrl=1
-zmqctrlendpoint=tcp://127.0.0.1:9400
-; There is no telnet RC available in this build
-
-
-[log]
-syslog=0
-filelog=0
-filename=odr-dabmod.log
-
-[input]
-transport=zeromq
-source=tcp://localhost:9100
-max_frames_queued=400
-
-; There are no [modulator], [cfr], [firfilter], [poly] nor [tii] sections
-
-[output]
-output=file
-
-[fileoutput]
-; to be confirmed
-format=complexf
-
-filename=/dev/csdiof1
-
-show_metadata=0
-; TODO add option for writing out timestamps to csdiof1
-
-[delaymanagement]
-synchronous=0
-mutenotimestamps=0
-offset=1.002
diff --git a/doc/example.ini b/doc/example.ini
index aca7634..f009fbe 100644
--- a/doc/example.ini
+++ b/doc/example.ini
@@ -69,13 +69,6 @@ loop=0
;transport=tcp
;source=localhost:9200
-; When recieving data using ZeroMQ, the source is the URI to be used
-;transport=zeromq
-;source=tcp://localhost:9100
-; The option max_frames_queued defines the maximum number of ETI frames
-; (frame duration: 24ms) that can be in the input queue
-;max_frames_queued=100
-
[modulator]
; Mode 'fix' uses a fixed factor and is really not recommended. It is more
; useful on an academic perspective for people trying to understand the DAB
@@ -164,7 +157,7 @@ enabled=0
polycoeffile=polyCoefs
[output]
-; choose output: possible values: uhd, file, zmq, soapysdr, limesdr, bladerf
+; choose output: possible values: uhd, file, zmq, dexter, soapysdr, limesdr, bladerf
output=uhd
[fileoutput]
@@ -322,6 +315,18 @@ channel=13C
; Set to 0 to disable
;dpd_port=50055
+[dexteroutput]
+txgain=65535
+
+; channel/frequency is applied to ad9957.center_frequency
+;frequency=234208000
+channel=13C
+
+; lo offset is applied to dexter_dsp_tx.frequency0
+lo_offset=0
+
+max_gps_holdover_time=3600
+
[limeoutput]
; Lime output directly runs against the LMS device driver. It does not support SFN nor predistortion.
device=
diff --git a/doc/receive_events.py b/doc/receive_events.py
new file mode 100755
index 0000000..bfd6f86
--- /dev/null
+++ b/doc/receive_events.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# This is an example program that shows
+# how to receive runtime events from ODR-DabMod
+#
+# LICENSE: see bottom of file
+
+import sys
+import zmq
+import json
+from pprint import pprint
+
+context = zmq.Context()
+sock = context.socket(zmq.SUB)
+
+ep = "tcp://127.0.0.1:5556"
+print(f"Receive from {ep}")
+sock.connect(ep)
+
+# subscribe to all events
+sock.setsockopt(zmq.SUBSCRIBE, bytes([]))
+
+while True:
+ parts = sock.recv_multipart()
+ if len(parts) == 2:
+ print("Received event '{}'".format(parts[0].decode()))
+ pprint(json.loads(parts[1].decode()))
+
+ else:
+ print("Received strange event:")
+ pprint(parts)
+
+ print()
+
+
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# For more information, please refer to <http://unlicense.org>
diff --git a/doc/zmq-ctrl/json_remote_server.py b/doc/zmq-ctrl/json_remote_server.py
new file mode 100755
index 0000000..728cf7c
--- /dev/null
+++ b/doc/zmq-ctrl/json_remote_server.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+#
+# This is an example program that illustrates
+# how to interact with the zeromq remote control
+# using JSON.
+#
+# LICENSE: see bottom of file
+
+import sys
+import zmq
+from pprint import pprint
+import json
+import re
+from http.server import BaseHTTPRequestHandler, HTTPServer
+import time
+
+re_url = re.compile(r"/([a-zA-Z0-9]+).json")
+
+ZMQ_REMOTE = "tcp://localhost:9400"
+HTTP_HOSTNAME = "localhost"
+HTTP_PORT = 8080
+
+class DabMuxServer(BaseHTTPRequestHandler):
+ def err500(self, message):
+ self.send_response(500)
+ self.send_header("Content-type", "application/json")
+ self.end_headers()
+ self.wfile.write(json.dumps({"error": message}).encode())
+
+ def do_GET(self):
+ m = re_url.match(self.path)
+ if m:
+ sock = context.socket(zmq.REQ)
+ poller = zmq.Poller()
+ poller.register(sock, zmq.POLLIN)
+ sock.connect(ZMQ_REMOTE)
+
+ sock.send(b"ping")
+ socks = dict(poller.poll(1000))
+ if socks:
+ if socks.get(sock) == zmq.POLLIN:
+ data = sock.recv()
+ if data != b"ok":
+ print(f"Received {data} to ping!", file=sys.stderr)
+ self.err500("ping failure")
+ return
+ else:
+ print("ZMQ error: ping timeout", file=sys.stderr)
+ self.err500("ping timeout")
+ return
+
+ sock.send(b"showjson", flags=zmq.SNDMORE)
+ sock.send(m.group(1).encode())
+
+ socks = dict(poller.poll(1000))
+ if socks:
+ if socks.get(sock) == zmq.POLLIN:
+ data = sock.recv_multipart()
+ print("Received: {}".format(len(data)), file=sys.stderr)
+ parts = []
+ for i, part_data in enumerate(data):
+ part = part_data.decode()
+ print(" RX {}: {}".format(i, part.replace('\n',' ')), file=sys.stderr)
+
+ if i == 0 and part != "fail":
+ self.send_response(200)
+ self.send_header("Content-type", "application/json")
+ self.end_headers()
+ self.wfile.write(part_data)
+ return
+ parts.append(part)
+ self.err500("data error " + " ".join(parts))
+ return
+
+ else:
+ print("ZMQ error: timeout", file=sys.stderr)
+ self.err500("timeout")
+ return
+ else:
+ self.send_response(200)
+ self.send_header("Content-type", "text/html")
+ self.end_headers()
+ self.wfile.write("""<html><head><title>ODR-DabMod RC HTTP server</title></head>\n""".encode())
+ self.wfile.write("""<body>\n""".encode())
+ for mod in ("sdr", "tist", "modulator", "tii", "ofdm", "gain", "guardinterval"):
+ self.wfile.write(f"""<p><a href="{mod}.json">{mod}.json</a></p>\n""".encode())
+ self.wfile.write("""</body></html>\n""".encode())
+
+
+if __name__ == "__main__":
+ context = zmq.Context()
+
+ webServer = HTTPServer((HTTP_HOSTNAME, HTTP_PORT), DabMuxServer)
+ print("Server started http://%s:%s" % (HTTP_HOSTNAME, HTTP_PORT))
+
+ try:
+ webServer.serve_forever()
+ except KeyboardInterrupt:
+ pass
+
+ webServer.server_close()
+
+ context.destroy(linger=5)
+
+
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# For more information, please refer to <http://unlicense.org>
+
+
diff --git a/doc/zmq-ctrl/zmq_remote.py b/doc/zmq-ctrl/zmq_remote.py
index 56465d3..7581575 100755
--- a/doc/zmq-ctrl/zmq_remote.py
+++ b/doc/zmq-ctrl/zmq_remote.py
@@ -16,7 +16,7 @@ poller = zmq.Poller()
poller.register(sock, zmq.POLLIN)
if len(sys.argv) < 2:
- print("Usage: program url cmd [args...]")
+ print("Usage: program url cmd [args...]", file=sys.stderr)
sys.exit(1)
sock.connect(sys.argv[1])
@@ -25,7 +25,7 @@ message_parts = sys.argv[2:]
# first do a ping test
-print("ping")
+print("ping", file=sys.stderr)
sock.send(b"ping")
socks = dict(poller.poll(1000))
@@ -33,9 +33,9 @@ if socks:
if socks.get(sock) == zmq.POLLIN:
data = sock.recv_multipart()
- print("Received: {}".format(len(data)))
+ print("Received: {}".format(len(data)), file=sys.stderr)
for i,part in enumerate(data):
- print(" {}".format(part))
+ print(" {}".format(part), file=sys.stderr)
for i, part in enumerate(message_parts):
if i == len(message_parts) - 1:
@@ -43,18 +43,22 @@ if socks:
else:
f = zmq.SNDMORE
- print("Send {}({}): '{}'".format(i, f, part))
+ print("Send {}({}): '{}'".format(i, f, part), file=sys.stderr)
sock.send(part.encode(), flags=f)
data = sock.recv_multipart()
- print("Received: {}".format(len(data)))
- for i,part in enumerate(data):
- print(" RX {}: {}".format(i, part.decode().replace('\n',' ')))
+ print("Received: {}".format(len(data)), file=sys.stderr)
+ for i, part in enumerate(data):
+ if message_parts[0] == 'showjson':
+ # This allows you to pipe the JSON into another tool
+ print(part.decode())
+ else:
+ print(" RX {}: {}".format(i, part.decode().replace('\n',' ')), file=sys.stderr)
else:
- print("ZMQ error: timeout")
+ print("ZMQ error: timeout", file=sys.stderr)
context.destroy(linger=5)
# This is free and unencumbered software released into the public domain.