Compare commits

...

135 Commits

Author SHA1 Message Date
Vadim Yanitskiy 2de47e28ce dists: add PKGBUILD script for Arch Linux
Change-Id: Iabf6db281e95e72cdf0bd744bb7fd00c09360a38
2021-05-05 14:16:24 +02:00
Vadim Yanitskiy a11692085e Fix compilation error: '_1' was not declared in this scope
Change-Id: I0f1f2df817a65f7d5b72c5280451346a0a011d47
2021-05-03 20:34:13 +02:00
Piotr Krysik 6e1473426d tests: Add test for Ubuntu 20.04
Change-Id: I38bbde4fad7bdc72ad99a1957678539ea813013e
2021-05-03 12:05:56 +02:00
Piotr Krysik 92e4032d6d tests: Remove test that don't work
Change-Id: I9f37131c565e6d87ae94f583d36a2de3d9500b38
2021-05-03 12:05:49 +02:00
Piotr Krysik 6e602f5b7c Port compile_demappers helper script to gr3.8
Change-Id: Iadcc19288496558fc65a46b72d36dcf047489ac3
2021-05-03 07:14:00 +02:00
Piotr Krysik d00289d273 Execute python apps with use of python3
Change-Id: Ib9ab805cc5a3878d168787736463dc495b96ddcf
2021-05-03 07:14:00 +02:00
Piotr Krysik e4da417f8d Remove local copy of associated osmo libraries
Change-Id: I2b4afedd9f2d568b5287d791891b2c2893fc6843
2021-05-03 07:14:00 +02:00
Piotr Krysik df417739b0 cmake: make formatting of install statements follow one pattern
Change-Id: Ib7d571af629b0af78397a411b0cca409a6d218d8
2021-05-03 07:14:00 +02:00
Piotr Krysik 21b0f7d228 cmake: change 'gsm' to 'grgsm'
Change-Id: I130a7912e179b1f04e68eb131e06800becca5a00
2021-05-03 07:14:00 +02:00
Piotr Krysik d8211032fa trx: Removing old and unused grc based radio_if
Change-Id: I7d43e6f2962b21ff03601cf1b1aafc222f2c4661
2021-05-03 07:14:00 +02:00
Vasil Velichkov b82bbeb026 Fix compiling with the local libosmocore copy
Change-Id: Ic72e6ca7f9cc40bc2d78b931e54e66cd71444835
2021-05-03 07:14:00 +02:00
Vasil Velichkov 284f1dbb40 Log import errors as currently GRC 3.8 suppress them
See gnuradio/grc/core/FlowGraph.py:194

Change-Id: Ie6213428c218720692a544c98dc32c16bd50cbe1
2021-05-03 07:14:00 +02:00
Vasil Velichkov e05ada3a78 travis: Test in Ubuntu 18.04 container
- Install gnuradio from the new official PPA repository
  https://launchpad.net/~gnuradio/+archive/ubuntu/gnuradio-releases

Change-Id: Iaa8813ab0ae91b667285ab3ef42ffaa279e3a885
2021-05-03 07:14:00 +02:00
Vasil Velichkov dfcf7fd5a3 Print the error message on stderr in a python2 compatible way
Change-Id: Iaea1510b02a2df924ef9777d107d22c45cb37d12
2021-05-03 07:14:00 +02:00
Vasil Velichkov cc8d86320e tests: export VOLK_GENERIC=1 to workaround VOLK's bug 278
Change-Id: Ib9ad4384388e480b8fa2f91e02359c85c749e802
2021-05-03 07:14:00 +02:00
Vasil Velichkov 71fb85cc79 tests: Get more information about CPU and user limits
Change-Id: I0bd3c206f422e11a59070a1c9aace38201ff7c85
2021-05-03 07:14:00 +02:00
Vasil Velichkov fc046c48cd tests: fix some shellcheck errors.
Execute "gnuradio-config-info --version" instead of
"gnuradio-companion --version"

Change-Id: Ia399324ae7a39e120e338c86d449d7c4d54bd866
2021-05-03 07:14:00 +02:00
Vasil Velichkov fa1bd24c1d travis: Use bionic build environment
https: //docs.travis-ci.com/user/reference/bionic/

Change-Id: I8f622506329ee97ff3555c2a43a2165303d9ae82
2021-05-03 07:14:00 +02:00
Vasil Velichkov f90804500f travis: Install gr-osmosdr from the apt repository
Also install liborc-dev as gnuradio depends on it

Change-Id: I0bbc33a39ef1e4edc1636c338e429639e0b15066
2021-05-03 07:14:00 +02:00
Vasil Velichkov a12e9e1a9f Add .dockerignore file
Change-Id: I8d4b527a2e5c7b69e5c7338cafba3fbdac381ae1
2021-05-03 07:14:00 +02:00
Vasil Velichkov 601c786d51 tests: Close the temp file handle in qa_burst_file_source
This fixes the following warning

./usr/lib64/python3.7/unittest/case.py:645: ResourceWarning: unclosed file <_io.BufferedWriter name='/tmp/tmpkkz_akd6'>
  testMethod()
ResourceWarning: Enable tracemalloc to get the object allocation traceback

Change-Id: I66c2be2e5bf6915e3df253b3a69f5516534e3750
2021-05-03 07:14:00 +02:00
Vasil Velichkov f6314031e7 Python 3 compatibility changes in fn_time.py
- Use range instead of xrange as it has been removed
- Use integer division operator (//)
- Import uniform and fn_time_delta_cpp only when started as a script
- Remove the unused imports

Change-Id: I268e0aec8fb8e6d490bfb8b0e9e6d169a9f6c352
2021-05-03 07:14:00 +02:00
Vasil Velichkov 45b04bb3cc Build the grgsm_livemon man page
Change-Id: Ie128d68965b5cb2c919afa408b4c8aa7ca87ea8c
2021-05-03 07:14:00 +02:00
Vasil Velichkov 0c2845650a tests: Do not specify filename when runing gr_unittest
This fixes the following warning

DEPRECATED: Using filename with gr_unittest does no longer have any effect.

Change-Id: I7d6dbc32ff794ebf2bc116fa7437062e6780b85f
2021-05-03 07:14:00 +02:00
Vasil Velichkov 0af1435815 Remove build_utils.py and build_utils_codes.py
These two files are no longer used

Change-Id: I80a364c729e75681a0afd926ea3ecd0eb2d65381
2021-05-03 07:14:00 +02:00
Vasil Velichkov 30eb567619 travis: Add /usr/local/lib/python3/dist-packages/ to PYTHONPATH
and run ldconfig after installing gr-iqbal and gr-osmosdr.

Due to debian-python-install patch [1] the OOT packages are installed in
/usr/local/lib/python3/dist-packages but this path is not in the python3
default search paths (sys.path) and because of this importing OOT
modules fails.

[1] https://salsa.debian.org/bottoms/pkg-gnuradio/blob/25e1de07/debian/patches/debian-python-install

Change-Id: I260c82d1a53dab85f7aac86f23e61309d8841255
2021-05-03 07:14:00 +02:00
Vasil Velichkov 65f95f5ae0 travis: Install liborc-0.4-dev needed for gr-iqbal
on Debian Testing and Kali with gnuradio (3.8.0.0-5)

Change-Id: I4512bb734691f553d63cac59fd2c7ba3ccf3f881
2021-05-03 07:14:00 +02:00
Vasil Velichkov c7134fff20 Do not add python/misc_utils to PYTHONPATH when executing tests
Change-Id: Ib19a181a3fd9bb78c1d3989bad0e55433f060950
2021-05-03 07:14:00 +02:00
Vasil Velichkov 6eea94f7de Fix grcc compilation with python3 by adding local subdirs to __path__
As the directory structure in the repository is different then the one
after the package gets installed we need to add those subdirectories to
the __path__ otherwise python3 is not able to load the modules using the
relative import syntax and grcc compilation and some unit tests fail.

Mofiy __path__ only when the CMAKE_BINARY_DIR environment variable is
present.

Revert "grgsm_livemon: Set cell_allocation to [0]"

This reverts commit 013d4c258c6ad31c2581f0caa4eee3aa609fd9de.

Change-Id: I223fd6181e8e36027039301186b671712a597ff8
2021-05-03 07:14:00 +02:00
Vasil Velichkov 783a1f7b56 Remove the RTLD_GLOBAL hack
It was removed from gnuradio back in 2014
39f14138ac

Change-Id: I1604ad5b9eefe3d4a2228b2a09e2069962844c97
2021-05-03 07:14:00 +02:00
Vasil Velichkov 5e0ea65121 travis: gnuradio-companion 3.8 does not have --version parameter
And currently grgsm, gr-osmosdr and gr-iqbal are installed in
/usr/local/lib/python3/dist-packages/ which is not in the default python
search path.

Change-Id: I7e00c84a4b72e9fa1dcf5ac453882f1733724ac0
2021-05-03 07:14:00 +02:00
Vasil Velichkov 9feb7da807 grgsm_decode: Print frequency or ARFCN message on stderr
For some yet unknown reasons in travis on Debian testing and Kali rolling
the message gets printed after the burst and decode.sh and decrypt.sh
tests fails because of this.

Instead of filtering this messages in the tests I think it is better
such messages to be printed on the standard error output

Change-Id: Ib18be898cac74769cabf1b748e40e21d23f08e98
2021-05-03 07:14:00 +02:00
Vasil Velichkov fc10d03390 grgsm_livemon: Specify localhost as string
Traceback (most recent call last):
  File "/home/vasko/gr38/lib/python3.7/dist-packages/gnuradio/grc/core/FlowGraph.py", line 216, in renew_namespace
    value = eval(parameter_block.params['value'].to_code(), namespace)
  File "<string>", line 1, in <module>
NameError: name 'localhost' is not defined

Change-Id: I6bae2fb1f09038cb0cd3410533d3b3fdc79ed354
2021-05-03 07:14:00 +02:00
Vasil Velichkov 88c2925d46 grgsm_livemon: Set cell_allocation to [0]
Gnuradio 3.8 does not like cell_allocation: '[arfcn.downlink2arfcn(fc)]'
and the Receiver block does not work with an empty cell allocation array

gnuradio.grc.core.platform:["Param - Cell allocation(cell_allocation):\n\tExpression None is invalid for type'float_vector'."]

Change-Id: Iae6de844509b13bdf834c9c7443382b1ab3b0a28
2021-05-03 07:14:00 +02:00
Vasil Velichkov 165288c464 grgsm_livemon: Fix UDP client and server blocks
During the convertion to YAML the block types was changed
from TCP to UDP

Change-Id: I542d7c36c30dc8179fa0ee84fc87e134cd2ba9f5
2021-05-03 07:14:00 +02:00
Vasil Velichkov cb1109851c grgsm_livemon: Change the type of several parameters to string
It seems gnuradio 3.8 does not like parameters with type None and does
not put them as command line arguments

Change-Id: Id67e37e826aa1cc14640d57207a92def682f11e3
2021-05-03 07:14:00 +02:00
Vasil Velichkov f8f25b8694 grgsm_livemon: Disable PPS sync
Because of the following error when used with USRP B100

[INFO] [MULTI_USRP]     1) catch time transition at pps edge
Traceback (most recent call last):
  File "./grgsm_livemon.py", line 365, in <module>
    main()
  File "./grgsm_livemon.py", line 343, in main
    tb = top_block_cls(fc=options.fc, gain=options.gain, osr=options.osr, ppm=options.ppm, samp_rate=options.samp_rate, shiftoff=options.shiftoff)
  File "./grgsm_livemon.py", line 114, in __init__
    self.rtlsdr_source_0.set_time_unknown_pps(osmosdr.time_spec_t())
  File "/home/vasko/gr38/lib/python3.7/dist-packages/osmosdr/osmosdr_swig.py", line 2543, in set_time_unknown_pps
    return _osmosdr_swig.source_sptr_set_time_unknown_pps(self, time_spec)
RuntimeError: RuntimeError: Board 0 may not be getting a PPS signal!
No PPS detected within the time interval.
See the application notes for your device.

Change-Id: Iee6124bdb2441666a53ac9ee5239894aea61dfde
2021-05-03 07:14:00 +02:00
Vasil Velichkov c00008fa7b travis: Manually install gr-iqbal and gr-osmosdr
Currently these two packages still depends on gnuradio 3.8 in debian
testing and kali rolling.

Change-Id: I4f956577293c48d803b8b45d06ba508792501274
2021-05-03 07:14:00 +02:00
Vasil Velichkov fc99ad4258 travis: Install only python3 packages
Change-Id: I3548fa7340afc63557cc65a7a396ecf96c607806
2021-05-03 07:14:00 +02:00
Vasil Velichkov 386dddb620 Convert grgsm_livemon and grgsm_livemon_headless to YAML
Convert by opening them in gnuradio-companion 3.8.0.0 (Python 3.7.4)
and then File -> Save As under different name without any other
modifications

Change-Id: I73023fc66d1ffd6c714a0610962c005395dc126b
2021-05-03 07:14:00 +02:00
Vasil Velichkov 46c90bec99 Various python3 related changes
- Use relative import for grgsm's modules
- Convert map to list
- Remove the hier_block.py workaround as as gnuradio 3.7 is no longer
  supported in this branch

Change-Id: I5ca8fd340823996e8c444aaf18ddacd85c92ab1c
2021-05-03 07:14:00 +02:00
Vasil Velichkov 333027f406 travis: Test only on distributions with gnuradio 3.8
Change-Id: I05706496687bff2dc4e9a111d8ecd4f878b53c12
2021-05-03 07:14:00 +02:00
Vasil Velichkov 14ea82d227 Migrate grc blocks from xml to yaml
Convert the blocks using cmdline_converter.py script from
c861a840e3/cmdline_converter.py

Change-Id: Iee5c611a2e100bd2fdf487611a867dc937d8c292
2021-05-03 07:14:00 +02:00
Vasil Velichkov 1789ae28ee GNU Radio 3.8 support
https://wiki.gnuradio.org/index.php/GNU_Radio_3.8_OOT_Module_Porting_Guide

Change-Id: I23dd638c8c48ed0a4b50559ce33fbd5e60b7dcbc
2021-05-03 07:14:00 +02:00
Vasil Velichkov fa184a9447 Fix uplink sub_slot and sub_types assignment in the sdcch4 and bcch_ccch demappers blocks
Add support for RACH bursts although they are not yet supported in the
receiver and control channel decoder blocks.

3GPP TS 45.002 version 15.1.0 Release 15
Table 3 : Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5)
Figure 8a: TDMA frame mapping for FCCH + SCH + BCCH + CCCH

Fixes the following tests:
qa_gsm_bcch_ccch_demapper.test_uplink
qa_gsm_bcch_ccch_sdcch4_demapper.test_uplink

Change-Id: Ia6b3070c1085bcdda6d98fd94a89c6e0982e2aec
2019-07-29 21:12:24 +03:00
Vasil Velichkov c895bf2f22 Fix uplink sub_slot assignment in the sdcch8 demapper block
3GPP TS 45.002 version 15.1.0 Release 15
Table 4 : Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5)

Fixes qa_gsm_sdcch8_demapper.test_uplink test

Change-Id: I29e9055805c8478010c51ceb40f86ba3aed5ecab
2019-07-29 21:12:24 +03:00
Vasil Velichkov 4954ae6fbf Fix sub_slot assignment in the universal_ctrl_chans_demapper block
3GPP TS 45.002 version 15.1.0 Release 15
Table 3 : Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5)
Table 4 : Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5)

Fixes the following tests:
qa_gsm_bcch_ccch_sdcch4_demapper.test_downlink
qa_gsm_sdcch8_demapper.test_downlink

Change-Id: Idc63407694fd1f7be962ab630d4e8c13b4a5d348
2019-07-29 21:12:24 +03:00
Vasil Velichkov ff88ba41ec Add control channels demappers tests
3GPP TS 45.002 version 15.1.0 Release 15
Table 3 : Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5)
Table 4 : Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5)
Figure 8a: TDMA frame mapping for FCCH + SCH + BCCH + CCCH
Figure 8b: TDMA frame mapping for FCCH + SCH + BCCH + CCCH + SDCCH/4(0...3) + SACCH/4(0...3)

Five of the six tests currently fail and are marked with
@unittest.expectedFailure. Fixes in subsequent commits.

Change-Id: I33b0948832a0c2506bffd389cc134c3236c74d27
2019-07-29 21:09:07 +03:00
Vasil Velichkov 54580d148d Filter out SoapyAudio devices
When gr-osmosdr is compiled with SoapySDR support and SoapyAudio is
installed the audio device is picked as a first choice when detecting
devices but grgsm tools are not able to work with audio devices. So in
such cases the user has to always specify the correct SDR device in the
args parameter which is a bit inconvenient.

When args is not specified call osmosdr.device_find to get all devices
and filter out unspported ones like SoapyAudio devices. When args is
specifed just try to create osmosdr.source with whatever value has been
specified.

Add -l and --list-devices command line option that prints information
about all detected devices.

Example commands:
  grgsm_capture --list-devices
  grgsm_capture --list-devices --args=nofake
  grgsm_capture --args=uhd,type=b210 -a 111 capture.cfile
  grgsm_livemon --args=rtl
  grgsm_livemon --args=uhd,type=b210

Change-Id: Ib84081041ca6c2bc18b9da0c32bac9d3ecef65ca
2019-05-03 00:20:34 +03:00
Vasil Velichkov 61e42c849d grgsm_capture: Fix device arguments
We need a space between numchan=1 and the rest of the device arguments
otherwise when --args is specified it fails with RuntimeError: bad lexical cast

$ grgsm_capture --args=soapy

Traceback (most recent call last):
  File "/usr/local/bin/grgsm_capture", line 179, in <module>
    device_args=options.device_args)
  File "/usr/local/bin/grgsm_capture", line 57, in __init__
    osmosdr.source(args="numchan=1" + device_args )
  File "/usr/local/lib64/python2.7/site-packages/osmosdr/osmosdr_swig.py", line 1170, in make
    return _osmosdr_swig.source_make(*args, **kwargs)
RuntimeError: bad lexical cast: source type value could not be interpreted as target

Change-Id: I2d1bcee835b695c91a5c44ec78a40b2d969f611c
2019-05-02 11:55:39 +00:00
Vasil Velichkov 61a3ca6cb4 Improve the TCH/H decoder logs
- Change "6,90 kbit/s" to "5.9 kbit/s"
  A typo reported in github ptrkrysik/gr-gsm#456
- Comment out the "Error! frame_nr:" message as it turns out to confuse
  users more then it actually helps debugging.
- When voice-boundary detection is enabled write the name of decoded
  control channel messages

Change-Id: I697ef944f30c4cabb62c888317dd3a7f8dcd5611
2019-05-02 12:59:20 +02:00
Piotr Krysik aaac615715 Improve slightly interface of plotting so it's easier to use it
Change-Id: Ia70ab45a8beb81512a9f83e316ad2d2bc385ef19
2019-04-01 09:43:26 +02:00
Vasil Velichkov c5bb436cda Fix the TCH/H decoder and demapper XML definitions
- The second argument of tch_h_decoder constructor is a string that
  accepts the value of MultiRate configuration element and not an enum
  like the tch_f_decoder decoder.
- Make the demapper's burst sink required.
- Make all parameters visible.
- Rename the TCH/H Channel parameter to Sub-channel number.
- Add the qa_tch_h_decoder test in the CMakeLists.txt
- Fix several typos

Change-Id: I92d4f49955c634df7d76f17cfb58d7106846c1bd
2019-03-19 17:36:28 +02:00
Piotr Krysik 81ba56f59d Major simplification and some argument changes in grgsm_capture
grmgs_capture tried to do too many things for a simple recorder.
It was simplified by removing the receiver and ability to
save data to bursts files.

All other stuff that is not necessary for recording signal to disk was
also removed:
-setters/getters,
-storing of parameters that never will be changed.

The 'fc' parameter name was changed to 'freq' to follow GNU Radio
guidelines.

The 'shiftoff' parameter was removed.

'bb_gain' and 'if_gain' parameters were added.

Variables specific to some of SDR's like:
-gains at different stages,
-bandwidth (not all devices can set it),
-antennas (some devices have just one, some not),
were moved to separate options group.

What is left to be exposed is:
-dc_offset_mode,
-iq_balance_mode,
-gain_mode.

Change-Id: I092a43eaddb09a99c6cc05fde13f0ae94d9e0251
2019-03-01 17:03:15 +00:00
Vasil Velichkov 57431ed50c grgsm_livemon: Use the osr variable in all blocks
In the GSM input adaptor and GSM Receiver blocks the osr was hardcoded
to 4 and cannot be changed using the command line parameter.

Change-Id: I4e85b898f05db636f18fdea6e5fee4fed6e0382a
2019-02-25 23:43:00 +02:00
Vasil Velichkov 2f0c096e30 MacOS fixes
- Include grgsm/endian.h in tch_h_decoder_impl.cc
- Revert 0ed39fbf93 as linking with
  boost_thread is needed

Fixes GH-444

Change-Id: I00884962295082cff3eb64fa21e9f73437be0001
2019-02-05 14:28:37 +00:00
Vadim Yanitskiy ca25d141f5 apps/grgsm_trx: introduce initial LMS driver support
Change-Id: Ie983b10d1814906b6e659213f865e58d0f5c08e4
2019-01-26 10:58:25 +07:00
Vadim Yanitskiy a53dd193dc apps/grgsm_trx: add RadioInterface driver selection argument
Change-Id: Ic11f878c176bad16b057f25725ab0cfecc01782f
2019-01-22 16:44:30 +07:00
Vadim Yanitskiy b6f6f471d9 trx/radio_if.py: print type of RadioInterface
Change-Id: I6c1ba8546caec122cd1ea0ed87656f691abec068
2019-01-22 16:44:24 +07:00
Vadim Yanitskiy 3120ba7017 python/trx: fork RadioInterfaceUHD from RadioInterface
Change-Id: I1644a3f6b8da0d5f2a1a133058269e5383948fda
2019-01-22 16:43:48 +07:00
Vadim Yanitskiy 404842da11 trx/ctrl_if.py: use relative import for UDPLink
Change-Id: If4b00f6332461d3c37cde5a1f724906ca3d3a30f
2019-01-22 14:41:30 +07:00
Vadim Yanitskiy 5823a419e9 trx/radio_if.py: update clock_offset_control in set_rx_freq()
Change-Id: I065bf664f775099c90c123c9ff75f262a73bf1be
2019-01-19 11:29:35 +07:00
Vadim Yanitskiy 8bd9e15c66 trx/radio_if.py: do not print anything if freq. shift is 0
Change-Id: I100ce2ab8effc00e164e13253894445bdc816f06
2019-01-19 11:29:35 +07:00
Vadim Yanitskiy 180a037a41 python/trx: introduce and use Transceiver class
Change-Id: I6dc88edbb69a68746cc8e01206dc86f7ea2fa80f
2019-01-19 11:29:35 +07:00
Vadim Yanitskiy baebe451cd trx/ctrl_if_bb.py: reset transceiver on POWEROFF
Change-Id: I1e7f74c56388a431794a0b32b8a9537c360f5d33
2019-01-19 11:29:28 +07:00
Vadim Yanitskiy b7a272e3f0 trx/radio_if.py: introduce a new @property 'ready'
Change-Id: I513da0f45c6a608d15fbd0e8eafe14d6af8833d7
2019-01-19 10:24:31 +07:00
Vadim Yanitskiy 1fe28253b9 trx/radio_if.py: do not init both rx_freq and tx_freq
Change-Id: I9f251958ec90141d144fdb027aff20182131a1d1
2019-01-19 10:24:05 +07:00
Vadim Yanitskiy 7da82f458f python/trx: get rid of FakePM class
Change-Id: Ie96eb9735ecaa3329135c7be976ffd277a2f64f4
2019-01-19 09:32:36 +07:00
Vadim Yanitskiy 435d7557e8 apps/grgsm_trx: move init code from run() to __init__()
Change-Id: I1bcc9c8a2d37d156bbec93be3838200f6c4a80c2
2019-01-19 09:02:12 +07:00
Vadim Yanitskiy f237f1a978 python/trx: use CamelCase naming for basic classes
Change-Id: Ica9c56d01191dda38e63b51caba2ec8c63b671c9
2019-01-16 17:11:55 +07:00
Vadim Yanitskiy bd4daec11c trx/radio_if.py: use existing 'dict_toggle_sign' block
Change-Id: Ifa616644a858f493b9f8706663f9e7fed717f3d0
2019-01-16 17:11:55 +07:00
Vadim Yanitskiy a1a871ee37 python/trx: rename 'change_sign_of_dict_elements' to 'dict_toggle_sign'
The old name was quite long, resulting into cumbersome imports:

  from change_sign_of_dict_elements import change_sign_of_dict_elements

let's use a shorter variant:

  from dict_toggle_sign import dict_toggle_sign

Change-Id: Ie75e1d6e5e74c7c1cf34154633c1472e4b85dbb6
2019-01-16 17:11:55 +07:00
Vadim Yanitskiy ace92ae2c5 python/trx/__init__.py: cosmetic: add missing new line
Change-Id: I379b321866bd892a52b0c272ed50c670da380a17
2019-01-16 17:11:55 +07:00
Vasil Velichkov 06321a39e0 Improve voice boundary detection
Decode Alerting and Progress messages and if the in-band information
flag is set start decoding the voice
2018-12-29 00:52:05 +01:00
Vasil Velichkov 6ade8b8f19 Add TCH/H decoder tests 2018-12-29 00:52:05 +01:00
Vasil Velichkov 7f259fdb68 Add TCH/H decoder block with AMR multirate support
Add new TCHH channel mode
Add two new optional arguments

    -m CHAN_MODE, --mode=CHAN_MODE
                        Channel mode. Valid options are 'BCCH' (Non-combined
                        C0), 'BCCH_SDCCH4'(Combined C0), 'SDCCH8' (Stand-alone
                        control channel) 'TCHF' (Traffic Channel, Full rate),
                        'TCHH' (Traffic Channel, Half rate)

    --sub-channel=TCH_H_CHANNEL
                        TCH/H sub-channel. [default=0]
    --multi-rate=MULTI_RATE
                        The MultiRrate configuration element from the
                        Assigment Command message. Example: 28111a40. See 3GPP
                        TS 44.018 - 10.5.2.21aa MultiRate configuration

Example:
    grgsm_decode -m TCHH --sub-channel 0 --multi-rate 2811 -o voice.amr ...
2018-12-29 00:52:05 +01:00
Vasil Velichkov 0ccec373b3 Add tests for the TCH/F and TCH/H Demappers 2018-12-29 00:52:05 +01:00
Vasil Velichkov 1828a315a8 Move HR demapping into a separate block 2018-12-29 00:52:05 +01:00
Andrew Artyushok fbcee39107 Add HR demapping 2018-12-29 00:52:05 +01:00
Piotr Krysik 003c8720f5 transmitter/txtime_setter: fix error print syntax error 2018-12-28 22:36:40 +01:00
David Holm 17852163ad lib/trx, lib/transmitter: Include grgsm/endian.h
MacOS X does not have endian.h and the build will fail unless
grgsm/endian.h is used.
2018-12-28 18:55:12 +01:00
Vadim Yanitskiy dc342dc88a trx/txtime_setter: print error if reference fn is missing
Change-Id: I2a6e3f41b6fe79b92d85ff98bc2cd9afd9bdc568
2018-12-21 06:55:11 +07:00
Vadim Yanitskiy b73b4a8637 trx/txtime_setter: reduce code nesting in process_txtime_of_burst()
Change-Id: I5c334e16d6b28a5e32cd62a177ad56bfc8e748ee
2018-12-21 06:50:44 +07:00
Vadim Yanitskiy ed03e41494 apps/grgsm_trx: (re)structurize help message
Change-Id: I612d8ae7d3ff99fee809e10d95919989bfbe0f59
2018-09-21 14:52:53 +07:00
Piotr Krysik b8632ffdac apps/grgsm_trx: remove redundant unit from freq_offset variable name
Frequency is always in Hz so there is no need to add that
information in the variable name.

Change-Id: I509771c3fe072069a680f66b0763ae6825f6d529
2018-09-13 16:34:35 +00:00
Vasil Velichkov b775afd672 Add .gitreview similar to the other osmocom's projects
A gitreview file is required to use git review.
More information about git review
https://docs.openstack.org/infra/git-review/
https://www.mediawiki.org/wiki/Gerrit/git-review

Change-Id: Ie07446ba1a13e53c87bcc9b23e3b775803d158f4
2018-09-13 13:56:35 +00:00
Vasil Velichkov fa2f784f4f grgsm_channelize: Add ichar data type
This is the output format of rtl_sdr and hackrf_transfer and this would
allow direct channelization without an additional post processing.

Change-Id: Ia489eca9ec7defc3a83946c42f1ae3f136efe4e8
2018-09-13 13:05:35 +00:00
Piotr Krysik 0f3bceb13d apps/grgsm_trx: remove unnecessary checks of freq_offset
Checking if freq_offset is None doesn't make sense currently
as it's always set to a float value by argparse (to 0 by default).

Change-Id: Ie8bae1ccde60d07fc25e0b874afa5aaaac04d8a7
2018-09-13 14:53:26 +02:00
Piotr Krysik 0631767b24 trx/radio_if: add freq_offset parameter to constructor
Change-Id: Ie1db02b719a0fec478b8a8b8a95643fb10fdfce5
2018-09-13 14:41:06 +02:00
Vasil Velichkov 89585b374b burst_file_source: Fix reading longer bursts
- Read bursts with pmt::deserialize directly from the std::filebuf
- Remove the unused unserialized variable
- Add tests

Since df978693 when the rx_time tags are present in the incomming stream
the gsm receiver adds fm_time to the burst's PMT and the bursts that
burst file sink writes becomes longer because of the additional field.

The burst file source block was expecting all burst to be 147 bytes long
and reading files with longer bursts was failing with an unhandled exception.

terminate called after throwing an instance of 'pmt::exception'
thread[thread-per-block[5]: <block dummy_burst_filter (2)>]: pmt_cdr: wrong_type : #f
  what():  pmt::deserialize: malformed input stream, tag value = : 115

Change-Id: I989b0d6a6b214088b7880e5cbf7bb6725492dbfc
2018-09-13 09:35:28 +00:00
Piotr Krysik 7379e341b0 apps/grgsm_trx: migrate from getopt to argparse
Change-Id: I24a17b4cd44db0ce95a19d7470f4f09f3c85a26d
2018-09-12 00:37:40 +07:00
Piotr Krysik b3d5c5743b trx/radio_if.py: clarify magic numbers in sample rate calculation
Change-Id: I55f283113d0324a0236b7bbf13bce5718003b857
2018-09-12 00:37:29 +07:00
Vadim Yanitskiy 38baac9678 apps/grgsm_trx: fix inaccurate sample rate calculation
Change-Id: I0c309588fa0f7822abfb3919327639735db07679
2018-09-12 00:36:13 +07:00
Vasil Velichkov 75ae9cc361 Format the output into ostringstream and then write it at once.
This fixes the garbled output when multiple printers are used in a
flowgraph.

closes #255
closes #420

Change-Id: I1012ed26371b4c67163545652f0a1ce0f576af9e
2018-09-11 09:12:02 +00:00
Vasil Velichkov fb1f65c572 grgsm_scanner: Add --debug option
When set the stdout and stderr won't be redirected to /dev/null which
will facilitate resolving issues

Change-Id: I11e99facb5a1ab9c9bfee3c314a91a74f98a2523
2018-09-11 08:13:23 +00:00
Piotr Krysik 1cc264fb0c Revert "grgsm_trx: Migrated argument parsing to argparse" that shouldn't be pushed
This reverts commit c62a3d9f55.
2018-09-06 19:57:57 +02:00
Piotr Krysik c62a3d9f55 grgsm_trx: Migrated argument parsing to argparse
Argparse makes adding new parameters easier and
adds consistent way of handling default values of
parameters and printing of their help info.

Change-Id: Idf99fd7a581464aa2f77fe01e721dbd162686811
2018-09-05 21:36:34 +02:00
Vadim Yanitskiy 97dc84e9f3 apps/grgsm_trx: add baseband frequency shift feature
An ability to shift the baseband frequency would allow one to
run both base stations and (OsmocomBB-based) mobile stations on
any frequency (e.g. in 2.4 GHz WiFi band)!

This is achieved by adding a given frequency offset to the
result of "ARFCN -> RX/TX frequency" calculation.

Usage example:

  grgsm_trx --freq-offset -500M

Both RX (Downlink) and TX (Uplink) frequencies will be shifted
by 500 MHz back, e.g. tuning request to ARFCN 105 would result
in tuning the radio to 456.0 MHz (instead of 956.0 MHz).

Related: OS#3520 (https://osmocom.org/versions/136)
Change-Id: I42e397e47402a87f4141ef31b25eff4c8c1267e2
2018-09-05 02:36:08 +07:00
Piotr Krysik 840885fe3c Changed submodule URLs to point to osmocom servers 2018-08-31 12:22:33 +02:00
Piotr Krysik 592ec9b785 Increasing version number
in order to correct wrongs of previous attempt

Change-Id: Ie067b48a9c67a13e928598ec722a7e27c464de8f
2018-08-12 20:13:50 +02:00
Piotr Krysik d30d0c23e3 New gr-gsm version
Change-Id: I72eafebe892692ad0db5ad149e14f2c59b41d3d2
2018-08-10 21:13:59 +02:00
Vadim Yanitskiy 2adbee48bf apps/grgsm_trx: print bind / remote address and port
Change-Id: If750d476f3972f1ab5c5b637438d14d40b1e3d87
2018-08-10 16:38:59 +07:00
Vadim Yanitskiy 473b35be86 apps/grgsm_trx: introduce bind address option
The new option (-b --bind-addr) allows one to specify the bind
address for both DATA and CTRL interfaces. By default, '0.0.0.0'
is used, so there are no restrictions for the L1 source address.

Change-Id: I3339f686b53db07cfd1bff9a516f4bdc28058cd9
2018-08-10 16:38:59 +07:00
Vadim Yanitskiy 5394c6012d gsm_trx_burst_if: allow to customize the bind address
Pleviously remote address for DATA interface was also used as the
bind address, what is definitely wrong. Let's change the API a bit
in order to allow one to specify a custom bind address.

Change-Id: I6e5f7b7119ac454217b8dd04f9ee0dd3b23972b6
2018-08-10 16:38:59 +07:00
Vadim Yanitskiy 0e246372bc trx/ctrl_if.py: send control responses to where commands are from
When we receive a control command, we should not simply send the
response to the default destination, but send it back to the exact
IP/prt from which the command originated.

This ensures correct routing of responses even in case multiple
programs are interfacing concurrently with a control socket.

Cherry-picked from: I24a0bba6eed059b101af95dac7d059f34dd715fc
Change-Id: I1f304ea887dc957d3ad53adb1e3c56ab27d8f196
2018-08-10 16:38:59 +07:00
Vadim Yanitskiy b085a2c854 trx/udp_link.py: set SO_REUSEADDR socket option
Setting this option allows one to reuse existing connections,
for example, by injecting CTRL commands or DATA bursts
into existing connections.

Cherry-picked from: I0882c76affa9a668a12d10967081054d2b666ed1
Change-Id: I6d256683a7aa0419cd5bd0a3eaa97aefdf3254f9
2018-08-10 16:38:59 +07:00
Vadim Yanitskiy bf6f6ec0de trx/udp_link.py: close socket in destructor
Previously it was required to call the UDPLink.shutdown() method
manually in order to close a socket. Let's do it automatically
using the destructor of UDPLink.

Cherry-picked from: I59c3dc61ec58cd9effeb789947d28fd602ca91f4
Change-Id: Ief7aa21d1e50682a90616833b679741957193aae
2018-08-10 16:38:59 +07:00
Vadim Yanitskiy 8e1fa8bdd7 apps/grgsm_trx: use format string for help message
Instead of using the hard-coded default values in help message,
it makes sense to use a format string, and pass the actual
values when printing help.

Change-Id: Ib1bf0ef3ded86aa92faeb9b63eb286283f5c8c3d
2018-08-10 16:38:59 +07:00
Vadim Yanitskiy 4fdb08fd20 trx/radio_if.py: drop useless import of osmosdr
Change-Id: Iacd5ca118957e3ecf05df81f511b17bb9a8982b5
2018-08-10 16:38:59 +07:00
Vadim Yanitskiy 0017a35aab trx/radio_if.py: reset UHD device time at startup
Some UHD devices, such as UmTRX, require one to manually reset the
hardware clock, otherwise the burst transmission doesn't work.

Change-Id: Idddc1387199bd22342ec5af25c8635e73352e315
2018-08-10 16:38:53 +07:00
Vadim Yanitskiy cae78211a6 grgsm_trx: change default TRX port number to 6700
In order to avoid clashes with OsmoTRX, which may be also
running on the same host, let's use a different port range
starting from 6700 by default.

This idea was introduced as a result of OS#2984.

Change-Id: Iaf0c78733bfefcb0b0938abf6d316e27d03ecab4
2018-08-10 15:11:23 +07:00
Vadim Yanitskiy 3674f48df5 apps/grgsm_trx: also print Piotr as a copyright holder
Despite the most part of Python code was written by Vadim, it's
heavily based on huge and impressive work done by Piotr. Let's
also print his credentials in the license header.

Change-Id: Icca7c679d84f99440ff502219f624e0f73112744
2018-08-10 15:11:23 +07:00
Piotr Krysik 332e2be78f tests: Fix Debian and Kali dockerfiles
Change-Id: I61d37cb6882a8ca7bbfc97412c52e745a2e5ec7c
2018-07-28 13:25:00 +02:00
Piotr Krysik e4010dbef0 Keep the old mailing list for now
but change wiki address and installation description
addres to the new (osmocom) ones.
2018-07-12 10:46:39 +02:00
Harald Welte 99997ff535 README.md: Turn URLs into hyperlinks (video, mailing list)
Change-Id: Iacf7c4b13b0e32ea7761b859f7422ab630c8616f
2018-07-12 10:24:20 +02:00
Harald Welte 8bb1b79a33 README.md: Change mailing list address to osmocom.org
Change-Id: Ie7b474138444f0ceea160f74df4b693030ea07a8
2018-07-12 10:24:20 +02:00
Piotr Krysik ac140210c9 Simplify cmake checks related to libosmocore 2018-06-19 12:07:28 +02:00
Vasil Velichkov e153e729cd Run tests with CTEST_OUTPUT_ON_FAILURE=1 2018-06-19 09:00:12 +02:00
Vasil Velichkov f1b6c6bc2a Add LOCAL_OSMOCOM cmake option
When set the gr-gsm will be compiled and linked with the local copies of
the osmocom libraries.
2018-06-19 09:00:03 +02:00
Piotr Krysik f00936d60d Placing grcc compilation utils in separate files
Avoiding increasing required cmake version with use of wrapper shell script.
2018-06-18 15:13:25 +02:00
Piotr Krysik c711e97af1 Separating libosmogsm from the rest 2018-06-18 15:13:13 +02:00
Vasil Velichkov 9b5519db84 Check that pkg-config is available
It is needed to properly detect the grcc full path
See also 3f6ab15a7a
2018-06-18 15:11:17 +02:00
Vasil Velichkov 8c4eefb205 Add DEBIAN_FRONTEND=noninteractive 2018-06-18 15:11:17 +02:00
Vasil Velichkov 487bf4764e Fix the parallel build with cmake 3.11
Copy UseSWIG.cmake from the gnuradio repository from commit
4433a7703fe3f5713c2200a0f7c11b13510f34cc

This macro is distributed in the Debian's gnuradio-dev package but it's
not available in Fedora/Centos gnuradio-devel package. The gnuradio's
version contains a fix for the parallel build 99a09af05fda6d0bab0cf3724a1c6bf453c71bc7
and some other improvements as well.
2018-06-18 15:11:17 +02:00
Vasil Velichkov 8f4b5ba372 Add CentOS7 docker container 2018-06-18 15:11:17 +02:00
Vasil Velichkov 014ed2be5c Add cmake options that enable/disable grcc compilation
To disable compilation of both grgsm_livemon and grgsm_livemon_headless
execute

  cmake -DENABLE_GRCC=OFF ..

To disable only one execute

  cmake -DENABLE_GRGSM_LIVEMON=OFF ..
  cmake -DENABLE_GRGSM_LIVEMON_HEADLESS=OFF ..
2018-06-18 15:11:17 +02:00
Piotr Krysik 47c3e9bf43 Changing tabs to spaces 2018-06-04 09:11:59 +02:00
Piotr Krysik 1e7241464a Disabling installation of desktop files
Installation of dekstop files is causing problems with packaging - github issue #335.
Disabling it then.
2018-06-04 09:11:47 +02:00
Piotr Krysik ea44d98558 Commenting out a line causeing crash on HackRF 2018-06-02 12:27:58 +02:00
Piotr Krysik 2779e62094 Fix includes after moving trx_burst_if 2018-05-06 22:23:06 +02:00
Piotr Krysik 69434963d9 Added short description of grgsm_trx 2018-05-05 13:06:22 +02:00
Piotr Krysik ea7a66cb86 Updated e-mail addresses of Vadim and Vasil 2018-05-05 13:06:02 +02:00
Piotr Krysik 650a436a8d Fix burst_to_fn_time name in gsm_burst_to_fn_time.xml 2018-05-05 12:40:14 +02:00
Piotr Krysik 993055342d Moving trx burst interface to trx directory
and to new 'Transceiver' cathegory in gnuradio-companion
2018-05-05 12:38:11 +02:00
Piotr Krysik 3c1452f94f Fix gsm_msg_to_tag block record in grc/gsm_block_tree.xml
so it appear in gnuradio-companion
2018-05-05 12:24:33 +02:00
353 changed files with 9275 additions and 29400 deletions

2
.dockerignore Normal file
View File

@ -0,0 +1,2 @@
build*
.git

4
.gitmodules vendored
View File

@ -1,6 +1,6 @@
[submodule "test_data"]
path = test_data
url = https://github.com/ptrkrysik/test_data.git
url = https://git.osmocom.org/ptrkrysik/test_data
[submodule "examples"]
path = examples
url = https://github.com/ptrkrysik/examples.git
url = https://git.osmocom.org/ptrkrysik/examples

3
.gitreview Normal file
View File

@ -0,0 +1,3 @@
[gerrit]
host=gerrit.osmocom.org
project=gr-gsm

View File

@ -1,14 +1,11 @@
sudo: required
dist: bionic
language: ruby
env:
- DOCKERFILE=tests/dockerfiles/Debian_testing.docker IMGNAME=debtest-grgsm
- DOCKERFILE=tests/dockerfiles/Ubuntu_16_04.docker IMGNAME=ubu16.04-grgsm
- DOCKERFILE=tests/dockerfiles/Ubuntu_16_04_nolibosmo.docker IMGNAME=ubu16.04-grgsm-nolibosmo
- DOCKERFILE=tests/dockerfiles/Kali.docker IMGNAME=kali-grgsm
- DOCKERFILE=tests/dockerfiles/Fedora_26.Dockerfile IMGNAME=fedora26-grgsm
- DOCKERFILE=tests/dockerfiles/Ubuntu_20_04.docker IMGNAME=ubuntu_20_04
- DOCKERFILE=tests/dockerfiles/Debian_testing.docker IMGNAME=debian_testing
services:
- docker
@ -17,6 +14,6 @@ before_install:
- cat $DOCKERFILE > Dockerfile ; docker build -t $IMGNAME .
script:
# - docker run -it --rm $IMGNAME sh -c 'cd /src/build;make test'
- docker run -it --rm $IMGNAME sh -c 'cd /src/build;make test'
- docker run -it --rm $IMGNAME /src/tests/scripts/decode.sh
- docker run -it --rm $IMGNAME /src/tests/scripts/decrypt.sh

View File

@ -1,6 +1,7 @@
# Copyright 2011,2012 Free Software Foundation, Inc.
# Copyright 2011,2012,2014,2016,2018 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -17,214 +18,131 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.8)
project(gr-gsm CXX C)
enable_testing()
#set(CMAKE_BUILD_TYPE "Debug")
#select the release build type by default to get optimization flags
# Install to PyBOMBS target prefix if defined
if(DEFINED ENV{PYBOMBS_PREFIX})
set(CMAKE_INSTALL_PREFIX $ENV{PYBOMBS_PREFIX})
message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}")
endif()
# Select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
message(STATUS "Build type not specified: defaulting to release.")
endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
########################################################################
# Set cmake policies.
########################################################################
# This will suppress developer warnings during the cmake process that can occur
# if a newer cmake version than the minimum is used.
if(POLICY CMP0026)
cmake_policy(SET CMP0026 OLD)
endif()
if(POLICY CMP0043)
cmake_policy(SET CMP0043 OLD)
endif()
if(POLICY CMP0045)
cmake_policy(SET CMP0045 OLD)
endif()
if(POLICY CMP0046)
cmake_policy(SET CMP0046 OLD)
endif()
########################################################################
# Set version variables (
########################################################################
# Make sure our local CMake Modules path comes first
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
# Set the version information here
set(VERSION_INFO_MAJOR_VERSION 0)
set(VERSION_INFO_API_COMPAT 41)
set(VERSION_INFO_MINOR_VERSION 4)
set(VERSION_INFO_MAINT_VERSION git)
include(GrVersion) #setup version info
set(VERSION_MAJOR 1)
set(VERSION_API 0)
set(VERSION_ABI 0)
set(VERSION_PATCH git)
cmake_policy(SET CMP0011 NEW)
# Enable generation of compile_commands.json for code completion engines
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
########################################################################
# Compiler specific setup
########################################################################
if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
AND NOT WIN32)
#http://gcc.gnu.org/wiki/Visibility
add_definitions(-fvisibility=hidden)
endif()
########################################################################
# Find boost
########################################################################
if(UNIX AND EXISTS "/usr/lib64")
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix
endif(UNIX AND EXISTS "/usr/lib64")
set(Boost_ADDITIONAL_VERSIONS
"1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39"
"1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44"
"1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49"
"1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54"
"1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
"1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
"1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
)
find_package(Boost "1.35" COMPONENTS filesystem system)# thread)
if(NOT Boost_FOUND)
message(FATAL_ERROR "Boost required to compile gr-gsm")
endif()
find_package(SWIG)
if(SWIG_FOUND)
# Minimum SWIG version required is 1.3.31
set(SWIG_VERSION_CHECK FALSE)
if("${SWIG_VERSION}" VERSION_GREATER "1.3.30")
set(SWIG_VERSION_CHECK TRUE)
endif()
else()
message(FATAL_ERROR "SWIG required to compile gr-gsm")
endif(SWIG_FOUND)
IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_CXX_STANDARD 11)
ELSE()
message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID MATCHES "Clang")
SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_C_STANDARD 11)
ELSE()
message(WARNING "C standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()
########################################################################
# Install directories
########################################################################
find_package(Gnuradio "3.8" REQUIRED COMPONENTS blocks filter fft CONFIG)
include(GrVersion)
include(GrPlatform) #define LIB_SUFFIX
set(GR_RUNTIME_DIR bin)
set(GR_LIBRARY_DIR lib${LIB_SUFFIX})
if(NOT CMAKE_MODULES_DIR)
set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake)
endif(NOT CMAKE_MODULES_DIR)
set(GR_INCLUDE_DIR include/grgsm)
set(GR_INCLUDE_DIR include/grgsm/misc_utils)
set(GR_INCLUDE_DIR include/grgsm/receiver)
set(GR_INCLUDE_DIR include/grgsm/demapping)
set(GR_INCLUDE_DIR include/grgsm/decoding)
set(GR_DATA_DIR share)
set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/gsm)
set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME})
set(GR_DOC_DIR ${GR_DATA_DIR}/doc)
set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME})
set(GR_CONF_DIR etc)
set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d)
set(GR_LIBEXEC_DIR libexec)
set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME})
set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
########################################################################
# Find gnuradio build dependencies
########################################################################
set(GR_REQUIRED_COMPONENTS RUNTIME FILTER PMT)
find_package(Gnuradio)
find_package(Volk)
find_package(CppUnit)
#find_package(Doxygen)
find_package(Libosmocore)
find_package(Libosmocodec)
find_package(Libosmocoding)
if(NOT GNURADIO_RUNTIME_FOUND)
message(FATAL_ERROR "GnuRadio Runtime required to compile gr-gsm")
endif()
if(NOT VOLK_FOUND)
message(FATAL_ERROR "Volk library required to compile gr-gsm")
endif()
if(NOT CPPUNIT_FOUND)
message(FATAL_ERROR "CppUnit required to compile gr-gsm")
endif()
if(NOT LIBOSMOCORE_FOUND OR NOT LIBOSMOCODEC_FOUND)
message(STATUS "Compiling local version of libosmocore")
elseif(NOT LIBOSMOCODING_FOUND)
message(STATUS "Compiling local version of libosmocoding")
endif()
########################################################################
# Setup doxygen option
########################################################################
#if(DOXYGEN_FOUND)
# option(ENABLE_DOXYGEN "Build docs using Doxygen" ON)
#else(DOXYGEN_FOUND)
option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) #TODO: write doxygen docs
#endif(DOXYGEN_FOUND)
########################################################################
# Setup the include and linker paths
########################################################################
list (APPEND grgsm_include_directories
${CMAKE_SOURCE_DIR}/lib
${CMAKE_SOURCE_DIR}/include
${CMAKE_BINARY_DIR}/lib
${CMAKE_BINARY_DIR}/include
${Boost_INCLUDE_DIRS}
${CPPUNIT_INCLUDE_DIRS}
${GNURADIO_ALL_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/lib/decoding
)
if(LIBOSMOCORE_FOUND)
list (APPEND grgsm_include_directories
${LIBOSMOCORE_INCLUDE_DIR}
)
endif()
include_directories(
${grgsm_include_directories}
)
list (APPEND grgsm_link_directories
${Boost_LIBRARY_DIRS}
${CPPUNIT_LIBRARY_DIRS}
${GNURADIO_ALL_LIBRARY_DIRS}
)
if(LIBOSMOCORE_FOUND)
list (APPEND grgsm_link_directories
${LIBOSMOCORE_LIBRARY_DIRS}
)
endif()
link_directories(
${grgsm_link_directories}
)
# Set component parameters
set(GR_GSM_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "" FORCE)
set(GR_GSM_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig CACHE INTERNAL "" FORCE)
########################################################################
# On Apple only, set install name and use rpath correctly, if not already set
########################################################################
if(APPLE)
if(NOT CMAKE_INSTALL_NAME_DIR)
set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE PATH "Library Install Name Destination Directory" FORCE)
set(CMAKE_INSTALL_NAME_DIR
${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
PATH "Library Install Name Destination Directory" FORCE)
endif(NOT CMAKE_INSTALL_NAME_DIR)
if(NOT CMAKE_INSTALL_RPATH)
set(cmakE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE PATH "Library Install RPath" FORCE)
set(CMAKE_INSTALL_RPATH
${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
PATH "Library Install RPath" FORCE)
endif(NOT CMAKE_INSTALL_RPATH)
if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "Do Build Using Library Install RPath" FORCE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE
BOOL "Do Build Using Library Install RPath" FORCE)
endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
endif(APPLE)
########################################################################
# Find gnuradio build dependencies
########################################################################
find_package(Doxygen)
########################################################################
# Find osmocom build dependencies
########################################################################
find_package(Libosmocore)
find_package(Libosmocodec)
find_package(Libosmocoding)
find_package(Libosmogsm)
########################################################################
# Setup doxygen option
########################################################################
if(DOXYGEN_FOUND)
option(ENABLE_DOXYGEN "Build docs using Doxygen" ON)
else(DOXYGEN_FOUND)
option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF)
endif(DOXYGEN_FOUND)
########################################################################
# Create uninstall target
########################################################################
@ -235,28 +153,26 @@ configure_file(
add_custom_target(uninstall
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)
)
########################################################################
# Add subdirectories
########################################################################
add_subdirectory(include/grgsm)
add_subdirectory(lib)
add_subdirectory(apps)
add_subdirectory(docs)
add_subdirectory(swig)
add_subdirectory(python)
add_subdirectory(grc)
add_subdirectory(apps)
add_subdirectory(docs)
########################################################################
# Install cmake search helper for this library
########################################################################
install(FILES cmake/Modules/gr-gsmConfig.cmake
DESTINATION lib${LIB_SUFFIX}/cmake/grgsm
)
########################################################################
# Print summary
########################################################################
message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Building for version: ${VERSION} / ${LIBVER}")
install(
FILES
cmake/Modules/gr-gsmConfig.cmake
DESTINATION ${CMAKE_MODULES_DIR}/grgsm
)

View File

@ -6,7 +6,7 @@ The aim is to provide set of tools for receiving information transmitted by GSM
Installation and usage
======================
Please see project's wiki https://github.com/ptrkrysik/gr-gsm/wiki for information on [installation](https://github.com/ptrkrysik/gr-gsm/wiki/Installation) and [usage](https://github.com/ptrkrysik/gr-gsm/wiki/Usage) of gr-gsm.
Please see project's [wiki](https://osmocom.org/projects/gr-gsm/wiki/index) for information on [installation](https://osmocom.org/projects/gr-gsm/wiki/Installation) and [usage](https://github.com/ptrkrysik/gr-gsm/wiki/Usage) of gr-gsm.
Mailing list
============
@ -20,9 +20,9 @@ Mailing list is a place for general discussions, questions about the usage and i
- version of gnuradio (it can be obtained with: gnuradio-companion --version)
- error messages (in case of pybombs installation they can be obtained after switching it to verbous mode with -v option).
To join the group with any e-mail addres (google account is not required) use this link:
To join the group with any e-mail address, use this link:
https://groups.google.com/forum/#!forum/gr-gsm/join
<https://groups.google.com/forum/#!forum/gr-gsm/join>
Development
===========
@ -34,7 +34,7 @@ Videos
======
Short presentation of *Airprobe*'like application of *gr-gsm*:
https://www.youtube.com/watch?v=Eofnb7zr8QE
<https://www.youtube.com/watch?v=Eofnb7zr8QE>
Credits
=======
@ -42,9 +42,9 @@ Credits
*Roman Khassraf* \<rkhassraf (at) gmail.com\> - blocks for demultiplexing and decoding of voice channels, decryption block supporting all ciphers used in GSM, blocks for storing and reading GSM bursts, project planning and user support
*Vadim Yanitskiy* - control and data interface for the transceiver, grgsm_trx application
*Vadim Yanitskiy* \<axilirator (at) gmail.com\> - control and data interface for the transceiver, grgsm_trx application
*Vasil Velichkov* - automatic compilation of grc applications, fixes and user support
*Vasil Velichkov* \<vvvelichkov (at) gmail.com\> - automatic compilation of grc applications, fixes and user support
*Pieter Robyns* \<pieter.robyns (at) uhasselt.be\> - block reversing channel hopping

View File

@ -1,6 +1,7 @@
# Copyright 2011 Free Software Foundation, Inc.
# Copyright 2011,2012,2014,2016,2018 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -18,65 +19,28 @@
# Boston, MA 02110-1301, USA.
include(GrPython)
include(GrccCompile)
add_subdirectory(helpers)
add_subdirectory(apps_data)
SET(PYTHONPATH
${CMAKE_SOURCE_DIR}/python
${CMAKE_SOURCE_DIR}/python/misc_utils
${CMAKE_SOURCE_DIR}/python/demapping
${CMAKE_SOURCE_DIR}/python/receiver
${CMAKE_SOURCE_DIR}/python/transmitter
${CMAKE_SOURCE_DIR}/python/trx
${CMAKE_BINARY_DIR}/swig
$ENV{PYTHONPATH}
)
string(REPLACE ";" ":" PYTHONPATH "${PYTHONPATH}")
GRCC_COMPILE(grgsm_livemon)
GRCC_COMPILE(grgsm_livemon_headless)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/grgsm_livemon
COMMAND "${CMAKE_COMMAND}"
-E env PYTHONPATH="${PYTHONPATH}" GRC_BLOCKS_PATH=${CMAKE_SOURCE_DIR}/grc
${PC_GNURADIO_RUNTIME_PREFIX}/${GR_RUNTIME_DIR}/grcc -d ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/grgsm_livemon.grc
COMMAND "${CMAKE_COMMAND}" -E rename grgsm_livemon.py grgsm_livemon
DEPENDS grgsm_livemon.grc
)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/grgsm_livemon_headless
COMMAND "${CMAKE_COMMAND}"
-E env PYTHONPATH="${PYTHONPATH}" GRC_BLOCKS_PATH=${CMAKE_SOURCE_DIR}/grc
${PC_GNURADIO_RUNTIME_PREFIX}/${GR_RUNTIME_DIR}/grcc -d ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/grgsm_livemon_headless.grc
COMMAND "${CMAKE_COMMAND}" -E rename grgsm_livemon_headless.py grgsm_livemon_headless
DEPENDS grgsm_livemon_headless.grc
)
set(grgsm_flowgraphs "")
OPTION(ENABLE_GRCC "Compile the flowgraphs with grcc" ON)
OPTION(ENABLE_GRGSM_LIVEMON "Compile grgsm_livemon" ON)
OPTION(ENABLE_GRGSM_LIVEMON_HEADLESS "Compile grgsm_livemon_headless" ON)
########################################################################
# Override the GR_UNIQUE_TARGET function to not append a hash
# to the `target` name, because we need a known name in order
# to add an explicit dependency that's needed for the parallel build
#
# The original code segment (taken from GrPython.cmake) is
#
# execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
#unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
#print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
# OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
#
########################################################################
function(GR_UNIQUE_TARGET desc)
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
print(re.sub('\\W', '_', '${desc} ${reldir}'))"
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_target(${_target} ALL DEPENDS ${ARGN})
endfunction(GR_UNIQUE_TARGET)
if(ENABLE_GRC AND ENABLE_GRCC AND ENABLE_GRGSM_LIVEMON)
list (APPEND grgsm_flowgraphs ${CMAKE_CURRENT_BINARY_DIR}/grgsm_livemon)
endif()
if(ENABLE_GRC AND ENABLE_GRCC AND ENABLE_GRGSM_LIVEMON_HEADLESS)
list (APPEND grgsm_flowgraphs ${CMAKE_CURRENT_BINARY_DIR}/grgsm_livemon_headless)
endif()
GR_PYTHON_INSTALL(
PROGRAMS
${CMAKE_CURRENT_BINARY_DIR}/grgsm_livemon
${CMAKE_CURRENT_BINARY_DIR}/grgsm_livemon_headless
${grgsm_flowgraphs}
grgsm_scanner
grgsm_decode
grgsm_trx
@ -85,10 +49,5 @@ GR_PYTHON_INSTALL(
# The add_dependencies(...) is very important for the parallel build `make -j $(nproc)`
# The `pygen_apps` target is generated in GR_PYTHON_INSTALL function which calls
# GR_UNIQUE_TARGET that we redefine above.
add_dependencies(pygen_apps _grgsm_swig)
install(
PROGRAMS
DESTINATION bin
)
# GR_UNIQUE_TARGET that we redefine in GrccCompile.
add_dependencies(pygen_apps grgsm_swig)

View File

@ -31,3 +31,6 @@ There are following helper programs for grgsm_decode program:
After these changes are done, build the
grgsm_livemon_headless python code using the grcc
compiler.
* grgsm_trx - a transceiver that together with Osmocom-BB (throught trxcon application)
forms a GSM mobile station. Currently it works on non-hopping channels only.

View File

@ -35,7 +35,9 @@ if(UNIX AND HAVE_XDG_UTILS)
${CMAKE_CURRENT_BINARY_DIR}/grgsm_setup_freedesktop
@ONLY)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/grgsm_setup_freedesktop
DESTINATION ${GR_PKG_LIBEXEC_DIR} COMPONENT "gr-gsm"
PROGRAMS
${CMAKE_CURRENT_BINARY_DIR}/grgsm_setup_freedesktop
DESTINATION ${GR_PKG_LIBEXEC_DIR}
COMPONENT "gr-gsm"
)
endif(UNIX AND HAVE_XDG_UTILS)

View File

@ -30,6 +30,7 @@ import collections
import grgsm
import pmt
import socket
import sys
class grgsm_decoder(gr.top_block):
@ -40,6 +41,8 @@ class grgsm_decoder(gr.top_block):
a5=1, a5_kc=None,
speech_file=None, speech_codec=None,
enable_voice_boundary_detection=False,
tch_h_channel=0,
multi_rate=0,
verbose=False,
print_bursts=False, ppm=0):
@ -100,11 +103,16 @@ class grgsm_decoder(gr.top_block):
self.tch_f_decoder = grgsm.tch_f_decoder(speech_codec, enable_voice_boundary_detection)
self.tch_f_pdu_to_tagged_stream = blocks.pdu_to_tagged_stream(blocks.byte_t, "packet_len")
self.tch_f_file_sink = blocks.file_sink(gr.sizeof_char*1, speech_file, False)
elif self.chan_mode == 'TCHH':
self.tch_h_demapper = grgsm.tch_h_chans_demapper(self.timeslot, tch_h_channel)
self.tch_h_decoder = grgsm.tch_h_decoder(tch_h_channel, multi_rate, enable_voice_boundary_detection)
self.tch_f_pdu_to_tagged_stream = blocks.pdu_to_tagged_stream(blocks.byte_t, "packet_len")
self.tch_f_file_sink = blocks.file_sink(gr.sizeof_char*1, speech_file, False)
if self.kc != [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]:
self.decryption = grgsm.decryption(self.kc, self.a5)
self.cch_decoder_decrypted = grgsm.control_channels_decoder()
if self.chan_mode == 'TCHF':
if self.chan_mode in ('TCHF', 'TCHH'):
self.decryption_tch_sacch = grgsm.decryption(self.kc, self.a5)
self.cch_decoder = grgsm.control_channels_decoder()
@ -209,12 +217,32 @@ class grgsm_decoder(gr.top_block):
if self.verbose:
self.msg_connect(self.tch_f_decoder, "msgs", self.message_printer, "msgs")
self.msg_connect(self.cch_decoder, "msgs", self.message_printer, "msgs")
elif self.chan_mode == 'TCHH':
self.msg_connect(self.timeslot_filter, "out", self.tch_h_demapper, "bursts")
if self.kc != [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]:
self.msg_connect(self.tch_h_demapper, "acch_bursts", self.decryption_tch_sacch, "bursts")
self.msg_connect(self.tch_h_demapper, "tch_bursts", self.decryption, "bursts")
self.msg_connect(self.decryption_tch_sacch, "bursts", self.cch_decoder, "bursts")
self.msg_connect(self.decryption, "bursts", self.tch_h_decoder, "bursts")
else:
self.msg_connect(self.tch_h_demapper, "acch_bursts", self.cch_decoder, "bursts")
self.msg_connect(self.tch_h_demapper, "tch_bursts", self.tch_h_decoder, "bursts")
self.msg_connect(self.tch_h_decoder, "msgs", self.socket_pdu, "pdus")
self.msg_connect(self.cch_decoder, "msgs", self.socket_pdu, "pdus")
self.msg_connect(self.tch_h_decoder, "voice", self.tch_f_pdu_to_tagged_stream, "pdus")
self.connect((self.tch_f_pdu_to_tagged_stream, 0), (self.tch_f_file_sink, 0))
if self.verbose:
self.msg_connect(self.tch_h_decoder, "msgs", self.message_printer, "msgs")
self.msg_connect(self.cch_decoder, "msgs", self.message_printer, "msgs")
if __name__ == '__main__':
# List of channel configurations
channel_modes = ['BCCH', 'BCCH_SDCCH4', 'SDCCH8', 'TCHF']
channel_modes = ['BCCH', 'BCCH_SDCCH4', 'SDCCH8', 'TCHF', 'TCHH']
# mapping options to grgsm's enums
tch_codecs = collections.OrderedDict([
@ -265,7 +293,7 @@ if __name__ == '__main__':
type='choice', choices=channel_modes,
help="Channel mode. Valid options are 'BCCH' (Non-combined C0), "
"'BCCH_SDCCH4'(Combined C0), 'SDCCH8' (Stand-alone control channel) "
"and 'TCHF' (Traffic Channel, Full rate) ")
"'TCHF' (Traffic Channel, Full rate), 'TCHH' (Traffic Channel, Half rate) ")
parser.add_option("-t", "--timeslot", dest="timeslot", type="intx", default=0,
help="Timeslot to decode [default=%default]")
parser.add_option("-u", "--subslot", dest="subslot", type="intx",
@ -309,11 +337,16 @@ if __name__ == '__main__':
parser, 'TCH Options', 'Options for setting Traffic channel decoding parameters.',
)
tch_options.add_option("-d", "--speech-codec", dest="speech_codec", default='FR',
type='choice', choices=tch_codecs.keys(),
type='choice', choices=list(tch_codecs.keys()),
help="TCH-F speech codec [default=%default]. "
"Valid options are " + ", ".join(tch_codecs.keys()))
tch_options.add_option("-o", "--output-tch", dest="speech_output_file", default="/tmp/speech.au.gsm",
help="TCH/F speech output file [default=%default].")
help="tch/f speech output file [default=%default].")
tch_options.add_option("--sub-channel", dest="tch_h_channel", default="0", type='intx',
help="TCH/H sub-channel. [default=0]")
tch_options.add_option("--multi-rate", dest="multi_rate", default="", type='string',
help="The MultiRate configuration element from the Assignment Command message. "
"Example: 28111a40. See 3GPP TS 44.018 - 10.5.2.21aa MultiRate configuration")
tch_options.add_option("--voice-boundary", dest="enable_voice_boundary_detection", action="store_true", default=False,
help="Enable voice boundary detection for traffic channels. This can help reduce noice in the output.")
parser.add_option_group(tch_options)
@ -336,7 +369,7 @@ if __name__ == '__main__':
parser.error("Invalid A5 version\n")
if options.cfile and (options.fc is None and options.arfcn is None):
print("You haven't provided a frequency or an ARFCN - working without automatic frequency offset correction.\n")
sys.stderr.write("You haven't provided a frequency or an ARFCN - working without automatic frequency offset correction.\n")
# handle frequency / arfcn input
arfcn = None
@ -358,6 +391,8 @@ if __name__ == '__main__':
a5=options.a5, a5_kc=kc,
speech_file=options.speech_output_file, speech_codec=tch_codecs.get(options.speech_codec),
enable_voice_boundary_detection=options.enable_voice_boundary_detection,
tch_h_channel=options.tch_h_channel,
multi_rate=options.multi_rate,
verbose=options.verbose,
print_bursts=options.print_bursts, ppm=options.ppm)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -36,13 +36,13 @@ import os
import osmosdr
import pmt
import time
import sys
# from wideband_receiver import *
class receiver_with_decoder(grgsm.hier_block):
class receiver_with_decoder(gr.hier_block2):
def __init__(self, OSR=4, chan_num=0, fc=939.4e6, ppm=0, samp_rate=0.2e6):
grgsm.hier_block.__init__(
gr.hier_block2.__init__(
self, "Receiver With Decoder",
gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
gr.io_signature(0, 0, 0),
@ -132,9 +132,9 @@ class receiver_with_decoder(grgsm.hier_block):
self.samp_rate_out = samp_rate_out
class wideband_receiver(grgsm.hier_block):
class wideband_receiver(gr.hier_block2):
def __init__(self, OSR=4, fc=939.4e6, samp_rate=0.4e6):
grgsm.hier_block.__init__(
gr.hier_block2.__init__(
self, "Wideband receiver",
gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
gr.io_signature(0, 0, 0),
@ -168,14 +168,14 @@ class wideband_receiver(grgsm.hier_block):
# Connections
##################################################
self.connect((self, 0), (self.pfb_channelizer_ccf_0, 0))
for chan in xrange(0, self.channels_num):
for chan in range(0, self.channels_num):
self.connect((self.pfb_channelizer_ccf_0, chan), (self.receivers_with_decoders[chan], 0))
self.msg_connect(self.receivers_with_decoders[chan], 'bursts', self, 'bursts')
self.msg_connect(self.receivers_with_decoders[chan], 'msgs', self, 'msgs')
def create_receivers(self):
self.receivers_with_decoders = {}
for chan in xrange(0, self.channels_num):
for chan in range(0, self.channels_num):
self.receivers_with_decoders[chan] = receiver_with_decoder(fc=self.fc, OSR=self.OSR, chan_num=chan,
samp_rate=self.OSR_PFB * 0.2e6)
@ -207,9 +207,10 @@ class wideband_scanner(gr.top_block):
self.ppm = ppm
# if no file name is given process data from rtl_sdr source
print "Args=", args
self.rtlsdr_source = osmosdr.source(args="numchan=" + str(1) + " " + args)
self.rtlsdr_source.set_min_output_buffer(int(sample_rate*rec_len))
print("Args=", args)
self.rtlsdr_source = osmosdr.source(args="numchan=" + str(1) + " " +
str(grgsm.device.get_default_args(args)))
#self.rtlsdr_source.set_min_output_buffer(int(sample_rate*rec_len)) #this line causes segfaults on HackRF
self.rtlsdr_source.set_sample_rate(sample_rate)
# capture half of GSM channel lower than channel center (-0.1MHz)
@ -260,6 +261,10 @@ class channel_info(object):
self.neighbours = neighbours
self.cell_arfcns = cell_arfcns
def __lt__(self, other):
return self.arfcn < other.arfcn
def get_verbose_info(self):
i = " |---- Configuration: %s\n" % self.get_ccch_conf()
i += " |---- Cell ARFCNs: " + ", ".join(map(str, self.cell_arfcns)) + "\n"
@ -297,7 +302,7 @@ class channel_info(object):
return "ARFCN: %4u, Freq: %6.1fM, CID: %5u, LAC: %5u, MCC: %3u, MNC: %3u, Pwr: %3i" % (
self.arfcn, self.freq / 1e6, self.cid, self.lac, self.mcc, self.mnc, self.power)
def do_scan(samp_rate, band, speed, ppm, gain, args, prn = None):
def do_scan(samp_rate, band, speed, ppm, gain, args, prn = None, debug = False):
signallist = []
channels_num = int(samp_rate / 0.2e6)
for arfcn_range in grgsm.arfcn.get_arfcn_ranges(band):
@ -311,14 +316,15 @@ def do_scan(samp_rate, band, speed, ppm, gain, args, prn = None):
while current_freq < stop_freq:
# silence rtl_sdr output:
# open 2 fds
null_fds = [os.open(os.devnull, os.O_RDWR) for x in xrange(2)]
# save the current file descriptors to a tuple
save = os.dup(1), os.dup(2)
# put /dev/null fds on 1 and 2
os.dup2(null_fds[0], 1)
os.dup2(null_fds[1], 2)
if not debug:
# silence rtl_sdr output:
# open 2 fds
null_fds = [os.open(os.devnull, os.O_RDWR) for x in range(2)]
# save the current file descriptors to a tuple
save = os.dup(1), os.dup(2)
# put /dev/null fds on 1 and 2
os.dup2(null_fds[0], 1)
os.dup2(null_fds[1], 2)
# instantiate scanner and processor
scanner = wideband_scanner(rec_len=6 - speed,
@ -359,12 +365,14 @@ def do_scan(samp_rate, band, speed, ppm, gain, args, prn = None):
scanner = None
# restore file descriptors so we can print the results
os.dup2(save[0], 1)
os.dup2(save[1], 2)
# close the temporary fds
os.close(null_fds[0])
os.close(null_fds[1])
if not debug:
# restore file descriptors so we can print the results
os.dup2(save[0], 1)
os.dup2(save[1], 2)
# close the temporary fds
os.close(null_fds[0])
os.close(null_fds[1])
if prn:
prn(found_list)
signallist.extend(found_list)
@ -384,11 +392,16 @@ def argument_parser():
parser.add_option("-g", "--gain", dest="gain", type="eng_float", default=24.0,
help="Set gain [default=%default]")
parser.add_option("", "--args", dest="args", type="string", default="",
help="Set device arguments [default=%default]")
help="Set device arguments [default=%default]."
" Use --list-devices the view the available devices")
parser.add_option("-l", "--list-devices", action="store_true",
help="List available SDR devices, use --args to specify hints")
parser.add_option("--speed", dest="speed", type="intx", default=4,
help="Scan speed [default=%default]. Value range 0-5.")
parser.add_option("-v", "--verbose", action="store_true",
help="If set, verbose information output is printed: ccch configuration, cell ARFCN's, neighbour ARFCN's")
parser.add_option("-d", "--debug", action="store_true",
help="Print additional debug messages")
"""
Dont forget: sudo sysctl kernel.shmmni=32000
@ -399,6 +412,10 @@ def main(options = None):
if options is None:
(options, args) = argument_parser().parse_args()
if options.list_devices:
grgsm.device.print_devices(options.args)
sys.exit(0)
if options.band not in grgsm.arfcn.get_bands():
parser.error("Invalid GSM band\n")
@ -410,12 +427,12 @@ def main(options = None):
def printfunc(found_list):
for info in sorted(found_list):
print info
print(info)
if options.verbose:
print info.get_verbose_info()
print ""
print(info.get_verbose_info())
print("")
do_scan(options.samp_rate, options.band, options.speed,
options.ppm, options.gain, options.args, prn = printfunc)
options.ppm, options.gain, options.args, prn = printfunc, debug = options.debug)
if __name__ == '__main__':
main()

View File

@ -3,7 +3,8 @@
# GR-GSM based transceiver
#
# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
# (C) 2016-2019 by Vadim Yanitskiy <axilirator@gmail.com>
# (C) 2017-2018 by Piotr Krysik <ptrkrysik@gmail.com>
#
# All Rights Reserved
#
@ -22,144 +23,134 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import signal
import getopt
import sys
from grgsm.trx import ctrl_if_bb
from grgsm.trx import radio_if
from grgsm.trx import fake_pm
from argparse import ArgumentParser
from argparse import ArgumentTypeError
from gnuradio import eng_notation
from grgsm.trx import RadioInterface
from grgsm.trx import Transceiver
COPYRIGHT = \
"Copyright (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>\n" \
"Copyright (C) 2016-2018 by Vadim Yanitskiy <axilirator@gmail.com>\n" \
"Copyright (C) 2017-2018 by Piotr Krysik <ptrkrysik@gmail.com>\n" \
"License GPLv2+: GNU GPL version 2 or later " \
"<http://gnu.org/licenses/gpl.html>\n" \
"This is free software: you are free to change and redistribute it.\n" \
"There is NO WARRANTY, to the extent permitted by law.\n"
class Application:
# Application variables
remote_addr = "127.0.0.1"
base_port = 5700
# PHY specific
phy_sample_rate = 4 * 1625000 / 6
phy_tx_antenna = "TX/RX"
phy_rx_antenna = "RX2"
phy_rx_gain = 30
phy_tx_gain = 10
phy_args = ""
phy_ppm = 0
def __init__(self):
self.print_copyright()
self.parse_argv()
def __init__(self, argv):
self.remote_addr = argv.remote_addr
self.bind_addr = argv.bind_addr
self.base_port = argv.base_port
self.phy_args = argv.args
self.phy_sample_rate = argv.sample_rate
self.phy_rx_gain = argv.rx_gain
self.phy_tx_gain = argv.tx_gain
self.phy_rx_antenna = argv.rx_antenna
self.phy_tx_antenna = argv.tx_antenna
self.phy_freq_offset = argv.freq_offset
self.phy_ppm = argv.ppm
# Set up signal handlers
signal.signal(signal.SIGINT, self.sig_handler)
def run(self):
if argv.driver == "uhd":
from grgsm.trx.radio_if_uhd import RadioInterfaceUHD as Radio
elif argv.driver == "lms":
from grgsm.trx.radio_if_lms import RadioInterfaceLMS as Radio
else:
raise ValueError("Unknown RadioInterface driver '%s'" % argv.driver)
# Init Radio interface
self.radio = radio_if(self.phy_args, self.phy_sample_rate,
self.radio = Radio(self.phy_args, self.phy_sample_rate,
self.phy_rx_gain, self.phy_tx_gain, self.phy_ppm,
self.phy_rx_antenna, self.phy_tx_antenna,
self.phy_freq_offset, self.bind_addr,
self.remote_addr, self.base_port)
# Power measurement emulation
# Noise: -120 .. -105
# BTS: -75 .. -50
self.pm = fake_pm(-120, -105, -75, -50)
# Init TRX CTRL interface
self.server = ctrl_if_bb(self.remote_addr,
self.base_port + 101, self.base_port + 1,
self.radio, self.pm)
# Init Transceiver
self.trx = Transceiver(self.bind_addr,
self.remote_addr, self.base_port,
radio_if = self.radio)
print("[i] Init complete")
def run(self):
# Enter main loop
while True:
self.server.loop()
self.trx.ctrl_if.loop()
def shutdown(self):
print("[i] Shutting down...")
self.server.shutdown()
self.radio.shutdown()
def print_copyright(self):
print(COPYRIGHT)
def print_help(self):
s = " Usage: " + sys.argv[0] + " [options]\n\n" \
" Some help...\n" \
" -h --help this text\n\n"
# TRX specific
s += " TRX interface specific\n" \
" -i --remote-addr Set remote address (default 127.0.0.1)\n" \
" -p --base-port Set base port number (default 5700)\n\n"
# PHY specific
s += " Radio interface specific\n" \
" -a --device-args Set device arguments\n" \
" -s --sample-rate Set sample rate\n" \
" -g --rx-gain Set RX gain (default 30)\n" \
" -G --tx-gain Set TX gain (default 10)\n" \
" --rx-antenna Set RX antenna (default RX2)\n" \
" --tx-antenna Set TX antenna (default TX/RX)\n" \
" --ppm Set frequency correction (default 0)\n"
print(s)
def parse_argv(self):
try:
opts, args = getopt.getopt(sys.argv[1:],
"i:p:a:s:g:G:h",
["help", "remote-addr=", "base-port=", "device-args=",
"sample-rate=", "rx-gain=", "tx-gain=", "ppm=",
"rx-antenna=", "tx-antenna="])
except getopt.GetoptError as err:
# Print(help and exit)
self.print_help()
print("[!] " + str(err))
sys.exit(2)
for o, v in opts:
if o in ("-h", "--help"):
self.print_help()
sys.exit(2)
# TRX specific
elif o in ("-i", "--remote-addr"):
self.remote_addr = v
elif o in ("-p", "--base-port"):
if int(v) >= 0 and int(v) <= 65535:
self.base_port = int(v)
else:
print("[!] The port number should be in range [0-65536]")
sys.exit(2)
# PHY specific
elif o in ("-a", "--device-args"):
self.phy_args = v
elif o in ("-s", "--sample-rate"):
self.phy_sample_rate = int(v)
elif o in ("-g", "--rx-gain"):
self.phy_rx_gain = int(v)
elif o in ("-G", "--tx-gain"):
self.phy_tx_gain = int(v)
elif o in ("--rx-antenna"):
self.phy_rx_antenna = v
elif o in ("--tx-antenna"):
self.phy_tx_antenna = v
elif o in ("--ppm"):
self.phy_ppm = int(v)
def sig_handler(self, signum, frame):
print("Signal %d received" % signum)
if signum is signal.SIGINT:
self.shutdown()
sys.exit(0)
def eng_float(value):
try:
return eng_notation.str_to_num(value)
except:
raise ArgumentTypeError("invalid engineering notation "
"value: {0}".format(value))
def parse_argv():
parser = ArgumentParser(prog = "grgsm_trx")
# TRX interface specific
trx_group = parser.add_argument_group("TRX interface")
trx_group.add_argument("-i", "--remote-addr",
dest = "remote_addr", type = str, default = "127.0.0.1",
help = "Set remote address (default %(default)s)")
trx_group.add_argument("-b", "--bind-addr",
dest = "bind_addr", type = str, default = "0.0.0.0",
help = "Set bind address (default %(default)s)")
trx_group.add_argument("-p", "--base_port",
dest = "base_port", type = int, default = 6700,
help = "Set base port number (default %(default)s)")
# PHY specific
phy_group = parser.add_argument_group("PHY parameters")
phy_group.add_argument("--driver",
dest = "driver", type = str, default = "uhd",
choices = ["uhd", "lms"],
help = "Set device driver (default %(default)s)")
phy_group.add_argument("-a", "--args",
dest = "args", type = str, default = "",
help = "Set device arguments")
phy_group.add_argument("-s", "--sample-rate",
dest = "sample_rate", type = eng_float,
default = RadioInterface.SAMPLE_RATE,
help = "Set samp_rate (default %(default)s)")
phy_group.add_argument("-g", "--rx-gain",
dest = "rx_gain", type = float, default = 30,
help = "Set RX gain (default %(default)s)")
phy_group.add_argument("-G", "--tx-gain",
dest = "tx_gain", type = float, default = 10,
help = "Set TX gain (default %(default)s)")
phy_group.add_argument("--rx-antenna",
dest = "rx_antenna", type = str, default = "RX2",
help = "Set RX antenna (default %(default)s)")
phy_group.add_argument("--tx-antenna",
dest = "tx_antenna", type = str, default = "TX/RX",
help = "Set TX antenna (default %(default)s)")
phy_group.add_argument("--freq-offset",
dest = "freq_offset", type = eng_float, default = 0,
help = "Shift baseband freq. (e.g. -500M)")
phy_group.add_argument("--ppm",
dest = "ppm", type = float, default = 0,
help = "Set frequency correction (default %(default)s)")
return parser.parse_args()
if __name__ == '__main__':
app = Application()
print(COPYRIGHT)
argv = parse_argv()
app = Application(argv)
app.run()

View File

@ -1,6 +1,7 @@
# Copyright 2011 Free Software Foundation, Inc.
# Copyright 2011,2012,2014,2016,2018 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,8 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @file
# @author (C) 2015 by Roman Khassraf <rkhassraf@gmail.com>
# (C) 2019 by Piotr Krysik <ptrkrysik@gmail.com>
# @section LICENSE
#
# Gr-gsm is free software; you can redistribute it and/or modify
@ -26,217 +27,170 @@ from gnuradio import eng_notation
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from math import pi
from optparse import OptionParser
import grgsm
from optparse import OptionParser, OptionGroup
import osmosdr
import pmt
import time
import grgsm
import signal
import sys
class grgsm_capture(gr.top_block):
def __init__(self, fc, gain, samp_rate, ppm, arfcn, cfile=None, burst_file=None, verbose=False, rec_length=None, args=""):
def __init__(self,
freq,
gain=30,
samp_rate=1e6,
rec_length=float('Inf'),
freq_corr=0,
output_filename=None,
bandwidth=0,
bb_gain=20,
if_gain=20,
antenna="",
device_args=""):
gr.top_block.__init__(self, "Gr-gsm Capture")
##################################################
# Parameters
##################################################
self.fc = fc
self.gain = gain
self.samp_rate = samp_rate
self.ppm = ppm
self.arfcn = arfcn
self.cfile = cfile
self.burst_file = burst_file
self.verbose = verbose
self.shiftoff = shiftoff = 400e3
self.rec_length = rec_length
##################################################
# Processing Blocks
# Setting up RF source
##################################################
self.rtlsdr_source = osmosdr.source( args="numchan=" + str(1) + " " + args )
self.rtlsdr_source.set_sample_rate(samp_rate)
self.rtlsdr_source.set_center_freq(fc - shiftoff, 0)
self.rtlsdr_source.set_freq_corr(ppm, 0)
self.rtlsdr_source.set_dc_offset_mode(2, 0)
self.rtlsdr_source.set_iq_balance_mode(2, 0)
self.rtlsdr_source.set_gain_mode(True, 0)
self.rtlsdr_source.set_gain(gain, 0)
self.rtlsdr_source.set_if_gain(20, 0)
self.rtlsdr_source.set_bb_gain(20, 0)
self.rtlsdr_source.set_antenna("", 0)
self.rtlsdr_source.set_bandwidth(250e3+abs(shiftoff), 0)
self.blocks_rotator = blocks.rotator_cc(-2*pi*shiftoff/samp_rate)
if self.rec_length is not None:
self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex, int(samp_rate*rec_length))
if self.verbose or self.burst_file:
self.gsm_receiver = grgsm.receiver(4, ([self.arfcn]), ([]))
self.gsm_input = grgsm.gsm_input(
ppm=0,
osr=4,
fc=fc,
samp_rate_in=samp_rate,
)
self.gsm_clock_offset_control = grgsm.clock_offset_control(fc-shiftoff, samp_rate, osr=4)
self.sdr_source = osmosdr.source(args="numchan=" + str(1) + " " +
str(grgsm.device.get_default_args(device_args)))
if self.burst_file:
self.gsm_burst_file_sink = grgsm.burst_file_sink(self.burst_file)
self.sdr_source.set_sample_rate(samp_rate)
self.sdr_source.set_center_freq(freq, 0)
self.sdr_source.set_freq_corr(freq_corr, 0)
self.sdr_source.set_dc_offset_mode(2, 0)
self.sdr_source.set_iq_balance_mode(2, 0)
self.sdr_source.set_gain_mode(True, 0)
self.sdr_source.set_gain(gain, 0)
self.sdr_source.set_if_gain(if_gain, 0)
self.sdr_source.set_bb_gain(bb_gain, 0)
self.sdr_source.set_antenna("", 0)
if bandwidth != 0:
self.sdr_source.set_bandwidth(bandwidth, 0)
if self.cfile:
self.blocks_file_sink = blocks.file_sink(gr.sizeof_gr_complex*1, self.cfile, False)
self.blocks_file_sink.set_unbuffered(False)
##################################################
# The rest of processing blocks
##################################################
if self.verbose:
self.gsm_bursts_printer_0 = grgsm.bursts_printer(pmt.intern(""),
False, False, False, False)
if rec_length != float('Inf'):
self.head = \
blocks.head(gr.sizeof_gr_complex, int(samp_rate*rec_length))
self.file_sink = blocks.file_sink(gr.sizeof_gr_complex*1, \
output_filename, False)
self.file_sink.set_unbuffered(False)
##################################################
# Connections
##################################################
if self.rec_length is not None: #if recording length is defined connect head block after the source
self.connect((self.rtlsdr_source, 0), (self.blocks_head_0, 0))
self.connect((self.blocks_head_0, 0), (self.blocks_rotator, 0))
if rec_length != float('Inf'): #if recording length is not infinite
#connect head block after the source
self.connect((self.sdr_source, 0), (self.head, 0))
self.connect((self.head, 0), (self.file_sink, 0))
else:
self.connect((self.rtlsdr_source, 0), (self.blocks_rotator, 0))
if self.cfile:
self.connect((self.blocks_rotator, 0), (self.blocks_file_sink, 0))
if self.verbose or self.burst_file:
self.connect((self.gsm_input, 0), (self.gsm_receiver, 0))
self.connect((self.blocks_rotator, 0), (self.gsm_input, 0))
self.msg_connect(self.gsm_clock_offset_control, "ctrl", self.gsm_input, "ctrl_in")
self.msg_connect(self.gsm_receiver, "measurements", self.gsm_clock_offset_control, "measurements")
if self.burst_file:
self.msg_connect(self.gsm_receiver, "C0", self.gsm_burst_file_sink, "in")
if self.verbose:
self.msg_connect(self.gsm_receiver, "C0", self.gsm_bursts_printer_0, "bursts")
def get_fc(self):
return self.fc
def set_fc(self, fc):
self.fc = fc
if self.verbose or self.burst_file:
self.gsm_input.set_fc(self.fc)
def get_arfcn(self):
return self.arfcn
def set_arfcn(self, arfcn):
self.arfcn = arfcn
if self.verbose or self.burst_file:
self.gsm_receiver.set_cell_allocation([self.arfcn])
new_freq = grgsm.arfcn.arfcn2downlink(self.arfcn)
self.set_fc(new_freq)
def get_gain(self):
return self.gain
def set_gain(self, gain):
self.gain = gain
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.rtlsdr_source.set_sample_rate(self.samp_rate)
if self.verbose or self.burst_file:
self.gsm_input.set_samp_rate_in(self.samp_rate)
def get_ppm(self):
return self.ppm
def set_ppm(self, ppm):
self.ppm = ppm
self.set_ppm_slider(self.ppm)
def get_rec_length(self):
return self.rec_length
def set_rec_length(self, rec_length):
self.rec_length = rec_length
self.blocks_head_0.set_length(int(self.samp_rate*self.rec_length))
self.connect((self.sdr_source, 0), (self.file_sink, 0))
if __name__ == '__main__':
parser = OptionParser(option_class=eng_option, usage="%prog [options]",
parser = OptionParser(option_class=eng_option, usage="%prog [options] output_filename",
description="RTL-SDR capturing app of gr-gsm.")
parser.add_option("-f", "--fc", dest="fc", type="eng_float",
parser.add_option("-f", "--freq", dest="freq", type="eng_float",
help="Set frequency [default=%default]")
parser.add_option("-a", "--arfcn", dest="arfcn", type="intx",
help="Set ARFCN instead of frequency (for PCS1900 add 0x8000 (2**15) to the ARFCN number)")
parser.add_option("-g", "--gain", dest="gain", type="eng_float",
parser.add_option("-a", "--arfcn", dest="arfcn", type="intx",
help="Set ARFCN instead of frequency (for PCS1900 add"
"0x8000 (2**15) to the ARFCN number)")
parser.add_option("-g", "--gain", dest="gain", type="eng_float",
default=eng_notation.num_to_str(30),
help="Set gain [default=%default]")
parser.add_option("-s", "--samp-rate", dest="samp_rate", type="eng_float",
parser.add_option("-s", "--samp-rate", dest="samp_rate", type="eng_float",
default=eng_notation.num_to_str(1000000),
help="Set samp_rate [default=%default]")
parser.add_option("-p", "--ppm", dest="ppm", type="intx", default=0,
help="Set ppm [default=%default]")
parser.add_option("-b", "--burst-file", dest="burst_file",
help="File where the captured bursts are saved")
parser.add_option("-c", "--cfile", dest="cfile",
help="File where the captured data are saved")
parser.add_option("", "--args", dest="args", type="string", default="",
help="Set device arguments [default=%default]")
parser.add_option("-v", "--verbose", action="store_true",
help="If set, the captured bursts are printed to stdout")
parser.add_option("-T", "--rec-length", dest="rec_length", type="float",
default='Inf', help="Set length of recording in seconds "
"[default=infinity]")
parser.add_option("-T", "--rec-length", dest="rec_length", type="eng_float",
help="Set length of recording in seconds [default=%default]")
parser.add_option("-p", "--freq-corr", dest="freq_corr", type="eng_float",
default="0", help="Set frequency correction in"
" ppm [default=%default]")
osmogroup = OptionGroup(parser, 'Additional osmosdr source options',
"Options specific to a subset of SDR receivers "
"supported by osmosdr source.")
osmogroup.add_option("-w", "--bandwidth", dest="bandwidth", type="eng_float",
default="0", help="Set bandwidth [default=samp_rate]")
osmogroup.add_option("", "--bb-gain", dest="bb_gain", type="eng_float",
default=eng_notation.num_to_str(20),
help="Set baseband gain [default=%default]")
osmogroup.add_option("", "--if-gain", dest="if_gain", type="eng_float",
default=eng_notation.num_to_str(20),
help="Set intermediate freque gain [default=%default]")
osmogroup.add_option("", "--ant", dest="antenna", type="string",
default="", help="Set antenna "
"[default=%default]")
osmogroup.add_option("", "--args", dest="device_args", type="string",
default="", help="Set device arguments "
"[default=%default]. Use --list-devices the view the available devices")
osmogroup.add_option("-l", "--list-devices", action="store_true",
help="List available SDR devices, use --args to specify hints")
parser.add_option_group(osmogroup)
(options, args) = parser.parse_args()
if options.cfile is None and options.burst_file is None:
parser.error("Please provide a cfile or a burst file (or both) to save the captured data\n")
if (options.fc is None and options.arfcn is None) or (options.fc is not None and options.arfcn is not None):
parser.error("You have to provide either a frequency or an ARFCN (but not both).\n")
if options.list_devices:
grgsm.device.print_devices(options.device_args)
sys.exit(0)
if not args:
parser.error("Please provide an output file name to save the captured data\n")
output_filename = args[0]
if (options.freq is None and options.arfcn is None) or \
(options.freq is not None and options.arfcn is not None):
parser.error("You have to provide either a frequency or"
"an ARFCN (but not both).\n")
arfcn = 0
fc = 939.4e6
freq = 0
if options.arfcn:
if not grgsm.arfcn.is_valid_arfcn(options.arfcn):
parser.error("ARFCN is not valid\n")
else:
arfcn = options.arfcn
fc = grgsm.arfcn.arfcn2downlink(arfcn)
elif options.fc:
fc = options.fc
arfcn = grgsm.arfcn.downlink2arfcn(options.fc)
tb = grgsm_capture(fc=fc, gain=options.gain, samp_rate=options.samp_rate,
ppm=options.ppm, arfcn=arfcn, cfile=options.cfile,
burst_file=options.burst_file, verbose=options.verbose,
rec_length=options.rec_length, args=options.args)
freq = grgsm.arfcn.arfcn2downlink(options.arfcn)
elif options.freq:
freq = options.freq
tb = grgsm_capture(freq=freq,
gain=options.gain,
freq_corr=options.freq_corr,
samp_rate=options.samp_rate,
output_filename=output_filename,
rec_length=options.rec_length,
bandwidth=options.bandwidth,
bb_gain=options.bb_gain,
if_gain=options.if_gain,
antenna=options.antenna,
device_args=options.device_args)
def signal_handler(signal, frame):
tb.stop()
tb.wait()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
tb.start()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @file
# @author (C) 2015 by Pieter Robyns <pieter.robyns@uhasselt.be>
@ -79,6 +79,10 @@ class grgsm_channelize(gr.top_block):
self.blocks_file_source = blocks.file_source(gr.sizeof_short, input_file, False)
self.source = blocks.interleaved_short_to_complex(False, False)
self.connect((self.blocks_file_source, 0), (self.source, 0))
elif data_type == "ichar":
self.blocks_file_source = blocks.file_source(gr.sizeof_char, input_file, False)
self.source = blocks.interleaved_char_to_complex(False)
self.connect((self.blocks_file_source, 0), (self.source, 0))
elif data_type == "complex":
self.source = blocks.file_source(gr.sizeof_gr_complex, input_file, False)
@ -114,7 +118,7 @@ if __name__ == '__main__':
help="Sample rate of the output capture files [default=%(default)s]")
parser.add_argument("-i", "--input_file", dest="input_file", type=str, required=True,
help="Path to wideband GSM capture file")
parser.add_argument("-t", "--data_type", dest="data_type", type=str, choices=["complex","ishort"], default="complex",
parser.add_argument("-t", "--data_type", dest="data_type", type=str, choices=["complex","ishort","ichar"], default="complex",
help="Type of the input file [default=%(default)s]")
parser.add_argument("-d", "--dest_dir", dest="dest_dir", type=str,
help="Destination directory - if not given defaults to input file name without extension")

View File

@ -1,10 +0,0 @@
#create logical links in order to keep legacy names of apps
macro(CREATE_SYMLINK _source _dest)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${_source})
set(dest ${CMAKE_CURRENT_BINARY_DIR}/${_dest})
list(APPEND symlinks ${dest})
add_custom_command(
DEPENDS ${source} OUTPUT ${dest}
COMMAND ln -sf ${_source} ${_dest}
)
endmacro(CREATE_SYMLINK)

View File

@ -1,36 +0,0 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GNURADIO_RUNTIME gnuradio-runtime)
if(PC_GNURADIO_RUNTIME_FOUND)
# look for include files
FIND_PATH(
GNURADIO_RUNTIME_INCLUDE_DIRS
NAMES gnuradio/top_block.h
HINTS $ENV{GNURADIO_RUNTIME_DIR}/include
${PC_GNURADIO_RUNTIME_INCLUDE_DIRS}
${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/local/include
/usr/include
)
# look for libs
FIND_LIBRARY(
GNURADIO_RUNTIME_LIBRARIES
NAMES gnuradio-runtime
HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib
${PC_GNURADIO_RUNTIME_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib/
${CMAKE_INSTALL_PREFIX}/lib64/
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
set(GNURADIO_RUNTIME_FOUND ${PC_GNURADIO_RUNTIME_FOUND})
endif(PC_GNURADIO_RUNTIME_FOUND)
INCLUDE(FindPackageHandleStandardArgs)
# do not check GNURADIO_RUNTIME_INCLUDE_DIRS, is not set when default include path us used.
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES)
MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS)

View File

@ -1,7 +1,6 @@
#find_package(PkgConfig)
INCLUDE(FindPkgConfig)
pkg_check_modules(PC_libosmocore libosmocore)
pkg_check_modules(PC_libosmogsm libosmogsm)
set(LIBOSMOCORE_DEFINITIONS ${PC_LIBOSMOCORE_CFLAGS_OTHER})
find_path(
@ -25,18 +24,8 @@ find_library(
/usr/lib
)
find_library(
LIBOSMOCORE_GSM_LIBRARY
NAMES libosmogsm osmogsm
HINTS ${PC_libosmocore_LIBDIR}
${PC_libosmocore_LIBRARY_DIRS}
${CMAKE_INSTALL_PREFIX}/lib/
${CMAKE_INSTALL_PREFIX}/lib64/
PATHS /usr/local/lib
/usr/lib
)
set(LIBOSMOCORE_LIBRARIES ${LIBOSMOCORE_LIBRARY} ${LIBOSMOCORE_GSM_LIBRARY})
set(LIBOSMOCORE_LIBRARIES ${LIBOSMOCORE_LIBRARY})
set(LIBOSMOCORE_INCLUDE_DIRS ${LIBOSMOCORE_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)

View File

@ -0,0 +1,32 @@
INCLUDE(FindPkgConfig)
pkg_check_modules(PC_libosmogsm libosmogsm)
set(LIBOSMOGSM_DEFINITIONS ${PC_LIBOSMOGSM_CFLAGS_OTHER})
find_path(
LIBOSMOGSM_INCLUDE_DIR
NAMES osmocom/gsm/gsm_utils.h
HINTS ${PC_libosmogsm_INCLUDEDIR}
${PC_libosmogsm_INCLUDE_DIRS}
${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/local/include
/usr/include
)
find_library(
LIBOSMOGSM_LIBRARY
NAMES libosmogsm osmogsm
HINTS ${PC_libosmogsm_LIBDIR}
${PC_libosmogsm_LIBRARY_DIRS}
${CMAKE_INSTALL_PREFIX}/lib/
${CMAKE_INSTALL_PREFIX}/lib64/
PATHS /usr/local/lib
/usr/lib
)
set(LIBOSMOGSM_LIBRARIES ${LIBOSMOGSM_LIBRARY})
set(LIBOSMOGSM_INCLUDE_DIRS ${LIBOSMOGSM_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(libosmogsm DEFAULT_MSG LIBOSMOGSM_LIBRARY LIBOSMOGSM_INCLUDE_DIR)
mark_as_advanced(LIBOSMOGSM_INCLUDE_DIR LIBOSMOGSM_LIBRARY )

View File

@ -1,142 +0,0 @@
#######################################################################
# Find the library for SWIG
#
# The goal here is to intercept calls to "FIND_PACKAGE(SWIG)" in order
# to do a global version check locally after passing on the "find" to
# SWIG-provided scripts.
########################################################################
# make this file non-reentrant within the current context
if(__INCLUDED_FIND_SWIG_CMAKE)
return()
endif()
set(__INCLUDED_FIND_SWIG_CMAKE TRUE)
# some status messages
message(STATUS "")
message(STATUS "Checking for module SWIG")
#
# First check to see if SWIG installed its own CMake file, or if the
# one provided by CMake finds SWIG.
#
# save the current MODULE path
set(SAVED_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
# clear the current MODULE path; uses system paths only
unset(CMAKE_MODULE_PATH)
# try to find SWIG via the provided parameters,
# handle REQUIRED internally later
unset(SWIG_FOUND)
# was the version specified?
unset(LOCAL_SWIG_FIND_VERSION)
if(SWIG_FIND_VERSION)
set(LOCAL_SWIG_FIND_VERSION ${SWIG_FIND_VERSION})
endif(SWIG_FIND_VERSION)
# was EXACT specified?
unset(LOCAL_SWIG_FIND_VERSION_EXACT)
if(SWIG_FIND_VERSION_EXACT)
set(LOCAL_SWIG_FIND_VERSION_EXACT "EXACT")
endif(SWIG_FIND_VERSION_EXACT)
# was REQUIRED specified?
unset(LOCAL_SWIG_FIND_REQUIRED)
if(SWIG_FIND_REQUIRED)
set(LOCAL_SWIG_FIND_REQUIRED "REQUIRED")
endif(SWIG_FIND_REQUIRED)
# try to find SWIG using the provided parameters, quietly;
#
# this call will error out internally (and not quietly) if:
# 1: EXACT is specified and the version found does not match the requested version;
# 2: REQUIRED is set and SWIG was not found;
#
# this call will return SWIG_FOUND == FALSE if REQUIRED is not set, and:
# 1: SWIG was not found;
# 2: The version found is less than the requested version.
find_package(
SWIG
${LOCAL_SWIG_FIND_VERSION}
${LOCAL_SWIG_FIND_VERSION_EXACT}
${LOCAL_SWIG_FIND_REQUIRED}
QUIET
)
# restore CMAKE_MODULE_PATH
set(CMAKE_MODULE_PATH ${SAVED_CMAKE_MODULE_PATH})
# specific version checks
set(SWIG_VERSION_CHECK FALSE)
if(SWIG_FOUND)
# SWIG was found; make sure the version meets GR's needs
message(STATUS "Found SWIG version ${SWIG_VERSION}.")
if("${SWIG_VERSION}" VERSION_GREATER "1.3.30")
if(NOT "${SWIG_VERSION}" VERSION_EQUAL "3.0.3" AND
NOT "${SWIG_VERSION}" VERSION_EQUAL "3.0.4")
set(SWIG_VERSION_CHECK TRUE)
else()
message(STATUS "SWIG versions 3.0.3 and 3.0.4 fail to work with GNU Radio.")
endif()
else()
message(STATUS "Minimum SWIG version required is 1.3.31 for GNU Radio.")
endif()
else()
# SWIG was either not found, or is less than the requested version
if(SWIG_VERSION)
# SWIG_VERSION is set, but SWIG_FOUND is false; probably a version mismatch
message(STATUS "Found SWIG version ${SWIG_VERSION}.")
message(STATUS "Requested SWIG version is at least ${SWIG_FIND_VERSION}.")
endif()
endif()
# did the version check fail?
if(NOT SWIG_VERSION_CHECK)
# yes: clear various variables and set FOUND to FALSE
message(STATUS "Disabling SWIG because version check failed.")
unset(SWIG_VERSION CACHE)
unset(SWIG_DIR CACHE)
unset(SWIG_EXECUTABLE CACHE)
set(SWIG_FOUND FALSE CACHE BOOL "Set to TRUE if a compatible version of SWIG is found" FORCE)
endif()
# check to see if SWIG variables were set
if(SWIG_FOUND AND SWIG_DIR AND SWIG_EXECUTABLE)
# yes: even if set SWIG_FOUND==TRUE, then these have already been
# done, but done quietly. It does not hurt to redo them here.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SWIG DEFAULT_MSG SWIG_EXECUTABLE SWIG_DIR)
mark_as_advanced(SWIG_EXECUTABLE SWIG_DIR)
elseif(SWIG_FIND_REQUIRED)
if(SWIG_FIND_VERSION)
message(FATAL_ERROR "The found SWIG version (${SWIG_VERSION}) is not compatible with the version required (${SWIG_FIND_VERSION}).")
else()
message(FATAL_ERROR "SWIG is required, but was not found.")
endif()
endif()

View File

@ -1,26 +0,0 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_VOLK volk)
FIND_PATH(
VOLK_INCLUDE_DIRS
NAMES volk/volk.h
HINTS $ENV{VOLK_DIR}/include
${PC_VOLK_INCLUDEDIR}
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
VOLK_LIBRARIES
NAMES volk
HINTS $ENV{VOLK_DIR}/lib
${PC_VOLK_LIBDIR}
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(VOLK DEFAULT_MSG VOLK_LIBRARIES VOLK_INCLUDE_DIRS)
MARK_AS_ADVANCED(VOLK_LIBRARIES VOLK_INCLUDE_DIRS)

View File

@ -1,459 +0,0 @@
# Copyright 2010-2011,2014 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio 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, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_MISC_UTILS_CMAKE)
return()
endif()
set(__INCLUDED_GR_MISC_UTILS_CMAKE TRUE)
########################################################################
# Set global variable macro.
# Used for subdirectories to export settings.
# Example: include and library paths.
########################################################################
function(GR_SET_GLOBAL var)
set(${var} ${ARGN} CACHE INTERNAL "" FORCE)
endfunction(GR_SET_GLOBAL)
########################################################################
# Set the pre-processor definition if the condition is true.
# - def the pre-processor definition to set and condition name
########################################################################
function(GR_ADD_COND_DEF def)
if(${def})
add_definitions(-D${def})
endif(${def})
endfunction(GR_ADD_COND_DEF)
########################################################################
# Check for a header and conditionally set a compile define.
# - hdr the relative path to the header file
# - def the pre-processor definition to set
########################################################################
function(GR_CHECK_HDR_N_DEF hdr def)
include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX(${hdr} ${def})
GR_ADD_COND_DEF(${def})
endfunction(GR_CHECK_HDR_N_DEF)
########################################################################
# Include subdirectory macro.
# Sets the CMake directory variables,
# includes the subdirectory CMakeLists.txt,
# resets the CMake directory variables.
#
# This macro includes subdirectories rather than adding them
# so that the subdirectory can affect variables in the level above.
# This provides a work-around for the lack of convenience libraries.
# This way a subdirectory can append to the list of library sources.
########################################################################
macro(GR_INCLUDE_SUBDIRECTORY subdir)
#insert the current directories on the front of the list
list(INSERT _cmake_source_dirs 0 ${CMAKE_CURRENT_SOURCE_DIR})
list(INSERT _cmake_binary_dirs 0 ${CMAKE_CURRENT_BINARY_DIR})
#set the current directories to the names of the subdirs
set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${subdir})
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${subdir})
#include the subdirectory CMakeLists to run it
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
#reset the value of the current directories
list(GET _cmake_source_dirs 0 CMAKE_CURRENT_SOURCE_DIR)
list(GET _cmake_binary_dirs 0 CMAKE_CURRENT_BINARY_DIR)
#pop the subdir names of the front of the list
list(REMOVE_AT _cmake_source_dirs 0)
list(REMOVE_AT _cmake_binary_dirs 0)
endmacro(GR_INCLUDE_SUBDIRECTORY)
########################################################################
# Check if a compiler flag works and conditionally set a compile define.
# - flag the compiler flag to check for
# - have the variable to set with result
########################################################################
macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(${flag} ${have})
if(${have})
if(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
STRING(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_dup)
if(${flag_dup} EQUAL -1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
endif(${flag_dup} EQUAL -1)
endif(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
endif(${have})
endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
########################################################################
# Generates the .la libtool file
# This appears to generate libtool files that cannot be used by auto*.
# Usage GR_LIBTOOL(TARGET [target] DESTINATION [dest])
# Notice: there is not COMPONENT option, these will not get distributed.
########################################################################
function(GR_LIBTOOL)
if(NOT DEFINED GENERATE_LIBTOOL)
set(GENERATE_LIBTOOL OFF) #disabled by default
endif()
if(GENERATE_LIBTOOL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_LIBTOOL "" "TARGET;DESTINATION" "" ${ARGN})
find_program(LIBTOOL libtool)
if(LIBTOOL)
include(CMakeMacroLibtoolFile)
CREATE_LIBTOOL_FILE(${GR_LIBTOOL_TARGET} /${GR_LIBTOOL_DESTINATION})
endif(LIBTOOL)
endif(GENERATE_LIBTOOL)
endfunction(GR_LIBTOOL)
########################################################################
# Do standard things to the library target
# - set target properties
# - make install rules
# Also handle gnuradio custom naming conventions w/ extras mode.
########################################################################
function(GR_LIBRARY_FOO target)
#parse the arguments for component names
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN})
#set additional target properties
set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER})
#install the generated files like so...
install(TARGETS ${target}
LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file
ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file
RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file
)
#extras mode enabled automatically on linux
if(NOT DEFINED LIBRARY_EXTRAS)
set(LIBRARY_EXTRAS ${LINUX})
endif()
#special extras mode to enable alternative naming conventions
if(LIBRARY_EXTRAS)
#create .la file before changing props
GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR})
#give the library a special name with ultra-zero soversion
set_target_properties(${target} PROPERTIES OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0")
set(target_name lib${target}-${LIBVER}.so.0.0.0)
#custom command to generate symlinks
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install
)
#and install the extra symlinks
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT}
)
endif(LIBRARY_EXTRAS)
endfunction(GR_LIBRARY_FOO)
########################################################################
# Create a dummy custom command that depends on other targets.
# Usage:
# GR_GEN_TARGET_DEPS(unique_name target_deps <target1> <target2> ...)
# ADD_CUSTOM_COMMAND(<the usual args> ${target_deps})
#
# Custom command cant depend on targets, but can depend on executables,
# and executables can depend on targets. So this is the process:
########################################################################
function(GR_GEN_TARGET_DEPS name var)
file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
"int main(void){return 0;}\n"
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp
)
add_executable(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp)
if(ARGN)
add_dependencies(${name} ${ARGN})
endif(ARGN)
if(CMAKE_CROSSCOMPILING)
set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross
else()
set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
endif()
endfunction(GR_GEN_TARGET_DEPS)
########################################################################
# Control use of gr_logger
# Usage:
# GR_LOGGING()
#
# Will set ENABLE_GR_LOG to 1 by default.
# Can manually set with -DENABLE_GR_LOG=0|1
########################################################################
function(GR_LOGGING)
find_package(Log4cpp)
OPTION(ENABLE_GR_LOG "Use gr_logger" ON)
if(ENABLE_GR_LOG)
# If gr_logger is enabled, make it usable
add_definitions( -DENABLE_GR_LOG )
# also test LOG4CPP; if we have it, use this version of the logger
# otherwise, default to the stdout/stderr model.
if(LOG4CPP_FOUND)
SET(HAVE_LOG4CPP True CACHE INTERNAL "" FORCE)
add_definitions( -DHAVE_LOG4CPP )
else(not LOG4CPP_FOUND)
SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
endif(LOG4CPP_FOUND)
SET(ENABLE_GR_LOG ${ENABLE_GR_LOG} CACHE INTERNAL "" FORCE)
else(ENABLE_GR_LOG)
SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
endif(ENABLE_GR_LOG)
message(STATUS "ENABLE_GR_LOG set to ${ENABLE_GR_LOG}.")
message(STATUS "HAVE_LOG4CPP set to ${HAVE_LOG4CPP}.")
message(STATUS "LOG4CPP_LIBRARIES set to ${LOG4CPP_LIBRARIES}.")
endfunction(GR_LOGGING)
########################################################################
# Check if HAVE_PTHREAD_SETSCHEDPARAM and HAVE_SCHED_SETSCHEDULER
# should be defined
########################################################################
macro(GR_CHECK_LINUX_SCHED_AVAIL)
set(CMAKE_REQUIRED_LIBRARIES -lpthread)
CHECK_CXX_SOURCE_COMPILES("
#include <pthread.h>
int main(){
pthread_t pthread;
pthread_setschedparam(pthread, 0, 0);
return 0;
} " HAVE_PTHREAD_SETSCHEDPARAM
)
GR_ADD_COND_DEF(HAVE_PTHREAD_SETSCHEDPARAM)
CHECK_CXX_SOURCE_COMPILES("
#include <sched.h>
int main(){
pid_t pid;
sched_setscheduler(pid, 0, 0);
return 0;
} " HAVE_SCHED_SETSCHEDULER
)
GR_ADD_COND_DEF(HAVE_SCHED_SETSCHEDULER)
endmacro(GR_CHECK_LINUX_SCHED_AVAIL)
########################################################################
# Macros to generate source and header files from template
########################################################################
macro(GR_EXPAND_X_H component root)
include(GrPython)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
"#!${PYTHON_EXECUTABLE}
import sys, os, re
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
if __name__ == '__main__':
import build_utils
root, inp = sys.argv[1:3]
for sig in sys.argv[3:]:
name = re.sub ('X+', sig, root)
d = build_utils.standard_dict2(name, sig, '${component}')
build_utils.expand_template(d, inp)
")
#make a list of all the generated headers
unset(expanded_files_h)
foreach(sig ${ARGN})
string(REGEX REPLACE "X+" ${sig} name ${root})
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
endforeach(sig)
unset(name)
#create a command to generate the headers
add_custom_command(
OUTPUT ${expanded_files_h}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}.h.t ${ARGN}
)
#install rules for the generated headers
list(APPEND generated_includes ${expanded_files_h})
endmacro(GR_EXPAND_X_H)
macro(GR_EXPAND_X_CC_H component root)
include(GrPython)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
"#!${PYTHON_EXECUTABLE}
import sys, os, re
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
if __name__ == '__main__':
import build_utils
root, inp = sys.argv[1:3]
for sig in sys.argv[3:]:
name = re.sub ('X+', sig, root)
d = build_utils.standard_impl_dict2(name, sig, '${component}')
build_utils.expand_template(d, inp)
")
#make a list of all the generated files
unset(expanded_files_cc)
unset(expanded_files_h)
foreach(sig ${ARGN})
string(REGEX REPLACE "X+" ${sig} name ${root})
list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
endforeach(sig)
unset(name)
#create a command to generate the source files
add_custom_command(
OUTPUT ${expanded_files_cc}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}.cc.t ${ARGN}
)
#create a command to generate the header files
add_custom_command(
OUTPUT ${expanded_files_h}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}.h.t ${ARGN}
)
#make source files depends on headers to force generation
set_source_files_properties(${expanded_files_cc}
PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
)
#install rules for the generated files
list(APPEND generated_sources ${expanded_files_cc})
list(APPEND generated_headers ${expanded_files_h})
endmacro(GR_EXPAND_X_CC_H)
macro(GR_EXPAND_X_CC_H_IMPL component root)
include(GrPython)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
"#!${PYTHON_EXECUTABLE}
import sys, os, re
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
if __name__ == '__main__':
import build_utils
root, inp = sys.argv[1:3]
for sig in sys.argv[3:]:
name = re.sub ('X+', sig, root)
d = build_utils.standard_dict(name, sig, '${component}')
build_utils.expand_template(d, inp, '_impl')
")
#make a list of all the generated files
unset(expanded_files_cc_impl)
unset(expanded_files_h_impl)
unset(expanded_files_h)
foreach(sig ${ARGN})
string(REGEX REPLACE "X+" ${sig} name ${root})
list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc)
list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h)
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/${component}/${name}.h)
endforeach(sig)
unset(name)
#create a command to generate the _impl.cc files
add_custom_command(
OUTPUT ${expanded_files_cc_impl}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}_impl.cc.t ${ARGN}
)
#create a command to generate the _impl.h files
add_custom_command(
OUTPUT ${expanded_files_h_impl}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}_impl.h.t ${ARGN}
)
#make _impl.cc source files depend on _impl.h to force generation
set_source_files_properties(${expanded_files_cc_impl}
PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}"
)
#make _impl.h source files depend on headers to force generation
set_source_files_properties(${expanded_files_h_impl}
PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
)
#install rules for the generated files
list(APPEND generated_sources ${expanded_files_cc_impl})
list(APPEND generated_headers ${expanded_files_h_impl})
endmacro(GR_EXPAND_X_CC_H_IMPL)

View File

@ -1,227 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio 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, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_PYTHON_CMAKE)
return()
endif()
set(__INCLUDED_GR_PYTHON_CMAKE TRUE)
########################################################################
# Setup the python interpreter:
# This allows the user to specify a specific interpreter,
# or finds the interpreter via the built-in cmake module.
########################################################################
#this allows the user to override PYTHON_EXECUTABLE
if(PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND TRUE)
#otherwise if not set, try to automatically find it
else(PYTHON_EXECUTABLE)
#use the built-in find script
find_package(PythonInterp 2)
#and if that fails use the find program routine
if(NOT PYTHONINTERP_FOUND)
find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python2.6 python2.5)
if(PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND TRUE)
endif(PYTHON_EXECUTABLE)
endif(NOT PYTHONINTERP_FOUND)
endif(PYTHON_EXECUTABLE)
#make the path to the executable appear in the cmake gui
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
#make sure we can use -B with python (introduced in 2.6)
if(PYTHON_EXECUTABLE)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -B -c ""
OUTPUT_QUIET ERROR_QUIET
RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
)
if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
set(PYTHON_DASH_B "-B")
endif()
endif(PYTHON_EXECUTABLE)
########################################################################
# Check for the existence of a python module:
# - desc a string description of the check
# - mod the name of the module to import
# - cmd an additional command to run
# - have the result variable to set
########################################################################
macro(GR_PYTHON_CHECK_MODULE desc mod cmd have)
message(STATUS "")
message(STATUS "Python checking for ${desc}")
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "
#########################################
try: import ${mod}
except: exit(-1)
try: assert ${cmd}
except: exit(-1)
#########################################"
RESULT_VARIABLE ${have}
)
if(${have} EQUAL 0)
message(STATUS "Python checking for ${desc} - found")
set(${have} TRUE)
else(${have} EQUAL 0)
message(STATUS "Python checking for ${desc} - not found")
set(${have} FALSE)
endif(${have} EQUAL 0)
endmacro(GR_PYTHON_CHECK_MODULE)
########################################################################
# Sets the python installation directory GR_PYTHON_DIR
########################################################################
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
from distutils import sysconfig
print sysconfig.get_python_lib(plat_specific=True, prefix='')
" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
)
file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR)
########################################################################
# Create an always-built target with a unique name
# Usage: GR_UNIQUE_TARGET(<description> <dependencies list>)
########################################################################
function(GR_UNIQUE_TARGET desc)
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_target(${_target} ALL DEPENDS ${ARGN})
endfunction(GR_UNIQUE_TARGET)
########################################################################
# Install python sources (also builds and installs byte-compiled python)
########################################################################
function(GR_PYTHON_INSTALL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN})
####################################################################
if(GR_PYTHON_INSTALL_FILES)
####################################################################
install(${ARGN}) #installs regular python files
#create a list of all generated files
unset(pysrcfiles)
unset(pycfiles)
unset(pyofiles)
foreach(pyfile ${GR_PYTHON_INSTALL_FILES})
get_filename_component(pyfile ${pyfile} ABSOLUTE)
list(APPEND pysrcfiles ${pyfile})
#determine if this file is in the source or binary directory
file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile})
string(LENGTH "${source_rel_path}" source_rel_path_len)
file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile})
string(LENGTH "${binary_rel_path}" binary_rel_path_len)
#and set the generated path appropriately
if(${source_rel_path_len} GREATER ${binary_rel_path_len})
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path})
else()
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path})
endif()
list(APPEND pycfiles ${pygenfile}c)
list(APPEND pyofiles ${pygenfile}o)
#ensure generation path exists
get_filename_component(pygen_path ${pygenfile} PATH)
file(MAKE_DIRECTORY ${pygen_path})
endforeach(pyfile)
#the command to generate the pyc files
add_custom_command(
DEPENDS ${pysrcfiles} OUTPUT ${pycfiles}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles}
)
#the command to generate the pyo files
add_custom_command(
DEPENDS ${pysrcfiles} OUTPUT ${pyofiles}
COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles}
)
#create install rule and add generated files to target list
set(python_install_gen_targets ${pycfiles} ${pyofiles})
install(FILES ${python_install_gen_targets}
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
)
####################################################################
elseif(GR_PYTHON_INSTALL_PROGRAMS)
####################################################################
file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native)
foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS})
get_filename_component(pyfile_name ${pyfile} NAME)
get_filename_component(pyfile ${pyfile} ABSOLUTE)
string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe")
list(APPEND python_install_gen_targets ${pyexefile})
get_filename_component(pyexefile_path ${pyexefile} PATH)
file(MAKE_DIRECTORY ${pyexefile_path})
add_custom_command(
OUTPUT ${pyexefile} DEPENDS ${pyfile}
COMMAND ${PYTHON_EXECUTABLE} -c
\"open('${pyexefile}', 'w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())\"
COMMENT "Shebangin ${pyfile_name}"
)
#on windows, python files need an extension to execute
get_filename_component(pyfile_ext ${pyfile} EXT)
if(WIN32 AND NOT pyfile_ext)
set(pyfile_name "${pyfile_name}.py")
endif()
install(PROGRAMS ${pyexefile} RENAME ${pyfile_name}
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
)
endforeach(pyfile)
endif()
GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets})
endfunction(GR_PYTHON_INSTALL)
########################################################################
# Write the python helper script that generates byte code files
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py "
import sys, py_compile
files = sys.argv[1:]
srcs, gens = files[:len(files)/2], files[len(files)/2:]
for src, gen in zip(srcs, gens):
py_compile.compile(file=src, cfile=gen, doraise=True)
")

View File

@ -1,229 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio 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, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_SWIG_CMAKE)
return()
endif()
set(__INCLUDED_GR_SWIG_CMAKE TRUE)
include(GrPython)
########################################################################
# Builds a swig documentation file to be generated into python docstrings
# Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....)
#
# Set the following variable to specify extra dependent targets:
# - GR_SWIG_DOCS_SOURCE_DEPS
# - GR_SWIG_DOCS_TARGET_DEPS
########################################################################
function(GR_SWIG_MAKE_DOCS output_file)
find_package(Doxygen)
if(DOXYGEN_FOUND)
#setup the input files variable list, quote formated
set(input_files)
unset(INPUT_PATHS)
foreach(input_path ${ARGN})
if (IS_DIRECTORY ${input_path}) #when input path is a directory
file(GLOB input_path_h_files ${input_path}/*.h)
else() #otherwise its just a file, no glob
set(input_path_h_files ${input_path})
endif()
list(APPEND input_files ${input_path_h_files})
set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"")
endforeach(input_path)
#determine the output directory
get_filename_component(name ${output_file} NAME_WE)
get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH)
set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs)
make_directory(${OUTPUT_DIRECTORY})
#generate the Doxyfile used by doxygen
configure_file(
${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in
${OUTPUT_DIRECTORY}/Doxyfile
@ONLY)
#Create a dummy custom command that depends on other targets
include(GrMiscUtils)
GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS})
#call doxygen on the Doxyfile + input headers
add_custom_command(
OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml
DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps}
COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile
COMMENT "Generating doxygen xml for ${name} docs"
)
#call the swig_doc script on the xml files
add_custom_command(
OUTPUT ${output_file}
DEPENDS ${input_files} ${OUTPUT_DIRECTORY}/xml/index.xml
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py
${OUTPUT_DIRECTORY}/xml
${output_file}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen
)
else(DOXYGEN_FOUND)
file(WRITE ${output_file} "\n") #no doxygen -> empty file
endif(DOXYGEN_FOUND)
endfunction(GR_SWIG_MAKE_DOCS)
########################################################################
# Build a swig target for the common gnuradio use case. Usage:
# GR_SWIG_MAKE(target ifile ifile ifile...)
#
# Set the following variables before calling:
# - GR_SWIG_FLAGS
# - GR_SWIG_INCLUDE_DIRS
# - GR_SWIG_LIBRARIES
# - GR_SWIG_SOURCE_DEPS
# - GR_SWIG_TARGET_DEPS
# - GR_SWIG_DOC_FILE
# - GR_SWIG_DOC_DIRS
########################################################################
macro(GR_SWIG_MAKE name)
set(ifiles ${ARGN})
#do swig doc generation if specified
if (GR_SWIG_DOC_FILE)
set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS})
set(GR_SWIG_DOCS_TAREGT_DEPS ${GR_SWIG_TARGET_DEPS})
GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS})
list(APPEND GR_SWIG_SOURCE_DEPS ${GR_SWIG_DOC_FILE})
endif()
#append additional include directories
find_package(PythonLibs 2)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
#determine include dependencies for swig file
execute_process(
COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_BINARY_DIR}/get_swig_deps.py
"${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
#Create a dummy custom command that depends on other targets
include(GrMiscUtils)
GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS})
set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag)
add_custom_command(
OUTPUT ${tag_file}
DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps}
COMMAND ${CMAKE_COMMAND} -E touch ${tag_file}
)
#append the specified include directories
include_directories(${GR_SWIG_INCLUDE_DIRS})
list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file})
#setup the swig flags with flags and include directories
set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS})
foreach(dir ${GR_SWIG_INCLUDE_DIRS})
list(APPEND CMAKE_SWIG_FLAGS "-I${dir}")
endforeach(dir)
#set the C++ property on the swig .i file so it builds
set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON)
#setup the actual swig library target to be built
include(UseSWIG)
SWIG_ADD_MODULE(${name} python ${ifiles})
SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES})
endmacro(GR_SWIG_MAKE)
########################################################################
# Install swig targets generated by GR_SWIG_MAKE. Usage:
# GR_SWIG_INSTALL(
# TARGETS target target target...
# [DESTINATION destination]
# [COMPONENT component]
# )
########################################################################
macro(GR_SWIG_INSTALL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN})
foreach(name ${GR_SWIG_INSTALL_TARGETS})
install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME}
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
)
include(GrPython)
GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
)
GR_LIBTOOL(
TARGET ${SWIG_MODULE_${name}_REAL_NAME}
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
)
endforeach(name)
endmacro(GR_SWIG_INSTALL)
########################################################################
# Generate a python file that can determine swig dependencies.
# Used by the make macro above to determine extra dependencies.
# When you build C++, CMake figures out the header dependencies.
# This code essentially performs that logic for swig includes.
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py "
import os, sys, re
include_matcher = re.compile('[#|%]include\\s*[<|\"](.*)[>|\"]')
include_dirs = sys.argv[2].split(';')
def get_swig_incs(file_path):
file_contents = open(file_path, 'r').read()
return include_matcher.findall(file_contents, re.MULTILINE)
def get_swig_deps(file_path, level):
deps = [file_path]
if level == 0: return deps
for inc_file in get_swig_incs(file_path):
for inc_dir in include_dirs:
inc_path = os.path.join(inc_dir, inc_file)
if not os.path.exists(inc_path): continue
deps.extend(get_swig_deps(inc_path, level-1))
return deps
if __name__ == '__main__':
ifiles = sys.argv[1].split(';')
deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], [])
#sys.stderr.write(';'.join(set(deps)) + '\\n\\n')
print(';'.join(set(deps)))
")

View File

@ -1,133 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio 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, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_TEST_CMAKE)
return()
endif()
set(__INCLUDED_GR_TEST_CMAKE TRUE)
########################################################################
# Add a unit test and setup the environment for a unit test.
# Takes the same arguments as the ADD_TEST function.
#
# Before calling set the following variables:
# GR_TEST_TARGET_DEPS - built targets for the library path
# GR_TEST_LIBRARY_DIRS - directories for the library path
# GR_TEST_PYTHON_DIRS - directories for the python path
########################################################################
function(GR_ADD_TEST test_name)
if(WIN32)
#Ensure that the build exe also appears in the PATH.
list(APPEND GR_TEST_TARGET_DEPS ${ARGN})
#In the land of windows, all libraries must be in the PATH.
#Since the dependent libraries are not yet installed,
#we must manually set them in the PATH to run tests.
#The following appends the path of a target dependency.
foreach(target ${GR_TEST_TARGET_DEPS})
get_target_property(location ${target} LOCATION)
if(location)
get_filename_component(path ${location} PATH)
string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path})
list(APPEND GR_TEST_LIBRARY_DIRS ${path})
endif(location)
endforeach(target)
#SWIG generates the python library files into a subdirectory.
#Therefore, we must append this subdirectory into PYTHONPATH.
#Only do this for the python directories matching the following:
foreach(pydir ${GR_TEST_PYTHON_DIRS})
get_filename_component(name ${pydir} NAME)
if(name MATCHES "^(swig|lib|src)$")
list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE})
endif()
endforeach(pydir)
endif(WIN32)
file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir)
file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list?
file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list?
set(environs "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}")
#http://www.cmake.org/pipermail/cmake/2009-May/029464.html
#Replaced this add test + set environs code with the shell script generation.
#Its nicer to be able to manually run the shell script to diagnose problems.
#ADD_TEST(${ARGV})
#SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}")
if(UNIX)
set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH")
#set both LD and DYLD paths to cover multiple UNIX OS library paths
list(APPEND libpath "$LD_LIBRARY_PATH" "$DYLD_LIBRARY_PATH")
list(APPEND pypath "$PYTHONPATH")
#replace list separator with the path separator
string(REPLACE ";" ":" libpath "${libpath}")
string(REPLACE ";" ":" pypath "${pypath}")
list(APPEND environs "PATH=${binpath}" "LD_LIBRARY_PATH=${libpath}" "DYLD_LIBRARY_PATH=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
find_program(SHELL sh)
set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)
file(WRITE ${sh_file} "#!${SHELL}\n")
#each line sets an environment variable
foreach(environ ${environs})
file(APPEND ${sh_file} "export ${environ}\n")
endforeach(environ)
#load the command to run with its arguments
foreach(arg ${ARGN})
file(APPEND ${sh_file} "${arg} ")
endforeach(arg)
file(APPEND ${sh_file} "\n")
#make the shell file executable
execute_process(COMMAND chmod +x ${sh_file})
add_test(${test_name} ${SHELL} ${sh_file})
endif(UNIX)
if(WIN32)
list(APPEND libpath ${DLL_PATHS} "%PATH%")
list(APPEND pypath "%PYTHONPATH%")
#replace list separator with the path separator (escaped)
string(REPLACE ";" "\\;" libpath "${libpath}")
string(REPLACE ";" "\\;" pypath "${pypath}")
list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat)
file(WRITE ${bat_file} "@echo off\n")
#each line sets an environment variable
foreach(environ ${environs})
file(APPEND ${bat_file} "SET ${environ}\n")
endforeach(environ)
#load the command to run with its arguments
foreach(arg ${ARGN})
file(APPEND ${bat_file} "${arg} ")
endforeach(arg)
file(APPEND ${bat_file} "\n")
add_test(${test_name} ${bat_file})
endif(WIN32)
endfunction(GR_ADD_TEST)

View File

@ -1,82 +0,0 @@
# Copyright 2011,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio 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, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_VERSION_CMAKE)
return()
endif()
set(__INCLUDED_GR_VERSION_CMAKE TRUE)
#eventually, replace version.sh and fill in the variables below
set(MAJOR_VERSION ${VERSION_INFO_MAJOR_VERSION})
set(API_COMPAT ${VERSION_INFO_API_COMPAT})
set(MINOR_VERSION ${VERSION_INFO_MINOR_VERSION})
set(MAINT_VERSION ${VERSION_INFO_MAINT_VERSION})
########################################################################
# Extract the version string from git describe.
########################################################################
find_package(Git)
if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
message(STATUS "Extracting version information from git describe...")
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --always --abbrev=8 --long
OUTPUT_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
else()
set(GIT_DESCRIBE "v${MAJOR_VERSION}.${API_COMPAT}.x-xxx-xunknown")
endif()
########################################################################
# Use the logic below to set the version constants
########################################################################
if("${MINOR_VERSION}" STREQUAL "git")
# VERSION: 3.3git-xxx-gxxxxxxxx
# DOCVER: 3.3git
# LIBVER: 3.3git
set(VERSION "${GIT_DESCRIBE}")
set(DOCVER "${MAJOR_VERSION}.${API_COMPAT}${MINOR_VERSION}")
set(LIBVER "${MAJOR_VERSION}.${API_COMPAT}${MINOR_VERSION}")
set(RC_MINOR_VERSION "0")
set(RC_MAINT_VERSION "0")
elseif("${MAINT_VERSION}" STREQUAL "git")
# VERSION: 3.3.1git-xxx-gxxxxxxxx
# DOCVER: 3.3.1git
# LIBVER: 3.3.1git
set(VERSION "${GIT_DESCRIBE}")
set(DOCVER "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}${MAINT_VERSION}")
set(LIBVER "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}${MAINT_VERSION}")
math(EXPR RC_MINOR_VERSION "${MINOR_VERSION} - 1")
set(RC_MAINT_VERSION "0")
else()
# This is a numbered release.
# VERSION: 3.3.1{.x}
# DOCVER: 3.3.1{.x}
# LIBVER: 3.3.1{.x}
if("${MAINT_VERSION}" STREQUAL "0")
set(VERSION "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}")
else()
set(VERSION "${MAJOR_VERSION}.${API_COMPAT}.${MINOR_VERSION}.${MAINT_VERSION}")
endif()
set(DOCVER "${VERSION}")
set(LIBVER "${VERSION}")
set(RC_MINOR_VERSION ${MINOR_VERSION})
set(RC_MAINT_VERSION ${MAINT_VERSION})
endif()

View File

@ -0,0 +1,69 @@
# Author (C) 2018 by Piotr Krysik <ptrkrysik@gmail.com>
# Author (C) 2018 by Vasil Velichkov <vvvelichkov@gmail.com>
#
# This file is part of GNU Radio
#
# GNU Radio 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, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
SET(PYTHONPATH
${CMAKE_SOURCE_DIR}/python
${CMAKE_SOURCE_DIR}/python/misc_utils
${CMAKE_SOURCE_DIR}/python/demapping
${CMAKE_SOURCE_DIR}/python/receiver
${CMAKE_SOURCE_DIR}/python/transmitter
${CMAKE_SOURCE_DIR}/python/trx
${CMAKE_BINARY_DIR}/swig
$ENV{PYTHONPATH}
)
string(REPLACE ";" ":" PYTHONPATH "${PYTHONPATH}")
find_program(GRCC grcc
PATHS ${CMAKE_INSTALL_PREFIX}/${GR_RUNTIME_DIR}
)
macro(GRCC_COMPILE file_name)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${file_name}
COMMAND "${CMAKE_COMMAND}"
-E env PYTHONPATH="${PYTHONPATH}" GRC_BLOCKS_PATH=${CMAKE_SOURCE_DIR}/grc
CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}
${GRCC} -o ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.grc
COMMAND "${CMAKE_COMMAND}" -E rename ${CMAKE_CURRENT_BINARY_DIR}/${file_name}.py ${CMAKE_CURRENT_BINARY_DIR}/${file_name}
DEPENDS ${file_name}.grc
)
endmacro(GRCC_COMPILE)
########################################################################
# Override the GR_UNIQUE_TARGET function to not append a hash
# to the `target` name, because we need a known name in order
# to add an explicit dependency that's needed for the parallel build
#
# The original code segment (taken from GrPython.cmake) is
#
# execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
#unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
#print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
# OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
#
########################################################################
function(GR_UNIQUE_TARGET desc)
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
print(re.sub('\\W', '_', '${desc} ${reldir}'))"
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_target(${_target} ALL DEPENDS ${ARGN})
endfunction(GR_UNIQUE_TARGET)

View File

@ -1,5 +1,4 @@
#
# Copyright 2004 Free Software Foundation, Inc.
# Copyright 2018 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@ -17,36 +16,11 @@
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
def i_code (code3):
return code3[0]
include(CMakeFindDependencyMacro)
def o_code (code3):
if len (code3) >= 2:
return code3[1]
else:
return code3[0]
def tap_code (code3):
if len (code3) >= 3:
return code3[2]
else:
return code3[0]
def i_type (code3):
return char_to_type[i_code (code3)]
def o_type (code3):
return char_to_type[o_code (code3)]
def tap_type (code3):
return char_to_type[tap_code (code3)]
char_to_type = {}
char_to_type['s'] = 'short'
char_to_type['i'] = 'int'
char_to_type['f'] = 'float'
char_to_type['c'] = 'gr_complex'
char_to_type['b'] = 'unsigned char'
set(target_deps "@TARGET_DEPENDENCIES@")
foreach(dep IN LISTS target_deps)
find_dependency(${dep})
endforeach()
include("${CMAKE_CURRENT_LIST_DIR}/@TARGET@Targets.cmake")

38
dists/arch/PKGBUILD Normal file
View File

@ -0,0 +1,38 @@
# Maintainer: Vadim Yanitskiy
pkgname=gr-gsm
pkgver=v1165.13e42c4
pkgrel=1
pkgdesc="GNU Radio blocks and tools for receiving GSM transmissions"
arch=('any')
url="https://github.com/ptrkrysik/gr-gsm"
license=('GPL2')
# TODO: libosmocore?
depends=('gnuradio' 'gnuradio-osmosdr' 'boost' 'swig')
makedepends=('cmake')
provides=('gr-gsm')
source=(git://git.osmocom.org/${pkgname})
sha1sums=('SKIP')
pkgver() {
cd "$srcdir/$pkgname"
printf "v%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
build() {
cd "$srcdir/$pkgname"
mkdir build && cd build
cmake \
-DCMAKE_INSTALL_PREFIX=/usr \
-DENABLE_DOXYGEN=OFF \
-Wno-dev \
..
make
}
package() {
cd "$srcdir/$pkgname/build"
make DESTDIR=${pkgdir} install
}
# vim:set ts=2 sw=2 et:

View File

@ -54,7 +54,11 @@ if(NOT RST2MAN_EXECUTABLE)
message(WARNING "rst2man from python-docutils is required to build man pages")
else()
build_man_page(MAN1_OUTPUT grgsm_livemon.rst grgsm_livemon.1)
install(FILES ${MAN1_OUTPUT} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1)
install(
FILES
${MAN1_OUTPUT}
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1
)
endif()

View File

@ -1,6 +1,7 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -49,4 +50,8 @@ add_custom_command(
add_custom_target(doxygen_target ALL DEPENDS ${BUILT_DIRS})
install(DIRECTORY ${BUILT_DIRS} DESTINATION ${GR_PKG_DOC_DIR})
install(
DIRECTORY
${BUILT_DIRS}
DESTINATION ${GR_PKG_DOC_DIR}
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -63,8 +64,9 @@ This line is uninformative and is only to test line breaks in the comments.
u'Outputs the vital aadvark statistics.'
"""
from __future__ import unicode_literals
from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
def _test():
import os

View File

@ -1,7 +1,8 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -24,24 +25,26 @@ A base class is created.
Classes based upon this are used to make more user-friendly interfaces
to the doxygen xml docs than the generated classes provide.
"""
from __future__ import print_function
from __future__ import unicode_literals
import os
import pdb
from xml.parsers.expat import ExpatError
from generated import compound
from .generated import compound
class Base(object):
class Duplicate(StandardError):
class Duplicate(Exception):
pass
class NoSuchMember(StandardError):
class NoSuchMember(Exception):
pass
class ParsingError(StandardError):
class ParsingError(Exception):
pass
def __init__(self, parse_data, top=None):
@ -94,7 +97,7 @@ class Base(object):
for cls in self.mem_classes:
if cls.can_parse(mem):
return cls
raise StandardError(("Did not find a class for object '%s'." \
raise Exception(("Did not find a class for object '%s'." \
% (mem.get_name())))
def convert_mem(self, mem):
@ -102,11 +105,11 @@ class Base(object):
cls = self.get_cls(mem)
converted = cls.from_parse_data(mem, self.top)
if converted is None:
raise StandardError('No class matched this object.')
raise Exception('No class matched this object.')
self.add_ref(converted)
return converted
except StandardError, e:
print e
except Exception as e:
print(e)
@classmethod
def includes(cls, inst):

View File

@ -1,7 +1,8 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -22,12 +23,14 @@
Classes providing more user-friendly interfaces to the doxygen xml
docs than the generated classes provide.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
import os
from generated import index
from base import Base
from text import description
from .generated import index
from .base import Base
from .text import description
class DoxyIndex(Base):
"""
@ -43,13 +46,16 @@ class DoxyIndex(Base):
self._root = index.parse(os.path.join(self._xml_path, 'index.xml'))
for mem in self._root.compound:
converted = self.convert_mem(mem)
# For files we want the contents to be accessible directly
# from the parent rather than having to go through the file
# object.
# For files and namespaces we want the contents to be
# accessible directly from the parent rather than having
# to go through the file object.
if self.get_cls(mem) == DoxyFile:
if mem.name.endswith('.h'):
self._members += converted.members()
self._members.append(converted)
elif self.get_cls(mem) == DoxyNamespace:
self._members += converted.members()
self._members.append(converted)
else:
self._members.append(converted)
@ -80,13 +86,29 @@ class DoxyCompMem(Base):
self._data['brief_description'] = bd
self._data['detailed_description'] = dd
def set_parameters(self, data):
vs = [ddc.value for ddc in data.detaileddescription.content_]
pls = []
for v in vs:
if hasattr(v, 'parameterlist'):
pls += v.parameterlist
pis = []
for pl in pls:
pis += pl.parameteritem
dpis = []
for pi in pis:
dpi = DoxyParameterItem(pi)
dpi._parse()
dpis.append(dpi)
self._data['params'] = dpis
class DoxyCompound(DoxyCompMem):
pass
class DoxyMember(DoxyCompMem):
pass
class DoxyFunction(DoxyMember):
__module__ = "gnuradio.utils.doxyxml"
@ -98,10 +120,13 @@ class DoxyFunction(DoxyMember):
return
super(DoxyFunction, self)._parse()
self.set_descriptions(self._parse_data)
self._data['params'] = []
prms = self._parse_data.param
for prm in prms:
self._data['params'].append(DoxyParam(prm))
self.set_parameters(self._parse_data)
if not self._data['params']:
# If the params weren't set by a comment then just grab the names.
self._data['params'] = []
prms = self._parse_data.param
for prm in prms:
self._data['params'].append(DoxyParam(prm))
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
@ -121,9 +146,39 @@ class DoxyParam(DoxyMember):
self.set_descriptions(self._parse_data)
self._data['declname'] = self._parse_data.declname
@property
def description(self):
descriptions = []
if self.brief_description:
descriptions.append(self.brief_description)
if self.detailed_description:
descriptions.append(self.detailed_description)
return '\n\n'.join(descriptions)
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
declname = property(lambda self: self.data()['declname'])
name = property(lambda self: self.data()['declname'])
class DoxyParameterItem(DoxyMember):
"""A different representation of a parameter in Doxygen."""
def _parse(self):
if self._parsed:
return
super(DoxyParameterItem, self)._parse()
names = []
for nl in self._parse_data.parameternamelist:
for pn in nl.parametername:
names.append(description(pn))
# Just take first name
self._data['name'] = names[0]
# Get description
pd = description(self._parse_data.get_parameterdescription())
self._data['description'] = pd
description = property(lambda self: self.data()['description'])
name = property(lambda self: self.data()['name'])
class DoxyClass(DoxyCompound):
@ -139,12 +194,14 @@ class DoxyClass(DoxyCompound):
if self._error:
return
self.set_descriptions(self._retrieved_data.compounddef)
self.set_parameters(self._retrieved_data.compounddef)
# Sectiondef.kind tells about whether private or public.
# We just ignore this for now.
self.process_memberdefs()
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
params = property(lambda self: self.data()['params'])
Base.mem_classes.append(DoxyClass)
@ -177,6 +234,16 @@ class DoxyNamespace(DoxyCompound):
kind = 'namespace'
def _parse(self):
if self._parsed:
return
super(DoxyNamespace, self)._parse()
self.retrieve_data()
self.set_descriptions(self._retrieved_data.compounddef)
if self._error:
return
self.process_memberdefs()
Base.mem_classes.append(DoxyNamespace)
@ -227,11 +294,11 @@ class DoxyOther(Base):
__module__ = "gnuradio.utils.doxyxml"
kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 'dir', 'page'])
kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum',
'dir', 'page', 'signal', 'slot', 'property'])
@classmethod
def can_parse(cls, obj):
return obj.kind in cls.kinds
Base.mem_classes.append(DoxyOther)

View File

@ -5,3 +5,4 @@ These do the real work of parsing the doxygen xml files but the
resultant classes are not very friendly to navigate so the rest of the
doxyxml module processes them further.
"""
from __future__ import unicode_literals

View File

@ -1,17 +1,19 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
Generated Mon Feb 9 19:08:05 2009 by generateDS.py.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
from string import lower as str_lower
from xml.dom import minidom
from xml.dom import Node
import sys
import compoundsuper as supermod
from compoundsuper import MixedContainer
from . import compoundsuper as supermod
from .compoundsuper import MixedContainer
class DoxygenTypeSub(supermod.DoxygenType):

View File

@ -1,15 +1,20 @@
#!/usr/bin/env python
#!/usr/bin/env python3
#
# Generated Thu Jun 11 18:44:25 2009 by generateDS.py.
#
from __future__ import print_function
from __future__ import unicode_literals
import sys
import getopt
from string import lower as str_lower
from xml.dom import minidom
from xml.dom import Node
import six
#
# User methods
#
@ -19,9 +24,9 @@ from xml.dom import Node
try:
from generatedssuper import GeneratedsSuper
except ImportError, exp:
except ImportError as exp:
class GeneratedsSuper:
class GeneratedsSuper(object):
def format_string(self, input_data, input_name=''):
return input_data
def format_integer(self, input_data, input_name=''):
@ -64,7 +69,7 @@ def showIndent(outfile, level):
outfile.write(' ')
def quote_xml(inStr):
s1 = (isinstance(inStr, basestring) and inStr or
s1 = (isinstance(inStr, six.string_types) and inStr or
'%s' % inStr)
s1 = s1.replace('&', '&amp;')
s1 = s1.replace('<', '&lt;')
@ -72,7 +77,7 @@ def quote_xml(inStr):
return s1
def quote_attrib(inStr):
s1 = (isinstance(inStr, basestring) and inStr or
s1 = (isinstance(inStr, six.string_types) and inStr or
'%s' % inStr)
s1 = s1.replace('&', '&amp;')
s1 = s1.replace('<', '&lt;')
@ -102,7 +107,7 @@ def quote_python(inStr):
return '"""%s"""' % s1
class MixedContainer:
class MixedContainer(object):
# Constants for category:
CategoryNone = 0
CategoryText = 1
@ -4221,7 +4226,7 @@ class codelineType(GeneratedsSuper):
if attrs.get('lineno'):
try:
self.lineno = int(attrs.get('lineno').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (lineno): %s' % exp)
if attrs.get('refkind'):
self.refkind = attrs.get('refkind').value
@ -4504,12 +4509,12 @@ class referenceType(GeneratedsSuper):
if attrs.get('endline'):
try:
self.endline = int(attrs.get('endline').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (endline): %s' % exp)
if attrs.get('startline'):
try:
self.startline = int(attrs.get('startline').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (startline): %s' % exp)
if attrs.get('refid'):
self.refid = attrs.get('refid').value
@ -4627,17 +4632,17 @@ class locationType(GeneratedsSuper):
if attrs.get('bodystart'):
try:
self.bodystart = int(attrs.get('bodystart').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (bodystart): %s' % exp)
if attrs.get('line'):
try:
self.line = int(attrs.get('line').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (line): %s' % exp)
if attrs.get('bodyend'):
try:
self.bodyend = int(attrs.get('bodyend').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (bodyend): %s' % exp)
if attrs.get('bodyfile'):
self.bodyfile = attrs.get('bodyfile').value
@ -6778,12 +6783,12 @@ class docTableType(GeneratedsSuper):
if attrs.get('rows'):
try:
self.rows = int(attrs.get('rows').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (rows): %s' % exp)
if attrs.get('cols'):
try:
self.cols = int(attrs.get('cols').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (cols): %s' % exp)
def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.ELEMENT_NODE and \
@ -7108,7 +7113,7 @@ class docHeadingType(GeneratedsSuper):
if attrs.get('level'):
try:
self.level = int(attrs.get('level').value)
except ValueError, exp:
except ValueError as exp:
raise ValueError('Bad integer attribute (level): %s' % exp)
def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.TEXT_NODE:
@ -8283,7 +8288,7 @@ Options:
"""
def usage():
print USAGE_TEXT
print(USAGE_TEXT)
sys.exit(1)
@ -8339,4 +8344,3 @@ if __name__ == '__main__':
main()
#import pdb
#pdb.run('main()')

View File

@ -1,16 +1,18 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
Generated Mon Feb 9 19:08:05 2009 by generateDS.py.
"""
from __future__ import absolute_import
from __future__ import unicode_literals
from xml.dom import minidom
import os
import sys
import compound
from . import compound
import indexsuper as supermod
from . import indexsuper as supermod
class DoxygenTypeSub(supermod.DoxygenType):
def __init__(self, version=None, compound=None):

View File

@ -1,15 +1,19 @@
#!/usr/bin/env python
#!/usr/bin/env python3
#
# Generated Thu Jun 11 18:43:54 2009 by generateDS.py.
#
from __future__ import print_function
from __future__ import unicode_literals
import sys
import getopt
from string import lower as str_lower
from xml.dom import minidom
from xml.dom import Node
import six
#
# User methods
#
@ -19,9 +23,9 @@ from xml.dom import Node
try:
from generatedssuper import GeneratedsSuper
except ImportError, exp:
except ImportError as exp:
class GeneratedsSuper:
class GeneratedsSuper(object):
def format_string(self, input_data, input_name=''):
return input_data
def format_integer(self, input_data, input_name=''):
@ -64,7 +68,7 @@ def showIndent(outfile, level):
outfile.write(' ')
def quote_xml(inStr):
s1 = (isinstance(inStr, basestring) and inStr or
s1 = (isinstance(inStr, six.string_types) and inStr or
'%s' % inStr)
s1 = s1.replace('&', '&amp;')
s1 = s1.replace('<', '&lt;')
@ -72,7 +76,7 @@ def quote_xml(inStr):
return s1
def quote_attrib(inStr):
s1 = (isinstance(inStr, basestring) and inStr or
s1 = (isinstance(inStr, six.string_types) and inStr or
'%s' % inStr)
s1 = s1.replace('&', '&amp;')
s1 = s1.replace('<', '&lt;')
@ -102,7 +106,7 @@ def quote_python(inStr):
return '"""%s"""' % s1
class MixedContainer:
class MixedContainer(object):
# Constants for category:
CategoryNone = 0
CategoryText = 1
@ -462,7 +466,7 @@ Options:
"""
def usage():
print USAGE_TEXT
print(USAGE_TEXT)
sys.exit(1)
@ -520,4 +524,3 @@ if __name__ == '__main__':
main()
#import pdb
#pdb.run('main()')

View File

@ -1,7 +1,8 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -21,12 +22,13 @@
"""
Utilities for extracting text from generated classes.
"""
from __future__ import unicode_literals
def is_string(txt):
if isinstance(txt, str):
return True
try:
if isinstance(txt, unicode):
if isinstance(txt, str):
return True
except NameError:
pass
@ -49,7 +51,7 @@ def description_bit(obj):
elif is_string(obj):
return obj
else:
raise StandardError('Expecting a string or something with content, content_ or value attribute')
raise Exception('Expecting a string or something with content, content_ or value attribute')
# If this bit is a paragraph then add one some line breaks.
if hasattr(obj, 'name') and obj.name == 'para':
result += "\n\n"

View File

@ -1,7 +1,8 @@
#
# Copyright 2010,2011 Free Software Foundation, Inc.
# Copyright 2010-2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-gsm
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -26,14 +27,12 @@ The file instructs SWIG to transfer the doxygen comments into the
python docstrings.
"""
from __future__ import unicode_literals
import sys
try:
from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base
except ImportError:
from gnuradio.doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base
import sys, time
from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile
from doxyxml import DoxyOther, base
def py_name(name):
bits = name.split('_')
@ -56,18 +55,41 @@ class Block(object):
# Check for a parsing error.
if item.error():
return False
return item.has_member(make_name(item.name()), DoxyFriend)
friendname = make_name(item.name())
is_a_block = item.has_member(friendname, DoxyFriend)
# But now sometimes the make function isn't a friend so check again.
if not is_a_block:
is_a_block = di.has_member(friendname, DoxyFunction)
return is_a_block
class Block2(object):
"""
Checks if doxyxml produced objects correspond to a new style
gnuradio block.
"""
@classmethod
def includes(cls, item):
if not isinstance(item, DoxyClass):
return False
# Check for a parsing error.
if item.error():
return False
is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther)
return is_a_block2
def utoascii(text):
"""
Convert unicode text into ascii and escape quotes.
Convert unicode text into ascii and escape quotes and backslashes.
"""
if text is None:
return ''
out = text.encode('ascii', 'replace')
out = out.replace('"', '\\"')
return out
# swig will require us to replace blackslash with 4 backslashes
out = out.replace(b'\\', b'\\\\\\\\')
out = out.replace(b'"', b'\\"').decode('ascii')
return str(out)
def combine_descriptions(obj):
@ -83,9 +105,15 @@ def combine_descriptions(obj):
description.append(dd)
return utoascii('\n\n'.join(description)).strip()
def format_params(parameteritems):
output = ['Args:']
template = ' {0} : {1}'
for pi in parameteritems:
output.append(template.format(pi.name, pi.description))
return '\n'.join(output)
entry_templ = '%feature("docstring") {name} "{docstring}"'
def make_entry(obj, name=None, templ="{description}", description=None):
def make_entry(obj, name=None, templ="{description}", description=None, params=[]):
"""
Create a docstring entry for a swig interface file.
@ -102,6 +130,9 @@ def make_entry(obj, name=None, templ="{description}", description=None):
return ''
if description is None:
description = combine_descriptions(obj)
if params:
description += '\n\n'
description += utoascii(format_params(params))
docstring = templ.format(description=description)
if not docstring:
return ''
@ -121,27 +152,31 @@ def make_func_entry(func, name=None, description=None, params=None):
used as the description instead of extracting it from func.
params - a parameter list that overrides using func.params.
"""
if params is None:
params = func.params
params = [prm.declname for prm in params]
if params:
sig = "Params: (%s)" % ", ".join(params)
else:
sig = "Params: (NONE)"
templ = "{description}\n\n" + sig
return make_entry(func, name=name, templ=utoascii(templ),
description=description)
#if params is None:
# params = func.params
#params = [prm.declname for prm in params]
#if params:
# sig = "Params: (%s)" % ", ".join(params)
#else:
# sig = "Params: (NONE)"
#templ = "{description}\n\n" + sig
#return make_entry(func, name=name, templ=utoascii(templ),
# description=description)
return make_entry(func, name=name, description=description, params=params)
def make_class_entry(klass, description=None):
def make_class_entry(klass, description=None, ignored_methods=[], params=None):
"""
Create a class docstring for a swig interface file.
"""
if params is None:
params = klass.params
output = []
output.append(make_entry(klass, description=description))
output.append(make_entry(klass, description=description, params=params))
for func in klass.in_category(DoxyFunction):
name = klass.name() + '::' + func.name()
output.append(make_func_entry(func, name=name))
if func.name() not in ignored_methods:
name = klass.name() + '::' + func.name()
output.append(make_func_entry(func, name=name))
return "\n\n".join(output)
@ -175,11 +210,33 @@ def make_block_entry(di, block):
# the make function.
output = []
output.append(make_class_entry(block, description=super_description))
creator = block.get_member(block.name(), DoxyFunction)
output.append(make_func_entry(make_func, description=super_description,
params=creator.params))
params=block.params))
return "\n\n".join(output)
def make_block2_entry(di, block):
"""
Create class and function docstrings of a new style gnuradio block for a
swig interface file.
"""
descriptions = []
# For new style blocks all the relevant documentation should be
# associated with the 'make' method.
class_description = combine_descriptions(block)
make_func = block.get_member('make', DoxyFunction)
make_description = combine_descriptions(make_func)
description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description
# Associate the combined description with the class and
# the make function.
output = []
output.append(make_class_entry(
block, description=description,
ignored_methods=['make'], params=make_func.params))
makename = block.name() + '::make'
output.append(make_func_entry(
make_func, name=makename, description=description,
params=make_func.params))
return "\n\n".join(output)
def make_swig_interface_file(di, swigdocfilename, custom_output=None):
@ -196,39 +253,59 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
# Create docstrings for the blocks.
blocks = di.in_category(Block)
blocks2 = di.in_category(Block2)
make_funcs = set([])
for block in blocks:
try:
make_func = di.get_member(make_name(block.name()), DoxyFunction)
make_funcs.add(make_func.name())
output.append(make_block_entry(di, block))
# Don't want to risk writing to output twice.
if make_func.name() not in make_funcs:
make_funcs.add(make_func.name())
output.append(make_block_entry(di, block))
except block.ParsingError:
print('Parsing error for block %s' % block.name())
sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
raise
for block in blocks2:
try:
make_func = block.get_member('make', DoxyFunction)
make_func_name = block.name() +'::make'
# Don't want to risk writing to output twice.
if make_func_name not in make_funcs:
make_funcs.add(make_func_name)
output.append(make_block2_entry(di, block))
except block.ParsingError:
sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
raise
# Create docstrings for functions
# Don't include the make functions since they have already been dealt with.
funcs = [f for f in di.in_category(DoxyFunction) if f.name() not in make_funcs]
funcs = [f for f in di.in_category(DoxyFunction)
if f.name() not in make_funcs and not f.name().startswith('std::')]
for f in funcs:
try:
output.append(make_func_entry(f))
except f.ParsingError:
print('Parsing error for function %s' % f.name())
sys.stderr.write('Parsing error for function {0}\n'.format(f.name()))
# Create docstrings for classes
block_names = [block.name() for block in blocks]
klasses = [k for k in di.in_category(DoxyClass) if k.name() not in block_names]
block_names += [block.name() for block in blocks2]
klasses = [k for k in di.in_category(DoxyClass)
if k.name() not in block_names and not k.name().startswith('std::')]
for k in klasses:
try:
output.append(make_class_entry(k))
except k.ParsingError:
print('Parsing error for class %s' % k.name())
sys.stderr.write('Parsing error for class {0}\n'.format(k.name()))
# Docstrings are not created for anything that is not a function or a class.
# If this excludes anything important please add it here.
output = "\n\n".join(output)
swig_doc = file(swigdocfilename, 'w')
swig_doc = open(swigdocfilename, 'w')
swig_doc.write(output)
swig_doc.close()
@ -236,7 +313,7 @@ if __name__ == "__main__":
# Parse command line options and set up doxyxml.
err_msg = "Execute using: python swig_doc.py xml_path outputfilename"
if len(sys.argv) != 3:
raise StandardError(err_msg)
raise Exception(err_msg)
xml_path = sys.argv[1]
swigdocfilename = sys.argv[2]
di = DoxyIndex(xml_path)

View File

@ -24,6 +24,9 @@ add_subdirectory(receiver)
add_subdirectory(flow_control)
add_subdirectory(misc_utils)
add_subdirectory(transmitter)
install(FILES
gsm_block_tree.xml DESTINATION share/gnuradio/grc/blocks
add_subdirectory(trx)
install(
FILES
gsm.tree.yml
DESTINATION share/gnuradio/grc/blocks
)

View File

@ -17,7 +17,10 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
install(FILES
gsm_control_channels_decoder.xml
gsm_tch_f_decoder.xml DESTINATION share/gnuradio/grc/blocks
install(
FILES
gsm_control_channels_decoder.block.yml
gsm_tch_f_decoder.block.yml
gsm_tch_h_decoder.block.yml
DESTINATION share/gnuradio/grc/blocks
)

View File

@ -0,0 +1,19 @@
# auto-generated by grc.converter
id: gsm_control_channels_decoder
label: Control channels decoder
inputs:
- domain: message
id: bursts
outputs:
- domain: message
id: msgs
optional: true
templates:
imports: import grgsm
make: grgsm.control_channels_decoder()
file_format: 1

View File

@ -1,16 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Control channels decoder</name>
<key>gsm_control_channels_decoder</key>
<import>import grgsm</import>
<make>grgsm.control_channels_decoder()</make>
<sink>
<name>bursts</name>
<type>message</type>
</sink>
<source>
<name>msgs</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

View File

@ -0,0 +1,41 @@
# auto-generated by grc.converter
id: gsm_tch_f_decoder
label: TCH/F decoder
parameters:
- id: mode
label: TCH coding mode
dtype: enum
options: [grgsm.TCH_FS, grgsm.TCH_EFR, grgsm.TCH_AFS12_2, grgsm.TCH_AFS10_2, grgsm.TCH_AFS7_95,
grgsm.TCH_AFS7_4, grgsm.TCH_AFS6_7, grgsm.TCH_AFS5_9, grgsm.TCH_AFS5_15, grgsm.TCH_AFS4_75]
option_labels: [GSM-FR, GSM-EFR, GSM-AMR 12.2, GSM-AMR 10.2, GSM-AMR 7.95, GSM-AMR
7.4, GSM-AMR 6.7, GSM-AMR 5.9, GSM-AMR 5.15, GSM-AMR 4.75]
- id: boundary_check
label: Voice boundary detection
dtype: bool
default: 'False'
options: ['False', 'True']
inputs:
- domain: message
id: bursts
outputs:
- domain: message
id: msgs
optional: true
- domain: message
id: voice
optional: true
templates:
imports: import grgsm
make: grgsm.tch_f_decoder(${mode}, ${boundary_check})
documentation: "If \"Voice boundary detection\" is enabled, then only bursts are decoded\
\ as voice where\n\n- the framenumber is greater then the framenumber of a received\
\ \"Connect\" or \"Connect Acknowlegde\" message, and \n- the framenumber is less\
\ then the framenumber of a \"Release\" message"
file_format: 1

View File

@ -1,90 +0,0 @@
<?xml version="1.0"?>
<block>
<name>TCH/F decoder</name>
<key>gsm_tch_f_decoder</key>
<import>import grgsm</import>
<make>grgsm.tch_f_decoder($mode, $boundary_check)</make>
<param>
<name>TCH coding mode</name>
<key>mode</key>
<type>enum</type>
<option>
<name>GSM-FR</name>
<key>grgsm.TCH_FS</key>
</option>
<option>
<name>GSM-EFR</name>
<key>grgsm.TCH_EFR</key>
</option>
<option>
<name>GSM-AMR 12.2</name>
<key>grgsm.TCH_AFS12_2</key>
</option>
<option>
<name>GSM-AMR 10.2</name>
<key>grgsm.TCH_AFS10_2</key>
</option>
<option>
<name>GSM-AMR 7.95</name>
<key>grgsm.TCH_AFS7_95</key>
</option>
<option>
<name>GSM-AMR 7.4</name>
<key>grgsm.TCH_AFS7_4</key>
</option>
<option>
<name>GSM-AMR 6.7</name>
<key>grgsm.TCH_AFS6_7</key>
</option>
<option>
<name>GSM-AMR 5.9</name>
<key>grgsm.TCH_AFS5_9</key>
</option>
<option>
<name>GSM-AMR 5.15</name>
<key>grgsm.TCH_AFS5_15</key>
</option>
<option>
<name>GSM-AMR 4.75</name>
<key>grgsm.TCH_AFS4_75</key>
</option>
</param>
<param>
<name>Voice boundary detection</name>
<key>boundary_check</key>
<value>False</value>
<type>bool</type>
<option>
<name>False</name>
<key>False</key>
</option>
<option>
<name>True</name>
<key>True</key>
</option>
</param>
<sink>
<name>bursts</name>
<type>message</type>
</sink>
<source>
<name>msgs</name>
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>voice</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>
If "Voice boundary detection" is enabled, then only bursts are decoded as voice where
- the framenumber is greater then the framenumber of a received "Connect" or "Connect Acknowlegde" message, and
- the framenumber is less then the framenumber of a "Release" message
</doc>
</block>

View File

@ -0,0 +1,51 @@
# auto-generated by grc.converter
id: gsm_tch_h_decoder
label: TCH/H decoder
parameters:
- id: sub_channel
label: Sub-channel number
dtype: int
default: '0'
options: ['0', '1']
hide: none
- id: multi_rate
label: MultiRate configuration
dtype: string
- id: boundary_check
label: Voice boundary detection
dtype: bool
default: 'False'
options: ['False', 'True']
inputs:
- domain: message
id: bursts
outputs:
- domain: message
id: msgs
optional: true
- domain: message
id: voice
optional: true
asserts:
- ${ sub_channel > -1 and sub_channel < 2 }
templates:
imports: import grgsm
make: grgsm.tch_h_decoder(${sub_channel}, ${multi_rate}, ${boundary_check})
documentation: |-
The MultiRate configuration string should contains the hex string from the
MultiRate configuration element from the Assignment Command message.
Example: 28111a40.
See 3GPP TS 44.018 - 10.5.2.21aa MultiRate configuratio
If "Voice boundary detection" is enabled, then only bursts are decoded as voice where
- the framenumber is greater then the framenumber of a received "Connect" or "Connect Acknowlegde" message, and
- the framenumber is less then the framenumber of a "Release" message
file_format: 1

View File

@ -17,6 +17,8 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
install(FILES
gsm_decryption.xml DESTINATION share/gnuradio/grc/blocks
install(
FILES
gsm_decryption.block.yml
DESTINATION share/gnuradio/grc/blocks
)

View File

@ -0,0 +1,31 @@
# auto-generated by grc.converter
id: gsm_decryption
label: Decryption
parameters:
- id: k_c
label: Kc session key
dtype: int_vector
default: '[0,0,0,0,0,0,0,0]'
- id: a5_version
label: A5 version
dtype: int
default: '1'
inputs:
- domain: message
id: bursts
outputs:
- domain: message
id: bursts
asserts:
- ${ a5_version > 0 }
- ${ a5_version < 5 }
templates:
imports: import grgsm
make: grgsm.decryption(${k_c}, ${a5_version})
file_format: 1

View File

@ -1,34 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Decryption</name>
<key>gsm_decryption</key>
<import>import grgsm</import>
<make>grgsm.decryption($k_c, $a5_version)</make>
<param>
<name>Kc session key</name>
<key>k_c</key>
<value>[0,0,0,0,0,0,0,0]</value>
<type>int_vector</type>
</param>
<param>
<name>A5 version</name>
<key>a5_version</key>
<value>1</value>
<type>int</type>
</param>
<check>$a5_version &gt; 0</check>
<check>$a5_version &lt; 5</check>
<sink>
<name>bursts</name>
<type>message</type>
</sink>
<source>
<name>bursts</name>
<type>message</type>
</source>
</block>

View File

@ -17,10 +17,13 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
install(FILES
gsm_universal_ctrl_chans_demapper.xml
gsm_bcch_ccch_demapper.xml
gsm_bcch_ccch_sdcch4_demapper.xml
gsm_sdcch8_demapper.xml
gsm_tch_f_chans_demapper.xml DESTINATION share/gnuradio/grc/blocks
install(
FILES
gsm_universal_ctrl_chans_demapper.block.yml
gsm_bcch_ccch_demapper.block.yml
gsm_bcch_ccch_sdcch4_demapper.block.yml
gsm_sdcch8_demapper.block.yml
gsm_tch_f_chans_demapper.block.yml
gsm_tch_h_chans_demapper.block.yml
DESTINATION share/gnuradio/grc/blocks
)

View File

@ -0,0 +1,35 @@
# auto-generated by grc.converter
id: gsm_bcch_ccch_demapper
label: BCCH + CCCH Demapper
parameters:
- id: timeslot_nr
label: timeslot_nr
dtype: raw
default: '0'
inputs:
- domain: message
id: bursts
optional: true
outputs:
- domain: message
id: bursts
optional: true
templates:
imports: import grgsm
make: |-
grgsm.gsm_bcch_ccch_demapper(
timeslot_nr=${timeslot_nr},
)
callbacks:
- set_timeslot_nr(${timeslot_nr})
documentation: |-
Piotr Krysik
Demapper for BCCH + CCCH control channels. This corresponds to channel combination iv specified in GSM 05.02, section 6.4
file_format: 1

View File

@ -1,30 +0,0 @@
<block>
<name>BCCH + CCCH Demapper</name>
<key>gsm_bcch_ccch_demapper</key>
<category></category>
<import>import grgsm</import>
<make>grgsm.gsm_bcch_ccch_demapper(
timeslot_nr=$timeslot_nr,
)</make>
<callback>set_timeslot_nr($timeslot_nr)</callback>
<param>
<name>timeslot_nr</name>
<key>timeslot_nr</key>
<value>0</value>
<type>raw</type>
</param>
<sink>
<name>bursts</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>bursts</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>Piotr Krysik
Demapper for BCCH + CCCH control channels. This corresponds to channel combination iv specified in GSM 05.02, section 6.4
</doc>
<grc_source>gr-gsm/hier_blocks/demapping/gsm_bcch_ccch_demapper.grc</grc_source>
</block>

View File

@ -0,0 +1,35 @@
# auto-generated by grc.converter
id: gsm_bcch_ccch_sdcch4_demapper
label: BCCH + CCCH + SDCCH/4 Demapper
parameters:
- id: timeslot_nr
label: timeslot_nr
dtype: raw
default: '0'
inputs:
- domain: message
id: bursts
optional: true
outputs:
- domain: message
id: bursts
optional: true
templates:
imports: import grgsm
make: |-
grgsm.gsm_bcch_ccch_sdcch4_demapper(
timeslot_nr=${timeslot_nr},
)
callbacks:
- set_timeslot_nr(${timeslot_nr})
documentation: |-
Piotr Krysik
Demapper for BCCH + CCCH + SDCCH/4 + SACCH/C4 control channels. This corresponds to channel combination v specified in GSM 05.02, section 6.4
file_format: 1

View File

@ -1,30 +0,0 @@
<block>
<name>BCCH + CCCH + SDCCH/4 Demapper</name>
<key>gsm_bcch_ccch_sdcch4_demapper</key>
<category></category>
<import>import grgsm</import>
<make>grgsm.gsm_bcch_ccch_sdcch4_demapper(
timeslot_nr=$timeslot_nr,
)</make>
<callback>set_timeslot_nr($timeslot_nr)</callback>
<param>
<name>timeslot_nr</name>
<key>timeslot_nr</key>
<value>0</value>
<type>raw</type>
</param>
<sink>
<name>bursts</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>bursts</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>Piotr Krysik
Demapper for BCCH + CCCH + SDCCH/4 + SACCH/C4 control channels. This corresponds to channel combination v specified in GSM 05.02, section 6.4
</doc>
<grc_source>gr-gsm/hier_blocks/demapping/gsm_bcch_ccch_sdcch4_demapper.grc</grc_source>
</block>

View File

@ -0,0 +1,35 @@
# auto-generated by grc.converter
id: gsm_sdcch8_demapper
label: SDCCH/8 Demapper
parameters:
- id: timeslot_nr
label: timeslot_nr
dtype: raw
default: '1'
inputs:
- domain: message
id: bursts
optional: true
outputs:
- domain: message
id: bursts
optional: true
templates:
imports: import grgsm
make: |-
grgsm.gsm_sdcch8_demapper(
timeslot_nr=${timeslot_nr},
)
callbacks:
- set_timeslot_nr(${timeslot_nr})
documentation: |-
Piotr Krysik
Demapper for SDCCH/8 + SACCH/C8 control channels. This corresponds to channel combination vii specified in GSM 05.02, section 6.4
file_format: 1

View File

@ -1,30 +0,0 @@
<block>
<name>SDCCH/8 Demapper</name>
<key>gsm_sdcch8_demapper</key>
<category></category>
<import>import grgsm</import>
<make>grgsm.gsm_sdcch8_demapper(
timeslot_nr=$timeslot_nr,
)</make>
<callback>set_timeslot_nr($timeslot_nr)</callback>
<param>
<name>timeslot_nr</name>
<key>timeslot_nr</key>
<value>1</value>
<type>raw</type>
</param>
<sink>
<name>bursts</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>bursts</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>Piotr Krysik
Demapper for SDCCH/8 + SACCH/C8 control channels. This corresponds to channel combination vii specified in GSM 05.02, section 6.4
</doc>
<grc_source>gr-gsm/hier_blocks/demapping/gsm_sdcch8_demapper.grc</grc_source>
</block>

View File

@ -0,0 +1,30 @@
# auto-generated by grc.converter
id: gsm_tch_f_chans_demapper
label: TCH/F Demapper
parameters:
- id: timeslot_nr
label: Timeslot
dtype: int
default: '2'
hide: part
inputs:
- domain: message
id: bursts
optional: true
outputs:
- domain: message
id: tch_bursts
optional: true
- domain: message
id: acch_bursts
optional: true
templates:
imports: import grgsm
make: grgsm.tch_f_chans_demapper(${timeslot_nr})
file_format: 1

View File

@ -1,31 +0,0 @@
<?xml version="1.0"?>
<block>
<name>TCH/F Demapper</name>
<key>gsm_tch_f_chans_demapper</key>
<import>import grgsm</import>
<make>grgsm.tch_f_chans_demapper($timeslot_nr)</make>
<param>
<name>timeslot_nr</name>
<key>timeslot_nr</key>
<value>2</value>
<type>int</type>
<hide>part</hide>
</param>
<sink>
<name>bursts</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>tch_bursts</name>
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>acch_bursts</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

View File

@ -0,0 +1,37 @@
# auto-generated by grc.converter
id: gsm_tch_h_chans_demapper
label: TCH/H Demapper
parameters:
- id: timeslot_nr
label: Timeslot
dtype: int
default: '2'
hide: none
- id: tch_h_channel
label: Sub-channel number
dtype: int
default: '0'
options: ['0', '1']
hide: none
inputs:
- domain: message
id: bursts
outputs:
- domain: message
id: tch_bursts
optional: true
- domain: message
id: acch_bursts
optional: true
asserts:
- ${ tch_h_channel > -1 and tch_h_channel < 2 }
templates:
imports: import grgsm
make: grgsm.tch_h_chans_demapper(${timeslot_nr}, ${tch_h_channel})
file_format: 1

View File

@ -0,0 +1,61 @@
# auto-generated by grc.converter
id: gsm_universal_ctrl_chans_demapper
label: Universal Control Channels Demapper
parameters:
- id: timeslot_nr
label: timeslot_nr
dtype: int
default: '0'
hide: part
- id: downlink_starts_fn_mod51
label: downlink_starts_fn_mod51
dtype: int_vector
default: '[0,0,2,2,2,2,6,6,6,6,0,0,12,12,12,12,16,16,16,16,0,0,22,22,22,22,26,26,26,26,0,0,32,32,32,32,36,36,36,36,0,0,42,42,42,42,46,46,46,46,0,]'
hide: part
- id: downlink_channel_types
label: downlink_channel_types
dtype: int_vector
default: '[0,0,1,1,1,1,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,]'
hide: part
- id: downlink_subslots
label: downlink_subslots
dtype: int_vector
default: '[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,]'
hide: part
- id: uplink_starts_fn_mod51
label: uplink_starts_fn_mod51
dtype: int_vector
default: '[0,0,0,0,0,0,6,6,6,6,10,10,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,37,41,41,41,41,0,0,47,47,47,47]'
hide: part
- id: uplink_channel_types
label: uplink_channel_types
dtype: int_vector
default: '[2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,0,2,2,2,2,]'
hide: part
- id: uplink_subslots
label: uplink_subslots
dtype: int_vector
default: '[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,]'
hide: part
inputs:
- domain: message
id: bursts
outputs:
- domain: message
id: bursts
templates:
imports: import grgsm
make: grgsm.universal_ctrl_chans_demapper(${timeslot_nr}, ${downlink_starts_fn_mod51},
${downlink_channel_types}, ${downlink_subslots}, ${uplink_starts_fn_mod51},
${uplink_channel_types}, ${uplink_subslots})
documentation: |-
Universal demapper for control channels.
Author: Piotr Krysik
file_format: 1

View File

@ -1,76 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Universal Control Channels Demapper</name>
<key>gsm_universal_ctrl_chans_demapper</key>
<import>import grgsm</import>
<make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $downlink_starts_fn_mod51, $downlink_channel_types, $downlink_subslots, $uplink_starts_fn_mod51, $uplink_channel_types, $uplink_subslots)</make>
<param>
<name>timeslot_nr</name>
<key>timeslot_nr</key>
<value>0</value>
<type>int</type>
<hide>part</hide>
</param>
<param>
<name>downlink_starts_fn_mod51</name>
<key>downlink_starts_fn_mod51</key>
<value>[0,0,2,2,2,2,6,6,6,6,0,0,12,12,12,12,16,16,16,16,0,0,22,22,22,22,26,26,26,26,0,0,32,32,32,32,36,36,36,36,0,0,42,42,42,42,46,46,46,46,0,]</value>
<type>int_vector</type>
<hide>part</hide>
</param>
<param>
<name>downlink_channel_types</name>
<key>downlink_channel_types</key>
<value>[0,0,1,1,1,1,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,]</value>
<type>int_vector</type>
<hide>part</hide>
</param>
<param>
<name>downlink_subslots</name>
<key>downlink_subslots</key>
<value>[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,]</value>
<type>int_vector</type>
<hide>part</hide>
</param>
<param>
<name>uplink_starts_fn_mod51</name>
<key>uplink_starts_fn_mod51</key>
<value>[0,0,0,0,0,0,6,6,6,6,10,10,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,37,37,37,41,41,41,41,0,0,47,47,47,47]</value>
<type>int_vector</type>
<hide>part</hide>
</param>
<param>
<name>uplink_channel_types</name>
<key>uplink_channel_types</key>
<value>[2,2,2,2,0,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,0,2,2,2,2,]</value>
<type>int_vector</type>
<hide>part</hide>
</param>
<param>
<name>uplink_subslots</name>
<key>uplink_subslots</key>
<value>[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,]</value>
<type>int_vector</type>
<hide>part</hide>
</param>
<sink>
<name>bursts</name>
<type>message</type>
</sink>
<source>
<name>bursts</name>
<type>message</type>
</source>
<doc>
Universal demapper for control channels.
Author: Piotr Krysik
</doc>
</block>

View File

@ -17,13 +17,15 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
install(FILES
gsm_burst_timeslot_splitter.xml
gsm_burst_fnr_filter.xml
gsm_burst_timeslot_filter.xml
gsm_burst_type_filter.xml
gsm_dummy_burst_filter.xml
gsm_burst_sdcch_subslot_splitter.xml
gsm_burst_sdcch_subslot_filter.xml
gsm_uplink_downlink_splitter.xml DESTINATION share/gnuradio/grc/blocks
install(
FILES
gsm_burst_timeslot_splitter.block.yml
gsm_burst_fnr_filter.block.yml
gsm_burst_timeslot_filter.block.yml
gsm_burst_type_filter.block.yml
gsm_dummy_burst_filter.block.yml
gsm_burst_sdcch_subslot_splitter.block.yml
gsm_burst_sdcch_subslot_filter.block.yml
gsm_uplink_downlink_splitter.block.yml
DESTINATION share/gnuradio/grc/blocks
)

View File

@ -0,0 +1,33 @@
# auto-generated by grc.converter
id: gsm_burst_fnr_filter
label: Burst Framenumber Filter
parameters:
- id: mode
label: Mode
dtype: enum
options: [grgsm.FILTER_LESS_OR_EQUAL, grgsm.FILTER_GREATER_OR_EQUAL]
option_labels: [Less or equal, Greater or equal]
- id: fnr
label: Framenumber
dtype: int
default: '1500123'
inputs:
- domain: message
id: in
outputs:
- domain: message
id: out
optional: true
templates:
imports: import grgsm
make: grgsm.burst_fnr_filter(${mode}, ${fnr})
documentation: |-
Burst framenumber filter forwards only blocks with a framenumber satisfying the configured mode, i.e. if mode is "Less or equal", then only bursts with a smaller or equal framenumber are forwarded.
file_format: 1

View File

@ -1,42 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst Framenumber Filter</name>
<key>gsm_burst_fnr_filter</key>
<import>import grgsm</import>
<make>grgsm.burst_fnr_filter($mode, $fnr)</make>
<param>
<name>Mode</name>
<key>mode</key>
<type>enum</type>
<option>
<name>Less or equal</name>
<key>grgsm.FILTER_LESS_OR_EQUAL</key>
</option>
<option>
<name>Greater or equal</name>
<key>grgsm.FILTER_GREATER_OR_EQUAL</key>
</option>
</param>
<param>
<name>Framenumber</name>
<key>fnr</key>
<value>1500123</value>
<type>int</type>
</param>
<sink>
<name>in</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>
Burst framenumber filter forwards only blocks with a framenumber satisfying the configured mode, i.e. if mode is "Less or equal", then only bursts with a smaller or equal framenumber are forwarded.
</doc>
</block>

View File

@ -0,0 +1,34 @@
# auto-generated by grc.converter
id: gsm_burst_sdcch_subslot_filter
label: Burst SDCCH Subslot Filter
parameters:
- id: mode
label: Mode
dtype: enum
options: [grgsm.SS_FILTER_SDCCH8, grgsm.SS_FILTER_SDCCH4]
option_labels: [SDCCH/8, SDCCH/4]
- id: subslot
label: Subslot
dtype: int
default: '0'
hide: none
inputs:
- domain: message
id: in
outputs:
- domain: message
id: out
optional: true
templates:
imports: import grgsm
make: grgsm.burst_sdcch_subslot_filter(${mode}, ${subslot})
documentation: |-
This block forwards only bursts in the subslot given by the parameter
file_format: 1

View File

@ -1,44 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst SDCCH Subslot Filter</name>
<key>gsm_burst_sdcch_subslot_filter</key>
<import>import grgsm</import>
<make>grgsm.burst_sdcch_subslot_filter($mode, $subslot)</make>
<param>
<name>Mode</name>
<key>mode</key>
<type>enum</type>
<option>
<name>SDCCH/8</name>
<key>grgsm.SS_FILTER_SDCCH8</key>
</option>
<option>
<name>SDCCH/4</name>
<key>grgsm.SS_FILTER_SDCCH4</key>
</option>
</param>
<param>
<name>Subslot</name>
<key>subslot</key>
<value>0</value>
<type>int</type>
<hide>none</hide>
</param>
<sink>
<name>in</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>
This block forwards only bursts in the subslot given by the parameter
</doc>
</block>

View File

@ -0,0 +1,39 @@
# auto-generated by grc.converter
id: gsm_burst_sdcch_subslot_splitter
label: Burst SDCCH Subslot Splitter
parameters:
- id: ports
label: Mode
dtype: enum
options: ['8', '4']
option_labels: [SDCCH/8, SDCCH/4]
hide: part
inputs:
- domain: message
id: in
outputs:
- domain: message
id: out
multiplicity: ${ ports }
optional: true
templates:
imports: import grgsm
make: |-
grgsm.burst_sdcch_subslot_splitter(
% if int(ports)==4:
grgsm.SPLITTER_SDCCH4
% else:
grgsm.SPLITTER_SDCCH8
% endif
)
documentation: |-
Burst SDCCH subslot splitter distributes bursts to eight different output ports depending on the subslots to which the bursts belong.
This means subslot 0 bursts are sent to port out0, subslot 1 bursts on port out1, and so on.
file_format: 1

View File

@ -1,44 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst SDCCH Subslot Splitter</name>
<key>gsm_burst_sdcch_subslot_splitter</key>
<import>import grgsm</import>
<make>grgsm.burst_sdcch_subslot_splitter(
#if int($ports())==4 #
grgsm.SPLITTER_SDCCH4
#else
grgsm.SPLITTER_SDCCH8
#end if
)</make>
<param>
<name>Mode</name>
<key>ports</key>
<type>enum</type>
<option>
<name>SDCCH/8</name>
<key>8</key>
</option>
<option>
<name>SDCCH/4</name>
<key>4</key>
</option>
</param>
<sink>
<name>in</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<nports>$ports</nports>
<optional>1</optional>
</source>
<doc>
Burst SDCCH subslot splitter distributes bursts to eight different output ports depending on the subslots to which the bursts belong.
This means subslot 0 bursts are sent to port out0, subslot 1 bursts on port out1, and so on.
</doc>
</block>

View File

@ -0,0 +1,29 @@
# auto-generated by grc.converter
id: gsm_burst_timeslot_filter
label: Burst Timeslot Filter
parameters:
- id: timeslot
label: Timeslot
dtype: int
default: '0'
hide: none
inputs:
- domain: message
id: in
outputs:
- domain: message
id: out
optional: true
templates:
imports: import grgsm
make: grgsm.burst_timeslot_filter(${timeslot})
documentation: |-
This block forwards only bursts in the timeslot given by the parameter
file_format: 1

View File

@ -1,30 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst Timeslot Filter</name>
<key>gsm_burst_timeslot_filter</key>
<import>import grgsm</import>
<make>grgsm.burst_timeslot_filter($timeslot)</make>
<param>
<name>Timeslot</name>
<key>timeslot</key>
<value>0</value>
<type>int</type>
<hide>none</hide>
</param>
<sink>
<name>in</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>
This block forwards only bursts in the timeslot given by the parameter
</doc>
</block>

View File

@ -0,0 +1,24 @@
# auto-generated by grc.converter
id: gsm_burst_timeslot_splitter
label: Burst Timeslot Splitter
inputs:
- domain: message
id: in
outputs:
- domain: message
id: out
multiplicity: '8'
optional: true
templates:
imports: import grgsm
make: grgsm.burst_timeslot_splitter()
documentation: "Burst timeslot splitter distributes bursts to eight different output\
\ ports depending on the timeslots of the bursts. \nThis means timeslot 0 bursts\
\ are sent to port out0, timeslot 1 bursts on port out1, and so on."
file_format: 1

View File

@ -1,24 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst Timeslot Splitter</name>
<key>gsm_burst_timeslot_splitter</key>
<import>import grgsm</import>
<make>grgsm.burst_timeslot_splitter()</make>
<sink>
<name>in</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<nports>8</nports>
<optional>1</optional>
</source>
<doc>
Burst timeslot splitter distributes bursts to eight different output ports depending on the timeslots of the bursts.
This means timeslot 0 bursts are sent to port out0, timeslot 1 bursts on port out1, and so on.
</doc>
</block>

View File

@ -0,0 +1,31 @@
# auto-generated by grc.converter
id: gsm_burst_type_filter
label: Burst Type Filter
parameters:
- id: selected_burst_types
label: Selected burst types
dtype: int_vector
default: '[0,1,2,3,4,5,6,7]'
inputs:
- domain: message
id: bursts_in
optional: true
outputs:
- domain: message
id: bursts_out
optional: true
templates:
imports: import grgsm
make: grgsm.burst_type_filter(${selected_burst_types})
documentation: |-
This block filters bursts based on their type.
For more information on burst types, see GSM 05.02.
file_format: 1

View File

@ -1,32 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst Type Filter</name>
<key>gsm_burst_type_filter</key>
<import>import grgsm</import>
<make>grgsm.burst_type_filter($selected_burst_types)</make>
<param>
<name>Selected burst types</name>
<key>selected_burst_types</key>
<value>[0,1,2,3,4,5,6,7]</value>
<type>int_vector</type>
</param>
<sink>
<name>bursts_in</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>bursts_out</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>
This block filters bursts based on their type.
For more information on burst types, see GSM 05.02.
</doc>
</block>

View File

@ -0,0 +1,22 @@
# auto-generated by grc.converter
id: gsm_dummy_burst_filter
label: Dummy Burst Filter
inputs:
- domain: message
id: in
outputs:
- domain: message
id: out
optional: true
templates:
imports: import grgsm
make: grgsm.dummy_burst_filter()
documentation: "This block filters dummy bursts. \n\nFor more information on dummy\
\ bursts, see GSM 05.02."
file_format: 1

View File

@ -1,24 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Dummy Burst Filter</name>
<key>gsm_dummy_burst_filter</key>
<import>import grgsm</import>
<make>grgsm.dummy_burst_filter()</make>
<sink>
<name>in</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>
This block filters dummy bursts.
For more information on dummy bursts, see GSM 05.02.
</doc>
</block>

View File

@ -0,0 +1,23 @@
# auto-generated by grc.converter
id: gsm_uplink_downlink_splitter
label: Up/Down-link splitter
inputs:
- domain: message
id: in
optional: true
outputs:
- domain: message
id: downlink
optional: true
- domain: message
id: uplink
optional: true
templates:
imports: import grgsm
make: grgsm.uplink_downlink_splitter()
file_format: 1

View File

@ -1,22 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Up/Down-link splitter</name>
<key>gsm_uplink_downlink_splitter</key>
<import>import grgsm</import>
<make>grgsm.uplink_downlink_splitter()</make>
<sink>
<name>in</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>downlink</name>
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>uplink</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

58
grc/gsm.tree.yml Normal file
View File

@ -0,0 +1,58 @@
'[GSM]':
- Receiver:
- gsm_receiver
- gsm_receiver_with_uplink
- gsm_cx_channel_hopper
- gsm_fcch_burst_tagger
- gsm_sch_detector
- gsm_fcch_detector
- gsm_clock_offset_control
- gsm_input
- Transmitter:
- gsm_txtime_bursts_tagger
- gsm_txtime_setter
- gsm_gmsk_mod
- gsm_preprocess_tx_burst
- gsm_gen_test_ab
- Transceiver:
- gsm_trx_burst_if
- Logical channels demapping:
- gsm_universal_ctrl_chans_demapper
- gsm_bcch_ccch_demapper
- gsm_bcch_ccch_sdcch4_demapper
- gsm_sdcch8_demapper
- gsm_tch_f_chans_demapper
- gsm_tch_h_chans_demapper
- Decryption:
- gsm_decryption
- Decoding:
- gsm_control_channels_decoder
- gsm_tch_f_decoder
- gsm_tch_h_decoder
- Flow control:
- gsm_burst_timeslot_splitter
- gsm_burst_sdcch_subslot_splitter
- gsm_burst_timeslot_filter
- gsm_burst_sdcch_subslot_filter
- gsm_burst_fnr_filter
- gsm_burst_type_filter
- gsm_dummy_burst_filter
- gsm_uplink_downlink_splitter
- Utilities:
- gsm_bursts_printer
- gsm_burst_file_sink
- gsm_burst_file_source
- gsm_collect_system_info
- gsm_message_file_sink
- gsm_message_file_source
- gsm_extract_system_info
- gsm_extract_immediate_assignment
- gsm_extract_cmc
- gsm_extract_assignment_cmd
- gsm_controlled_rotator_cc
- gsm_controlled_fractional_resampler_cc
- gsm_message_printer
- gsm_clock_offset_corrector_tagged
- gsm_msg_to_tag
- gsm_tmsi_dumper
- gsm_burst_to_fn_time

View File

@ -1,82 +0,0 @@
<?xml version="1.0"?>
<!--
###################################################
##Block Tree for GSM blocks.
###################################################
-->
<cat>
<name></name> <!-- Blank for Root Name -->
<cat>
<name>GSM</name>
<cat>
<name>Receiver</name>
<block>gsm_receiver</block>
<block>gsm_receiver_with_uplink</block>
<block>gsm_cx_channel_hopper</block>
<block>gsm_fcch_burst_tagger</block>
<block>gsm_sch_detector</block>
<block>gsm_fcch_detector</block>
<block>gsm_clock_offset_control</block>
<block>gsm_input</block>
</cat>
<cat>
<name>Transmitter</name>
<block>gsm_txtime_bursts_tagger</block>
<block>gsm_txtime_setter</block>
<block>gsm_gmsk_mod</block>
<block>gsm_preprocess_tx_burst</block>
<block>gsm_gen_test_ab</block>
</cat>
<cat>
<name>Logical channels demapping</name>
<block>gsm_universal_ctrl_chans_demapper</block>
<block>gsm_bcch_ccch_demapper</block>
<block>gsm_bcch_ccch_sdcch4_demapper</block>
<block>gsm_sdcch8_demapper</block>
<block>gsm_tch_f_chans_demapper</block>
</cat>
<cat>
<name>Decryption</name>
<block>gsm_decryption</block>
</cat>
<cat>
<name>Decoding</name>
<block>gsm_control_channels_decoder</block>
<block>gsm_tch_f_decoder</block>
</cat>
<cat>
<name>Flow control</name>
<block>gsm_burst_timeslot_splitter</block>
<block>gsm_burst_sdcch_subslot_splitter</block>
<block>gsm_burst_timeslot_filter</block>
<block>gsm_burst_sdcch_subslot_filter</block>
<block>gsm_burst_fnr_filter</block>
<block>gsm_burst_type_filter</block>
<block>gsm_dummy_burst_filter</block>
<block>gsm_uplink_downlink_splitter</block>
</cat>
<cat>
<name>Utilities</name>
<block>gsm_bursts_printer</block>
<block>gsm_burst_file_sink</block>
<block>gsm_burst_file_source</block>
<block>gsm_collect_system_info</block>
<block>gsm_message_file_sink</block>
<block>gsm_message_file_source</block>
<block>gsm_extract_system_info</block>
<block>gsm_extract_immediate_assignment</block>
<block>gsm_extract_cmc</block>
<block>gsm_extract_assignment_cmd</block>
<block>gsm_controlled_rotator_cc</block>
<block>gsm_controlled_fractional_resampler_cc</block>
<block>gsm_message_printer</block>
<block>gsm_clock_offset_corrector_tagged</block>
<block>gsm_msg_to_tag.xml</block>
<block>gsm_tmsi_dumper</block>
<block>gsm_trx_burst_if</block>
<block>gsm_burst_to_fn_time</block>
</cat>
</cat>
</cat>

View File

@ -17,24 +17,24 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
install(FILES
gsm_extract_system_info.xml
gsm_extract_immediate_assignment.xml
gsm_collect_system_info.xml
gsm_extract_cmc.xml
gsm_extract_assignment_cmd.xml
gsm_controlled_rotator_cc.xml
gsm_message_printer.xml
gsm_bursts_printer.xml
gsm_clock_offset_corrector_tagged.xml
gsm_tmsi_dumper.xml
gsm_burst_file_sink.xml
gsm_burst_file_source.xml
gsm_message_file_sink.xml
gsm_message_file_source.xml
gsm_trx_burst_if.xml
gsm_msg_to_tag.xml
gsm_controlled_fractional_resampler_cc.xml
gsm_burst_to_fn_time.xml
install(
FILES
gsm_extract_system_info.block.yml
gsm_extract_immediate_assignment.block.yml
gsm_collect_system_info.block.yml
gsm_extract_cmc.block.yml
gsm_extract_assignment_cmd.block.yml
gsm_controlled_rotator_cc.block.yml
gsm_message_printer.block.yml
gsm_bursts_printer.block.yml
gsm_clock_offset_corrector_tagged.block.yml
gsm_tmsi_dumper.block.yml
gsm_burst_file_sink.block.yml
gsm_burst_file_source.block.yml
gsm_message_file_sink.block.yml
gsm_message_file_source.block.yml
gsm_msg_to_tag.block.yml
gsm_controlled_fractional_resampler_cc.block.yml
gsm_burst_to_fn_time.block.yml
DESTINATION share/gnuradio/grc/blocks
)

View File

@ -0,0 +1,20 @@
# auto-generated by grc.converter
id: gsm_burst_file_sink
label: Burst File Sink
parameters:
- id: filename
label: Destination file
dtype: file_open
default: /tmp/bursts
inputs:
- domain: message
id: in
templates:
imports: import grgsm
make: grgsm.burst_file_sink(${filename})
file_format: 1

View File

@ -1,19 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst File Sink</name>
<key>gsm_burst_file_sink</key>
<import>import grgsm</import>
<make>grgsm.burst_file_sink($filename)</make>
<param>
<name>Destination file</name>
<key>filename</key>
<value>/tmp/bursts</value>
<type>file_open</type>
</param>
<sink>
<name>in</name>
<type>message</type>
</sink>
</block>

View File

@ -0,0 +1,20 @@
# auto-generated by grc.converter
id: gsm_burst_file_source
label: Burst File Source
parameters:
- id: filename
label: Source file
dtype: file_open
default: /tmp/bursts
outputs:
- domain: message
id: out
templates:
imports: import grgsm
make: grgsm.burst_file_source(${filename})
file_format: 1

View File

@ -1,19 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst File Source</name>
<key>gsm_burst_file_source</key>
<import>import grgsm</import>
<make>grgsm.burst_file_source($filename)</make>
<param>
<name>Source file</name>
<key>filename</key>
<value>/tmp/bursts</value>
<type>file_open</type>
</param>
<source>
<name>out</name>
<type>message</type>
</source>
</block>

View File

@ -0,0 +1,20 @@
# auto-generated by grc.converter
id: gsm_burst_to_fn_time
label: Burst to FN time
inputs:
- domain: message
id: bursts_in
optional: true
outputs:
- domain: message
id: fn_time_out
optional: true
templates:
imports: import grgsm
make: grgsm.burst_to_fn_time()
file_format: 1

View File

@ -1,19 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Burst to FN time</name>
<key>gsm_burst_to_fn_time</key>
<import>import grgsm</import>
<make>grgsm.gsm_burst_to_fn_time()</make>
<sink>
<name>bursts_in</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>fn_time_out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

View File

@ -0,0 +1,57 @@
# auto-generated by grc.converter
id: gsm_bursts_printer
label: Bursts Printer
parameters:
- id: prepend_string
label: Prepend String
dtype: string
hide: part
- id: prepend_fnr
label: Prepend Frame Number
dtype: bool
default: 'False'
options: ['False', 'True']
- id: prepend_frame_count
label: Prepend Frame Count
dtype: bool
default: 'False'
options: ['False', 'True']
- id: print_payload_only
label: Print payload only
dtype: bool
default: 'False'
options: ['False', 'True']
- id: ignore_dummy_bursts
label: Ignore dummy bursts
dtype: bool
default: 'False'
options: ['False', 'True']
inputs:
- domain: message
id: bursts
templates:
imports: |-
import grgsm
import pmt
make: |-
grgsm.bursts_printer(pmt.intern(${prepend_string}), ${prepend_fnr},
${prepend_frame_count}, ${print_payload_only}, ${ignore_dummy_bursts})
documentation: |-
This block prints bursts to output. By default the whole burst including tail bits, stealing bits and training sequence is printed.
If "Prepend Frame Number" is enabled, then the framenumber is prepended to each burst.
If "Prepend Frame Count" is enabled, then the frame count for A5 is prependend to each burst.
If "Print payload only" is enabled, then only the two data blocks of a burst are printed, tail bits, stealing bits and training sequence are omitted.
If "Ignore dummy bursts" is enabled, then the burst printer will not print dummy bursts (see GSM 05.02)
Enabling first three options (or all four options) results in an output that is similar to the output of airprobe, i.e. the format is "frame_nr frame_count: databits"
file_format: 1

View File

@ -1,92 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Bursts Printer</name>
<key>gsm_bursts_printer</key>
<import>import grgsm</import>
<import>import pmt</import>
<make>grgsm.bursts_printer(pmt.intern($prepend_string), $prepend_fnr,
$prepend_frame_count, $print_payload_only, $ignore_dummy_bursts)</make>
<param>
<name>Prepend String</name>
<key>prepend_string</key>
<value></value>
<type>string</type>
<hide>part</hide>
</param>
<param>
<name>Prepend Frame Number</name>
<key>prepend_fnr</key>
<value>False</value>
<type>bool</type>
<option>
<name>False</name>
<key>False</key>
</option>
<option>
<name>True</name>
<key>True</key>
</option>
</param>
<param>
<name>Prepend Frame Count</name>
<key>prepend_frame_count</key>
<value>False</value>
<type>bool</type>
<option>
<name>False</name>
<key>False</key>
</option>
<option>
<name>True</name>
<key>True</key>
</option>
</param>
<param>
<name>Print payload only</name>
<key>print_payload_only</key>
<value>False</value>
<type>bool</type>
<option>
<name>False</name>
<key>False</key>
</option>
<option>
<name>True</name>
<key>True</key>
</option>
</param>
<param>
<name>Ignore dummy bursts</name>
<key>ignore_dummy_bursts</key>
<value>False</value>
<type>bool</type>
<option>
<name>False</name>
<key>False</key>
</option>
<option>
<name>True</name>
<key>True</key>
</option>
</param>
<sink>
<name>bursts</name>
<type>message</type>
</sink>
<doc>
This block prints bursts to output. By default the whole burst including tail bits, stealing bits and training sequence is printed.
If "Prepend Frame Number" is enabled, then the framenumber is prepended to each burst.
If "Prepend Frame Count" is enabled, then the frame count for A5 is prependend to each burst.
If "Print payload only" is enabled, then only the two data blocks of a burst are printed, tail bits, stealing bits and training sequence are omitted.
If "Ignore dummy bursts" is enabled, then the burst printer will not print dummy bursts (see GSM 05.02)
Enabling first three options (or all four options) results in an output that is similar to the output of airprobe, i.e. the format is "frame_nr frame_count: databits"
</doc>
</block>

View File

@ -0,0 +1,56 @@
# auto-generated by grc.converter
id: gsm_clock_offset_corrector_tagged
label: Clock Offset Corrector Tagged
parameters:
- id: fc
label: fc
dtype: raw
default: 936.6e6
- id: ppm
label: ppm
dtype: raw
default: '0'
- id: samp_rate_in
label: samp_rate_in
dtype: raw
default: 1625000.0/6.0*4.0
- id: osr
label: OSR
dtype: raw
default: osr
inputs:
- domain: message
id: ctrl
optional: true
- domain: stream
dtype: complex
vlen: 1
outputs:
- domain: stream
dtype: complex
vlen: 1
templates:
imports: import grgsm
make: |-
grgsm.clock_offset_corrector_tagged(
fc=${fc},
samp_rate_in=${samp_rate_in},
ppm=${ppm},
osr=${osr}
)
callbacks:
- set_fc(${fc})
- set_ppm(${ppm})
- set_samp_rate_in(${samp_rate_in})
- set_osr(${osr})
documentation: |-
Piotr Krysik
Clock offset corrector with blocks that use tags to switch offsets
file_format: 1

View File

@ -1,57 +0,0 @@
<block>
<name>Clock Offset Corrector Tagged</name>
<key>gsm_clock_offset_corrector_tagged</key>
<import>import grgsm</import>
<make>grgsm.clock_offset_corrector_tagged(
fc=$fc,
samp_rate_in=$samp_rate_in,
ppm=$ppm,
osr=$osr
)</make>
<callback>set_fc($fc)</callback>
<callback>set_ppm($ppm)</callback>
<callback>set_samp_rate_in($samp_rate_in)</callback>
<callback>set_osr($osr)</callback>
<param>
<name>fc</name>
<key>fc</key>
<value>936.6e6</value>
<type>raw</type>
</param>
<param>
<name>ppm</name>
<key>ppm</key>
<value>0</value>
<type>raw</type>
</param>
<param>
<name>samp_rate_in</name>
<key>samp_rate_in</key>
<value>1625000.0/6.0*4.0</value>
<type>raw</type>
</param>
<param>
<name>OSR</name>
<key>osr</key>
<value>osr</value>
<type>raw</type>
</param>
<sink>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</sink>
<sink>
<name>in</name>
<type>complex</type>
<vlen>1</vlen>
</sink>
<source>
<name>out</name>
<type>complex</type>
<vlen>1</vlen>
</source>
<doc>Piotr Krysik
Clock offset corrector with blocks that use tags to switch offsets
</doc>
</block>

View File

@ -0,0 +1,23 @@
# auto-generated by grc.converter
id: gsm_collect_system_info
label: Collect System Info
inputs:
- domain: message
id: msgs
templates:
imports: import grgsm
make: grgsm.collect_system_info()
documentation: |-
This blocks collect System Information Messages, which can be retrieved using the following methods:
get_framenumbers(): Get the list with the framenumbers of the System Information Messages
get_system_information_type(): Get the types of the System Information Messages
get_data(): Get the whole System Information Messages in Hex representation
file_format: 1

View File

@ -1,20 +0,0 @@
<?xml version="1.0"?>
<block>
<name>Collect System Info</name>
<key>gsm_collect_system_info</key>
<import>import grgsm</import>
<make>grgsm.collect_system_info()</make>
<sink>
<name>msgs</name>
<type>message</type>
</sink>
<doc>
This blocks collect System Information Messages, which can be retrieved using the following methods:
get_framenumbers(): Get the list with the framenumbers of the System Information Messages
get_system_information_type(): Get the types of the System Information Messages
get_data(): Get the whole System Information Messages in Hex representation
</doc>
</block>

View File

@ -0,0 +1,28 @@
# auto-generated by grc.converter
id: gsm_controlled_fractional_resampler_cc
label: Controlled Fractional Resampler
parameters:
- id: phase_shift
label: Phase Shift
dtype: real
- id: resamp_ratio
label: Resampling Ratio
dtype: real
inputs:
- domain: stream
dtype: complex
outputs:
- domain: stream
dtype: complex
templates:
imports: import grgsm
make: grgsm.controlled_fractional_resampler_cc(${phase_shift}, ${resamp_ratio})
callbacks:
- set_resamp_ratio(${resamp_ratio})
file_format: 1

Some files were not shown because too many files have changed in this diff Show More