From 87e15a07a18627a9b678f2d202b93e14842b7fb3 Mon Sep 17 00:00:00 2001 From: Jason McHuff Date: Sat, 20 May 2023 21:03:16 -0700 Subject: [PATCH 1/4] update README.md and docs/CONFIGURE.md --- README.md | 20 +++++---- docs/CONFIGURE.md | 107 ++++++++++++++++++++++------------------------ 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 2792ae8e6..eef63651e 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ RTL-SDR dongles; HackRF; Ettus USRP B200, B210, B205; BladeRF; Airspy ## Version Notes ### V4.0 - The executable generated has changed from `recorder` to `trunk-recorder` to help differentiate it from other applications that maybe installed. -- A new method is used to detect the end of call. Instead of waiting for a timeout after the last trunking message is recieved, the voice channel is monitored for messages announcing the end of a transmission. Each transmission is stored in a separate file and then merged together after a talkgroup stops using a frequency. +- A new method is used to detect the end of call. Instead of waiting for a timeout after the last trunking message is received, the voice channel is monitored for messages announcing the end of a transmission. Each transmission is stored in a separate file and then merged together after a talkgroup stops using a frequency. - The format for audio filenames has changed slightly. It is now: [ Talkgroup ID ]\_[ Unix Timestamp ]-[ Frequency ]-call\_[ Call Counter ].wav @@ -61,25 +61,27 @@ By default, Trunk Recorder just dumps a lot of recorded files into a directory. * [OpenMHz](https://github.com/robotastic/trunk-recorder/wiki/Uploading-to-OpenMHz) - This is my free hosted platform for sharing recordings * [Trunk Player](https://github.com/ScanOC/trunk-player) - A great Python based server, if you want to you want to run your own * [Rdio Scanner](https://github.com/chuot/rdio-scanner) - Provide a good looking, scanner style interface for listening to Trunk Recorder -* [Broadcastify Calls (API)](https://forums.radioreference.com/threads/405236/)-[Wiki](https://wiki.radioreference.com/index.php/Broadcastify-Calls-Trunk-Recorder) +* Broadcastify Calls (API): see Radio Reference [forum thread](https://forums.radioreference.com/threads/405236/) and [wiki page](https://wiki.radioreference.com/index.php/Broadcastify-Calls-Trunk-Recorder) * [Broadcastify via Liquidsoap](https://github.com/robotastic/trunk-recorder/wiki/Streaming-online-to-Broadcastify-with-Liquid-Soap) * [audioplayer.php](https://github.com/robotastic/trunk-recorder/wiki/Using-audioplayer.php) ### Plugins -* [MQTT Status](https://github.com/robotastic/trunk-recorder-mqtt-statistics) - Publishes the current status of a Trunk Recorder instance over MQTT -* [MQTT Stastics](https://github.com/robotastic/trunk-recorder-mqtt-statistics) - Publishe statistics about a Trunk Recorder instance over MQTT - +* [MQTT Status](https://github.com/robotastic/trunk-recorder-mqtt-status) - Publishes the current status of a Trunk Recorder instance over MQTT +* [MQTT Statistics](https://github.com/robotastic/trunk-recorder-mqtt-statistics) - Publishes statistics about a Trunk Recorder instance over MQTT +* [Decode rates logger](https://github/rosecitytransit/trunk-recorder-decode-rate) - Logs trunking control channel decode rates to a CSV file, and includes a PHP file that outputs an SVG graph ### Troubleshooting -If are having trouble, check out the [FAQ](docs/FAQ.md) and/or ask a question on the [Discord Server](Https://discord.gg/trunk-recorder) +If are having trouble, check out the [FAQ](docs/FAQ.md) and/or ask a question on the [Discord Server](https://discord.gg/trunk-recorder) ___ ### How Trunking Works -Here is a little background on trunking radio systems, for those not familiar. In a Trunking system, one of the radio channels is set aside for to manage the assignment of radio channels to talkgroups. When someone wants to talk, they send a message on the control channel. The system then assigns them a channel and sends a Channel Grant message on the control channel. This lets the talker know what channel to transmit on and anyone who is a member of the talkgroup know that they should listen to that channel. +For those not familiar, trunking systems allow a large number of user groups to share a limited number of radio frequencies by temporarily, dynamically assigning radio frequencies to talkgroups (channels) on-demand. It is understood that most user groups actually use the radio very sporadically and don't need a dedicated frequency. + +Most trunking system types (such as SmartNet and P25) set aside one of the radio frequencies as a "control channel" that manages and broadcasts radio frequency assignments. When someone presses the Push to Talk button on their radio, the radio sends a message to the system which then assigns a voice frequency and broadcasts a Channel Grant message about it on the control channel. This lets the radio know what frequency to transmit on and tells other radios set to the same talkgroup to listen. -In order to follow all of the transmissions, this system constantly listens to and decodes the control channel. When a channel is granted to a talkgroup, the system creates a monitoring process. This process will start to process and decode the part of the radio spectrum for that channel which the SDR is already pulling in. +In order to follow all of the transmissions, Trunk Recorder constantly listens to and decodes the control channel. When a frequency is granted to a talkgroup, Trunk Recorder creates a monitoring process which decodes the portion of the radio spectrum for that frequency from the SDR that is already pulling it in. -No message is transmitted on the control channel when a talkgroup’s conversation is over. So instead the monitoring process keeps track of transmissions and if there has been no activity for 5 seconds, it ends the recording. +No message is transmitted on the control channel when a conversation on a talkgroup is over. The monitoring process keeps track of transmissions and if there has been no activity for a specified period, it ends the recording. diff --git a/docs/CONFIGURE.md b/docs/CONFIGURE.md index 4511ba5e2..93a4252cf 100644 --- a/docs/CONFIGURE.md +++ b/docs/CONFIGURE.md @@ -12,9 +12,9 @@ Before you can start entering values, you will need to do a little research abou The next step is to try and receive the control channel for the trunked system, using [http://gqrx.dk/](GQRX). GQRX visualizes what your SDR is receiving and makes it easy to fine-tune the system and associated spectrum. While the system you are trying to tune in may have a lot of control channels, it is generally only transmitting on one. Type in the different frequencies to look for the active control channel. Control channels are always broadcasting, and show up as a persistent line on the waterfall graph. -There is a good chance that when you tune to the active control channel, it will actually be a few thousand Hz above or below the frequency you tuned to. This is because the tuners on most SDRs are not super accurate and have frequency drifting. Click on the transmission to get the frequency that your SDR thinks it is at. +There is a chance that when you tune to the active control channel, it will actually be a few thousand Hz above or below the frequency you tuned to. This is because the tuners on some SDRs are not super accurate and have frequency drifting. Click on the transmission to get the frequency that your SDR thinks it is at. -Trunk Recorder needs to know the amount of tuning error for your SDR in order to successfully tune-in to transmissions. To calculate this, take frequency that the SDR was tuned to... for example 854.548MHz, and subtract the actual frequency for the channel, 854.5625MHz. +If so, Trunk Recorder needs to know the amount of tuning error for your SDR in order to successfully tune-in to transmissions. To calculate this, take frequency that the SDR was tuned to... for example 854.548MHz, and subtract the actual frequency for the channel, 854.5625MHz. `854.548 - 854.5625 = -0.0145 MHz` @@ -45,7 +45,7 @@ When you set the center frequency for a source, **you are picking the frequency For example, if you are using a HackRF, with 8MHz of bandwidth, and you tune the center frequency to 854MHz, it would cover from 850.0MHz to 858.0MHz. -To find your ideal center frequency, look at what the lowest frequency you want to cover is and what the highest is. You need to need to be able cover slightly beyond the frequncy of a channel. This is because the frequency is for the center of the channel and the actual channel is wider and a bit of filtering is done to receive it. The sample rate should be higher than the difference between the low and high frequency. Most SDRs do not perform as well right at the beginnging and end of the frequency range they are set to. It is best to set a slightly higher sample rate than needed, to avoid those spots. Also, some SDRs have some artifacts right at there center frequency, so ensure that center frequency doesn't land on the frequency of a channel you are trying to record. +To find your ideal center frequency, look at what the lowest frequency you want to cover is and what the highest is. You need to need to be able cover slightly beyond the frequncy of a channel. This is because the frequency is for the center of the channel and the actual channel is wider and a bit of filtering is done to receive it. The sample rate should be higher than the difference between the low and high frequency. Most SDRs do not perform as well right at the beginnging and end of the frequency range they are set to. It is best to set a slightly higher sample rate than needed, to avoid those spots. Also, some SDRs have some artifacts right at there center frequency, so ensure that center frequency doesn't land on the frequency of a channel you are trying to record. ### Multiple Sources If the low frequency and high frequency of the system you are trying to capture is greater than the amount of bandwidth your SDR can capture, you need to use multiple SDRs. @@ -91,11 +91,11 @@ Here is a map of the different sections of the *config.json* file: ```json { - Global Configs + Global Configs - "sources": [{ Source Object }, { Source Object }], - "systems": [{ System Object }, { System Object }], - "plugins": [{ Plugin Object }] + "sources": [{ Source Object }, { Source Object }], + "systems": [{ System Object }, { System Object }], + "plugins": [{ Plugin Object }] } ``` @@ -105,7 +105,7 @@ Here is a map of the different sections of the *config.json* file: | Key | Required | Default Value | Type | Description | | ---------------------------- | :------: | ----------------- | ----------------------------------------------------------- | ------------------------------------------------------------ | -| ver | ✓ | | number | the version of formatting for the config file. **This should be set to 2**. Trunk Recorder will not start without this set. | +| ver | ✓ | | number | The version of formatting for the config file. **This should be set to 2**. Trunk Recorder will not start without this set. | | sources | ✓ | | array of JSON objects
[{}] | An array of JSON formatted [Source Objects](#source-object) that define the different SDRs available. Source Objects are described below. | | systems | ✓ | | array of JSON objects
[{}] | An array of JSON formatted [System Objects](#system-object) that define the trunking systems that will be recorded. System Objects are described below. | | plugins | | | array of JSON objects
[{}] | An array of JSON formatted [Plugin Objects](#plugin-object) that define the different plugins to use. Refer to the [Plugin System](notes/PLUGIN-SYSTEM.md) documentation for more details. | @@ -115,14 +115,15 @@ Here is a map of the different sections of the *config.json* file: | uploadServer | | | string | The URL for uploading to OpenMHz. The default is an empty string. See the Config tab for your system in OpenMHz to find what the value should be. | | broadcastifyCallsServer | | | string | The URL for uploading to Broadcastify Calls. The default is an empty string. Refer to [Broadcastify's wiki](https://wiki.radioreference.com/index.php/Broadcastify-Calls-API) for the upload URL. | | broadcastifySslVerifyDisable | | false | **true** / **false** | Optionally disable SSL verification for Broadcastify uploads, given their apparent habit of letting their SSL certificate expire | -| | | | | | | logFile | | false | **true** / **false** | Save the console output to a file. | +| logDir | | logs/ | string | Where the console output logs should be put | | frequencyFormat | | "exp" | **"exp" "mhz"** or **"hz"** | the display format for frequencies to display in the console and log file. | | controlWarnRate | | 10 | number | Log the control channel decode rate when it falls bellow this threshold. The value of *-1* will always log the decode rate. | +| controlRetuneLimit | | 0 | number | Number of times to attempt to retune to a different control channel when there's no signal. *0* means unlimited attemps. The counter is reset when a signal is found. Should be at least equal to the number of channels defined in order for all to be attempted. | | statusAsString | | true | **true** / **false** | Show status as strings instead of numeric values | | statusServer | | | string | The URL for a WebSocket connect. Trunk Recorder will send JSON formatted update message to this address. HTTPS is currently not supported, but will be in the future. OpenMHz does not support this currently. [JSON format of messages](./notes/STATUS-JSON.md) | | broadcastSignals | | true | **true** / **false** | Broadcast decoded signals to the status server. | -| logLevel | | "info" | **"trace" "debug" "info" "warning" "error"** or **"fatal"** | the logging level to display in the console and log file. The options are *trace*, *debug*, *info*, *warning*, *error* & *fatal*. The default is *info*. | +| logLevel | | "info" | **"trace", "debug", "info", "warning", "error"** or **"fatal"** | the logging level to display in the console and log file. The options are *trace*, *debug*, *info*, *warning*, *error* & *fatal*. The default is *info*. | | debugRecorder | | true | **true** / **false** | Will attach a debug recorder to each Source. The debug recorder will allow you to examine the channel of a call be recorded. There is a single Recorder per Source. It will monitor a recording and when it is done, it will monitor the next recording started. The information is sent over a network connection and can be viewed using the `udp-debug.grc` graph in GnuRadio Companion | | debugRecorderPort | | 1234 | number | The network port that the Debug Recorders will start on. For each Source an additional Debug Recorder will be added and the port used will be one higher than the last one. For example the ports for a system with 3 Sources would be: 1234, 12345, 1236. | | debugRecorderAddress | | "127.0.0.1" | string | The network address of the computer that will be monitoring the Debug Recorders. UDP packets will be sent from Trunk Recorder to this computer. The default is *"127.0.0.1"* which is the address used for monitoring on the same computer as Trunk Recorder. | @@ -134,24 +135,24 @@ Here is a map of the different sections of the *config.json* file: | Key | Required | Default Value | Type | Description | | :--------------- | :------: | :-----------: | ------------------------------------------------------------ | ------------------------------------------------------------ | -| center | ✓ | | number | the center frequency in Hz to tune the SDR to | -| rate | ✓ | | number | the sampling rate to set the SDR to, in samples / second | -| error | | 0 | number | the tuning error for the SDR, in Hz. This is the difference between the target value and the actual value. So if you wanted to recv 856MHz but you had to tune your SDR to 855MHz (when set to 0ppm) to actually receive it, you would set this to -1000000. You should also probably get a new SDR if it is off by this much. | +| center | ✓ | | number | The center frequency in Hz to tune the SDR to | +| rate | ✓ | | number | The sampling rate to set the SDR to, in samples / second | +| error | | 0 | number | The tuning error for the SDR, in Hz. This is the difference between the target value and the actual value. So if you wanted to recv 856MHz but you had to tune your SDR to 855MHz (when set to 0ppm) to actually receive it, you would set this to -1000000. You should also probably get a new SDR if it is off by this much. | | gain | ✓ | | number | The RF gain setting for the SDR. Use a program like GQRX to find a good value. | | digitalRecorders | | | number | The number of Digital Recorders to have attached to this source. This is essentially the number of simultaneous calls you can record at the same time in the frequency range that this Source will be tuned to. It is limited by the CPU power of the machine. Some experimentation might be needed to find the appropriate number. *This is only required for Trunk systems. Channels in Conventional systems have dedicated recorders and do not need to be included here.* | -| analogRecorders | | | number | the number of Analog Recorder to have attached to this source. This is the same as Digital Recorders except for Analog Voice channels. *This is only required for Trunk systems. Channels in Conventional systems have dedicated recorders and do not need to be included here.* | +| analogRecorders | | | number | The number of Analog Recorder to have attached to this source. The same as Digital Recorders except for Analog Voice channels. *This is only required for Trunk systems. Channels in Conventional systems have dedicated recorders and do not need to be included here.* | | driver | ✓ | | **"usrp"** or **"osmosdr"** | The GNURadio block you wish to use for the SDR. | -| device | | | **string**
See the [osmosdr page](http://sdr.osmocom.org/trac/wiki/GrOsmoSDR) for supported devices and parameters. | Osmosdr device name and possibly serial number or index of the device.
You only need to do add this key if there are more than one osmosdr devices being used.
Example: `bladerf=00001` for BladeRF with serial 00001 or `rtl=00923838` for RTL-SDR with serial 00923838, just `airspy` for an airspy.
It seems that when you have 5 or more RTLSDRs on one system you need to decrease the buffer size. I think it has something to do with the driver. Try adding buflen: `"device": "rtl=serial_num,buflen=65536"`, there should be no space between buflen and the comma | -| ppm | | 0 | number | the tuning error for the SDR in ppm (parts per million), as an alternative to `error` above. Use a program like GQRX to find an accurate value. | -| agc | | false | **true** / **false** | whether or not to enable the SDR's automatic gain control (if supported). This is false by default. It is not recommended to set this as it often yields worse performance compared to a manual gain setting. | -| gainSettings | | | { "stageName": value} | set the gain for any stage. The value for this setting should be passed as an object, where the key specifies the name of the gain stage and the value is the amount of gain, as an int. For example:
````"gainSettings": { "IF": 10, "BB": 11},```` | -| ifGain | | | number | [AirSpy/hackrf only] sets the **IF** gain. | -| bbGain | | | number | [hackrf only] sets the **BB** gain. | -| mixGain | | | number | [AirSpy only] sets the **MIX** gain. | -| lnaGain | | | number | [AirSpy/bladeRF only] sets the **LNA** gain. | -| vga1Gain | | | number | [bladeRF only] sets the **VGA1** gain. | -| vga2Gain | | | number | [bladeRF only] sets the **VGA2** gain. | -| antenna | | | string, e.g.: **"TX/RX"** | [usrp] selects which antenna jack to use | +| device | | | **string**
See the [osmosdr page](http://sdr.osmocom.org/trac/wiki/GrOsmoSDR) for supported devices and parameters. | Osmosdr device name and possibly serial number or index of the device.
You only need to do add this key if there are more than one osmosdr devices being used.
Example: `bladerf=00001` for BladeRF with serial 00001 or `rtl=00923838` for RTL-SDR with serial 00923838, just `airspy` for an airspy.
It seems that when you have 5 or more RTLSDRs on one system you need to decrease the buffer size. I think it has something to do with the driver. Try adding buflen: `"device": "rtl=serial_num,buflen=65536"`, there should be no space between the comma and `buflen`. | +| ppm | | 0 | number | The tuning error for the SDR in ppm (parts per million), as an alternative to `error` above. Use a program like GQRX to find an accurate value. | +| agc | | false | **true** / **false** | Whether or not to enable the SDR's automatic gain control (if supported). This is false by default. It is not recommended to set this as it often yields worse performance compared to a manual gain setting. | +| gainSettings | | | { "stageName": value} | Set the gain for any stage. The value for this setting should be passed as an object, where the key specifies the name of the gain stage and the value is the amount of gain, as an int. For example:
````"gainSettings": { "IF": 10, "BB": 11},```` | +| ifGain | | | number | *AirSpy/hackrf only* sets the **IF** gain. | +| bbGain | | | number | *hackrf only* sets the **BB** gain. | +| mixGain | | | number | *AirSpy only* sets the **MIX** gain. | +| lnaGain | | | number | *AirSpy/bladeRF only* sets the **LNA** gain. | +| vga1Gain | | | number | *bladeRF only* sets the **VGA1** gain. | +| vga2Gain | | | number | *bladeRF only* sets the **VGA2** gain. | +| antenna | | | string, e.g.: **"TX/RX"** | *usrp only* selects which antenna jack to use | | enabled | | true | **true** / **false** | control whether a configured source is enabled or disabled | @@ -160,43 +161,43 @@ Here is a map of the different sections of the *config.json* file: | Key | Required | Default Value | Type | Description | | ---------------------- | :------: | ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | shortName | ✓ | | string | This is a nickname for the system. It is used to help name and organize the recordings from this system. It should be 4-6 letters with no spaces. | -| type | ✓ | | **"smartnet" "p25" "conventional, conventionalDMR"** or **"conventionalP25"** | The type of radio system. | +| type | ✓ | | **"smartnet"**, **"p25"**, **"conventional"**, **"conventionalDMR"** or **"conventionalP25"** | The type of radio system. | | control_channels | ✓ | | array of numbers;
[496537500, 496437500] | **For trunked systems** The control channel frequencies for the system, in Hz. The frequencies will automatically be cycled through if the system moves to an alternate channel. | | channels | ✓ | | array of numbers;
[166725000, 166925000, 167075000, 166850000] | **For conventional systems** The channel frequencies, in Hz, used for the system. The channels get assigned a virtual talkgroup number based upon their position in the array. Squelch levels need to be specified for the Source(s) being used. | -| channelFile | ✓ | | string | **For conventional systems** The filename for a CSV file that provides information about the conventional channels. The format for the file is described below. Squelch levels need to be specified for the Source(s) being used. *Use channels or channelFile, not both*. | +| channelFile | ✓ | | string | **For conventional systems** The filename for a CSV file that provides information about the conventional channels. The format for the file is described below. Squelch levels need to be specified for the Source(s) being used. *Use channels or channelFile, not both*. | | modulation | | "qpsk" | **"qpsk"** or **"fsk4"** | The type of digital modulation that the system uses. You do not need to specify this with **conventionalDMR** systems. | -| squelch | | -160 | number | Squelch in DB, this needs to be set for all conventional systems. The squelch setting is also used for analog talkgroups in a SmartNet system. I generally use -60 for my rtl-sdr. The closer the squelch is to 0, the stronger the signal has to be to unmute it. | +| squelch | | -160 | number | Squelch in DB, this needs to be set for all conventional systems. The squelch setting is also used for analog talkgroups in a SmartNet system. I generally use -60 for my rtl-sdr. The closer the squelch is to 0, the stronger the signal has to be to unmute it. | | talkgroupsFile | | | string | The filename for a CSV file that provides information about the talkgroups. It determines whether a talkgroup is analog or digital, and what priority it should have. This file should be located in the same directory as the trunk-recorder executable. | -| apiKey | | | string | [*if uploadServer is set*] System-specific API key for uploading calls to OpenMHz.com. See the Config tab for your system in OpenMHz to find what the value should be. | -| broadcastifyApiKey | | | string | [*if broadcastifyCallsServer is set*] System-specific API key for Broadcastify Calls | -| broadcastifySystemId | | | number | [*if broadcastifyCallsServer is set*] System ID for Broadcastify Calls
(this is an integer, and different from the RadioReference system ID) | -| uploadScript | | | string | This is the filename of a script that is called after each recording has finished. Checkout *encode-upload.sh.sample* as an example. The script should be located in the same directory as the trunk-recorder executable. | +| apiKey | | | string | *if uploadServer is set* System-specific API key for uploading calls to OpenMHz.com. See the Config tab for your system in OpenMHz to find what the value should be. | +| broadcastifyApiKey | | | string | *if broadcastifyCallsServer is set* System-specific API key for Broadcastify Calls | +| broadcastifySystemId | | | number | *if broadcastifyCallsServer is set* System ID for Broadcastify Calls
(this is an integer, and different from the RadioReference system ID) | +| uploadScript | | | string | The filename of a script that is called after each recording has finished. Checkout *encode-upload.sh.sample* as an example. Should probably start with `./` ( or `../`). | | compressWav | | true | bool | Convert the recorded .wav file to an .m4a file. **This is required for both OpenMHz and Broadcastify!** The `sox` and `fdkaac` packages need to be installed for this command to work. | -| unitScript | | | string | This is the filename of a script that runs when a radio (unit) registers (is turned on), affiliates (joins a talk group), deregisters (is turned off), gets an acknowledgment response, transmits, gets a data channel grant, a unit-unit answer request or a Location Registration Response. Passed as parameters: `shortName radioID on\|join\|off\|ackresp\|call\|data\|ans_req\|location`. On joins and transmissions, `talkgroup` is passed as a fourth parameter; on answer requests, the `source` is. On joins and transmissions, `patchedTalkgroups` (comma separated list of talkgroup IDs) is passed as a fifth parameter if the talkgroup is part of a patch on the system. See *examples/unit-script.sh* for a logging example. Note that for paths relative to recorder, this should start with `./`( or `../`). | +| unitScript | | | string | The filename of a script that runs when a radio (unit) registers (is turned on), affiliates (joins a talk group), deregisters (is turned off), gets an acknowledgment response, transmits, gets a data channel grant, a unit-unit answer request or a Location Registration Response. Passed as parameters: `shortName radioID on\|join\|off\|ackresp\|call\|data\|ans_req\|location`. On joins and transmissions, `talkgroup` is passed as a fourth parameter; on answer requests, the `source` is. On joins and transmissions, `patchedTalkgroups` (comma separated list of talkgroup IDs) is passed as a fifth parameter if the talkgroup is part of a patch on the system. See *examples/unit-script.sh* for a logging example. Note that for paths relative to trunk-recorder, this should start with `./`( or `../`). | | audioArchive | | true | **true** / **false** | Should the recorded audio files be kept after successfully uploading them? | | transmissionArchive | | false | **true** / **false** | Should each of the individual transmission be kept? These transmission are combined together with other recent ones to form a single call. | | callLog | | false | **true** / **false** | Should a json file with the call details be kept after successful uploads? | | analogLevels | | 8 | number (1-32) | The amount of amplification that will be applied to the analog audio. | -| maxDev | | 4000 | number | Allows you to set the maximum deviation for analog channels. If you analog recordings sound good or if you have a completely digital system, then there is no need to touch this. | +| maxDev | | 4000 | number | The maximum deviation for analog channels. If you analog recordings sound good or if you have a completely digital system, then there is no need to touch this. | | digitalLevels | | 1 | number (1-16) | The amount of amplification that will be applied to the digital audio. | -| unitTagsFile | | | string | This is the filename of a CSV file that provides information about the unit tags. The format for the file is described below. | +| unitTagsFile | | | string | The filename of a CSV file that provides information about the unit tags. The format for the file is described below. | | recordUnknown | | true | **true** / **false** | Record talkgroups if they are not listed in the Talkgroups File. | -| recordUUVCalls | | true | **true** / **false** | [ P25 only ] Record Unit to Unit Voice calls. | +| recordUUVCalls | | true | **true** / **false** | *P25 only* Record Unit to Unit Voice calls. | | hideEncrypted | | false | **true** / **false** | Hide encrypted talkgroups log entries | | hideUnknownTalkgroups | | false | **true** / **false** | Hide unknown talkgroups log entries | | minDuration | | 0
(which is disabled) | number | The minimum call duration in seconds (decimals allowed), calls below this number will have recordings deleted and will not be uploaded. | | minTransmissionDuration| | 0
(which is disabled) | number | The minimum transmission duration in seconds (decimals allowed), transmissions below this number will not be added to their corresponding call. | | maxDuration | | 0
(which is disabled) | number | The maximum call duration in seconds (decimals allowed), calls above this number will have recordings split into multiple parts. | | talkgroupDisplayFormat | | "id" | **"id" "id_tag"** or **"tag_id"** | The display format for talkgroups in the console and log file. (*id_tag* and *tag_id* is only valid if **talkgroupsFile** is specified) | -| bandplan | | "800_standard" | **"800_standard" "800_reband" "800_splinter"** or **"400_custom"** | [SmartNet only] this is the SmartNet bandplan that will be used. | -| bandplanBase | | | number | [SmartNet, 400_custom only] this is for the *400_custom* bandplan only. This is the base frequency, specified in Hz. | -| bandplanHigh | | | number | [SmartNet, 400_custom only] this is the highest channel in the system, specified in Hz. | -| bandplanSpacing | | | number | [SmartNet, 400_custom only] this is the channel spacing, specified in Hz. Typically this is *25000*. | -| bandplanOffset | | | number | [SmartNet, 400_custom only] this is the offset used to calculate frequencies. | -| decodeMDC | | false | **true** / **false** | [ Conventional systems only ] enable the MDC-1200 signaling decoder. | -| decodeFSync | | false | **true** / **false** | [ Conventional systems only ] enable the Fleet Sync signaling decoder. | -| decodeStar | | false | **true** / **false** | [ Conventional systems only ] enable the Star signaling decoder. | -| decodeTPS | | false | **true** / **false** | [ Conventional systems only ] enable the Motorola Tactical Public Safety (aka FDNY Fireground) signaling decoder. | +| bandplan | | "800_standard" | **"800_standard" "800_reband" "800_splinter"** or **"400_custom"** | [SmartNet only] The SmartNet bandplan that will be used. | +| bandplanBase | | | number | *400_custom only* The base frequency, specified in Hz. | +| bandplanHigh | | | number | *SmartNet, 400_custom only* The highest channel in the system, specified in Hz. | +| bandplanSpacing | | | number | *SmartNet, 400_custom only* The channel spacing, specified in Hz. Typically this is *25000*. | +| bandplanOffset | | | number | *SmartNet, 400_custom only* The offset used to calculate frequencies. | +| decodeMDC | | false | **true** / **false** | *Conventional systems only* enable the MDC-1200 signaling decoder. | +| decodeFSync | | false | **true** / **false** | *Conventional systems only* enable the Fleet Sync signaling decoder. | +| decodeStar | | false | **true** / **false** | *Conventional systems only* enable the Star signaling decoder. | +| decodeTPS | | false | **true** / **false** | *Conventional systems only* enable the Motorola Tactical Public Safety (aka FDNY Fireground) signaling decoder. | | enabled | | true | **true** / **false** | control whether a configured system is enabled or disabled | #### System Object - Experimental Options @@ -205,7 +206,7 @@ Here is a map of the different sections of the *config.json* file: | ---------------------- | :------: | ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | multiSite | | false | **true** / **false** | Enables multiSite mode for this system | | multiSiteSystemName | | | string | The name of the system that this site belongs to. **This is required for SmartNet in Multi-Site mode.** | -| multiSiteSystemNumber | | 0 | number | An arbitrary number used to identify this system for SmartNet in Multi-Site mode. | +| multiSiteSystemNumber | | 0 | number | An arbitrary number used to identify this system for SmartNet in Multi-Site mode. | Multi-Site mode attempts to avoid recording duplicate calls being broadcasted on multiple sites. Trunk recorder will not record duplicate calls on the same talkgroup for systems that have multiSite enabled. To ensure that both calls belong to the same system, Trunk Recorder will verify that both sites have the same WACN for P25, or the same multiSiteSystemName for SmartNet. By default, trunk-recorder will record the call from the first site that it receives the grant on, and any additional grants for the same call on other sites will be ignored. If you want to to specify the preferred site for a specific talk group, you can specify the preferred NAC in decimal format in the talk group CSV file. @@ -353,14 +354,10 @@ This example will stream audio from all talkgroups being recorded on System Coun ##### Example - Sending Audio to pulseaudio pulseaudio is the default sound system on many Linux computers, including the Raspberry Pi. If configured to do so, pulseaudio can accept raw audio via TCP connection using the module-simple-protocol-tcp module. Each TCP connection will show up as a different "application" in the pavucontrol volume mixer. -An example command to set up pulseaudio to receive 8 kHz audio (digital audio) from simplestream on TCP port 9125: +An example command to set up pulseaudio to receive 8 kHz digital audio from simplestream on TCP port 9125 (for 16 kHz analog audio, use `rate=16000`): ``` pacmd load-module module-simple-protocol-tcp sink=1 playback=true port=9125 format=s16le rate=8000 channels=1 ``` -An example command to set up pulseaudio to receive 16 kHz audio (analog audio) from simplestream on TCP port 9125: -``` -pacmd load-module module-simple-protocol-tcp sink=1 playback=true port=9125 format=s16le rate=16000 channels=1 -``` The matching simplestream config to send audio from talkgroup 58918 to TCP port 9125 would then be something like this: ```yaml { @@ -378,15 +375,15 @@ The matching simplestream config to send audio from talkgroup 58918 to TCP port ## talkgroupsFile -This file provides info on the different talkgroups in a trunking system. A lot of this info can be found on the [Radio Reference](http://www.radioreference.com/) website. You need to be a Radio Reference member to download the table for your system preformatted as a CSV file. If you are not a Radio Reference member, try clicking on the "List All in one table" link, selecting everything in the table and copying it into Excel or a spreadsheet, and then exporting or saving as a CSV file. +This file provides info on the different talkgroups in a trunking system. A lot of this info can be found on the [Radio Reference](http://www.radioreference.com/) website. You need to be a Radio Reference member to download the table for your system preformatted as a CSV file. You can also try clicking on the "List All in one table" link, selecting everything in the table and copying it into a spreadsheet program, and then exporting or saving as a CSV file. -**Note** - You can use the direct CSV from Radio Reference for talk groups, but setting priority is not supported with this file format. If you need to use the Priority field, you'll need to reorder the CSV to match the format described below. +**Note:** You can use the direct CSV from Radio Reference for talk groups, but setting priority is not supported with this file format. If you need to use the Priority field, you'll need to reorder the CSV to match the format described below. You may add an additional column that adds a priority for each talkgroup. The priority field specifies the number of recorders the system must have available to record a new call for the talkgroup. For example, a priority of 1, the highest means as long as at least a single recorder is available, the system will record the new call. If the priority is 2, the system would at least 2 free recorders to record the new call, and so on. If there is no priority set for a talkgroup entry, a prioity of 1 is assumed. Talkgroups assigned a priority of -1 will never be recorded, regardless of the number of available recorders. -The Trunk Record program really only uses the priority information and the Dec Talkgroup ID. The Website uses the same file though to help display information about each talkgroup. +Trunk Recorder really only uses the priority information and the decimal talkgroup ID. The Website uses the same file though to help display information about each talkgroup. Here are the column headers and some sample data: NOTE: If you are adding the Priority to a RR csv, as well as changing order you must use a heading for the first column other than "Decimal" eg DEC for TR to detect you are supplying this layout. @@ -399,7 +396,7 @@ Here are the column headers and some sample data: NOTE: If you are adding the Pr ## channelFile -This file allows for you to specify additional information about conventional channels. A recorder is started for each line in the file and set the to frequency specified. The type of recorder is based on the type of System. A *Conventional* system would have Analog Recorders, while a *ConventionalP25* or *ConventionalDMR* would have digital recorders. +This file allows for you to specify additional information about conventional channels. A recorder is started for each line in the file and set the to frequency specified. The type of recorder is based on the type of System. A **Conventional** system would have Analog Recorders, while **ConventionalP25** or **ConventionalDMR** would have digital recorders. *Tone based squelch is currently not supported.* From 8f6175706b81abad2466e2a896fb635ff538ac54 Mon Sep 17 00:00:00 2001 From: Jason McHuff Date: Sat, 20 May 2023 21:28:05 -0700 Subject: [PATCH 2/4] 3 minor fixes fix tbsk typo in p25_parser.cc remove duplicate include line in p25_frame_assembler_impl.cc remove duplicate add_file_log line in main.cc/have it capture log file config lines (fixes #754) --- lib/op25_repeater/lib/p25_frame_assembler_impl.cc | 1 - trunk-recorder/main.cc | 15 ++++----------- trunk-recorder/systems/p25_parser.cc | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/lib/op25_repeater/lib/p25_frame_assembler_impl.cc b/lib/op25_repeater/lib/p25_frame_assembler_impl.cc index 1b9b7ebba..00ba1c31f 100644 --- a/lib/op25_repeater/lib/p25_frame_assembler_impl.cc +++ b/lib/op25_repeater/lib/p25_frame_assembler_impl.cc @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/trunk-recorder/main.cc b/trunk-recorder/main.cc index a4375bf60..560cfec6d 100644 --- a/trunk-recorder/main.cc +++ b/trunk-recorder/main.cc @@ -151,10 +151,9 @@ bool load_config(string config_file) { BOOST_LOG_TRIVIAL(info) << "After you have made these updates, make sure you add \"ver\": 2, to the top.\n\n"; return false; } + config.log_file = pt.get("logFile", false); - BOOST_LOG_TRIVIAL(info) << "Log to File: " << config.log_file; config.log_dir = pt.get("logDir", "logs"); - BOOST_LOG_TRIVIAL(info) << "Log Directory: " << config.log_dir; if (config.log_file) { logging::add_file_log( keywords::file_name = config.log_dir + "/%m-%d-%Y_%H%M_%2N.log", @@ -163,6 +162,9 @@ bool load_config(string config_file) { keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0), keywords::auto_flush = true); } + BOOST_LOG_TRIVIAL(info) << "Log to File: " << config.log_file; + BOOST_LOG_TRIVIAL(info) << "Log Directory: " << config.log_dir; + BOOST_LOG_TRIVIAL(info) << "\n-------------------------------------\n Trunk Recorder\n-------------------------------------\n"; BOOST_LOG_TRIVIAL(info) << "\n\n-------------------------------------\nINSTANCE\n-------------------------------------\n"; @@ -1756,15 +1758,6 @@ int main(int argc, char **argv) { start_plugins(sources, systems); - if (config.log_file) { - logging::add_file_log( - keywords::file_name = config.log_dir + "/%m-%d-%Y_%H%M_%2N.log", - keywords::format = "[%TimeStamp%] (%Severity%) %Message%", - keywords::rotation_size = 100 * 1024 * 1024, - keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0), - keywords::auto_flush = true); - } - if (setup_systems()) { signal(SIGINT, exit_interupt); tb->unlock(); diff --git a/trunk-recorder/systems/p25_parser.cc b/trunk-recorder/systems/p25_parser.cc index f11ea739c..af94f8604 100644 --- a/trunk-recorder/systems/p25_parser.cc +++ b/trunk-recorder/systems/p25_parser.cc @@ -310,7 +310,7 @@ std::vector P25Parser::decode_tsbk(boost::dynamic_bitset<> &tsbk, message.tdma_slot = 0; } - os << "tbsk02\tMoto Patch Grant\tChannel ID: " << std::setw(5) << ch << "\tFreq: " << format_freq(f) << "\tsg " << std::setw(7) << sg << "\tTDMA " << get_tdma_slot(ch, sys_num) << "\tsa " << sa; + os << "tsbk02\tMoto Patch Grant\tChannel ID: " << std::setw(5) << ch << "\tFreq: " << format_freq(f) << "\tsg " << std::setw(7) << sg << "\tTDMA " << get_tdma_slot(ch, sys_num) << "\tsa " << sa; message.meta = os.str(); BOOST_LOG_TRIVIAL(debug) << os.str(); } else { From 3559a08d122c28412292f83004c688862e8e44db Mon Sep 17 00:00:00 2001 From: Jason McHuff Date: Sat, 20 May 2023 22:55:24 -0700 Subject: [PATCH 3/4] for those who include my plugin as an internal one --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 13c8249f5..999fecdd6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,7 @@ audio/ junk/ tester/ fake/ -2015/ -2016/ +2[0-9][0-9][0-9]/ wmata/ CMakeFiles/ build/ @@ -32,3 +31,4 @@ top_block.py debug_recorder.py /cmake_build/ /.cache/ +plugins/decode_rates From 6e05d2350d83d86b6b09b734b98adbc8b985e809 Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Sat, 27 May 2023 08:05:04 -0400 Subject: [PATCH 4/4] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 999fecdd6..162722cca 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,3 @@ top_block.py debug_recorder.py /cmake_build/ /.cache/ -plugins/decode_rates