diff --git a/README.md b/README.md
index 6fbb034..0cd3ef2 100644
--- a/README.md
+++ b/README.md
@@ -50,3 +50,4 @@ Any transmit capable device that can be used to transmit using a GNURadio gr-osm
**lrs_pager.py** Generates a pager.bin file to be transmitted by lrs_tx.py. This code is based on [github.com/tony-tiger/lrs](https://github.com/tony-tiger/lrs)
**lrs_tx.py** Transmits an LRS signal, based on a pager.bin file generated by lrs_pager.py
**pocsagtx_osmocom.py** Transmits POCSAG messages using [gr-mixalot](https://github.com/unsynchronized/gr-mixalot)
+**gotenna_pro_bladerf.py** Transmits goTenna Pro broadcast messages using bladeRF and packet encoding from [gr-tenna](https://github.com/argilo/gr-tenna)
diff --git a/challengectl.py b/challengectl.py
index 7966968..06937e8 100755
--- a/challengectl.py
+++ b/challengectl.py
@@ -15,6 +15,7 @@
import subprocess
from challenges import ask, cw, usb_tx, nbfm, spectrum_paint, pocsagtx_osmocom, lrs_pager, lrs_tx
+from challenges.gotenna import gotenna_pro_tx_bladerf, gotenna_pro_tx_usrp
def build_database(flagfile, devicefile):
"""Create sqlite database based on flags file and devices file. Database file name will be based on
@@ -232,6 +233,50 @@ def fire_lrs(self, device_string, flag_q, device_q, *flag_args):
flag_q.put(flag_args[0])
print("Returned flag to pool")
+ def fire_gotenna_pro(self, device_string, flag_q, device_q, *flag_args):
+ print("\nTransmitting goTenna Pro\n")
+ flag_args = flag_args[0]
+ flag = flag_args[1]
+ modopts = flag_args[2]
+ mintime = flag_args[4]
+ maxtime = flag_args[5]
+ freq = int(flag_args[6]) * 1000
+ norandsleep = flag_args[8]
+
+ devargs = [arg.strip() for arg in device_string.split(",") if arg.strip() != ""]
+ devtypes = [arg.lower() for arg in devargs]
+ gotenna_module = None
+ if("uhd" in devtypes):
+ gotenna_module = gotenna_pro_tx_usrp
+ gotennaopts = gotenna_module.argument_parser().parse_args(modopts.split())
+ gotennaopts.device_addr = ",".join([arg for arg in devargs if arg.lower() != "uhd"])
+ elif(any(devtype.startswith("hackrf") for devtype in devtypes)):
+ print("goTenna Pro is not supported on HackRF, skipping device {}".format(device_string))
+ elif(any(devtype.startswith("bladerf") for devtype in devtypes)):
+ gotenna_module = gotenna_pro_tx_bladerf
+ gotennaopts = gotenna_module.argument_parser().parse_args(modopts.split())
+ gotennaopts.device_args = device_string
+ antenna = get_antenna_port(device_string)
+ if(antenna != ""):
+ gotennaopts.antenna = antenna
+ else:
+ print("goTenna Pro is not supported on device {}, skipping".format(device_string))
+
+ if(gotenna_module != None):
+ gotennaopts.message = flag
+ gotennaopts.frequency = freq
+
+ gotenna_module.main(options=gotennaopts)
+ sleep(3)
+ disable_amp(device_string)
+ device_q.put(device_string)
+
+ if(norandsleep == False):
+ sleep(randint(mintime, maxtime))
+ replaceinqueue = flag_args[7]
+ if(replaceinqueue != False):
+ flag_q.put(flag_args[0])
+
def select_freq(band):
"""Read from frequencies text file, select row that starts with band argument.
diff --git a/challenges/gotenna/__init__.py b/challenges/gotenna/__init__.py
new file mode 100644
index 0000000..98476f2
--- /dev/null
+++ b/challenges/gotenna/__init__.py
@@ -0,0 +1,4 @@
+# The flowgraphs in this package are generated by GNU Radio Companion from the
+# .grc files beside them, so they import the packet library under its bare name.
+# Importing challenges.gotenna_packet first registers it under that name.
+#from challenges import gotenna_packet # noqa: F401
diff --git a/challenges/gotenna/gotenna_pro_tx_bladerf.grc b/challenges/gotenna/gotenna_pro_tx_bladerf.grc
new file mode 100644
index 0000000..4d93c25
--- /dev/null
+++ b/challenges/gotenna/gotenna_pro_tx_bladerf.grc
@@ -0,0 +1,932 @@
+options:
+ parameters:
+ author: ''
+ catch_exceptions: 'True'
+ category: '[GRC Hier Blocks]'
+ cmake_opt: ''
+ comment: ''
+ copyright: ''
+ description: ''
+ gen_cmake: 'On'
+ gen_linking: dynamic
+ generate_options: no_gui
+ hier_block_src_path: '.:'
+ id: gotenna_pro_tx_bladerf
+ max_nouts: '0'
+ output_language: python
+ placement: (0,0)
+ qt_qss_theme: ''
+ realtime_scheduling: ''
+ run: 'True'
+ run_command: '{python} -u {filename}'
+ run_options: run
+ sizing_mode: fixed
+ thread_safe_setters: ''
+ title: ''
+ window_size: ''
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 8]
+ rotation: 0
+ state: enabled
+
+blocks:
+- name: center_freq
+ id: variable
+ parameters:
+ comment: ''
+ value: frequency - offset
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [80, 460]
+ rotation: 0
+ state: enabled
+- name: control_chan
+ id: variable
+ parameters:
+ comment: ''
+ value: '2'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [120, 524]
+ rotation: 0
+ state: enabled
+- name: data_chan
+ id: variable
+ parameters:
+ comment: ''
+ value: '2'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [224, 524]
+ rotation: 0
+ state: enabled
+- name: fsk_deviation_hz
+ id: variable
+ parameters:
+ comment: ''
+ value: '{2400: 400, 4800: 750, 9600: 1100}[baud_rate]'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 332.0]
+ rotation: 0
+ state: enabled
+- name: hw_rate
+ id: variable
+ parameters:
+ comment: ''
+ value: '5760000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [184, 460.0]
+ rotation: 0
+ state: enabled
+- name: interp
+ id: variable
+ parameters:
+ comment: ''
+ value: 480000 // baud_rate
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 460]
+ rotation: 0
+ state: enabled
+- name: offset
+ id: variable
+ parameters:
+ comment: ''
+ value: '250000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 268.0]
+ rotation: 0
+ state: enabled
+- name: packets
+ id: variable
+ parameters:
+ comment: ''
+ value: gotenna_packet.encode_pro_broadcast_packets(message_type, counter_num,
+ sender_gid, recipient_gid, callsign, message, publickey_data)
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 612.0]
+ rotation: 0
+ state: enabled
+- name: samp_per_sym
+ id: variable
+ parameters:
+ comment: ''
+ value: '4'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 524]
+ rotation: 0
+ state: enabled
+- name: samp_rate
+ id: variable
+ parameters:
+ comment: ''
+ value: baud_rate * samp_per_sym * interp
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 396]
+ rotation: 0
+ state: enabled
+- name: silence_time
+ id: variable
+ parameters:
+ comment: ''
+ value: '4000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [160, 612.0]
+ rotation: 0
+ state: enabled
+- name: taps
+ id: variable
+ parameters:
+ comment: ''
+ value: firdes.gaussian(1.0, samp_per_sym, 0.5, 64)
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 188.0]
+ rotation: 0
+ state: enabled
+- name: antenna
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Transmit antenna
+ short_id: ''
+ type: str
+ value: ''
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 44.0]
+ rotation: 0
+ state: true
+- name: baud_rate
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Baud rate
+ short_id: ''
+ type: intx
+ value: '9600'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [768, 44.0]
+ rotation: 0
+ state: enabled
+- name: blocks_char_to_float_0
+ id: blocks_char_to_float
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ scale: '1'
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [432, 196.0]
+ rotation: 180
+ state: enabled
+- name: blocks_multiply_xx_0
+ id: blocks_multiply_xx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ num_inputs: '2'
+ type: complex
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [632, 328.0]
+ rotation: 0
+ state: enabled
+- name: blocks_multiply_xx_1
+ id: blocks_multiply_xx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ num_inputs: '2'
+ type: complex
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [960, 408.0]
+ rotation: 0
+ state: enabled
+- name: blocks_repeat_0
+ id: blocks_repeat
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ interp: 8 * samp_per_sym
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: complex
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [448, 388.0]
+ rotation: 0
+ state: enabled
+- name: blocks_repeat_1
+ id: blocks_repeat
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ interp: 8 * samp_per_sym * (hw_rate // (baud_rate * samp_per_sym))
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: float
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [592, 516.0]
+ rotation: 0
+ state: enabled
+- name: blocks_repeat_2
+ id: blocks_repeat
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ interp: samp_per_sym
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: float
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [256, 196.0]
+ rotation: 180
+ state: enabled
+- name: blocks_vco_c_0
+ id: blocks_vco_c
+ parameters:
+ affinity: ''
+ alias: ''
+ amplitude: '0.9'
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ samp_rate: hw_rate
+ sensitivity: 2*math.pi
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [768, 500.0]
+ rotation: 0
+ state: enabled
+- name: blocks_vco_c_1
+ id: blocks_vco_c
+ parameters:
+ affinity: ''
+ alias: ''
+ amplitude: '1.0'
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ samp_rate: baud_rate * samp_per_sym
+ sensitivity: 2 * math.pi * fsk_deviation_hz
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [440, 276.0]
+ rotation: 0
+ state: enabled
+- name: blocks_vector_source_x_0
+ id: blocks_vector_source_x
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ repeat: 'False'
+ tags: '[]'
+ type: byte
+ vector: '[0]*silence_time+gotenna_packet.pro_gfsk_symbols(packets)+[0]*silence_time'
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [776, 180.0]
+ rotation: 180
+ state: enabled
+- name: blocks_vector_source_x_1
+ id: blocks_vector_source_x
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ repeat: 'True'
+ tags: '[]'
+ type: complex
+ vector: '[1]'
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [216, 372.0]
+ rotation: 0
+ state: enabled
+- name: blocks_vector_source_x_2
+ id: blocks_vector_source_x
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ repeat: 'True'
+ tags: '[]'
+ type: float
+ vector: '[offset]'
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [360, 500.0]
+ rotation: 0
+ state: enabled
+- name: callsign
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Sender callsign
+ short_id: ''
+ type: str
+ value: VE3IRR
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [512, 44.0]
+ rotation: 0
+ state: true
+- name: counter_num
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Counter
+ short_id: ''
+ type: intx
+ value: '0'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1248, 44.0]
+ rotation: 0
+ state: true
+- name: device_args
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Osmocom device arguments
+ short_id: ''
+ type: str
+ value: bladerf=0,biastee=1
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [136, 44.0]
+ rotation: 0
+ state: true
+- name: digital_map_bb_0
+ id: digital_map_bb
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ map: '[-3, -1, 3, 1, 0]'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [600, 196.0]
+ rotation: 180
+ state: enabled
+- name: frequency
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Frequency
+ short_id: ''
+ type: eng_float
+ value: '450000000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [872, 44.0]
+ rotation: 0
+ state: enabled
+- name: import_0
+ id: import
+ parameters:
+ alias: ''
+ comment: ''
+ imports: import gotenna_packet
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 92.0]
+ rotation: 0
+ state: enabled
+- name: import_1
+ id: import
+ parameters:
+ alias: ''
+ comment: ''
+ imports: import math
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 140]
+ rotation: 0
+ state: enabled
+- name: interp_fir_filter_xxx_0
+ id: interp_fir_filter_xxx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ interp: '1'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ samp_delay: '0'
+ taps: taps
+ type: fff
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [216, 284.0]
+ rotation: 0
+ state: enabled
+- name: message
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Message
+ short_id: ''
+ type: str
+ value: Hello world!
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [648, 44.0]
+ rotation: 0
+ state: true
+- name: message_type
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: type
+ short_id: ''
+ type: str
+ value: BROADCAST
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [984, 44.0]
+ rotation: 0
+ state: true
+- name: osmosdr_sink_0
+ id: osmosdr_sink
+ parameters:
+ affinity: ''
+ alias: ''
+ ant0: antenna
+ ant1: ''
+ ant10: ''
+ ant11: ''
+ ant12: ''
+ ant13: ''
+ ant14: ''
+ ant15: ''
+ ant16: ''
+ ant17: ''
+ ant18: ''
+ ant19: ''
+ ant2: ''
+ ant20: ''
+ ant21: ''
+ ant22: ''
+ ant23: ''
+ ant24: ''
+ ant25: ''
+ ant26: ''
+ ant27: ''
+ ant28: ''
+ ant29: ''
+ ant3: ''
+ ant30: ''
+ ant31: ''
+ ant4: ''
+ ant5: ''
+ ant6: ''
+ ant7: ''
+ ant8: ''
+ ant9: ''
+ args: device_args
+ bb_gain0: '0'
+ bb_gain1: '20'
+ bb_gain10: '20'
+ bb_gain11: '20'
+ bb_gain12: '20'
+ bb_gain13: '20'
+ bb_gain14: '20'
+ bb_gain15: '20'
+ bb_gain16: '20'
+ bb_gain17: '20'
+ bb_gain18: '20'
+ bb_gain19: '20'
+ bb_gain2: '20'
+ bb_gain20: '20'
+ bb_gain21: '20'
+ bb_gain22: '20'
+ bb_gain23: '20'
+ bb_gain24: '20'
+ bb_gain25: '20'
+ bb_gain26: '20'
+ bb_gain27: '20'
+ bb_gain28: '20'
+ bb_gain29: '20'
+ bb_gain3: '20'
+ bb_gain30: '20'
+ bb_gain31: '20'
+ bb_gain4: '20'
+ bb_gain5: '20'
+ bb_gain6: '20'
+ bb_gain7: '20'
+ bb_gain8: '20'
+ bb_gain9: '20'
+ bw0: '1000000'
+ bw1: '0'
+ bw10: '0'
+ bw11: '0'
+ bw12: '0'
+ bw13: '0'
+ bw14: '0'
+ bw15: '0'
+ bw16: '0'
+ bw17: '0'
+ bw18: '0'
+ bw19: '0'
+ bw2: '0'
+ bw20: '0'
+ bw21: '0'
+ bw22: '0'
+ bw23: '0'
+ bw24: '0'
+ bw25: '0'
+ bw26: '0'
+ bw27: '0'
+ bw28: '0'
+ bw29: '0'
+ bw3: '0'
+ bw30: '0'
+ bw31: '0'
+ bw4: '0'
+ bw5: '0'
+ bw6: '0'
+ bw7: '0'
+ bw8: '0'
+ bw9: '0'
+ clock_source0: ''
+ clock_source1: ''
+ clock_source2: ''
+ clock_source3: ''
+ clock_source4: ''
+ clock_source5: ''
+ clock_source6: ''
+ clock_source7: ''
+ comment: ''
+ corr0: '0'
+ corr1: '0'
+ corr10: '0'
+ corr11: '0'
+ corr12: '0'
+ corr13: '0'
+ corr14: '0'
+ corr15: '0'
+ corr16: '0'
+ corr17: '0'
+ corr18: '0'
+ corr19: '0'
+ corr2: '0'
+ corr20: '0'
+ corr21: '0'
+ corr22: '0'
+ corr23: '0'
+ corr24: '0'
+ corr25: '0'
+ corr26: '0'
+ corr27: '0'
+ corr28: '0'
+ corr29: '0'
+ corr3: '0'
+ corr30: '0'
+ corr31: '0'
+ corr4: '0'
+ corr5: '0'
+ corr6: '0'
+ corr7: '0'
+ corr8: '0'
+ corr9: '0'
+ freq0: center_freq
+ freq1: 100e6
+ freq10: 100e6
+ freq11: 100e6
+ freq12: 100e6
+ freq13: 100e6
+ freq14: 100e6
+ freq15: 100e6
+ freq16: 100e6
+ freq17: 100e6
+ freq18: 100e6
+ freq19: 100e6
+ freq2: 100e6
+ freq20: 100e6
+ freq21: 100e6
+ freq22: 100e6
+ freq23: 100e6
+ freq24: 100e6
+ freq25: 100e6
+ freq26: 100e6
+ freq27: 100e6
+ freq28: 100e6
+ freq29: 100e6
+ freq3: 100e6
+ freq30: 100e6
+ freq31: 100e6
+ freq4: 100e6
+ freq5: 100e6
+ freq6: 100e6
+ freq7: 100e6
+ freq8: 100e6
+ freq9: 100e6
+ gain0: '60'
+ gain1: '10'
+ gain10: '10'
+ gain11: '10'
+ gain12: '10'
+ gain13: '10'
+ gain14: '10'
+ gain15: '10'
+ gain16: '10'
+ gain17: '10'
+ gain18: '10'
+ gain19: '10'
+ gain2: '10'
+ gain20: '10'
+ gain21: '10'
+ gain22: '10'
+ gain23: '10'
+ gain24: '10'
+ gain25: '10'
+ gain26: '10'
+ gain27: '10'
+ gain28: '10'
+ gain29: '10'
+ gain3: '10'
+ gain30: '10'
+ gain31: '10'
+ gain4: '10'
+ gain5: '10'
+ gain6: '10'
+ gain7: '10'
+ gain8: '10'
+ gain9: '10'
+ if_gain0: '0'
+ if_gain1: '20'
+ if_gain10: '20'
+ if_gain11: '20'
+ if_gain12: '20'
+ if_gain13: '20'
+ if_gain14: '20'
+ if_gain15: '20'
+ if_gain16: '20'
+ if_gain17: '20'
+ if_gain18: '20'
+ if_gain19: '20'
+ if_gain2: '20'
+ if_gain20: '20'
+ if_gain21: '20'
+ if_gain22: '20'
+ if_gain23: '20'
+ if_gain24: '20'
+ if_gain25: '20'
+ if_gain26: '20'
+ if_gain27: '20'
+ if_gain28: '20'
+ if_gain29: '20'
+ if_gain3: '20'
+ if_gain30: '20'
+ if_gain31: '20'
+ if_gain4: '20'
+ if_gain5: '20'
+ if_gain6: '20'
+ if_gain7: '20'
+ if_gain8: '20'
+ if_gain9: '20'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ nchan: '1'
+ num_mboards: '1'
+ sample_rate: hw_rate
+ sync: sync
+ time_source0: ''
+ time_source1: ''
+ time_source2: ''
+ time_source3: ''
+ time_source4: ''
+ time_source5: ''
+ time_source6: ''
+ time_source7: ''
+ type: fc32
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1184, 332.0]
+ rotation: 0
+ state: enabled
+- name: publickey_data
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Sender Public Key
+ short_id: ''
+ type: str
+ value: base64key
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1104, 44.0]
+ rotation: 0
+ state: true
+- name: rational_resampler_xxx_0
+ id: rational_resampler_xxx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ decim: '1'
+ fbw: '0'
+ interp: hw_rate // (baud_rate * samp_per_sym)
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ taps: ''
+ type: ccc
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [760, 316.0]
+ rotation: 0
+ state: enabled
+- name: recipient_gid
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Recipient GID
+ short_id: ''
+ type: intx
+ value: '1234567891'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [272, 44.0]
+ rotation: 0
+ state: true
+- name: sender_gid
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Sender GID
+ short_id: ''
+ type: intx
+ value: '1234567890'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [400, 44.0]
+ rotation: 0
+ state: true
+
+connections:
+- [blocks_char_to_float_0, '0', blocks_repeat_2, '0']
+- [blocks_multiply_xx_0, '0', rational_resampler_xxx_0, '0']
+- [blocks_multiply_xx_1, '0', osmosdr_sink_0, '0']
+- [blocks_repeat_0, '0', blocks_multiply_xx_0, '1']
+- [blocks_repeat_1, '0', blocks_vco_c_0, '0']
+- [blocks_repeat_2, '0', interp_fir_filter_xxx_0, '0']
+- [blocks_vco_c_0, '0', blocks_multiply_xx_1, '1']
+- [blocks_vco_c_1, '0', blocks_multiply_xx_0, '0']
+- [blocks_vector_source_x_0, '0', digital_map_bb_0, '0']
+- [blocks_vector_source_x_1, '0', blocks_repeat_0, '0']
+- [blocks_vector_source_x_2, '0', blocks_repeat_1, '0']
+- [digital_map_bb_0, '0', blocks_char_to_float_0, '0']
+- [interp_fir_filter_xxx_0, '0', blocks_vco_c_1, '0']
+- [rational_resampler_xxx_0, '0', blocks_multiply_xx_1, '0']
+
+metadata:
+ file_format: 1
+ grc_version: 3.10.7.0
diff --git a/challenges/gotenna/gotenna_pro_tx_bladerf.py b/challenges/gotenna/gotenna_pro_tx_bladerf.py
new file mode 100755
index 0000000..5a8d886
--- /dev/null
+++ b/challenges/gotenna/gotenna_pro_tx_bladerf.py
@@ -0,0 +1,346 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+#
+# SPDX-License-Identifier: GPL-3.0
+#
+# GNU Radio Python Flow Graph
+# Title: Gotenna Pro Tx Bladerf
+# GNU Radio version: 3.10.5.0
+
+from gnuradio import blocks
+from gnuradio import digital
+from gnuradio import filter
+from gnuradio.filter import firdes
+from gnuradio import gr
+from gnuradio.fft import window
+import sys
+import signal
+from argparse import ArgumentParser
+from gnuradio.eng_arg import eng_float, intx
+from gnuradio import eng_notation
+import gotenna_packet
+import math
+import osmosdr
+import time
+
+
+
+
+class gotenna_pro_tx_bladerf(gr.top_block):
+
+ def __init__(self, antenna='', baud_rate=9600, callsign='VE3IRR', counter_num=0, device_args='bladerf=0,biastee=1', frequency=450000000, message='Hello world!', message_type='BROADCAST', publickey_data='base64key', recipient_gid=1234567891, sender_gid=1234567890):
+ gr.top_block.__init__(self, "Gotenna Pro Tx Bladerf", catch_exceptions=True)
+
+ ##################################################
+ # Parameters
+ ##################################################
+ self.antenna = antenna
+ self.baud_rate = baud_rate
+ self.callsign = callsign
+ self.counter_num = counter_num
+ self.device_args = device_args
+ self.frequency = frequency
+ self.message = message
+ self.message_type = message_type
+ self.publickey_data = publickey_data
+ self.recipient_gid = recipient_gid
+ self.sender_gid = sender_gid
+
+ ##################################################
+ # Variables
+ ##################################################
+ self.samp_per_sym = samp_per_sym = 4
+ self.offset = offset = 250000
+ self.interp = interp = 480000 // baud_rate
+ self.taps = taps = firdes.gaussian(1.0, samp_per_sym, 0.5, 64)
+ self.silence_time = silence_time = 4000
+ self.samp_rate = samp_rate = baud_rate * samp_per_sym * interp
+ self.packets = packets = gotenna_packet.encode_pro_broadcast_packets(message_type, counter_num, sender_gid, recipient_gid, callsign, message, publickey_data)
+ self.hw_rate = hw_rate = 5760000
+ self.fsk_deviation_hz = fsk_deviation_hz = {2400: 400, 4800: 750, 9600: 1100}[baud_rate]
+ self.data_chan = data_chan = 2
+ self.control_chan = control_chan = 2
+ self.center_freq = center_freq = frequency - offset
+
+ ##################################################
+ # Blocks
+ ##################################################
+ self.rational_resampler_xxx_0 = filter.rational_resampler_ccc(
+ interpolation=(hw_rate // (baud_rate * samp_per_sym)),
+ decimation=1,
+ taps=[],
+ fractional_bw=0)
+ self.osmosdr_sink_0 = osmosdr.sink(
+ args="numchan=" + str(1) + " " + device_args
+ )
+ self.osmosdr_sink_0.set_time_unknown_pps(osmosdr.time_spec_t())
+ self.osmosdr_sink_0.set_sample_rate(hw_rate)
+ self.osmosdr_sink_0.set_center_freq(center_freq, 0)
+ self.osmosdr_sink_0.set_freq_corr(0, 0)
+ self.osmosdr_sink_0.set_gain(60, 0)
+ self.osmosdr_sink_0.set_if_gain(0, 0)
+ self.osmosdr_sink_0.set_bb_gain(0, 0)
+ self.osmosdr_sink_0.set_antenna(antenna, 0)
+ self.osmosdr_sink_0.set_bandwidth(1000000, 0)
+ self.interp_fir_filter_xxx_0 = filter.interp_fir_filter_fff(1, taps)
+ self.interp_fir_filter_xxx_0.declare_sample_delay(0)
+ self.digital_map_bb_0 = digital.map_bb([-3, -1, 3, 1, 0])
+ self.blocks_vector_source_x_2 = blocks.vector_source_f([offset], True, 1, [])
+ self.blocks_vector_source_x_1 = blocks.vector_source_c([1], True, 1, [])
+ self.blocks_vector_source_x_0 = blocks.vector_source_b([0]*silence_time+gotenna_packet.pro_gfsk_symbols(packets)+[0]*silence_time, False, 1, [])
+ self.blocks_vco_c_1 = blocks.vco_c((baud_rate * samp_per_sym), (2 * math.pi * fsk_deviation_hz), 1.0)
+ self.blocks_vco_c_0 = blocks.vco_c(hw_rate, (2*math.pi), 0.9)
+ self.blocks_repeat_2 = blocks.repeat(gr.sizeof_float*1, samp_per_sym)
+ self.blocks_repeat_1 = blocks.repeat(gr.sizeof_float*1, (8 * samp_per_sym * (hw_rate // (baud_rate * samp_per_sym))))
+ self.blocks_repeat_0 = blocks.repeat(gr.sizeof_gr_complex*1, (8 * samp_per_sym))
+ self.blocks_multiply_xx_1 = blocks.multiply_vcc(1)
+ self.blocks_multiply_xx_0 = blocks.multiply_vcc(1)
+ self.blocks_char_to_float_0 = blocks.char_to_float(1, 1)
+
+
+ ##################################################
+ # Connections
+ ##################################################
+ self.connect((self.blocks_char_to_float_0, 0), (self.blocks_repeat_2, 0))
+ self.connect((self.blocks_multiply_xx_0, 0), (self.rational_resampler_xxx_0, 0))
+ self.connect((self.blocks_multiply_xx_1, 0), (self.osmosdr_sink_0, 0))
+ self.connect((self.blocks_repeat_0, 0), (self.blocks_multiply_xx_0, 1))
+ self.connect((self.blocks_repeat_1, 0), (self.blocks_vco_c_0, 0))
+ self.connect((self.blocks_repeat_2, 0), (self.interp_fir_filter_xxx_0, 0))
+ self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_1, 1))
+ self.connect((self.blocks_vco_c_1, 0), (self.blocks_multiply_xx_0, 0))
+ self.connect((self.blocks_vector_source_x_0, 0), (self.digital_map_bb_0, 0))
+ self.connect((self.blocks_vector_source_x_1, 0), (self.blocks_repeat_0, 0))
+ self.connect((self.blocks_vector_source_x_2, 0), (self.blocks_repeat_1, 0))
+ self.connect((self.digital_map_bb_0, 0), (self.blocks_char_to_float_0, 0))
+ self.connect((self.interp_fir_filter_xxx_0, 0), (self.blocks_vco_c_1, 0))
+ self.connect((self.rational_resampler_xxx_0, 0), (self.blocks_multiply_xx_1, 0))
+
+
+ def get_antenna(self):
+ return self.antenna
+
+ def set_antenna(self, antenna):
+ self.antenna = antenna
+ self.osmosdr_sink_0.set_antenna(self.antenna, 0)
+
+ def get_baud_rate(self):
+ return self.baud_rate
+
+ def set_baud_rate(self, baud_rate):
+ self.baud_rate = baud_rate
+ self.set_fsk_deviation_hz({2400: 400, 4800: 750, 9600: 1100}[self.baud_rate])
+ self.set_interp(480000 // self.baud_rate)
+ self.set_samp_rate(self.baud_rate * self.samp_per_sym * self.interp)
+ self.blocks_repeat_1.set_interpolation((8 * self.samp_per_sym * (self.hw_rate // (self.baud_rate * self.samp_per_sym))))
+
+ def get_callsign(self):
+ return self.callsign
+
+ def set_callsign(self, callsign):
+ self.callsign = callsign
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_counter_num(self):
+ return self.counter_num
+
+ def set_counter_num(self, counter_num):
+ self.counter_num = counter_num
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_device_args(self):
+ return self.device_args
+
+ def set_device_args(self, device_args):
+ self.device_args = device_args
+
+ def get_frequency(self):
+ return self.frequency
+
+ def set_frequency(self, frequency):
+ self.frequency = frequency
+ self.set_center_freq(self.frequency - self.offset)
+
+ def get_message(self):
+ return self.message
+
+ def set_message(self, message):
+ self.message = message
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_message_type(self):
+ return self.message_type
+
+ def set_message_type(self, message_type):
+ self.message_type = message_type
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_publickey_data(self):
+ return self.publickey_data
+
+ def set_publickey_data(self, publickey_data):
+ self.publickey_data = publickey_data
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_recipient_gid(self):
+ return self.recipient_gid
+
+ def set_recipient_gid(self, recipient_gid):
+ self.recipient_gid = recipient_gid
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_sender_gid(self):
+ return self.sender_gid
+
+ def set_sender_gid(self, sender_gid):
+ self.sender_gid = sender_gid
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_samp_per_sym(self):
+ return self.samp_per_sym
+
+ def set_samp_per_sym(self, samp_per_sym):
+ self.samp_per_sym = samp_per_sym
+ self.set_samp_rate(self.baud_rate * self.samp_per_sym * self.interp)
+ self.set_taps(firdes.gaussian(1.0, self.samp_per_sym, 0.5, 64))
+ self.blocks_repeat_0.set_interpolation((8 * self.samp_per_sym))
+ self.blocks_repeat_1.set_interpolation((8 * self.samp_per_sym * (self.hw_rate // (self.baud_rate * self.samp_per_sym))))
+ self.blocks_repeat_2.set_interpolation(self.samp_per_sym)
+
+ def get_offset(self):
+ return self.offset
+
+ def set_offset(self, offset):
+ self.offset = offset
+ self.set_center_freq(self.frequency - self.offset)
+ self.blocks_vector_source_x_2.set_data([self.offset], [])
+
+ def get_interp(self):
+ return self.interp
+
+ def set_interp(self, interp):
+ self.interp = interp
+ self.set_samp_rate(self.baud_rate * self.samp_per_sym * self.interp)
+
+ def get_taps(self):
+ return self.taps
+
+ def set_taps(self, taps):
+ self.taps = taps
+ self.interp_fir_filter_xxx_0.set_taps(self.taps)
+
+ def get_silence_time(self):
+ return self.silence_time
+
+ def set_silence_time(self, silence_time):
+ self.silence_time = silence_time
+ self.blocks_vector_source_x_0.set_data([0]*self.silence_time+gotenna_packet.pro_gfsk_symbols(self.packets)+[0]*self.silence_time, [])
+
+ def get_samp_rate(self):
+ return self.samp_rate
+
+ def set_samp_rate(self, samp_rate):
+ self.samp_rate = samp_rate
+
+ def get_packets(self):
+ return self.packets
+
+ def set_packets(self, packets):
+ self.packets = packets
+ self.blocks_vector_source_x_0.set_data([0]*self.silence_time+gotenna_packet.pro_gfsk_symbols(self.packets)+[0]*self.silence_time, [])
+
+ def get_hw_rate(self):
+ return self.hw_rate
+
+ def set_hw_rate(self, hw_rate):
+ self.hw_rate = hw_rate
+ self.blocks_repeat_1.set_interpolation((8 * self.samp_per_sym * (self.hw_rate // (self.baud_rate * self.samp_per_sym))))
+ self.osmosdr_sink_0.set_sample_rate(self.hw_rate)
+
+ def get_fsk_deviation_hz(self):
+ return self.fsk_deviation_hz
+
+ def set_fsk_deviation_hz(self, fsk_deviation_hz):
+ self.fsk_deviation_hz = fsk_deviation_hz
+
+ def get_data_chan(self):
+ return self.data_chan
+
+ def set_data_chan(self, data_chan):
+ self.data_chan = data_chan
+
+ def get_control_chan(self):
+ return self.control_chan
+
+ def set_control_chan(self, control_chan):
+ self.control_chan = control_chan
+
+ def get_center_freq(self):
+ return self.center_freq
+
+ def set_center_freq(self, center_freq):
+ self.center_freq = center_freq
+ self.osmosdr_sink_0.set_center_freq(self.center_freq, 0)
+
+
+
+def argument_parser():
+ parser = ArgumentParser()
+ parser.add_argument(
+ "--antenna", dest="antenna", type=str, default='',
+ help="Set Transmit antenna [default=%(default)r]")
+ parser.add_argument(
+ "--baud-rate", dest="baud_rate", type=intx, default=9600,
+ help="Set Baud rate [default=%(default)r]")
+ parser.add_argument(
+ "--callsign", dest="callsign", type=str, default='VE3IRR',
+ help="Set Sender callsign [default=%(default)r]")
+ parser.add_argument(
+ "--counter-num", dest="counter_num", type=intx, default=0,
+ help="Set Counter [default=%(default)r]")
+ parser.add_argument(
+ "--device-args", dest="device_args", type=str, default='bladerf=0,biastee=1',
+ help="Set Osmocom device arguments [default=%(default)r]")
+ parser.add_argument(
+ "--frequency", dest="frequency", type=eng_float, default=eng_notation.num_to_str(float(450000000)),
+ help="Set Frequency [default=%(default)r]")
+ parser.add_argument(
+ "--message", dest="message", type=str, default='Hello world!',
+ help="Set Message [default=%(default)r]")
+ parser.add_argument(
+ "--message-type", dest="message_type", type=str, default='BROADCAST',
+ help="Set type [default=%(default)r]")
+ parser.add_argument(
+ "--publickey-data", dest="publickey_data", type=str, default='base64key',
+ help="Set Sender Public Key [default=%(default)r]")
+ parser.add_argument(
+ "--recipient-gid", dest="recipient_gid", type=intx, default=1234567891,
+ help="Set Recipient GID [default=%(default)r]")
+ parser.add_argument(
+ "--sender-gid", dest="sender_gid", type=intx, default=1234567890,
+ help="Set Sender GID [default=%(default)r]")
+ return parser
+
+
+def main(top_block_cls=gotenna_pro_tx_bladerf, options=None):
+ if options is None:
+ options = argument_parser().parse_args()
+ tb = top_block_cls(antenna=options.antenna, baud_rate=options.baud_rate, callsign=options.callsign, counter_num=options.counter_num, device_args=options.device_args, frequency=options.frequency, message=options.message, message_type=options.message_type, publickey_data=options.publickey_data, recipient_gid=options.recipient_gid, sender_gid=options.sender_gid)
+
+ #def sig_handler(sig=None, frame=None):
+ # tb.stop()
+ # tb.wait()
+
+ # sys.exit(0)
+
+ #signal.signal(signal.SIGINT, sig_handler)
+ #signal.signal(signal.SIGTERM, sig_handler)
+
+ tb.start()
+
+ tb.wait()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/challenges/gotenna/gotenna_pro_tx_usrp.grc b/challenges/gotenna/gotenna_pro_tx_usrp.grc
new file mode 100644
index 0000000..43de67d
--- /dev/null
+++ b/challenges/gotenna/gotenna_pro_tx_usrp.grc
@@ -0,0 +1,947 @@
+options:
+ parameters:
+ author: ''
+ catch_exceptions: 'True'
+ category: '[GRC Hier Blocks]'
+ cmake_opt: ''
+ comment: ''
+ copyright: ''
+ description: ''
+ gen_cmake: 'On'
+ gen_linking: dynamic
+ generate_options: no_gui
+ hier_block_src_path: '.:'
+ id: gotenna_pro_tx_usrp
+ max_nouts: '0'
+ output_language: python
+ placement: (0,0)
+ qt_qss_theme: ''
+ realtime_scheduling: ''
+ run: 'True'
+ run_command: '{python} -u {filename}'
+ run_options: run
+ sizing_mode: fixed
+ thread_safe_setters: ''
+ title: ''
+ window_size: ''
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 8]
+ rotation: 0
+ state: enabled
+
+blocks:
+- name: center_freq
+ id: variable
+ parameters:
+ comment: ''
+ value: frequency - offset
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [80, 460]
+ rotation: 0
+ state: enabled
+- name: control_chan
+ id: variable
+ parameters:
+ comment: ''
+ value: '2'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [120, 524]
+ rotation: 0
+ state: enabled
+- name: data_chan
+ id: variable
+ parameters:
+ comment: ''
+ value: '2'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [224, 524]
+ rotation: 0
+ state: enabled
+- name: fsk_deviation_hz
+ id: variable
+ parameters:
+ comment: ''
+ value: '{2400: 400, 4800: 750, 9600: 1100}[baud_rate]'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 332.0]
+ rotation: 0
+ state: enabled
+- name: interp
+ id: variable
+ parameters:
+ comment: ''
+ value: 480000 // baud_rate
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 460]
+ rotation: 0
+ state: enabled
+- name: offset
+ id: variable
+ parameters:
+ comment: ''
+ value: '250000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 268.0]
+ rotation: 0
+ state: enabled
+- name: packets
+ id: variable
+ parameters:
+ comment: ''
+ value: gotenna_packet.encode_pro_broadcast_packets(message_type, counter_num,
+ sender_gid, recipient_gid, callsign, message, publickey_data)
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 612.0]
+ rotation: 0
+ state: enabled
+- name: samp_per_sym
+ id: variable
+ parameters:
+ comment: ''
+ value: '4'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 524]
+ rotation: 0
+ state: enabled
+- name: samp_rate
+ id: variable
+ parameters:
+ comment: ''
+ value: baud_rate * samp_per_sym * interp
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 396]
+ rotation: 0
+ state: enabled
+- name: taps
+ id: variable
+ parameters:
+ comment: ''
+ value: firdes.gaussian(1.0, samp_per_sym, 0.5, 64)
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 188.0]
+ rotation: 0
+ state: enabled
+- name: baud_rate
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Baud rate
+ short_id: ''
+ type: intx
+ value: '9600'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [768, 44.0]
+ rotation: 0
+ state: enabled
+- name: blocks_char_to_float_0
+ id: blocks_char_to_float
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ scale: '1'
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [432, 196.0]
+ rotation: 180
+ state: enabled
+- name: blocks_file_sink_0
+ id: blocks_file_sink
+ parameters:
+ affinity: ''
+ alias: ''
+ append: 'False'
+ comment: ''
+ file: pro_synth.cf32
+ type: complex
+ unbuffered: 'False'
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1136, 492.0]
+ rotation: 0
+ state: disabled
+- name: blocks_multiply_xx_0
+ id: blocks_multiply_xx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ num_inputs: '2'
+ type: complex
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [632, 328.0]
+ rotation: 0
+ state: enabled
+- name: blocks_multiply_xx_1
+ id: blocks_multiply_xx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ num_inputs: '2'
+ type: complex
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [960, 408.0]
+ rotation: 0
+ state: enabled
+- name: blocks_repeat_0
+ id: blocks_repeat
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ interp: 8 * samp_per_sym
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: complex
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [448, 388.0]
+ rotation: 0
+ state: enabled
+- name: blocks_repeat_1
+ id: blocks_repeat
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ interp: 8 * samp_per_sym * interp
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: float
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [592, 516.0]
+ rotation: 0
+ state: enabled
+- name: blocks_repeat_2
+ id: blocks_repeat
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ interp: samp_per_sym
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: float
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [256, 196.0]
+ rotation: 180
+ state: enabled
+- name: blocks_vco_c_0
+ id: blocks_vco_c
+ parameters:
+ affinity: ''
+ alias: ''
+ amplitude: '0.9'
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ samp_rate: samp_rate
+ sensitivity: 2*math.pi
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [768, 500.0]
+ rotation: 0
+ state: enabled
+- name: blocks_vco_c_1
+ id: blocks_vco_c
+ parameters:
+ affinity: ''
+ alias: ''
+ amplitude: '1.0'
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ samp_rate: baud_rate * samp_per_sym
+ sensitivity: 2 * math.pi * fsk_deviation_hz
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [440, 276.0]
+ rotation: 0
+ state: enabled
+- name: blocks_vector_source_x_0
+ id: blocks_vector_source_x
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ repeat: 'False'
+ tags: '[]'
+ type: byte
+ vector: gotenna_packet.pro_gfsk_symbols(packets)
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [776, 180.0]
+ rotation: 180
+ state: enabled
+- name: blocks_vector_source_x_1
+ id: blocks_vector_source_x
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ repeat: 'True'
+ tags: '[]'
+ type: complex
+ vector: '[1]'
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [216, 372.0]
+ rotation: 0
+ state: enabled
+- name: blocks_vector_source_x_2
+ id: blocks_vector_source_x
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ repeat: 'True'
+ tags: '[]'
+ type: float
+ vector: '[offset]'
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [360, 500.0]
+ rotation: 0
+ state: enabled
+- name: callsign
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Sender callsign
+ short_id: ''
+ type: str
+ value: VE3IRR
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [512, 44.0]
+ rotation: 0
+ state: true
+- name: counter_num
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Counter
+ short_id: ''
+ type: intx
+ value: '0'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1288, 44.0]
+ rotation: 0
+ state: true
+- name: device_addr
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: UHD device address
+ short_id: ''
+ type: str
+ value: ''
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 44.0]
+ rotation: 0
+ state: true
+- name: digital_map_bb_0
+ id: digital_map_bb
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ map: '[-3, -1, 3, 1, 0]'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [600, 196.0]
+ rotation: 180
+ state: enabled
+- name: frequency
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Frequency
+ short_id: ''
+ type: eng_float
+ value: '450000000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [872, 44.0]
+ rotation: 0
+ state: enabled
+- name: import_0
+ id: import
+ parameters:
+ alias: ''
+ comment: ''
+ imports: import gotenna_packet
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 92.0]
+ rotation: 0
+ state: enabled
+- name: import_1
+ id: import
+ parameters:
+ alias: ''
+ comment: ''
+ imports: import math
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [8, 140]
+ rotation: 0
+ state: enabled
+- name: interp_fir_filter_xxx_0
+ id: interp_fir_filter_xxx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ interp: '1'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ samp_delay: '0'
+ taps: taps
+ type: fff
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [216, 284.0]
+ rotation: 0
+ state: enabled
+- name: message
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Message
+ short_id: ''
+ type: str
+ value: Hello world!
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [648, 44.0]
+ rotation: 0
+ state: true
+- name: message_type
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: type
+ short_id: ''
+ type: str
+ value: BROADCAST
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [984, 44.0]
+ rotation: 0
+ state: true
+- name: publickey_data
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Sender Public Key
+ short_id: ''
+ type: str
+ value: base64key
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1104, 44.0]
+ rotation: 0
+ state: true
+- name: rational_resampler_xxx_0
+ id: rational_resampler_xxx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ decim: '1'
+ fbw: '0'
+ interp: interp
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ taps: ''
+ type: ccc
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [760, 316.0]
+ rotation: 0
+ state: enabled
+- name: rational_resampler_xxx_1
+ id: rational_resampler_xxx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ decim: '48'
+ fbw: '0'
+ interp: '25'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ taps: '[]'
+ type: ccc
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [992, 580.0]
+ rotation: 0
+ state: disabled
+- name: recipient_gid
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Recipient GID
+ short_id: ''
+ type: intx
+ value: '1234567891'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [272, 44.0]
+ rotation: 0
+ state: true
+- name: sender_gid
+ id: parameter
+ parameters:
+ alias: ''
+ comment: ''
+ hide: none
+ label: Sender GID
+ short_id: ''
+ type: intx
+ value: '1234567890'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [400, 44.0]
+ rotation: 0
+ state: true
+- name: uhd_usrp_sink_0
+ id: uhd_usrp_sink
+ parameters:
+ affinity: ''
+ alias: ''
+ ant0: '"TX/RX"'
+ ant1: ''
+ ant10: ''
+ ant11: ''
+ ant12: ''
+ ant13: ''
+ ant14: ''
+ ant15: ''
+ ant16: ''
+ ant17: ''
+ ant18: ''
+ ant19: ''
+ ant2: ''
+ ant20: ''
+ ant21: ''
+ ant22: ''
+ ant23: ''
+ ant24: ''
+ ant25: ''
+ ant26: ''
+ ant27: ''
+ ant28: ''
+ ant29: ''
+ ant3: ''
+ ant30: ''
+ ant31: ''
+ ant4: ''
+ ant5: ''
+ ant6: ''
+ ant7: ''
+ ant8: ''
+ ant9: ''
+ bw0: '0'
+ bw1: '0'
+ bw10: '0'
+ bw11: '0'
+ bw12: '0'
+ bw13: '0'
+ bw14: '0'
+ bw15: '0'
+ bw16: '0'
+ bw17: '0'
+ bw18: '0'
+ bw19: '0'
+ bw2: '0'
+ bw20: '0'
+ bw21: '0'
+ bw22: '0'
+ bw23: '0'
+ bw24: '0'
+ bw25: '0'
+ bw26: '0'
+ bw27: '0'
+ bw28: '0'
+ bw29: '0'
+ bw3: '0'
+ bw30: '0'
+ bw31: '0'
+ bw4: '0'
+ bw5: '0'
+ bw6: '0'
+ bw7: '0'
+ bw8: '0'
+ bw9: '0'
+ center_freq0: center_freq
+ center_freq1: '0'
+ center_freq10: '0'
+ center_freq11: '0'
+ center_freq12: '0'
+ center_freq13: '0'
+ center_freq14: '0'
+ center_freq15: '0'
+ center_freq16: '0'
+ center_freq17: '0'
+ center_freq18: '0'
+ center_freq19: '0'
+ center_freq2: '0'
+ center_freq20: '0'
+ center_freq21: '0'
+ center_freq22: '0'
+ center_freq23: '0'
+ center_freq24: '0'
+ center_freq25: '0'
+ center_freq26: '0'
+ center_freq27: '0'
+ center_freq28: '0'
+ center_freq29: '0'
+ center_freq3: '0'
+ center_freq30: '0'
+ center_freq31: '0'
+ center_freq4: '0'
+ center_freq5: '0'
+ center_freq6: '0'
+ center_freq7: '0'
+ center_freq8: '0'
+ center_freq9: '0'
+ clock_rate: '0.0'
+ clock_source0: ''
+ clock_source1: ''
+ clock_source2: ''
+ clock_source3: ''
+ clock_source4: ''
+ clock_source5: ''
+ clock_source6: ''
+ clock_source7: ''
+ comment: ''
+ dev_addr: device_addr
+ dev_args: '""'
+ gain0: '70'
+ gain1: '0'
+ gain10: '0'
+ gain11: '0'
+ gain12: '0'
+ gain13: '0'
+ gain14: '0'
+ gain15: '0'
+ gain16: '0'
+ gain17: '0'
+ gain18: '0'
+ gain19: '0'
+ gain2: '0'
+ gain20: '0'
+ gain21: '0'
+ gain22: '0'
+ gain23: '0'
+ gain24: '0'
+ gain25: '0'
+ gain26: '0'
+ gain27: '0'
+ gain28: '0'
+ gain29: '0'
+ gain3: '0'
+ gain30: '0'
+ gain31: '0'
+ gain4: '0'
+ gain5: '0'
+ gain6: '0'
+ gain7: '0'
+ gain8: '0'
+ gain9: '0'
+ gain_type0: default
+ gain_type1: default
+ gain_type10: default
+ gain_type11: default
+ gain_type12: default
+ gain_type13: default
+ gain_type14: default
+ gain_type15: default
+ gain_type16: default
+ gain_type17: default
+ gain_type18: default
+ gain_type19: default
+ gain_type2: default
+ gain_type20: default
+ gain_type21: default
+ gain_type22: default
+ gain_type23: default
+ gain_type24: default
+ gain_type25: default
+ gain_type26: default
+ gain_type27: default
+ gain_type28: default
+ gain_type29: default
+ gain_type3: default
+ gain_type30: default
+ gain_type31: default
+ gain_type4: default
+ gain_type5: default
+ gain_type6: default
+ gain_type7: default
+ gain_type8: default
+ gain_type9: default
+ len_tag_name: ''
+ lo_export0: 'False'
+ lo_export1: 'False'
+ lo_export10: 'False'
+ lo_export11: 'False'
+ lo_export12: 'False'
+ lo_export13: 'False'
+ lo_export14: 'False'
+ lo_export15: 'False'
+ lo_export16: 'False'
+ lo_export17: 'False'
+ lo_export18: 'False'
+ lo_export19: 'False'
+ lo_export2: 'False'
+ lo_export20: 'False'
+ lo_export21: 'False'
+ lo_export22: 'False'
+ lo_export23: 'False'
+ lo_export24: 'False'
+ lo_export25: 'False'
+ lo_export26: 'False'
+ lo_export27: 'False'
+ lo_export28: 'False'
+ lo_export29: 'False'
+ lo_export3: 'False'
+ lo_export30: 'False'
+ lo_export31: 'False'
+ lo_export4: 'False'
+ lo_export5: 'False'
+ lo_export6: 'False'
+ lo_export7: 'False'
+ lo_export8: 'False'
+ lo_export9: 'False'
+ lo_source0: internal
+ lo_source1: internal
+ lo_source10: internal
+ lo_source11: internal
+ lo_source12: internal
+ lo_source13: internal
+ lo_source14: internal
+ lo_source15: internal
+ lo_source16: internal
+ lo_source17: internal
+ lo_source18: internal
+ lo_source19: internal
+ lo_source2: internal
+ lo_source20: internal
+ lo_source21: internal
+ lo_source22: internal
+ lo_source23: internal
+ lo_source24: internal
+ lo_source25: internal
+ lo_source26: internal
+ lo_source27: internal
+ lo_source28: internal
+ lo_source29: internal
+ lo_source3: internal
+ lo_source30: internal
+ lo_source31: internal
+ lo_source4: internal
+ lo_source5: internal
+ lo_source6: internal
+ lo_source7: internal
+ lo_source8: internal
+ lo_source9: internal
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ nchan: '1'
+ num_mboards: '1'
+ otw: ''
+ samp_rate: samp_rate
+ sd_spec0: ''
+ sd_spec1: ''
+ sd_spec2: ''
+ sd_spec3: ''
+ sd_spec4: ''
+ sd_spec5: ''
+ sd_spec6: ''
+ sd_spec7: ''
+ show_lo_controls: 'False'
+ start_time: '-1.0'
+ stream_args: ''
+ stream_chans: '[]'
+ sync: sync
+ time_source0: ''
+ time_source1: ''
+ time_source2: ''
+ time_source3: ''
+ time_source4: ''
+ time_source5: ''
+ time_source6: ''
+ time_source7: ''
+ type: fc32
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1144, 380.0]
+ rotation: 0
+ state: enabled
+
+connections:
+- [blocks_char_to_float_0, '0', blocks_repeat_2, '0']
+- [blocks_multiply_xx_0, '0', rational_resampler_xxx_0, '0']
+- [blocks_multiply_xx_1, '0', rational_resampler_xxx_1, '0']
+- [blocks_multiply_xx_1, '0', uhd_usrp_sink_0, '0']
+- [blocks_repeat_0, '0', blocks_multiply_xx_0, '1']
+- [blocks_repeat_1, '0', blocks_vco_c_0, '0']
+- [blocks_repeat_2, '0', interp_fir_filter_xxx_0, '0']
+- [blocks_vco_c_0, '0', blocks_multiply_xx_1, '1']
+- [blocks_vco_c_1, '0', blocks_multiply_xx_0, '0']
+- [blocks_vector_source_x_0, '0', digital_map_bb_0, '0']
+- [blocks_vector_source_x_1, '0', blocks_repeat_0, '0']
+- [blocks_vector_source_x_2, '0', blocks_repeat_1, '0']
+- [digital_map_bb_0, '0', blocks_char_to_float_0, '0']
+- [interp_fir_filter_xxx_0, '0', blocks_vco_c_1, '0']
+- [rational_resampler_xxx_0, '0', blocks_multiply_xx_1, '0']
+- [rational_resampler_xxx_1, '0', blocks_file_sink_0, '0']
+
+metadata:
+ file_format: 1
+ grc_version: 3.10.9.2
diff --git a/challenges/gotenna/gotenna_pro_tx_usrp.py b/challenges/gotenna/gotenna_pro_tx_usrp.py
new file mode 100755
index 0000000..06982dd
--- /dev/null
+++ b/challenges/gotenna/gotenna_pro_tx_usrp.py
@@ -0,0 +1,322 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+#
+# SPDX-License-Identifier: GPL-3.0
+#
+# GNU Radio Python Flow Graph
+# Title: Gotenna Pro Tx Usrp
+# GNU Radio version: 3.10.5.0
+
+from gnuradio import blocks
+from gnuradio import digital
+from gnuradio import filter
+from gnuradio.filter import firdes
+from gnuradio import gr
+from gnuradio.fft import window
+import sys
+import signal
+from argparse import ArgumentParser
+from gnuradio.eng_arg import eng_float, intx
+from gnuradio import eng_notation
+from gnuradio import uhd
+import time
+import gotenna_packet
+import math
+
+
+
+
+class gotenna_pro_tx_usrp(gr.top_block):
+
+ def __init__(self, baud_rate=9600, callsign='VE3IRR', counter_num=0, device_addr='', frequency=450000000, message='Hello world!', message_type='BROADCAST', publickey_data='base64key', recipient_gid=1234567891, sender_gid=1234567890):
+ gr.top_block.__init__(self, "Gotenna Pro Tx Usrp", catch_exceptions=True)
+
+ ##################################################
+ # Parameters
+ ##################################################
+ self.baud_rate = baud_rate
+ self.callsign = callsign
+ self.counter_num = counter_num
+ self.device_addr = device_addr
+ self.frequency = frequency
+ self.message = message
+ self.message_type = message_type
+ self.publickey_data = publickey_data
+ self.recipient_gid = recipient_gid
+ self.sender_gid = sender_gid
+
+ ##################################################
+ # Variables
+ ##################################################
+ self.samp_per_sym = samp_per_sym = 4
+ self.offset = offset = 250000
+ self.interp = interp = 480000 // baud_rate
+ self.taps = taps = firdes.gaussian(1.0, samp_per_sym, 0.5, 64)
+ self.samp_rate = samp_rate = baud_rate * samp_per_sym * interp
+ self.packets = packets = gotenna_packet.encode_pro_broadcast_packets(message_type, counter_num, sender_gid, recipient_gid, callsign, message, publickey_data)
+ self.fsk_deviation_hz = fsk_deviation_hz = {2400: 400, 4800: 750, 9600: 1100}[baud_rate]
+ self.data_chan = data_chan = 2
+ self.control_chan = control_chan = 2
+ self.center_freq = center_freq = frequency - offset
+
+ ##################################################
+ # Blocks
+ ##################################################
+ self.uhd_usrp_sink_0 = uhd.usrp_sink(
+ ",".join((device_addr, "")),
+ uhd.stream_args(
+ cpu_format="fc32",
+ args='',
+ channels=list(range(0,1)),
+ ),
+ '',
+ )
+ self.uhd_usrp_sink_0.set_samp_rate(samp_rate)
+ self.uhd_usrp_sink_0.set_time_unknown_pps(uhd.time_spec(0))
+
+ self.uhd_usrp_sink_0.set_center_freq(center_freq, 0)
+ self.uhd_usrp_sink_0.set_antenna("TX/RX", 0)
+ self.uhd_usrp_sink_0.set_gain(70, 0)
+ self.rational_resampler_xxx_0 = filter.rational_resampler_ccc(
+ interpolation=interp,
+ decimation=1,
+ taps=[],
+ fractional_bw=0)
+ self.interp_fir_filter_xxx_0 = filter.interp_fir_filter_fff(1, taps)
+ self.interp_fir_filter_xxx_0.declare_sample_delay(0)
+ self.digital_map_bb_0 = digital.map_bb([-3, -1, 3, 1, 0])
+ self.blocks_vector_source_x_2 = blocks.vector_source_f([offset], True, 1, [])
+ self.blocks_vector_source_x_1 = blocks.vector_source_c([1], True, 1, [])
+ self.blocks_vector_source_x_0 = blocks.vector_source_b(gotenna_packet.pro_gfsk_symbols(packets), False, 1, [])
+ self.blocks_vco_c_1 = blocks.vco_c((baud_rate * samp_per_sym), (2 * math.pi * fsk_deviation_hz), 1.0)
+ self.blocks_vco_c_0 = blocks.vco_c(samp_rate, (2*math.pi), 0.9)
+ self.blocks_repeat_2 = blocks.repeat(gr.sizeof_float*1, samp_per_sym)
+ self.blocks_repeat_1 = blocks.repeat(gr.sizeof_float*1, (8 * samp_per_sym * interp))
+ self.blocks_repeat_0 = blocks.repeat(gr.sizeof_gr_complex*1, (8 * samp_per_sym))
+ self.blocks_multiply_xx_1 = blocks.multiply_vcc(1)
+ self.blocks_multiply_xx_0 = blocks.multiply_vcc(1)
+ self.blocks_char_to_float_0 = blocks.char_to_float(1, 1)
+
+
+ ##################################################
+ # Connections
+ ##################################################
+ self.connect((self.blocks_char_to_float_0, 0), (self.blocks_repeat_2, 0))
+ self.connect((self.blocks_multiply_xx_0, 0), (self.rational_resampler_xxx_0, 0))
+ self.connect((self.blocks_multiply_xx_1, 0), (self.uhd_usrp_sink_0, 0))
+ self.connect((self.blocks_repeat_0, 0), (self.blocks_multiply_xx_0, 1))
+ self.connect((self.blocks_repeat_1, 0), (self.blocks_vco_c_0, 0))
+ self.connect((self.blocks_repeat_2, 0), (self.interp_fir_filter_xxx_0, 0))
+ self.connect((self.blocks_vco_c_0, 0), (self.blocks_multiply_xx_1, 1))
+ self.connect((self.blocks_vco_c_1, 0), (self.blocks_multiply_xx_0, 0))
+ self.connect((self.blocks_vector_source_x_0, 0), (self.digital_map_bb_0, 0))
+ self.connect((self.blocks_vector_source_x_1, 0), (self.blocks_repeat_0, 0))
+ self.connect((self.blocks_vector_source_x_2, 0), (self.blocks_repeat_1, 0))
+ self.connect((self.digital_map_bb_0, 0), (self.blocks_char_to_float_0, 0))
+ self.connect((self.interp_fir_filter_xxx_0, 0), (self.blocks_vco_c_1, 0))
+ self.connect((self.rational_resampler_xxx_0, 0), (self.blocks_multiply_xx_1, 0))
+
+
+ def get_baud_rate(self):
+ return self.baud_rate
+
+ def set_baud_rate(self, baud_rate):
+ self.baud_rate = baud_rate
+ self.set_fsk_deviation_hz({2400: 400, 4800: 750, 9600: 1100}[self.baud_rate])
+ self.set_interp(480000 // self.baud_rate)
+ self.set_samp_rate(self.baud_rate * self.samp_per_sym * self.interp)
+
+ def get_callsign(self):
+ return self.callsign
+
+ def set_callsign(self, callsign):
+ self.callsign = callsign
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_counter_num(self):
+ return self.counter_num
+
+ def set_counter_num(self, counter_num):
+ self.counter_num = counter_num
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_device_addr(self):
+ return self.device_addr
+
+ def set_device_addr(self, device_addr):
+ self.device_addr = device_addr
+
+ def get_frequency(self):
+ return self.frequency
+
+ def set_frequency(self, frequency):
+ self.frequency = frequency
+ self.set_center_freq(self.frequency - self.offset)
+
+ def get_message(self):
+ return self.message
+
+ def set_message(self, message):
+ self.message = message
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_message_type(self):
+ return self.message_type
+
+ def set_message_type(self, message_type):
+ self.message_type = message_type
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_publickey_data(self):
+ return self.publickey_data
+
+ def set_publickey_data(self, publickey_data):
+ self.publickey_data = publickey_data
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_recipient_gid(self):
+ return self.recipient_gid
+
+ def set_recipient_gid(self, recipient_gid):
+ self.recipient_gid = recipient_gid
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_sender_gid(self):
+ return self.sender_gid
+
+ def set_sender_gid(self, sender_gid):
+ self.sender_gid = sender_gid
+ self.set_packets(gotenna_packet.encode_pro_broadcast_packets(self.message_type, self.counter_num, self.sender_gid, self.recipient_gid, self.callsign, self.message, self.publickey_data))
+
+ def get_samp_per_sym(self):
+ return self.samp_per_sym
+
+ def set_samp_per_sym(self, samp_per_sym):
+ self.samp_per_sym = samp_per_sym
+ self.set_samp_rate(self.baud_rate * self.samp_per_sym * self.interp)
+ self.set_taps(firdes.gaussian(1.0, self.samp_per_sym, 0.5, 64))
+ self.blocks_repeat_0.set_interpolation((8 * self.samp_per_sym))
+ self.blocks_repeat_1.set_interpolation((8 * self.samp_per_sym * self.interp))
+ self.blocks_repeat_2.set_interpolation(self.samp_per_sym)
+
+ def get_offset(self):
+ return self.offset
+
+ def set_offset(self, offset):
+ self.offset = offset
+ self.set_center_freq(self.frequency - self.offset)
+ self.blocks_vector_source_x_2.set_data([self.offset], [])
+
+ def get_interp(self):
+ return self.interp
+
+ def set_interp(self, interp):
+ self.interp = interp
+ self.set_samp_rate(self.baud_rate * self.samp_per_sym * self.interp)
+ self.blocks_repeat_1.set_interpolation((8 * self.samp_per_sym * self.interp))
+
+ def get_taps(self):
+ return self.taps
+
+ def set_taps(self, taps):
+ self.taps = taps
+ self.interp_fir_filter_xxx_0.set_taps(self.taps)
+
+ def get_samp_rate(self):
+ return self.samp_rate
+
+ def set_samp_rate(self, samp_rate):
+ self.samp_rate = samp_rate
+ self.uhd_usrp_sink_0.set_samp_rate(self.samp_rate)
+
+ def get_packets(self):
+ return self.packets
+
+ def set_packets(self, packets):
+ self.packets = packets
+ self.blocks_vector_source_x_0.set_data(gotenna_packet.pro_gfsk_symbols(self.packets), [])
+
+ def get_fsk_deviation_hz(self):
+ return self.fsk_deviation_hz
+
+ def set_fsk_deviation_hz(self, fsk_deviation_hz):
+ self.fsk_deviation_hz = fsk_deviation_hz
+
+ def get_data_chan(self):
+ return self.data_chan
+
+ def set_data_chan(self, data_chan):
+ self.data_chan = data_chan
+
+ def get_control_chan(self):
+ return self.control_chan
+
+ def set_control_chan(self, control_chan):
+ self.control_chan = control_chan
+
+ def get_center_freq(self):
+ return self.center_freq
+
+ def set_center_freq(self, center_freq):
+ self.center_freq = center_freq
+ self.uhd_usrp_sink_0.set_center_freq(self.center_freq, 0)
+
+
+
+def argument_parser():
+ parser = ArgumentParser()
+ parser.add_argument(
+ "--baud-rate", dest="baud_rate", type=intx, default=9600,
+ help="Set Baud rate [default=%(default)r]")
+ parser.add_argument(
+ "--callsign", dest="callsign", type=str, default='VE3IRR',
+ help="Set Sender callsign [default=%(default)r]")
+ parser.add_argument(
+ "--counter-num", dest="counter_num", type=intx, default=0,
+ help="Set Counter [default=%(default)r]")
+ parser.add_argument(
+ "--device-addr", dest="device_addr", type=str, default='',
+ help="Set UHD device address [default=%(default)r]")
+ parser.add_argument(
+ "--frequency", dest="frequency", type=eng_float, default=eng_notation.num_to_str(float(450000000)),
+ help="Set Frequency [default=%(default)r]")
+ parser.add_argument(
+ "--message", dest="message", type=str, default='Hello world!',
+ help="Set Message [default=%(default)r]")
+ parser.add_argument(
+ "--message-type", dest="message_type", type=str, default='BROADCAST',
+ help="Set type [default=%(default)r]")
+ parser.add_argument(
+ "--publickey-data", dest="publickey_data", type=str, default='base64key',
+ help="Set Sender Public Key [default=%(default)r]")
+ parser.add_argument(
+ "--recipient-gid", dest="recipient_gid", type=intx, default=1234567891,
+ help="Set Recipient GID [default=%(default)r]")
+ parser.add_argument(
+ "--sender-gid", dest="sender_gid", type=intx, default=1234567890,
+ help="Set Sender GID [default=%(default)r]")
+ return parser
+
+
+def main(top_block_cls=gotenna_pro_tx_usrp, options=None):
+ if options is None:
+ options = argument_parser().parse_args()
+ tb = top_block_cls(baud_rate=options.baud_rate, callsign=options.callsign, counter_num=options.counter_num, device_addr=options.device_addr, frequency=options.frequency, message=options.message, message_type=options.message_type, publickey_data=options.publickey_data, recipient_gid=options.recipient_gid, sender_gid=options.sender_gid)
+
+ #def sig_handler(sig=None, frame=None):
+ # tb.stop()
+ # tb.wait()
+
+ # sys.exit(0)
+
+ #signal.signal(signal.SIGINT, sig_handler)
+ #signal.signal(signal.SIGTERM, sig_handler)
+
+ tb.start()
+
+ tb.wait()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/flags.txt.ci b/flags.txt.ci
index 6a87785..2fcf093 100644
--- a/flags.txt.ci
+++ b/flags.txt.ci
@@ -5,3 +5,4 @@ testflagsfile,1660312800,1660496400
3,SDR_ASK_1,The Silence of the Lambs was filmed in Pittsburgh Pennsylvania.,ask,,,60,90,ham_440,,
4,POCSAG_RX,The Clock That Went Backward,pocsag,198468,,60,90,444500,,
5,LRS_RX,-s 20 -p 238 -pf 1,lrs,,,60,90,467750,,
+6,GOTENNA_PRO,RFCTF{gotenna_pro_test},gotenna_pro,"--callsign RFCTF --sender-gid 1234567890 --recipient-gid 1234567891 --baud-rate 9600 --message-type BROADCAST --counter-num 0",,60,90,450000,,