Skip to content
Snippets Groups Projects
Commit 8a59c858 authored by Daniel Meißner's avatar Daniel Meißner Committed by Daniel Meißner
Browse files

initial commit

parents
No related branches found
No related tags found
No related merge requests found
__pycache__
*pyc
This diff is collapsed.
.DEFAULT:= echo
echo:
@echo "clean | remove pyc files"
clean:
find . -name "*pyc" -delete
# SU aka Spectrum Usage
## Requirements
### Software
* Linux
* Python 2.7
* GNU Radio
* SciPy
* PyQt5
### Hardware
* Two CPU cores, more are even better
* 100 GB of disc space
* HackRF One, rad1o or RTL-SDR DVB-T stick
## Licence
Copyright (c) 2015, Daniel Meißner <daniel.meissner@smail.inf.h-brs.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Sat Dec 19 12:30:35 2015</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value></value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 8)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>no_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(320, 13)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>freq</value>
</param>
<param>
<key>value</key>
<value>868e6</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(200, 13)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>2e6</value>
</param>
</block>
<block>
<key>blocks_file_meta_sink</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>detached</key>
<value>False</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>extra_dict</key>
<value>""</value>
</param>
<param>
<key>file</key>
<value>bla</value>
</param>
<param>
<key>_coordinate</key>
<value>(328, 154)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_file_meta_sink_0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>max_seg_size</key>
<value>1000000</value>
</param>
<param>
<key>rel_rate</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>unbuffered</key>
<value>False</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>rtlsdr_source</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>ant0</key>
<value></value>
</param>
<param>
<key>bb_gain0</key>
<value>20</value>
</param>
<param>
<key>bw0</key>
<value>0</value>
</param>
<param>
<key>dc_offset_mode0</key>
<value>0</value>
</param>
<param>
<key>corr0</key>
<value>0</value>
</param>
<param>
<key>freq0</key>
<value>freq</value>
</param>
<param>
<key>gain_mode0</key>
<value>False</value>
</param>
<param>
<key>if_gain0</key>
<value>20</value>
</param>
<param>
<key>iq_balance_mode0</key>
<value>0</value>
</param>
<param>
<key>gain0</key>
<value>0</value>
</param>
<param>
<key>ant1</key>
<value></value>
</param>
<param>
<key>bb_gain1</key>
<value>20</value>
</param>
<param>
<key>bw1</key>
<value>0</value>
</param>
<param>
<key>dc_offset_mode1</key>
<value>0</value>
</param>
<param>
<key>corr1</key>
<value>0</value>
</param>
<param>
<key>freq1</key>
<value>100e6</value>
</param>
<param>
<key>gain_mode1</key>
<value>False</value>
</param>
<param>
<key>if_gain1</key>
<value>20</value>
</param>
<param>
<key>iq_balance_mode1</key>
<value>0</value>
</param>
<param>
<key>gain1</key>
<value>10</value>
</param>
<param>
<key>ant2</key>
<value></value>
</param>
<param>
<key>bb_gain2</key>
<value>20</value>
</param>
<param>
<key>bw2</key>
<value>0</value>
</param>
<param>
<key>dc_offset_mode2</key>
<value>0</value>
</param>
<param>
<key>corr2</key>
<value>0</value>
</param>
<param>
<key>freq2</key>
<value>100e6</value>
</param>
<param>
<key>gain_mode2</key>
<value>False</value>
</param>
<param>
<key>if_gain2</key>
<value>20</value>
</param>
<param>
<key>iq_balance_mode2</key>
<value>0</value>
</param>
<param>
<key>gain2</key>
<value>10</value>
</param>
<param>
<key>ant3</key>
<value></value>
</param>
<param>
<key>bb_gain3</key>
<value>20</value>
</param>
<param>
<key>bw3</key>
<value>0</value>
</param>
<param>
<key>dc_offset_mode3</key>
<value>0</value>
</param>
<param>
<key>corr3</key>
<value>0</value>
</param>
<param>
<key>freq3</key>
<value>100e6</value>
</param>
<param>
<key>gain_mode3</key>
<value>False</value>
</param>
<param>
<key>if_gain3</key>
<value>20</value>
</param>
<param>
<key>iq_balance_mode3</key>
<value>0</value>
</param>
<param>
<key>gain3</key>
<value>10</value>
</param>
<param>
<key>ant4</key>
<value></value>
</param>
<param>
<key>bb_gain4</key>
<value>20</value>
</param>
<param>
<key>bw4</key>
<value>0</value>
</param>
<param>
<key>dc_offset_mode4</key>
<value>0</value>
</param>
<param>
<key>corr4</key>
<value>0</value>
</param>
<param>
<key>freq4</key>
<value>100e6</value>
</param>
<param>
<key>gain_mode4</key>
<value>False</value>
</param>
<param>
<key>if_gain4</key>
<value>20</value>
</param>
<param>
<key>iq_balance_mode4</key>
<value>0</value>
</param>
<param>
<key>gain4</key>
<value>10</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>args</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(72, 140)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>rtlsdr_source_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>nchan</key>
<value>1</value>
</param>
<param>
<key>type</key>
<value>fc32</value>
</param>
<param>
<key>sample_rate</key>
<value>samp_rate</value>
</param>
</block>
<connection>
<source_block_id>rtlsdr_source_0</source_block_id>
<sink_block_id>blocks_file_meta_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>
#!/usr/bin/env python2
##################################################
# GNU Radio Python Flow Graph
# Title: Top Block
# Generated: Sat Dec 19 12:53:49 2015
##################################################
from gnuradio import eng_notation
from gnuradio import gr
from gnuradio import gr, blocks
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import osmosdr
class top_block(gr.top_block):
def __init__(self):
gr.top_block.__init__(self, "Top Block")
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 2e6
self.freq = freq = 868e6
##################################################
# Blocks
##################################################
self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + "" )
self.rtlsdr_source_0.set_sample_rate(samp_rate)
self.rtlsdr_source_0.set_center_freq(freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_dc_offset_mode(0, 0)
self.rtlsdr_source_0.set_iq_balance_mode(0, 0)
self.rtlsdr_source_0.set_gain_mode(False, 0)
self.rtlsdr_source_0.set_gain(0, 0)
self.rtlsdr_source_0.set_if_gain(20, 0)
self.rtlsdr_source_0.set_bb_gain(20, 0)
self.rtlsdr_source_0.set_antenna("", 0)
self.rtlsdr_source_0.set_bandwidth(0, 0)
self.blocks_file_meta_sink_0 = blocks.file_meta_sink(gr.sizeof_gr_complex*1, "bla", samp_rate, 1, blocks.GR_FILE_FLOAT, True, 1000000, "", False)
self.blocks_file_meta_sink_0.set_unbuffered(False)
##################################################
# Connections
##################################################
self.connect((self.rtlsdr_source_0, 0), (self.blocks_file_meta_sink_0, 0))
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
def get_freq(self):
return self.freq
def set_freq(self, freq):
self.freq = freq
self.rtlsdr_source_0.set_center_freq(self.freq, 0)
if __name__ == '__main__':
parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
(options, args) = parser.parse_args()
tb = top_block()
tb.start()
try:
raw_input('Press Enter to quit: ')
except EOFError:
pass
tb.stop()
tb.wait()
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
import sys
import os
def check_dependencies():
"""
"""
print("Check dependencies…")
print("… checked.")
def check_user():
"""
Check for running user. SU should not be run as root.
"""
if os.getuid() == 0:
print("Do not run %s as root" % __file__ )
sys.exit()
# -*- coding: utf-8 -*-
import os
import osmosdr
from gnuradio import eng_notation
from gnuradio import gr
from gnuradio import gr, blocks
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
class FileSink(self):
"""
FileSink class to create I/Q sample binary dump files.
"""
def __init__(self, dump_file, samp_rate, capture_time, device):
self.file_path = dump_file
self.sample_rate = samp_rate
self.freq = freq
self.capture_time = capture_time
self.capture_device = device
def needed_disc_space(self):
"""
Calculate needed disc space for dump.
"""
pass
def capture(self):
"""
Capture samples to dump file.
"""
pass
def _dump_file_writable(self):
"""
Check permissions for specified file dump path.
"""
if os.path.exists(self.pathfile):
return os.access(self.file_path, os.W_OK)
elif os.access(os.path.dirname(self.file_path), os.W_OK) and \
os.access(self.file_path, os.W_OK):
return True
else:
return False
def get_file_path(self):
return self.file_path
def get_samp_rate(self):
return samp_rate
def get_capture_time(self):
return self.capture_time
def get_capture_device(self):
return self.get_capture_device
# -*- coding: utf-8 -*-
import sys
import os
import logging
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class SuGui(QtWidgets.QMainWindow):
def __init__(self):
super(SuGui, self).__init__()
uic.loadUi('lib/gui/su_mainwindow.ui', self)
self.show()
# button events
self.button_start.clicked.connect(self.buttonStart)
self.button_stop.clicked.connect(self.buttonStop)
self.button_close.clicked.connect(self.buttonClose)
def buttonStart(self):
pass
def buttonStop(self):
pass
def buttonClose(self):
logging.info("Close application")
QtCore.QCoreApplication.instance().quit()
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SuMainWindow</class>
<widget class="QMainWindow" name="SuMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>572</width>
<height>363</height>
</rect>
</property>
<property name="windowTitle">
<string>SU - Spectrum Usage</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="button_start">
<property name="geometry">
<rect>
<x>410</x>
<y>80</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
<widget class="QGroupBox" name="box_freq">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>101</width>
<height>61</height>
</rect>
</property>
<property name="title">
<string>Frequency</string>
</property>
<widget class="QRadioButton" name="rb_433">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>433 MHz</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_868">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>868 MHz</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="box_measure_time">
<property name="geometry">
<rect>
<x>10</x>
<y>190</y>
<width>120</width>
<height>131</height>
</rect>
</property>
<property name="title">
<string>Measurement time</string>
</property>
<widget class="QRadioButton" name="rb_1m">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>1 min</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_5m">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>5 min</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_10m">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>10 min</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_1h_2">
<property name="geometry">
<rect>
<x>10</x>
<y>80</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>1h</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QRadioButton" name="rb_1h">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>24 h</string>
</property>
</widget>
</widget>
<widget class="QPushButton" name="button_stop">
<property name="geometry">
<rect>
<x>410</x>
<y>40</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Stop </string>
</property>
</widget>
<widget class="QGroupBox" name="box_samp_rate">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>101</width>
<height>91</height>
</rect>
</property>
<property name="title">
<string>Sample rate</string>
</property>
<widget class="QRadioButton" name="rb_1mhz">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>1 MHz</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_3mhz">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>3 MHz</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_2mhz">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>102</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>2 MHz</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="box_iq_dump_file">
<property name="geometry">
<rect>
<x>160</x>
<y>20</y>
<width>241</width>
<height>91</height>
</rect>
</property>
<property name="title">
<string>I/Q dump file</string>
</property>
<widget class="QLineEdit" name="lineEdit_dump_file">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>221</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_disk_space">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>71</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_file_overwrite">
<property name="geometry">
<rect>
<x>130</x>
<y>60</y>
<width>101</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
<widget class="QPushButton" name="button_close">
<property name="geometry">
<rect>
<x>410</x>
<y>280</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Close</string>
</property>
</widget>
<widget class="QLabel" name="label_status">
<property name="geometry">
<rect>
<x>160</x>
<y>150</y>
<width>211</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>572</width>
<height>19</height>
</rect>
</property>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionAbout"/>
</widget>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionQuit"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuHelp"/>
</widget>
<action name="actionAbout">
<property name="text">
<string>About</string>
</property>
</action>
<action name="actionQuit">
<property name="text">
<string>Quit</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
# -*- coding: utf-8 -*-
__version__ = '0.0.1'
su.py 0 → 100755
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
# stdlib
import logging
import sys
import argparse
import os
from lib.version import __version__
import lib.dependencies as dep
import lib.gui.gui as gui
from PyQt5 import QtCore, QtGui, QtWidgets
class Su(object):
"""
"""
@staticmethod
def version():
return __version__
@staticmethod
def name():
return "Spectrum Usage (su)"
def parse_arguments():
parser = argparse.ArgumentParser()
# verbose
parser.add_argument("-v", "--verbose", help="increase output verbosity",
action="store_true")
# version
parser.add_argument("--version", action="version",
version='%(prog)s {version}'. \
format(version=Su.version()))
return parser.parse_args()
def main():
args = parse_arguments()
dep.check_user()
dep.check_dependencies()
if args.verbose:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
logging.info("Started %s - v%s" % (__file__, Su.version()))
# starting gui
app = QtWidgets.QApplication(sys.argv)
window = gui.SuGui()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment