Skip to content

Commit

Permalink
Merge pull request #664 from robotastic/no-overlap
Browse files Browse the repository at this point in the history
a new approach for tracking call timeouts
  • Loading branch information
robotastic authored Apr 8, 2022
2 parents 71564fa + dce3666 commit 80b32dc
Show file tree
Hide file tree
Showing 33 changed files with 538 additions and 371 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ list(APPEND trunk_recorder_sources

lib/lfsr/lfsr.cxx
lib/gr_blocks/freq_xlating_fft_filter.cc
lib/gr_blocks/nonstop_wavfile_sink_impl.cc
lib/gr_blocks/transmission_sink.cc
lib/gr_blocks/decoders/fsync_decode.cc
lib/gr_blocks/decoders/mdc_decode.cc
lib/gr_blocks/decoders/star_decode.cc
Expand Down
73 changes: 73 additions & 0 deletions docs/notes/CALL-HANDLING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
```mermaid
flowchart TD
A[Control Channel] -->|GRANT| B["handle_call_grant()"]
B --> C{Existing Call on Freq?}
C -.->|Yes| D{Same Talkgroup?}
C -.->|No| G["new Call()"]
D -.->|Yes| E["call->set_record_more_transmissions(True)"]
D -.->|No| F[Delete Existing Call]
F -.-> G
G -.-> H["start_recording()"]
```

```mermaid
flowchart TD
A1[Voice Channel] --> B1[Transmission Sink]
B1 -.->|Samples| C1{State}
C1 -.->|STOPPED| D1[Drop Samples]
C1 -.->|IDLE| F1["Setup files\nrecord_more_transmissions = false;\nd_first_work = false;\nstate = RECORDING"]
C1 -.->|RECORDING| G1[Write Samples]
F1 -.-> G1
B1 -.->|TERMINATOR| H1["End Transmission"]
H1 -.-> I1{"record_more_transmissions"}
I1 -.->|False| J1["state = STOPPED"]
I1 -.->|True| K1["state = IDLE"]
L1["set_record_more_transmissions(True)"] -.-> N1{state == STOPPED}
N1 -.->|True| O1["state == IDLE"]
N1 -.->|False| P1["record_mode_transmissions = True"]
O1 -.-> P1
```




```mermaid
flowchart TD
A[Control Channel] -->|UPDATE| B["handle_call_update()"]
B -.-> C[Find Call]
C -.-> D{"call->state"}
D -.->|COMPLETED| E[Do Nothing]
D -.->|INACTIVE| F["call->state==RECORDING"]
F -.-> G["call->update()"]
D -.->|RECORDING| G
G -.-> H["call->set_record_more_transmissions(True)"]
```


```mermaid
flowchart TD
A[For Each Call] -->|Call| B{state}
B -.->|RECORDING| C{"last_update > 1.0"}
C -.->|True| E["call->set_record_more_transmissions(false)\nstate = INACTIVE"]
C -.->|False| D[Next]
E -.-> D
B -.->|MONITORING| F{"last_update > 1.0"}
F -.->|True| G["Delete Call"]
G -.-> D
F -.->|False| D
B -.->|COMPLETED| H["Conclude Call"]
H -.-> Z["Delete Call"]
Z -.-> D
B -.->|INACTIVE| I{"since last_update > 5.0"}
I -.->|True| J[state = COMPLETED]
J -.-> K[Conclude Call]
K -.-> L[Delete Call]
I -.->|False| D
L -.-> D
```
4 changes: 2 additions & 2 deletions docs/notes/STATES.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ If there is an existing Call that covers all of this, then it will simply be upd
If not, a new Call is created and an attempt to start a recording is made by calling **start_recorder()**. **start_recorder()** first checks to see if a talkgroup entry is defined in the *talkgroup.csv* file for the talkgroup number in the message. If the **recordUnknown** flag is set to false in the *config.json* and a talkgroup entry is not found, then a recording will not be started.
Encrypted transmissions are not recorded. If a talkgroup entry does exist and the talkgroup is marked as encrypted, it will be skipped. The same is true if the message's encrypted flag is set.

After these checks, **start_recorder()** will now try to assign a recorder. It does this by going through the Sources and finding the first one that covers the frequency in the message. The function will then try to get either an analog or digital recorder from the Source by calling **get_analog_recorder()** or **get_digital_recorder()**, respectively. The **get_analog_recorder()** and **get_digital_recorder()** functions in *source.cc* simply go through the vector of Recorders that were created for that Source and checking their state. The first recorder with the state of **available** is returned. For both types of recorders, their state actually comes from nonstop_wavefile_sink block that is at the end of the recorders gnuradio graph. We will dive into that lifecycle later. The nonstop_wavefile_sink block that part of the recorder, will receive some information about the call and will set its state to **idle**
After these checks, **start_recorder()** will now try to assign a recorder. It does this by going through the Sources and finding the first one that covers the frequency in the message. The function will then try to get either an analog or digital recorder from the Source by calling **get_analog_recorder()** or **get_digital_recorder()**, respectively. The **get_analog_recorder()** and **get_digital_recorder()** functions in *source.cc* simply go through the vector of Recorders that were created for that Source and checking their state. The first recorder with the state of **available** is returned. For both types of recorders, their state actually comes from transmission_sink block that is at the end of the recorders gnuradio graph. We will dive into that lifecycle later. The transmission_sink block that part of the recorder, will receive some information about the call and will set its state to **idle**

Back in *main.cc*, if a recorder was return, it is associated with the call and the call's state is set to **recording**. If it wasn't possible to get a recorder, the call's state is set to **monitoring**. This serves to track that the Talkgroup will be on that frequency and that Trunk Recorder does not have to try and assign a recorder everytime it gets an **UPDATE** trunking message.

When a **GRANT** or **UPDATE** message comes in and goes through **handle_call()**, the function will see that a call has already been assigned and will call that call's **update()** function. This function simply sets the call's *last_update* variable to the current time.

As voice samples make their way through the recorder, they eventually end up in the **nonstop_wav_file_sink_impl.cc** block. When a wav_sink and its recorder are first associated with a call, its state is initially set to **idle**. When in **idle** and a voice sample comes in, the wav_sink will change its state to **recording**, open a new file and being writing samples to it. The wav_sink starts a *Transmission* which tracks each of the indivdiual transmissions that make up a call on a digital system. The variable *d_stop_time* is also updated with the current time. This is used in analog systems to determine is there has been a break in writing to the file, signaling a new file should be started.
As voice samples make their way through the recorder, they eventually end up in the **transmission_sink.cc** block. When a wav_sink and its recorder are first associated with a call, its state is initially set to **idle**. When in **idle** and a voice sample comes in, the wav_sink will change its state to **recording**, open a new file and being writing samples to it. The wav_sink starts a *Transmission* which tracks each of the indivdiual transmissions that make up a call on a digital system. The variable *d_stop_time* is also updated with the current time. This is used in analog systems to determine is there has been a break in writing to the file, signaling a new file should be started.

In digital system, a Terminator Data Unit (TDU) is sent on the voice channel at the start and end of the call. The digital recorder processes this and passes it along to the wav_sink. When the wav_sink is in the state **recording**, signifying it has written samples to a file, and it receieves a TDU it will end the current transmission. The wav_sink has an internal flag called *record_more_transmissions*. If this flag is set to *false* the wav_sink's state will be set to **stopped**, otherwise it will be set to **idle**. When a wav_sink is in state **stopped**, any voice samples that come in will be dropped and not written to a file, and new Transmission will not be created. However, when the state is **idle**, it will operate like it was just created.

Expand Down
98 changes: 0 additions & 98 deletions lib/gr_blocks/nonstop_wavfile_sink.h

This file was deleted.

Loading

0 comments on commit 80b32dc

Please sign in to comment.