core rc2-final

master
Max 2 years ago
parent 180a4dec97
commit 51042858e8
  1. 265
      op25/gr-op25_repeater/apps/README-July-2021
  2. 98
      op25/gr-op25_repeater/apps/cfg-trunkx.json
  3. 602
      op25/gr-op25_repeater/apps/color-map.json
  4. 383
      op25/gr-op25_repeater/apps/emap.py
  5. 32
      op25/gr-op25_repeater/apps/gr_gnuplot.py
  6. 86
      op25/gr-op25_repeater/apps/http_server.py
  7. 28
      op25/gr-op25_repeater/apps/install-sql.sh
  8. 504
      op25/gr-op25_repeater/apps/multi_rx.py
  9. 5
      op25/gr-op25_repeater/apps/p25_decoder.py
  10. 11
      op25/gr-op25_repeater/apps/p25_demodulator.py
  11. 40
      op25/gr-op25_repeater/apps/rx.py
  12. 12
      op25/gr-op25_repeater/apps/site-alias.json
  13. 337
      op25/gr-op25_repeater/apps/sql_dbi.py
  14. 3
      op25/gr-op25_repeater/apps/trunk.tsv
  15. 964
      op25/gr-op25_repeater/apps/trunking.py
  16. 99
      op25/gr-op25_repeater/apps/tsvfile.py
  17. 34
      op25/gr-op25_repeater/apps/ui-settings.json
  18. 2
      op25/gr-op25_repeater/include/op25_repeater/frame_assembler.h
  19. 4
      op25/gr-op25_repeater/include/op25_repeater/gardner_costas_cc.h
  20. 2
      op25/gr-op25_repeater/include/op25_repeater/p25_frame_assembler.h
  21. 9
      op25/gr-op25_repeater/lib/frame_assembler_impl.cc
  22. 3
      op25/gr-op25_repeater/lib/frame_assembler_impl.h
  23. 63
      op25/gr-op25_repeater/lib/gardner_costas_cc_impl.cc
  24. 17
      op25/gr-op25_repeater/lib/gardner_costas_cc_impl.h
  25. 26
      op25/gr-op25_repeater/lib/p25_frame_assembler_impl.cc
  26. 3
      op25/gr-op25_repeater/lib/p25_frame_assembler_impl.h
  27. 16
      op25/gr-op25_repeater/lib/p25_framer.cc
  28. 3
      op25/gr-op25_repeater/lib/p25_framer.h
  29. 22
      op25/gr-op25_repeater/lib/p25p1_fdma.cc
  30. 3
      op25/gr-op25_repeater/lib/p25p1_fdma.h
  31. 48
      op25/gr-op25_repeater/lib/p25p2_tdma.cc
  32. 6
      op25/gr-op25_repeater/lib/p25p2_tdma.h
  33. 22
      op25/gr-op25_repeater/lib/rx_sync.cc
  34. 3
      op25/gr-op25_repeater/lib/rx_sync.h

@ -0,0 +1,265 @@
New features in this release (June, 2021)
=========================================
1. With thanks to OP25 user Triptolemus, the web client is enhanced to
include comprehensive logs of recent control channel signalling and
call activity. Many other features are also added:
* unit ID (subscriber ID) tagging - similar to the existing TGID
tags setup.
* tag color coding (for both TGID and SUID tags).
* tag ranges and wildcarding - for both the TGID and SUID tag maps,
a single definition line may be used to create tags for a range of
IDs.
* real time system frequency status table
* smart colors
* user settings (colors, preferences) may be edited and saved via a
convenient set of web forms and applications
* Experimental TDMA Control Channel support
2. The multi_rx app adds extensions to include trunked P25 call following
concurrent with full-time tracking of one or more P25 control channels.
If necessary, additional SDR devices may be configured to allow full
coverage of all control channels without loss of CC data even during voice
call reception. Several new command line options to multi_rx have been
added - -T (trunking TSV file) -l (terminal type) as well as -X and -U,
all having the same meaning as in rx.py.
3. Control channel logging to SQL database is added. For details see the
section on the Flask Datatables App, below.
Installation
============
First locate and change to your current OP25 install build/ directory and
run the command
sude make uninstall
Since this version includes library C++ code updates it requires a full
source rebuild via the standard install script (install.sh).
The installation will include one or more SDR receivers, depending
on the the amount of spectrum utilized by the target trunking system, how
many control channels are to be monitored concurrently, and whether voice
call following is desired.
* When SQL logging is used, it is most desirable to keep the control channel
tuned in 100% of the time. With a single SDR this is not possible when the
range of control channel and voice channel frequencies exceed the tuning band
of the SDR.
* When voice call following is to be used, a separate voice channel must be
defined for each device over which voice reception is desired. It is
redundant to have more than one voice channel assigned to a given device.
* A separate SDR can be dedicated to voice call following if needed. If there
is already a frequency-locked ("tunable"=false) device whose tuning band
includes all desired voice frequencies, a separate voice SDR is not needed.
* This version of OP25 follows the same voice call system as in rx.py.
That is, a single call at a time is monitored and a 3-second (nominal)
time delay is applied at the end of each call to catch possible replies.
* A single device may be shared by multiple channels. When more than one channel
is assigned to a device, the device should be tuned to a fixed frequency and
"tunable" should be set to "false".
Simplified example: Of all frequencies (control and voice) in the system,
the lowest frequency is 464.05 and the highest is 464.6. An RTL-SDR having
a maximum sample rate of 2.56 MHz is to be used. Since the band required is
0.55 MHz, a single SDR configuration can be used. The sample rate for
this example, 2.56 MHz, could be reduced to 1.0 MHz to conserve CPU.
NOTE: Proper logging of CC activity requires two things:
1) Device and/or channel resources must be allocated so that there
is 100% time coverage of the control channel. Voice channel
operation on the same SDR can only occur when the entire system
fits within the SDR tuning band.
2) Control channel reception and demodulation must be 100% error-free.
Occasional errors are potentially corrected by the FEC but a better
course is to increase the receive SNR and/or decrease the system BER.
Notes on JSON Configuration/Parameters
======================================
Example json config files are included in the apps/ directory. You
should choose one of these files (as described above) and make edits
to a working copy of the file. The name of the resulting JSON config
file must be passed to multi_rx.py via the "-c" parameter.
cfg-trunk.json - When all system frequencies (CC and VC) will fit
within the SDR tuning band (without retuning the SDR),
or voice decode is not needed.
cfg-trunk2.json - When two SDRs are needed to cover both CC and all VCs.
cfg-trunkx.json - Large system example with voice following and several CCs.
There are several key values to note:
"tunable" In the single-SDR configuration where all system frequencies
(primary/secondary CCs and VCs) are within the SDR band,
you should set this to "false". In this case the SDR is
fixed-tuned and remains on a single frequency, the center
frequency. You must set the center frequency to a value
halfway between the lowest and highest frequencies in the
system, via the device "frequency" setting.
"frequency" See above. When "tunable" is set to "true" this value must
be filled in. Otherwise the value is used to set the device
frequency at startup time (must be a valid frequency for the
device). The device will most likely be retuned one or more
times during execution.
"decode" Assists multi_rx in assigning channels to the proper device(s).
If the value of "decode" starts with the string "p25_decoder",
multi_rx uses the p25 decoder instead of its standard decoder.
Note that "tunable" is a device-specific parameter, and that "decode" is a
channel-specific parameter. Also, while both the device and channel define
the "frequency" parameter, the description above is for device entries. A
channel entry may also define a frequency, but the channel "frequency" parameter
is ignored (in this version).
When the p25_decoder is used, there is a parameter string consisting of a
colon-separated list of parameters with each parameter in the form "key=value",
with the parameter string defined as the value of the "decode" parameter.
Here are two examples:
"decode": "p25_decoder:role=cc:dev=rtl11:nac=0x4e1", [control]
"decode": "p25_decoder:role=vc:dev=rtl12_vc", [voice]
The valid parameter keywords are:
"p25_decoder" Required for trunked P25. This keyword introduces the
parameter list. There is no value.
"role" Must be set to "vc" or "cc".
"dev" Must be set to the name of the device. Each channel is
assigned to exactly one device.
"nac" Comma-separated list of NACs for the channel. Only trunked
systems having a NAC in the list can be assigned to this
channel.
"sysid" Comma-separated list of SYSIDs for the channel. Only trunked
systems having a SYSID in the list can be assigned to this
channel.
The "nac" and "sysid" options are only checked for control channels ("role=cc").
Values starting with "0x" are hexadecimal; otherwise decimal values are assumed .
A blank/default value for "sysid" and/or "nac" indicates that parameter is not
checked.
The following startup messages in the stderr log are typical in a 2-SDR config:
assigning channel "p25 control channel" (channel id 1) to device "rtl11_cc"
assigning channel "p25 voice channel" (channel id 2) to device "rtl12_vc"
Note that the channel ID displayed in the "tuning error +/-1200" messages can be
linked to the specific device(s) encountering the error using this ID.
Experimental TDMA Control Channel Support
=========================================
The following specifics detail the JSON configuration file channel parameters
needed to define a TDMA control channel:
"demod_type": "cqpsk",
"if_rate": 24000,
"symbol_rate": 6000,
"decode": "p25_decoder:role=cc:dev=<device-name>:nac=0x4e1",
The NAC should be changed to match that of the system being received, and
<device-name> should refer to the assigned device.
Colors and Tags for Talkgroup and Radio IDs
===========================================
Tags and colors are defined in two TSV files, one for TGIDs and one for SUIDs.
The TSV file format, compatible with earlier versions of OP25 has the TAB
separated columns defined as:
column one: decimal TG or SU ID. May contain wildcards (see below)
column two: tag text (string)
column three(optional): encoded priority/color value, decimal (see below)
The color code is directly mapped by client JS into style sheet (CSS) colors.
If only two columns are present the third column is defaulted to zero.
The file names of the two files are specified (comma-separated) in the
trunking TSV "TGID Tags File" column (the trunking TSV in turn is the
file referred to by the "-T" command option of rx.py or multi_rx.py).
The talkgroup tags file name is specified first, followed by a comma,
then the SUID tags file. The SUID tags file can't be specified alone.
Wildcard IDs (column one) may be (for example)
* 123-678 [all IDs in range, inclusive, are set to same tag/color]
* 444.... [all IDs from 4440000 to 4449999]
* 456* [all IDs starting with 456]
* 54321 [defines that one ID]
Column three contains a color value from 0-99 (decimal).
In the TGID file (only), the column value also contains a talkgroup
priority, encoded as follows:
- the low-order two decimal digits (tens and units digits) are the
color code
- the remaining upper-order decimal digits (hundreds digit and above) are
the priority value for talkgroup pre-emption purposes.
Setup SQL Log Database (Optional)
=================================
This addition provides a permanent server-side log of control channel
activity via logging to an SQL database. See the next section for details
on installing and using the log viewer.
1. Make sure that sqlite3 is installed in python
WARNING: OP25 MUST NOT BE RUNNING DURING THIS STEP
2. Initialize DB (any existing DB data will be destroyed)
op25/.../apps$ python sql_dbi.py reset_db
WARNING: OP25 MUST NOT BE RUNNING DURING THIS STEP
3. Import talkgroups tags file
op25/.../apps$ python sql_dbi.py import_tgid tags.tsv <sysid>
also, import the radio ID tags file (optional)
op25/.../apps$ python sql_dbi.py import_unit radio-tags.tsv <sysid>
import the System ID tags file (see below)
op25/.../apps$ python sql_dbi.py import_sysid sysid-tags.tsv 0
The sysid tags must be a TSV file containing two columns
column 1 is the P25 trunked sysid (int, decimal)
colunn 2 is the System Name (text)
(Note: there is no header row line in this TSV file).
NOTE: in the various import commands above, the sysid (decimal) must follow
as the next argument after the TSV file name. For the sysid tags file, the
sysid should be set to zero.
4. Run op25 as usual. Logfile data should be inserted into DB in real time
and you should be able to view activity via the OP25 http console (once
the flask/datatables app has been set up; see next section).
Setup Flask Datatables App
==========================
0. The DB must first be established (see previous section)
1. Install the necessary libs. If you are running the install in Ubuntu
16.04 there are two lines in the script that must be un-commented prior
to running; then, in any case do:
op25/.../apps$ sh install-sql.sh
Note: you may need to 'sudo apt install git' prior to running this script.
2. Update your .bashrc file as instructed, then re-login to pick up the
update to PATH. Verify that the updated PATH is correct. You can run
the command "echo $PATH" to display its current value. Here is an example
response: /home/op25/.local/bin:/usr/local/sbin:/usr/local/bin.....
You should confirm that the file "flask" exists and is executable (see
warning below).
$ ls -l ~/.local/bin/flask
-rwxr-xr-x 1 op25 op25 212 Apr 29 21:43 /home/op25/.local/bin/flask
3. First change to the "..../apps/oplog" directory, then run the following
commands to start the flask http process (listens on port 5000)
op25/.../apps/oplog$ export FLASK_APP=op25
op25/.../apps/oplog$ FLASK_DEBUG=1 flask run
WARNING: if you receive the following messages when attempting the "flask run"
command
-------------------------------------------------------------
Command 'flask' not found, but can be installed with:
sudo apt install python3-flask
-------------------------------------------------------------
most likely this indicates the PATH is not properly set up (see step 2).
In this case we do NOT recommend that you attempt to install the apt version
of flask. The install-sql.sh script (step 1, above) should have installed a
version of flask in a directory such as:
$ ls -l ~/.local/bin/flask
-rwxr-xr-x 1 op25 op25 212 Apr 29 21:43 /home/op25/.local/bin/flask
If install of the apt version of flask is attempted, it may result in an
obsolete and/or incompatible flask version being installed.

@ -0,0 +1,98 @@
{
"channels": [
{
"demod_type": "cqpsk",
"destination": "udp://127.0.0.1:23456",
"excess_bw": 0.2,
"filter_type": "rc",
"frequency": 0,
"if_rate": 24000,
"name": "Oswego CC",
"plot": "symbol",
"decode": "p25_decoder:role=cc:dev=rtl12:nac=0x2a4",
"symbol_rate": 4800
},
{
"demod_type": "cqpsk",
"destination": "udp://127.0.0.1:23456",
"excess_bw": 0.2,
"filter_type": "rc",
"frequency": 0,
"if_rate": 24000,
"name": "Cayuga CC",
"plot": "symbol",
"decode": "p25_decoder:role=cc:dev=rtl12:nac=0x2a8",
"symbol_rate": 4800
},
{
"demod_type": "cqpsk",
"destination": "udp://127.0.0.1:23456",
"excess_bw": 0.2,
"filter_type": "rc",
"frequency": 0,
"if_rate": 24000,
"name": "460 MHz VC",
"plot": "symbol",
"decode": "p25_decoder:role=vc:dev=rtl12",
"symbol_rate": 4800
},
{
"demod_type": "cqpsk",
"destination": "udp://127.0.0.1:23456",
"excess_bw": 0.2,
"filter_type": "rc",
"frequency": 0,
"if_rate": 24000,
"name": "453-454 MHz VC",
"plot": "symbol",
"decode": "p25_decoder:role=vc:dev=rtl11",
"symbol_rate": 4800
},
{
"demod_type": "cqpsk",
"destination": "udp://127.0.0.1:56124",
"excess_bw": 0.2,
"filter_type": "rc",
"frequency": 0,
"if_rate": 24000,
"name": "Onondaga CC",
"plot": "symbol",
"decode": "p25_decoder:role=cc:dev=rtl12:nac=0x2a0",
"symbol_rate": 4800
},
{
"demod_type": "cqpsk",
"destination": "udp://127.0.0.1:56124",
"excess_bw": 0.2,
"filter_type": "rc",
"frequency": 0,
"if_rate": 24000,
"name": "Cortland CC",
"plot": "constellation",
"decode": "p25_decoder:role=cc:dev=rtl11:nac=0x4e1",
"symbol_rate": 4800
}
],
"devices": [
{
"args": "rtl=00000012",
"frequency": 460500000,
"gains": "lna:49",
"name": "rtl12",
"offset": 0,
"ppm": 54,
"rate": 1000000,
"tunable": false
},
{
"args": "rtl=00000011",
"frequency": 453850000,
"gains": "lna:49",
"name": "rtl11",
"offset": 0,
"ppm": 55,
"rate": 2048000,
"tunable": false
}
]
}

@ -0,0 +1,602 @@
[
[
500,
"placeholder",
"do-not-use",
false
],
[
1,
"#0066ff",
"",
false
],
[
2,
"#ff0000",
"",
false
],
[
3,
"#ff9900",
"",
false
],
[
4,
"#eeeeee",
"",
false
],
[
5,
"#9966ff",
"",
false
],
[
6,
"#00ff00",
"",
false
],
[
7,
"#009933",
"",
false
],
[
8,
"#ffff00",
"",
false
],
[
9,
"#eee",
"",
false
],
[
10,
"#ff6666",
"",
false
],
[
11,
"#0080C0",
"",
false
],
[
12,
"#666666",
"",
false
],
[
13,
"#666666",
"",
false
],
[
14,
"#666666",
"",
false
],
[
15,
"#666666",
"",
false
],
[
16,
"#666666",
"",
false
],
[
17,
"#666666",
"",
false
],
[
18,
"#666666",
"",
false
],
[
19,
"#666666",
"",
false
],
[
20,
"#666666",
"",
false
],
[
21,
"#666666",
"",
false
],
[
22,
"#ff0000",
"",
true
],
[
23,
"#666666",
"",
false
],
[
24,
"#666666",
"",
false
],
[
25,
"#666666",
"",
false
],
[
26,
"#666666",
"",
false
],
[
27,
"#666666",
"",
false
],
[
28,
"#666666",
"",
false
],
[
29,
"#666666",
"",
false
],
[
30,
"#666666",
"",
false
],
[
31,
"#666666",
"",
false
],
[
32,
"#666666",
"",
false
],
[
33,
"#666666",
"",
false
],
[
34,
"#666666",
"",
false
],
[
35,
"#666666",
"",
false
],
[
36,
"#666666",
"",
false
],
[
37,
"#666666",
"",
false
],
[
38,
"#666666",
"",
false
],
[
39,
"#666666",
"",
false
],
[
40,
"#666666",
"",
false
],
[
41,
"#666666",
"",
false
],
[
42,
"#666666",
"",
false
],
[
43,
"#666666",
"",
false
],
[
44,
"#666666",
"",
false
],
[
45,
"#666666",
"",
false
],
[
46,
"#666666",
"",
false
],
[
47,
"#666666",
"",
false
],
[
48,
"#666666",
"",
false
],
[
49,
"#666666",
"",
false
],
[
50,
"#666666",
"",
false
],
[
51,
"#666666",
"",
false
],
[
52,
"#666666",
"",
false
],
[
53,
"#666666",
"",
false
],
[
54,
"#666666",
"",
false
],
[
55,
"#666666",
"",
false
],
[
56,
"#666666",
"",
false
],
[
57,
"#666666",
"",
false
],
[
58,
"#666666",
"",
false
],
[
59,
"#666666",
"",
false
],
[
60,
"#666666",
"",
false
],
[
61,
"#666666",
"",
false
],
[
62,
"#666666",
"",
false
],
[
63,
"#666666",
"",
false
],
[
64,
"#666666",
"",
false
],
[
65,
"#666666",
"",
false
],
[
66,
"#666666",
"",
false
],
[
67,
"#666666",
"",
false
],
[
68,
"#666666",
"",
false
],
[
69,
"#666666",
"",
false
],
[
70,
"#666666",
"",
false
],
[
71,
"#666666",
"",
false
],
[
72,
"#666666",
"",
false
],
[
73,
"#666666",
"",
false
],
[
74,
"#666666",
"",
false
],
[
75,
"#666666",
"",
false
],
[
76,
"#666666",
"",
false
],
[
77,
"#666666",
"",
false
],
[
78,
"#666666",
"",
false
],
[
79,
"#666666",
"",
false
],
[
80,
"#666666",
"",
false
],
[
81,
"#666666",
"",
false
],
[
82,
"#666666",
"",
false
],
[
83,
"#666666",
"",
false
],
[
84,
"#666666",
"",
false
],
[
85,
"#666666",
"",
false
],
[
86,
"#666666",
"",
false
],
[
87,
"#666666",
"",
false
],
[
88,
"#666666",
"",
false
],
[
89,
"#666666",
"",
false
],
[
90,
"#666666",
"",
false
],
[
91,
"#666666",
"",
false
],
[
92,
"#666666",
"",
false
],
[
93,
"#666666",
"",
false
],
[
94,
"#666666",
"",
false
],
[
95,
"#666666",
"",
false
],
[
96,
"#666666",
"",
false
],
[
97,
"#666666",
"",
false
],
[
98,
"#666666",
"",
false
],
[
99,
"#00ff00",
"#000000",
false
]
]

@ -0,0 +1,383 @@
#sql_dbi events map
events_map = {
"grp_v_ch_grant_mbt": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'options'],
['frequency', 'frequency'],
['tgid', 'group'],
['suid', 'srcaddr'],
],
"grg_exenc_cmd": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'mfrid'],
['tgid', 'sg'],
['p', 'keyid'],
],
"grp_v_ch_grant": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'mfrid'],
['p', 'options'],
['frequency', 'frequency'],
['tgid', 'group'],
['suid', 'srcaddr'],
],
"mot_grg_cn_grant": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'mfrid'],
['frequency', 'frequency'],
['tgid', 'sg'],
['suid', 'sa'],
],
"grp_v_ch_grant_updt": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'mfrid'],
['frequency', 'frequency1'],
['tgid', 'group1'],
],
"grp_v_ch_grant_updt_exp": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'mfrid'],
['p', 'options'],
['frequency', 'frequency'],
['tgid', 'group'],
],
"ack_resp_fne": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'aiv'],
['p2', 'ex'],
['p3', 'addl'],
['wacn', 'wacn'],
['suid', 'source'],
['suid2', 'target'],
],
"deny_resp": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'aiv'],
['p2', 'reason'],
['p3', 'additional'],
['suid', 'target'],
],
"grp_aff_resp": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'affiliation'],
['p2', 'group_aff_value'],
['tgid', 'announce_group'],
['tgid2', 'group'],
['suid', 'target'],
],
"grp_aff_q": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['suid', 'source'],
['suid2', 'target'],
],
"loc_reg_resp": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'rv'],
['p2', 'rfss'],
['p3', 'siteid'],
['tgid', 'group'],
['suid', 'target'],
],
"u_reg_resp": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'rv'],
['suid', 'source'],
['suid2', 'target'],
],
"u_reg_cmd": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['suid', 'source'],
['suid2', 'target'],
],
"u_de_reg_ack": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['wacn', 'wacn'],
['suid', 'source'],
],
"ext_fnct_cmd": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'mfrid'],
['p', 'efclass'],
['p2', 'efoperand'],
['suid', 'efargs'],
],
"end_call": [
['time', 'time'],
['sysid', 'sysid'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'code'],
['suid', 'srcaddr'],
['tgid', 'tgid'],
['p2', 'duration'],
['p3', 'count'],
],
}
# cc_event to numerical id (oplog and sql_dbi)
cc_events = {
"ack_resp_fne": 1,
"deny_resp": 2,
"end_call": 3,
"ext_fnct_cmd": 4,
"grg_exenc_cmd": 5,
"grp_aff_q": 6,
"grp_aff_resp": 7,
"grp_v_ch_grant": 8,
"grp_v_ch_grant_mbt": 9,
"grp_v_ch_grant_updt": 10,
"grp_v_ch_grant_updt_exp": 11,
"loc_reg_resp": 12,
"u_de_reg_ack": 13,
"u_reg_cmd": 14,
"u_reg_resp": 15,
"mot_grg_cn_grant": 16,
}
# sql column names to DataTables (Oplog)
oplog_map = {
"grp_v_ch_grant_mbt": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'MFRID'],
['p', 'Options'],
['frequency', 'Frequency'],
['tgid', 'Talkgroup ID'],
['tgid', 'Talkgroup'],
['suid', 'Source ID'],
['suid', 'Source'],
],
"grg_exenc_cmd": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'MFRID'],
['tgid', 'SG (tgid)'],
['p', 'Key ID'],
],
"grp_v_ch_grant": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'MFRID'],
['p', 'Options'],
['frequency', 'Frequency'],
['tgid', 'Talkgroup ID'],
['tgid', 'Talkgroup'],
['suid', 'Source ID'],
['suid', 'Source'],
],
"mot_grg_cn_grant": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'MFRID'],
['frequency', 'Frequency'],
['tgid', 'Talkgroup ID'],
['tgid', 'Talkgroup'],
['suid', 'Source ID'],
['suid', 'Source'],
],
"grp_v_ch_grant_updt": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'MFRID'],
['frequency', 'Frequency'],
['tgid', 'Talkgroup ID'],
['tgid', 'Talkgroup'],
],
"grp_v_ch_grant_updt_exp": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'mfrid'],
['p', 'Options'],
['frequency', 'Frequency'],
['tgid', 'Talkgroup ID'],
['tgid', 'Talkgroup'],
],
"ack_resp_fne": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'aiv'],
['p2', 'ex'],
['p3', 'Additional'],
['wacn', 'wacn'],
['suid', 'System Source'],
['suid2', 'Target ID'],
['suid2', 'Target'],
],
"deny_resp": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'aiv'],
['p2', 'Reason'],
['p3', 'Additional'],
['suid', 'Target ID'],
['suid', 'Target'],
],
"grp_aff_resp": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'Affiliation'],
['p2', 'Group Aff Value'],
['tgid', 'Announce Group'],
['tgid2', 'Talkgroup ID'],
['tgid2', 'Talkgroup'],
['suid', 'Target ID'],
['suid', 'Target'],
],
"grp_aff_q": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['suid', 'System Source'],
['suid2', 'Target ID'],
['suid2', 'Target'],
],
"loc_reg_resp": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'rv'],
['p2', 'RFSS'],
['p3', 'Site'],
['tgid', 'Talkgroup ID'],
['tgid', 'Talkgroup'],
['suid', 'Target ID'],
['suid', 'Target'],
],
"u_reg_resp": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'rv'],
['suid', 'Source ID'],
['suid', 'Source'],
['suid2', 'Target'],
],
"u_reg_cmd": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['suid', 'System Source'],
['suid2', 'Target ID'],
['suid2', 'Target'],
],
"u_de_reg_ack": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['wacn', 'WACN'],
['suid', 'Source ID'],
['suid', 'Source'],
],
"ext_fnct_cmd": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['mfrid', 'MFRID'],
['p', 'Class'],
['p2', 'Operand'],
['suid', 'System Source'],
],
"end_call": [
['time', 'Time'],
['sysid', 'System'],
['opcode', 'opcode'],
['cc_event', 'cc_event'],
['p', 'Code'],
['suid', 'Source ID'],
['suid', 'Source'],
['tgid', 'Talkgroup ID'],
['tgid', 'Talkgroup'],
['p2', 'Duration (ms)'],
['p3', 'Count (p3)'],
],
}
# friendly long description strings, used in Oplog
cc_desc = {
"ack_resp_fne": "Acknowledge Response FNE - 0x20",
"deny_resp": "Deny Response - 0x27",
"end_call": "End Call (not a naitve control channel event)",
"ext_fnct_cmd": "Extended Function Command - 0x24",
"grg_exenc_cmd": "Harris Group Regroup Explicit Encryption Command - 0x30",
"grp_aff_q": "Group Affiliation Query - 0x2A",
"grp_aff_resp": "Group Affiliation Response - 0x2B",
"grp_v_ch_grant": "Group Voice Channel Grant - 0x00",
"grp_v_ch_grant_mbt": "Group Voice Channel Grant, Multiple Block Trunking",
"grp_v_ch_grant_updt": "Group Voice Channel Grant Update - 0x02",
"grp_v_ch_grant_updt_exp": "Group Voice Channel Grant Update, Explicit - 0x03",
"loc_reg_resp": "Location Registration Response 0x2B",
"mot_grg_cn_grant": "Motorola Patch Channel Grant - 0x02",
"u_de_reg_ack": "De-Registration Acknowledge (Logout) - 0x2F",
"u_reg_cmd": "Unit Registration Command (Force Unit Registration) - 0x2D",
"u_reg_resp": "Unit Registration Response - 0x2C"
}

@ -58,7 +58,7 @@ def limit(a,lim):
PSEQ = 0
class wrap_gp(object):
def __init__(self, sps=_def_sps, logfile=None, title=None, color_cfg='plot-colors.json'):
def __init__(self, sps=_def_sps, logfile=None, title="", color_cfg='plot-colors.json'):
global PSEQ
self.sps = sps
self.center_freq = 0.0
@ -270,16 +270,16 @@ class wrap_gp(object):
h += 'set format ""\n'
h += 'set style line 11 lt 1 lw 2 pt 2 ps 2\n'
h+= 'set title "Constellation" %s\n' % (label_color)
h+= 'set title "Constellation %s" %s\n' % (self.title, label_color)
elif mode == 'eye':
h+= background
h+= 'set yrange [-4:4]\n'
h+= 'set title "Datascope" %s\n' % (label_color)
h+= 'set title "Datascope %s" %s\n' % (self.title, label_color)
plot_color = ''
elif mode == 'symbol':
h+= background
h+= 'set yrange [-4:4]\n'
h+= 'set title "Symbol" %s\n' % (label_color)
h+= 'set title "Symbol %s" %s\n' % (self.title, label_color)
elif mode == 'fft' or mode == 'mixer':
h+= background
h+= 'unset arrow; unset title\n'
@ -289,9 +289,9 @@ class wrap_gp(object):
h+= 'set grid\n'
h+= 'set yrange [-100:0]\n'
if mode == 'mixer': # mixer
h+= 'set title "Mixer: balance %3.0f (smaller is better)" %s\n' % (np.abs(self.avg_sum_pwr * 1000), label_color)
h+= 'set title "Mixer %s: balance %3.0f (smaller is better)" %s\n' % (self.title, np.abs(self.avg_sum_pwr * 1000), label_color)
else: # fft
h+= 'set title "Spectrum" %s\n' % (label_color)
h+= 'set title "Spectrum %s" %s\n' % (self.title, label_color)
if self.center_freq:
arrow_pos = (self.center_freq - self.relative_freq) / 1e6
h+= 'set arrow from %f, graph 0 to %f, graph 1 nohead\n' % (arrow_pos, arrow_pos)
@ -299,7 +299,7 @@ class wrap_gp(object):
elif mode == 'float':
h+= background
h+= 'set yrange [-2:2]\n'
h+= 'set title "Oscilloscope" %s\n' % (label_color)
h+= 'set title "Oscilloscope %s" %s\n' % (self.title, label_color)
elif mode == 'correlation':
h+= background
title = 'Correlation'
@ -358,6 +358,9 @@ class eye_sink_f(gr.sync_block):
consumed = self.gnuplot.plot(in0, 100*self.sps, mode='eye')
return consumed ### len(input_items[0])
def set_title(self, title):
self.gnuplot.set_title(title)
def kill(self):
self.gnuplot.kill()
@ -377,6 +380,9 @@ class constellation_sink_c(gr.sync_block):
self.gnuplot.plot(in0, 1000, mode='constellation')
return len(input_items[0])
def set_title(self, title):
self.gnuplot.set_title(title)
def kill(self):
self.gnuplot.kill()
@ -400,6 +406,9 @@ class fft_sink_c(gr.sync_block):
self.gnuplot.plot(in0, FFT_BINS, mode='fft')
return len(input_items[0])
def set_title(self, title):
self.gnuplot.set_title(title)
def kill(self):
self.gnuplot.kill()