#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: Simulated multi stream
# Author: Martyn van Dijke
# GNU Radio version: 3.8.2.0

from gnuradio import blocks
from gnuradio import filter
from gnuradio.filter import firdes
from gnuradio import gr
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
import lora_sdr


class lora_sim_multi(gr.top_block):

    def __init__(self):
        gr.top_block.__init__(self, "Simulated multi stream")

        ##################################################
        # Variables
        ##################################################
        # Input data in the system.
        src_data = "@@source_data@@"
        self.bw = bw = @@bw@@
        self.sf = sf = @@sf@@
        self.samp_rate = samp_rate = bw
        self.pay_len = pay_len = @@pay_len@@
        self.n_frame = n_frame = @@n_frame@@
        self.impl_head = impl_head = @@impl_head@@
        self.has_crc = has_crc = @@has_crc@@
        self.frame_period = frame_period = @@frame_period@@
        self.cr = cr = @@cr@@
        self.mean = mean = @@mean@@
        self.delay_sf6 = delay_sf6 = @@delay_sf6@@
        self.delay_sf5 = delay_sf5 = @@delay_sf5@@
        self.delay_sf4 = delay_sf4 = @@delay_sf4@@
        self.delay_sf3 = delay_sf3 = @@delay_sf3@@
        self.delay_sf2 = delay_sf2 = @@delay_sf2@@
        self.delay_sf1 = delay_sf1 = @@delay_sf1@@
        self.multi_control = multi_control = True
        # static parameters
        self.sf6 = sf6 = 12
        self.sf5 = sf5 = 11
        self.sf4 = sf4 = 10
        self.sf3 = sf3 = 9
        self.sf2 = sf2 = 8
        self.sf = sf = 7

    ##################################################
        # Blocks
        ##################################################
        self.lora_sdr_hier_tx_0 = lora_sdr.hier_tx(
            pay_len, n_frame, src_data, cr, sf, impl_head, has_crc, samp_rate, bw, mean, True)
        self.lora_sdr_hier_rx_0_2_0 = lora_sdr.hier_rx(
            samp_rate, bw, 10, impl_head, cr, pay_len, has_crc, False)
        self.lora_sdr_hier_rx_0_1_0_0_1_0 = lora_sdr.hier_rx(
            samp_rate, bw, 7, impl_head, cr, pay_len, has_crc, True)
        self.lora_sdr_hier_rx_0_1_0_0_1 = lora_sdr.hier_rx(
            samp_rate, bw, 11, impl_head, cr, pay_len, has_crc, False)
        self.lora_sdr_hier_rx_0_1_0_0_0_0_0 = lora_sdr.hier_rx(
            samp_rate, bw, 8, impl_head, cr, pay_len, has_crc, False)
        self.lora_sdr_hier_rx_0_1_0_0_0_0 = lora_sdr.hier_rx(
            samp_rate, bw, 12, impl_head, cr, pay_len, has_crc, False)
        self.lora_sdr_hier_rx_0_0_0_0 = lora_sdr.hier_rx(
            samp_rate, bw, 9, impl_head, cr, pay_len, has_crc, False)
        self.interp_fir_filter_xxx_0_0_0_0_0_0_0 = filter.interp_fir_filter_ccf(4, (-0.128616616593872, -0.212206590789194, -0.180063263231421, 3.89817183251938e-17, 0.300105438719035,
                                                                                    0.636619772367581, 0.900316316157106, 1, 0.900316316157106, 0.636619772367581, 0.300105438719035, 3.89817183251938e-17, -0.180063263231421, -0.212206590789194, -0.128616616593872))
        self.interp_fir_filter_xxx_0_0_0_0_0_0_0.declare_sample_delay(0)
        self.interp_fir_filter_xxx_0_0_0_0_0_0_0.set_min_output_buffer(32768)
        self.interp_fir_filter_xxx_0_0_0_0_0_0 = filter.interp_fir_filter_ccf(4, (-0.128616616593872, -0.212206590789194, -0.180063263231421, 3.89817183251938e-17, 0.300105438719035,
                                                                                  0.636619772367581, 0.900316316157106, 1, 0.900316316157106, 0.636619772367581, 0.300105438719035, 3.89817183251938e-17, -0.180063263231421, -0.212206590789194, -0.128616616593872))
        self.interp_fir_filter_xxx_0_0_0_0_0_0.declare_sample_delay(0)
        self.interp_fir_filter_xxx_0_0_0_0_0_0.set_min_output_buffer(16384)
        self.interp_fir_filter_xxx_0_0_0_0_0 = filter.interp_fir_filter_ccf(4, (-0.128616616593872, -0.212206590789194, -0.180063263231421, 3.89817183251938e-17, 0.300105438719035,
                                                                                0.636619772367581, 0.900316316157106, 1, 0.900316316157106, 0.636619772367581, 0.300105438719035, 3.89817183251938e-17, -0.180063263231421, -0.212206590789194, -0.128616616593872))
        self.interp_fir_filter_xxx_0_0_0_0_0.declare_sample_delay(0)
        self.interp_fir_filter_xxx_0_0_0_0_0.set_min_output_buffer(8192)
        self.interp_fir_filter_xxx_0_0_0_0 = filter.interp_fir_filter_ccf(4, (-0.128616616593872, -0.212206590789194, -0.180063263231421, 3.89817183251938e-17, 0.300105438719035, 0.636619772367581,
                                                                              0.900316316157106, 1, 0.900316316157106, 0.636619772367581, 0.300105438719035, 3.89817183251938e-17, -0.180063263231421, -0.212206590789194, -0.128616616593872))
        self.interp_fir_filter_xxx_0_0_0_0.declare_sample_delay(0)
        self.interp_fir_filter_xxx_0_0_0_0.set_min_output_buffer(4096)
        self.interp_fir_filter_xxx_0_0_0 = filter.interp_fir_filter_ccf(4, (-0.128616616593872, -0.212206590789194, -0.180063263231421, 3.89817183251938e-17, 0.300105438719035, 0.636619772367581,
                                                                            0.900316316157106, 1, 0.900316316157106, 0.636619772367581, 0.300105438719035, 3.89817183251938e-17, -0.180063263231421, -0.212206590789194, -0.128616616593872))
        self.interp_fir_filter_xxx_0_0_0.declare_sample_delay(0)
        self.interp_fir_filter_xxx_0_0_0.set_min_output_buffer(2048)
        self.interp_fir_filter_xxx_0_0 = filter.interp_fir_filter_ccf(4, (-0.128616616593872, -0.212206590789194, -0.180063263231421, 3.89817183251938e-17, 0.300105438719035, 0.636619772367581,
                                                                          0.900316316157106, 1, 0.900316316157106, 0.636619772367581, 0.300105438719035, 3.89817183251938e-17, -0.180063263231421, -0.212206590789194, -0.128616616593872))
        self.interp_fir_filter_xxx_0_0.declare_sample_delay(0)
        self.interp_fir_filter_xxx_0_0.set_min_output_buffer(1024)
        self.blocks_throttle_0_0 = blocks.throttle(
            gr.sizeof_gr_complex*1, samp_rate, True)
        self.blocks_delay_0 = blocks.delay(gr.sizeof_gr_complex*1, delay_sf1)

        ##################################################
        # Connections
        ##################################################
        self.connect((self.blocks_delay_0, 0), (self.blocks_throttle_0_0, 0))
        self.connect((self.blocks_throttle_0_0, 0),
                     (self.interp_fir_filter_xxx_0_0, 0))
        self.connect((self.blocks_throttle_0_0, 0),
                     (self.interp_fir_filter_xxx_0_0_0, 0))
        self.connect((self.blocks_throttle_0_0, 0),
                     (self.interp_fir_filter_xxx_0_0_0_0, 0))
        self.connect((self.blocks_throttle_0_0, 0),
                     (self.interp_fir_filter_xxx_0_0_0_0_0, 0))
        self.connect((self.blocks_throttle_0_0, 0),
                     (self.interp_fir_filter_xxx_0_0_0_0_0_0, 0))
        self.connect((self.blocks_throttle_0_0, 0),
                     (self.interp_fir_filter_xxx_0_0_0_0_0_0_0, 0))
        self.connect((self.interp_fir_filter_xxx_0_0, 0),
                     (self.lora_sdr_hier_rx_0_1_0_0_1_0, 0))
        self.connect((self.interp_fir_filter_xxx_0_0_0, 0),
                     (self.lora_sdr_hier_rx_0_1_0_0_0_0_0, 0))
        self.connect((self.interp_fir_filter_xxx_0_0_0_0, 0),
                     (self.lora_sdr_hier_rx_0_0_0_0, 0))
        self.connect((self.interp_fir_filter_xxx_0_0_0_0_0, 0),
                     (self.lora_sdr_hier_rx_0_2_0, 0))
        self.connect((self.interp_fir_filter_xxx_0_0_0_0_0_0, 0),
                     (self.lora_sdr_hier_rx_0_1_0_0_1, 0))
        self.connect((self.interp_fir_filter_xxx_0_0_0_0_0_0_0, 0),
                     (self.lora_sdr_hier_rx_0_1_0_0_0_0, 0))
        self.connect((self.lora_sdr_hier_tx_0, 0), (self.blocks_delay_0, 0))

    def get_bw(self):
        return self.bw

    def set_bw(self, bw):
        with self._lock:
            self.bw = bw
            self.set_samp_rate(self.bw)

    def get_sf6(self):
        return self.sf6

    def set_sf6(self, sf6):
        with self._lock:
            self.sf6 = sf6

    def get_sf5(self):
        return self.sf5

    def set_sf5(self, sf5):
        with self._lock:
            self.sf5 = sf5

    def get_sf4(self):
        return self.sf4

    def set_sf4(self, sf4):
        with self._lock:
            self.sf4 = sf4

    def get_sf3(self):
        return self.sf3

    def set_sf3(self, sf3):
        with self._lock:
            self.sf3 = sf3

    def get_sf2(self):
        return self.sf2

    def set_sf2(self, sf2):
        with self._lock:
            self.sf2 = sf2

    def get_sf(self):
        return self.sf

    def set_sf(self, sf):
        with self._lock:
            self.sf = sf

    def get_samp_rate(self):
        return self.samp_rate

    def set_samp_rate(self, samp_rate):
        with self._lock:
            self.samp_rate = samp_rate
            self.blocks_throttle_0_0.set_sample_rate(self.samp_rate)

    def get_pay_len(self):
        return self.pay_len

    def set_pay_len(self, pay_len):
        with self._lock:
            self.pay_len = pay_len

    def get_n_frame(self):
        return self.n_frame

    def set_n_frame(self, n_frame):
        with self._lock:
            self.n_frame = n_frame

    def get_multi_control(self):
        return self.multi_control

    def set_multi_control(self, multi_control):
        with self._lock:
            self.multi_control = multi_control

    def get_mult_const(self):
        return self.mult_const

    def set_mult_const(self, mult_const):
        with self._lock:
            self.mult_const = mult_const

    def get_impl_head(self):
        return self.impl_head

    def set_impl_head(self, impl_head):
        with self._lock:
            self.impl_head = impl_head

    def get_has_crc(self):
        return self.has_crc

    def set_has_crc(self, has_crc):
        with self._lock:
            self.has_crc = has_crc

    def get_frame_period(self):
        return self.frame_period

    def set_frame_period(self, frame_period):
        with self._lock:
            self.frame_period = frame_period

    def get_delay_sf6(self):
        return self.delay_sf6

    def set_delay_sf6(self, delay_sf6):
        with self._lock:
            self.delay_sf6 = delay_sf6

    def get_delay_sf5(self):
        return self.delay_sf5

    def set_delay_sf5(self, delay_sf5):
        with self._lock:
            self.delay_sf5 = delay_sf5

    def get_delay_sf4(self):
        return self.delay_sf4

    def set_delay_sf4(self, delay_sf4):
        with self._lock:
            self.delay_sf4 = delay_sf4

    def get_delay_sf3(self):
        return self.delay_sf3

    def set_delay_sf3(self, delay_sf3):
        with self._lock:
            self.delay_sf3 = delay_sf3

    def get_delay_sf2(self):
        return self.delay_sf2

    def set_delay_sf2(self, delay_sf2):
        with self._lock:
            self.delay_sf2 = delay_sf2

    def get_delay_sf1(self):
        return self.delay_sf1

    def set_delay_sf1(self, delay_sf1):
        with self._lock:
            self.delay_sf1 = delay_sf1
            self.blocks_delay_0.set_dly(self.delay_sf1)

    def get_cr(self):
        return self.cr

    def set_cr(self, cr):
        with self._lock:
            self.cr = cr


def main(top_block_cls=lora_sim_multi, options=None):
    tb = top_block_cls()

    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()
