def __init__(self):
        gr.top_block.__init__(self)

        usage = "usage: %prog [options] center_freq1 band_width1 [center_freq2 band_width2 ...]"
        parser = OptionParser(option_class=eng_option, usage=usage)
        parser.add_option(
            "-a",
            "--args",
            type="string",
            default="",
            help="UHD device device address args [default=%default]")
        parser.add_option("",
                          "--spec",
                          type="string",
                          default=None,
                          help="Subdevice of UHD device where appropriate")
        parser.add_option("-A",
                          "--antenna",
                          type="string",
                          default=None,
                          help="select Rx Antenna where appropriate")
        parser.add_option("-s",
                          "--samp-rate",
                          type="eng_float",
                          default=1e6,
                          help="set sample rate [default=%default]")
        parser.add_option("-g",
                          "--gain",
                          type="eng_float",
                          default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option(
            "",
            "--acquisition-period",
            type="eng_float",
            default=3,
            metavar="SECS",
            help=
            "time to delay (in seconds) after changing frequency [default=%default]"
        )
        parser.add_option(
            "",
            "--dwell-delay",
            type="eng_float",
            default=3,
            metavar="SECS",
            help=
            "time to dwell (in seconds) at a given frequency [default=%default]"
        )
        parser.add_option(
            "",
            "--meas-interval",
            type="eng_float",
            default=0.1,
            metavar="SECS",
            help=
            "interval over which to measure statistic (in seconds) [default=%default]"
        )
        parser.add_option(
            "-c",
            "--number-channels",
            type="int",
            default=100,
            help=
            "number of uniform channels for which to report power measurements [default=%default]"
        )
        parser.add_option(
            "-l",
            "--lo-offset",
            type="eng_float",
            default=0,
            metavar="Hz",
            help="lo_offset in Hz [default=half the sample rate]")
        parser.add_option("-F",
                          "--fft-size",
                          type="int",
                          default=1024,
                          help="specify number of FFT bins [default=%default]")
        parser.add_option("",
                          "--real-time",
                          action="store_true",
                          default=False,
                          help="Attempt to enable real-time scheduling")
        parser.add_option("-d",
                          "--dest-url",
                          type="string",
                          default="",
                          help="set destination url for posting data")
        parser.add_option("",
                          "--skip-DC",
                          action="store_true",
                          default=False,
                          help="skip the DC bin when mapping channels")

        (options, args) = parser.parse_args()
        if (len(args) < 2) or (len(args) % 2 == 1):
            parser.print_help()
            sys.exit(1)

        self.center_freq = []
        self.bandwidth = []
        for i in range(len(args) / 2):
            self.center_freq.append(eng_notation.str_to_num(args[2 * i]))
            self.bandwidth.append(eng_notation.str_to_num(args[2 * i + 1]))
        self.band_ind = len(self.center_freq) - 1

        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        # build graph
        self.u = uhd.usrp_source(device_addr=options.args,
                                 stream_args=uhd.stream_args('fc32'))

        # Set the subdevice spec
        if (options.spec):
            self.u.set_subdev_spec(options.spec, 0)

        # Set the antenna
        if (options.antenna):
            self.u.set_antenna(options.antenna, 0)

        self.u.set_samp_rate(options.samp_rate)
        usrp_rate = self.u.get_samp_rate()

        if usrp_rate != options.samp_rate:
            if usrp_rate < options.samp_rate:
                # create list of allowable rates
                samp_rates = self.u.get_samp_rates()
                rate_list = [0.0] * len(samp_rates)
                for i in range(len(rate_list)):
                    last_rate = samp_rates.pop()
                    rate_list[len(rate_list) - 1 - i] = last_rate.start()

# choose next higher rate
                rate_ind = rate_list.index(usrp_rate) + 1
                if rate_ind < len(rate_list):
                    self.u.set_samp_rate(rate_list[rate_ind])
                    usrp_rate = self.u.get_samp_rate()
                print "New actual sample rate =", usrp_rate / 1e6, "MHz"
            resamp = filter.fractional_resampler_cc(
                0.0, usrp_rate / options.samp_rate)

        self.samp_rate = options.samp_rate

        if (options.lo_offset):
            self.lo_offset = options.lo_offset
        else:
            self.lo_offset = usrp_rate / 2.0
            print "LO offset set to", self.lo_offset / 1e6, "MHz"

        self.fft_size = options.fft_size
        self.num_ch = options.number_channels
        self.acq_period = options.acquisition_period
        self.dwell_delay = options.dwell_delay

        self.head = blocks.head(gr.sizeof_gr_complex,
                                int(self.dwell_delay * usrp_rate))

        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)

        mywindow = filter.window.blackmanharris(self.fft_size)
        ffter = fft.fft_vcc(self.fft_size, True, mywindow, True)
        window_power = sum(map(lambda x: x * x, mywindow))

        c2mag = blocks.complex_to_mag_squared(self.fft_size)

        self.bin2ch_map = [[0] * self.fft_size
                           for i in range(len(self.center_freq))]
        hz_per_bin = self.samp_rate / self.fft_size
        for i in range(len(self.center_freq)):
            channel_bw = hz_per_bin * round(
                self.bandwidth[i] / self.num_ch / hz_per_bin)
            self.bandwidth[i] = channel_bw * self.num_ch
            print "Actual width of band", i + 1, "is", self.bandwidth[
                i] / 1e6, "MHz."
            start_freq = self.center_freq[i] - self.bandwidth[i] / 2.0
            stop_freq = start_freq + self.bandwidth[i]
            for j in range(self.fft_size):
                fj = self.bin_freq(j, self.center_freq[i])
                if (fj >= start_freq) and (fj < stop_freq):
                    channel_num = int(
                        math.floor((fj - start_freq) / channel_bw)) + 1
                    self.bin2ch_map[i][j] = channel_num
            if options.skip_DC:
                self.bin2ch_map[i][(self.fft_size + 1) / 2 +
                                   1:] = self.bin2ch_map[i][(self.fft_size +
                                                             1) / 2:-1]
                self.bin2ch_map[i][(self.fft_size + 1) / 2] = 0
            if self.bandwidth[i] > self.samp_rate:
                print "Warning: Width of band", i + 1, "(" + str(
                    self.bandwidth[i] /
                    1e6), "MHz) is greater than the sample rate (" + str(
                        self.samp_rate / 1e6), "MHz)."

        self.aggr = myblocks.bin_aggregator_ff(self.fft_size, self.num_ch,
                                               self.bin2ch_map[0])

        meas_frames = max(1,
                          int(
                              round(options.meas_interval * self.samp_rate /
                                    self.fft_size)))  # in fft_frames
        self.meas_duration = meas_frames * self.fft_size / self.samp_rate
        print "Actual measurement duration =", self.meas_duration, "s"

        self.stats = myblocks.bin_statistics_ff(self.num_ch, meas_frames)

        # Divide magnitude-square by a constant to obtain power
        # in Watts.  Assumes unit of USRP source is volts.
        impedance = 50.0  # ohms
        Vsq2W_dB = -10.0 * math.log10(self.fft_size * window_power * impedance)

        # Convert from Watts to dBm.
        W2dBm = blocks.nlog10_ff(10.0, self.num_ch, 30.0 + Vsq2W_dB)

        f2c = blocks.float_to_char(self.num_ch, 1.0)

        self.dest_url = options.dest_url

        # file descriptor is set in main loop; use dummy value for now
        self.srvr = myblocks.file_descriptor_sink(self.num_ch * gr.sizeof_char,
                                                  0)

        self.connect(self.u, self.head)

        if usrp_rate > self.samp_rate:
            # insert resampler
            self.connect(self.head, resamp, s2v)
        else:
            self.connect(self.head, s2v)
        self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, f2c,
                     self.srvr)
        #self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, self.srvr)

        g = self.u.get_gain_range()
        if options.gain is None:
            # if no gain was specified, use the mid-point in dB
            options.gain = float(g.start() + g.stop()) / 2.0

        self.set_gain(options.gain)
        print "gain =", options.gain, "dB in range (%0.1f dB, %0.1f dB)" % (
            float(g.start()), float(g.stop()))
        self.atten = float(g.stop()) - options.gain
    def __init__(self):
        gr.top_block.__init__(self)

        usage = "usage: %prog [options] center_freq band_width"
        parser = OptionParser(option_class=eng_option, usage=usage)
        parser.add_option(
            "-s",
            "--samp-rate",
            type="eng_float",
            default=10e6,
            help="set sample rate: 8/10/12.5/16/20 MHz [default=%default]")
        parser.add_option(
            "-g",
            "--rf-gain",
            type="eng_float",
            default=0,
            help="set the overall gain in dB (default is midpoint)"
        )  #FIXME range?
        parser.add_option(
            "",
            "--lna-gain",
            type="eng_float",
            default=24,
            help="set RX IF gain in dB (default is midpoint): 0-40dB, 8dB steps"
        )
        parser.add_option(
            "",
            "--vga-gain",
            type="eng_float",
            default=32,
            help="set BB gain in dB (default is midpoint): 0-62dB, 2dB steps")
        parser.add_option("",
                          "--antenna",
                          action="store_false",
                          default=True,
                          help="Disable Antenna Port Power [default=%default]")
        parser.add_option(
            "",
            "--bandwidth",
            type="eng_float",
            default=10e6,
            help=
            "Set the BB Filter Bandwidth in MHz: 1.75-28 MHz[default=%default]"
        )
        parser.add_option("",
                          "--g-mode",
                          action="store_false",
                          default=True,
                          help="set the gain mode[default=%default]")
        parser.add_option("",
                          "--iq-balance",
                          type="eng_float",
                          default=2,
                          help="set the iq_balance_mode [default=%default]")
        parser.add_option("",
                          "--dc-off",
                          type="eng_float",
                          default=1,
                          help="set the dc offset mode [default=%default]")

        parser.add_option(
            "",
            "--meas-interval",
            type="eng_float",
            default=0.1,
            metavar="SECS",
            help=
            "interval over which to measure statistic (in seconds) [default=%default]"
        )
        parser.add_option(
            "-c",
            "--number-channels",
            type="int",
            default=56,
            help=
            "number of uniform channels for which to report power measurements [default=%default]"
        )
        parser.add_option("-F",
                          "--fft-size",
                          type="int",
                          default=1024,
                          help="specify number of FFT bins [default=%default]")
        parser.add_option("",
                          "--real-time",
                          action="store_true",
                          default=False,
                          help="Attempt to enable real-time scheduling")
        parser.add_option("-d",
                          "--dest-host",
                          type="string",
                          default="",
                          help="set destination host for sending data")
        parser.add_option("",
                          "--skip-DC",
                          action="store_true",
                          default=False,
                          help="skip the DC bin when mapping channels")
        parser.add_option(
            "",
            "--avoid-LO",
            action="store_true",
            default=False,
            help=
            "Avoid LO by sampling at higher rate, shift frequency and take only a desired chunk"
        )

        #        parser.add_option("-l", "--lo-offset", type="eng_float", default=0, metavar="Hz",
        #                          help="lo_offset in Hz [default=half the sample rate]")
        #        parser.add_option("", "--tx-VGA-gain", type="eng_float", default=None,
        #                          help="set TX IF gain in dB (default is midpoint): 0-47dB, 1dB steps")
        (options, args) = parser.parse_args()
        if len(args) != 2:
            parser.print_help()
            sys.exit(1)

        self.center_freq = eng_notation.str_to_num(args[0])
        if options.avoid_LO:
            self.center_freq = self.center_freq + options.samp_rate / 4.0
            print "Avoiding LO...\nShifting center Frequency to", self.center_freq
        self.bandwidth = eng_notation.str_to_num(args[1])

        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        # build graph
        self.u = osmosdr.source(args="numchan=" + str(1) + " " + "hackrf=0")
        self.u.set_sample_rate(options.samp_rate)
        self.u.set_freq_corr(0, 0)
        self.u.set_dc_offset_mode(int(options.dc_off), 0)
        self.u.set_iq_balance_mode(int(options.iq_balance), 0)
        print "options.g_mode: ", options.g_mode
        self.u.set_gain_mode(options.g_mode, 0)
        self.u.set_gain(options.rf_gain, 0)
        self.u.set_if_gain(options.lna_gain, 0)
        self.u.set_bb_gain(options.vga_gain, 0)
        self.u.set_antenna("", 0)
        self.u.set_bandwidth(options.bandwidth, 0)

        #if hackrf_rate != options.samp_rate: #FIXME How to read back hackrf_rate
        #    if hackrf_rate < options.samp_rate:
        #        # create list of allowable rates
        #        samp_rates = self.u.get_samp_rates()
        #        rate_list = [0.0]*len(samp_rates)
        #        for i in range(len(rate_list)):
        #           last_rate = samp_rates.pop()
        #           rate_list[len(rate_list) - 1 - i] = last_rate.start()
        #       # choose next higher rate
        #       rate_ind = rate_list.index(hackrf_rate) + 1
        #       if rate_ind < len(rate_list):
        #           self.u.set_samp_rate(rate_list[rate_ind])
        #           hackrf_rate = self.u.get_samp_rate()
        #       print "New actual sample rate =", hackrf_rate/1e6, "MHz"
        #    resamp = filter.fractional_resampler_cc(0.0, hackrf_rate / options.samp_rate)

        self.samp_rate = options.samp_rate
        self.fft_size = options.fft_size
        self.num_ch = options.number_channels
        self.avoid_LO = options.avoid_LO

        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)

        mywindow = filter.window.blackmanharris(self.fft_size)
        ffter = fft.fft_vcc(self.fft_size, True, mywindow, True)
        window_power = sum(map(lambda x: x * x, mywindow))

        c2mag = blocks.complex_to_mag_squared(self.fft_size)
        self.bin2ch_map = [0] * self.fft_size
        hz_per_bin = self.samp_rate / self.fft_size
        print "\nhz_per_bin: ", hz_per_bin / 1e3, "kHz"
        channel_bw = hz_per_bin * round(
            self.bandwidth / self.num_ch / hz_per_bin)
        print "RB Bandwidth: ", channel_bw / 1e3, "kHz"
        self.bandwidth = channel_bw * self.num_ch
        print "Actual width of band is", self.bandwidth / 1e6, "MHz."
        start_freq = self.center_freq - self.bandwidth / 2.0
        #print "Initiallay set frequency range to: [",start_freq/1e6, "MHz-",stop_freq/1e6,"MHz ]"
        if options.avoid_LO:
            start_freq = (self.center_freq -
                          options.samp_rate / 4) - self.bandwidth / 2.0
        stop_freq = start_freq + self.bandwidth
        if options.avoid_LO:
            print "Avoiding LO, frequencies are shifted to: [", start_freq / 1e6, "MHz-", stop_freq / 1e6, "MHz ]"

        for j in range(self.fft_size):
            fj = self.bin_freq(j, self.center_freq)
            if (fj >= start_freq) and (fj < stop_freq):
                channel_num = int(math.floor(
                    (fj - start_freq) / channel_bw)) + 1
                self.bin2ch_map[j] = channel_num
        if options.skip_DC:
            self.bin2ch_map[(self.fft_size + 1) / 2 +
                            1:] = self.bin2ch_map[(self.fft_size + 1) / 2:-1]
            self.bin2ch_map[(self.fft_size + 1) / 2] = 0
        if self.bandwidth > self.samp_rate:
            print "Warning: Width of band (" + str(
                self.bandwidth /
                1e6), "MHz) is greater than the sample rate (" + str(
                    self.samp_rate / 1e6), "MHz)."

        self.aggr = myblocks.bin_aggregator_ff(self.fft_size, self.num_ch,
                                               self.bin2ch_map)

        meas_frames = max(1,
                          int(
                              round(options.meas_interval * self.samp_rate /
                                    self.fft_size)))  # in fft_frames
        self.meas_duration = meas_frames * self.fft_size / self.samp_rate
        print "Actual measurement duration =", self.meas_duration, "s"

        self.stats = myblocks.bin_statistics_ff(self.num_ch, meas_frames)

        # Divide magnitude-square by a constant to obtain power
        # in Watts.  Assumes unit of HackRF source is volts.
        impedance = 50.0  # ohms
        Vsq2W_dB = -10.0 * math.log10(self.fft_size * window_power * impedance)

        # Convert from Watts to dBm.
        W2dBm = blocks.nlog10_ff(10.0, self.num_ch, 30.0 + Vsq2W_dB)

        f2c = blocks.float_to_char(self.num_ch, 1.0)

        self.dest_host = options.dest_host

        # ssl socket is set in main loop; use dummy value for now
        self.srvr = myblocks.sslsocket_sink(numpy.int8, self.num_ch, 0)

        if options.samp_rate > self.samp_rate:
            # insert resampler
            self.connect(self.u, resamp, s2v)
        else:
            self.connect(self.u, s2v)
        self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, f2c,
                     self.srvr)
        #self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, self.srvr)

        g_start = 0
        g_stop = 20
        # FIXME Find out the Gain range of HACK_RF
        if options.rf_gain is None:
            # if no gain was specified, use the mid-point in dB
            options.rf_gain = float(g_start + g_stop) / 2.0
        self.set_gain(options.rf_gain)

        print "gain =", options.rf_gain, "dB in range (%0.1f dB, %0.1f dB)" % (
            float(g_start), float(g_stop))
        self.atten = float(g_stop) - options.rf_gain
    def __init__(self):
        gr.top_block.__init__(self)

        usage = "usage: %prog [options] center_freq band_width"
        parser = OptionParser(option_class=eng_option, usage=usage)
        parser.add_option("-a", "--args", type="string", default="",
                          help="UHD device device address args [default=%default]")
        parser.add_option("", "--spec", type="string", default=None,
	                  help="Subdevice of UHD device where appropriate")
        parser.add_option("-A", "--antenna", type="string", default=None,
                          help="select Rx Antenna where appropriate")
        parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6,
                          help="set sample rate [default=%default]")
        parser.add_option("-g", "--gain", type="eng_float", default=None,
                          help="set gain in dB (default is midpoint)")
        parser.add_option("", "--meas-interval", type="eng_float",
                          default=0.1, metavar="SECS",
                          help="interval over which to measure statistic (in seconds) [default=%default]")
        parser.add_option("-c", "--number-channels", type="int", default=100, 
                          help="number of uniform channels for which to report power measurements [default=%default]")
        parser.add_option("-l", "--lo-offset", type="eng_float",
                          default=0, metavar="Hz",
                          help="lo_offset in Hz [default=half the sample rate]")
        parser.add_option("-F", "--fft-size", type="int", default=1024,
                          help="specify number of FFT bins [default=%default]")
        parser.add_option("", "--real-time", action="store_true", default=False,
                          help="Attempt to enable real-time scheduling")
    	parser.add_option("-d", "--dest-host", type="string", default="",
                          help="set destination host for sending data")
        parser.add_option("", "--skip-DC", action="store_true", default=False,
                          help="skip the DC bin when mapping channels")

        (options, args) = parser.parse_args()
        if len(args) != 2:
            parser.print_help()
            sys.exit(1)

	self.center_freq = eng_notation.str_to_num(args[0])
	self.bandwidth = eng_notation.str_to_num(args[1])

        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        # build graph
        self.u = uhd.usrp_source(device_addr=options.args,
                                 stream_args=uhd.stream_args('fc32'))

        # Set the subdevice spec
        if(options.spec):
            self.u.set_subdev_spec(options.spec, 0)

        # Set the antenna
        if(options.antenna):
            self.u.set_antenna(options.antenna, 0)
        
        self.u.set_samp_rate(options.samp_rate)
        usrp_rate = self.u.get_samp_rate()

	if usrp_rate != options.samp_rate:
	    if usrp_rate < options.samp_rate:
	        # create list of allowable rates
	        samp_rates = self.u.get_samp_rates()
	        rate_list = [0.0]*len(samp_rates)
	        for i in range(len(rate_list)):
		    last_rate = samp_rates.pop()
		    rate_list[len(rate_list) - 1 - i] = last_rate.start()
		# choose next higher rate
		rate_ind = rate_list.index(usrp_rate) + 1
		if rate_ind < len(rate_list):
		    self.u.set_samp_rate(rate_list[rate_ind])
		    usrp_rate = self.u.get_samp_rate()
		print "New actual sample rate =", usrp_rate/1e6, "MHz"
	    resamp = filter.fractional_resampler_cc(0.0, usrp_rate / options.samp_rate)

	self.samp_rate = options.samp_rate
        
	if(options.lo_offset):
            self.lo_offset = options.lo_offset
	else:
	    self.lo_offset = usrp_rate / 2.0
	    print "LO offset set to", self.lo_offset/1e6, "MHz"

        self.fft_size = options.fft_size
        self.num_ch = options.number_channels
        
        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)

        mywindow = filter.window.blackmanharris(self.fft_size)
        ffter = fft.fft_vcc(self.fft_size, True, mywindow, True)
        window_power = sum(map(lambda x: x*x, mywindow))

        c2mag = blocks.complex_to_mag_squared(self.fft_size)

	self.bin2ch_map = [0] * self.fft_size
        hz_per_bin = self.samp_rate / self.fft_size
	channel_bw = hz_per_bin * round(self.bandwidth / self.num_ch / hz_per_bin)
	self.bandwidth = channel_bw * self.num_ch
	print "Actual width of band is", self.bandwidth/1e6, "MHz."
	start_freq = self.center_freq - self.bandwidth/2.0
	stop_freq = start_freq + self.bandwidth
	for j in range(self.fft_size):
	    fj = self.bin_freq(j, self.center_freq)
	    if (fj >= start_freq) and (fj < stop_freq):
	        channel_num = int(math.floor((fj - start_freq) / channel_bw)) + 1
	        self.bin2ch_map[j] = channel_num
	if options.skip_DC:
	    self.bin2ch_map[(self.fft_size + 1) / 2 + 1:] = self.bin2ch_map[(self.fft_size + 1) / 2 : -1]
	    self.bin2ch_map[(self.fft_size + 1) / 2] = 0
	if self.bandwidth > self.samp_rate:
	    print "Warning: Width of band (" + str(self.bandwidth/1e6), "MHz) is greater than the sample rate (" + str(self.samp_rate/1e6), "MHz)."

	self.aggr = myblocks.bin_aggregator_ff(self.fft_size, self.num_ch, self.bin2ch_map)

        meas_frames = max(1, int(round(options.meas_interval * self.samp_rate / self.fft_size))) # in fft_frames
	self.meas_duration = meas_frames * self.fft_size / self.samp_rate
	print "Actual measurement duration =", self.meas_duration, "s"

        self.stats = myblocks.bin_statistics_ff(self.num_ch, meas_frames)

	# Divide magnitude-square by a constant to obtain power
	# in Watts.  Assumes unit of USRP source is volts.
	impedance = 50.0   # ohms
	Vsq2W_dB = -10.0 * math.log10(self.fft_size * window_power * impedance)

	# Convert from Watts to dBm.
	W2dBm = blocks.nlog10_ff(10.0, self.num_ch, 30.0 + Vsq2W_dB)

	f2c = blocks.float_to_char(self.num_ch, 1.0)

	self.dest_host = options.dest_host

	# file descriptor is set in main loop; use dummy value for now
	self.srvr = myblocks.file_descriptor_sink(self.num_ch * gr.sizeof_char, 0)

	if usrp_rate > self.samp_rate:
	    # insert resampler
	    self.connect(self.u, resamp, s2v)
	else:
	    self.connect(self.u, s2v)
	self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, f2c, self.srvr)
	#self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, self.srvr)

        g = self.u.get_gain_range()
        if options.gain is None:
            # if no gain was specified, use the mid-point in dB
            options.gain = float(g.start()+g.stop())/2.0

        self.set_gain(options.gain)
        print "gain =", options.gain, "dB in range (%0.1f dB, %0.1f dB)" % (float(g.start()), float(g.stop()))
	self.atten = float(g.stop()) - options.gain
    def __init__(self):
        gr.top_block.__init__(self)

        usage = "usage: %prog [options] center_freq band_width"
        parser = OptionParser(option_class=eng_option, usage=usage)
        parser.add_option("-s", "--samp-rate", type="eng_float", default=10e6,
                          help="set sample rate: 8/10/12.5/16/20 MHz [default=%default]")
        parser.add_option("-g", "--rf-gain", type="eng_float", default=0,
                          help="set the overall gain in dB (default is midpoint)") #FIXME range?
        parser.add_option("", "--lna-gain", type="eng_float", default=24,
                          help="set RX IF gain in dB (default is midpoint): 0-40dB, 8dB steps")
        parser.add_option("", "--vga-gain", type="eng_float", default=32,
                          help="set BB gain in dB (default is midpoint): 0-62dB, 2dB steps")
        parser.add_option("", "--antenna", action="store_false", default=True,
                          help="Disable Antenna Port Power [default=%default]")
        parser.add_option("", "--bandwidth", type="eng_float", default=10e6,
                          help="Set the BB Filter Bandwidth in MHz: 1.75-28 MHz[default=%default]")
        parser.add_option("", "--g-mode", action="store_false", default=True,
                          help="set the gain mode[default=%default]")
        parser.add_option("", "--iq-balance", type="eng_float", default=2,
                          help="set the iq_balance_mode [default=%default]")
	parser.add_option("", "--dc-off", type="eng_float", default=1,
                          help="set the dc offset mode [default=%default]")

        parser.add_option("", "--meas-interval", type="eng_float",
                          default=0.1, metavar="SECS",
                          help="interval over which to measure statistic (in seconds) [default=%default]")
        parser.add_option("-c", "--number-channels", type="int", default=56,
                          help="number of uniform channels for which to report power measurements [default=%default]") 
        parser.add_option("-F", "--fft-size", type="int", default=1024,
                          help="specify number of FFT bins [default=%default]")
        parser.add_option("", "--real-time", action="store_true", default=False,
                          help="Attempt to enable real-time scheduling")
        parser.add_option("-d", "--dest-host", type="string", default="",
                          help="set destination host for sending data")
        parser.add_option("", "--skip-DC", action="store_true", default=False,
                          help="skip the DC bin when mapping channels")
        parser.add_option("", "--avoid-LO", action="store_true", default=False,
                          help="Avoid LO by sampling at higher rate, shift frequency and take only a desired chunk")

#        parser.add_option("-l", "--lo-offset", type="eng_float", default=0, metavar="Hz", 
#                          help="lo_offset in Hz [default=half the sample rate]")
#        parser.add_option("", "--tx-VGA-gain", type="eng_float", default=None,
#                          help="set TX IF gain in dB (default is midpoint): 0-47dB, 1dB steps")
        (options, args) = parser.parse_args()
        if len(args) != 2:
            parser.print_help()
            sys.exit(1)

	self.center_freq = eng_notation.str_to_num(args[0])
        if options.avoid_LO:
                self.center_freq = self.center_freq + options.samp_rate/4.0
		print "Avoiding LO...\nShifting center Frequency to", self.center_freq
	self.bandwidth = eng_notation.str_to_num(args[1])

        if not options.real_time:
            realtime = False
        else:
            # Attempt to enable realtime scheduling
            r = gr.enable_realtime_scheduling()
            if r == gr.RT_OK:
                realtime = True
            else:
                realtime = False
                print "Note: failed to enable realtime scheduling"

        # build graph
        self.u = osmosdr.source( args="numchan=" + str(1) + " " + "hackrf=0" )
        self.u.set_sample_rate(options.samp_rate)
        self.u.set_freq_corr(0, 0)
        self.u.set_dc_offset_mode(int(options.dc_off), 0)
        self.u.set_iq_balance_mode(int(options.iq_balance), 0)
	print "options.g_mode: ", options.g_mode
        self.u.set_gain_mode(options.g_mode, 0)
        self.u.set_gain(options.rf_gain, 0)
        self.u.set_if_gain(options.lna_gain, 0)
        self.u.set_bb_gain(options.vga_gain, 0)
        self.u.set_antenna("", 0)
        self.u.set_bandwidth(options.bandwidth, 0)

        #if hackrf_rate != options.samp_rate: #FIXME How to read back hackrf_rate
        #    if hackrf_rate < options.samp_rate:
        #        # create list of allowable rates
        #        samp_rates = self.u.get_samp_rates()
        #        rate_list = [0.0]*len(samp_rates)
        #        for i in range(len(rate_list)):
        #           last_rate = samp_rates.pop()
        #           rate_list[len(rate_list) - 1 - i] = last_rate.start()
        #       # choose next higher rate
        #       rate_ind = rate_list.index(hackrf_rate) + 1
        #       if rate_ind < len(rate_list):
        #           self.u.set_samp_rate(rate_list[rate_ind])
        #           hackrf_rate = self.u.get_samp_rate()
        #       print "New actual sample rate =", hackrf_rate/1e6, "MHz"
        #    resamp = filter.fractional_resampler_cc(0.0, hackrf_rate / options.samp_rate)
	
	self.samp_rate = options.samp_rate
        self.fft_size = options.fft_size
        self.num_ch = options.number_channels
        self.avoid_LO = options.avoid_LO 

        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size)

        mywindow = filter.window.blackmanharris(self.fft_size)
        ffter = fft.fft_vcc(self.fft_size, True, mywindow, True)
        window_power = sum(map(lambda x: x*x, mywindow))

        c2mag = blocks.complex_to_mag_squared(self.fft_size)
	self.bin2ch_map = [0] * self.fft_size
        hz_per_bin = self.samp_rate / self.fft_size
	print "\nhz_per_bin: ", hz_per_bin/1e3, "kHz"
	channel_bw = hz_per_bin * round(self.bandwidth / self.num_ch / hz_per_bin)
	print "RB Bandwidth: ", channel_bw/1e3, "kHz"
	self.bandwidth = channel_bw * self.num_ch
	print "Actual width of band is", self.bandwidth/1e6, "MHz."
        start_freq = self.center_freq - self.bandwidth/2.0
        #print "Initiallay set frequency range to: [",start_freq/1e6, "MHz-",stop_freq/1e6,"MHz ]"
        if options.avoid_LO:
                start_freq = (self.center_freq - options.samp_rate/4) - self.bandwidth/2.0
        stop_freq = start_freq + self.bandwidth
        if options.avoid_LO:
                print "Avoiding LO, frequencies are shifted to: [",start_freq/1e6, "MHz-",stop_freq/1e6,"MHz ]"

	for j in range(self.fft_size):
	    fj = self.bin_freq(j, self.center_freq)
	    if (fj >= start_freq) and (fj < stop_freq):
	        channel_num = int(math.floor((fj - start_freq) / channel_bw)) + 1
	        self.bin2ch_map[j] = channel_num
	if options.skip_DC:
	    self.bin2ch_map[(self.fft_size + 1) / 2 + 1:] = self.bin2ch_map[(self.fft_size + 1) / 2 : -1]
	    self.bin2ch_map[(self.fft_size + 1) / 2] = 0
	if self.bandwidth > self.samp_rate:
	    print "Warning: Width of band (" + str(self.bandwidth/1e6), "MHz) is greater than the sample rate (" + str(self.samp_rate/1e6), "MHz)."

	self.aggr = myblocks.bin_aggregator_ff(self.fft_size, self.num_ch, self.bin2ch_map)

        meas_frames = max(1, int(round(options.meas_interval * self.samp_rate / self.fft_size))) # in fft_frames
	self.meas_duration = meas_frames * self.fft_size / self.samp_rate
	print "Actual measurement duration =", self.meas_duration, "s"

        self.stats = myblocks.bin_statistics_ff(self.num_ch, meas_frames)

	# Divide magnitude-square by a constant to obtain power
	# in Watts.  Assumes unit of HackRF source is volts.
	impedance = 50.0   # ohms
	Vsq2W_dB = -10.0 * math.log10(self.fft_size * window_power * impedance)

	# Convert from Watts to dBm.
	W2dBm = blocks.nlog10_ff(10.0, self.num_ch, 30.0 + Vsq2W_dB)

	f2c = blocks.float_to_char(self.num_ch, 1.0)

	self.dest_host = options.dest_host

	# ssl socket is set in main loop; use dummy value for now
	self.srvr = myblocks.sslsocket_sink(numpy.int8, self.num_ch, 0)

	if options.samp_rate > self.samp_rate:
	    # insert resampler
	    self.connect(self.u, resamp, s2v)
	else:
	    self.connect(self.u, s2v)
	self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, f2c, self.srvr)
	#self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, self.srvr)

        g_start = 0
        g_stop  = 20
        # FIXME Find out the Gain range of HACK_RF
        if options.rf_gain is None:
            # if no gain was specified, use the mid-point in dB
            options.rf_gain = float(g_start+g_stop)/2.0
        self.set_gain(options.rf_gain)

        print "gain =", options.rf_gain, "dB in range (%0.1f dB, %0.1f dB)" % (float(g_start), float(g_stop))
	self.atten = float(g_stop) - options.rf_gain