aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2016-11-08 16:56:14 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2018-11-27 17:54:20 +0100
commit3b835505bf8cae95fc226419ced59c237cf39ccb (patch)
tree2e3689be216c5d6d4ebcb3950dd78d5d72bcfd48
parent8a1dfa0b7715312c3307527e87c2c58d69f3685f (diff)
Sync DTX FSM with OsmoBTS code
-rw-r--r--doc/manuals/dtx.dot86
-rw-r--r--doc/manuals/rtp-amr.adoc19
2 files changed, 70 insertions, 35 deletions
diff --git a/doc/manuals/dtx.dot b/doc/manuals/dtx.dot
index 1c60ee72..b9f0b5f2 100644
--- a/doc/manuals/dtx.dot
+++ b/doc/manuals/dtx.dot
@@ -1,43 +1,68 @@
digraph dtx_dl_amr_fsm {
- node [shape = doublecircle] ST_VOICE ST_FACCH_V ST_FACCH ST_SID_U
+ node [shape = doublecircle] ST_VOICE ST_FACCH ST_U_NOINH
node [shape = circle]
// default state for non-DTX and DTX when SPEECH is in progress
ST_VOICE -> ST_SID_F1 [ label = "E_SID_F" ]
- ST_VOICE -> ST_SID_F1 [ label = "E_SID_U" ]
+ ST_VOICE -> ST_F1_INH_V [ label = "E_INHIB" ]
+ ST_VOICE -> ST_U_NOINH [ label = "E_SID_U" ]
ST_VOICE -> ST_VOICE [ label = "E_VOICE" ]
ST_VOICE -> ST_VOICE [ label = "E_FACCH" ]
// SID-FIRST or SID-FIRST-P1 in case of AMR HR: start of silence period (might be interrupted in case of AMR HR)
ST_SID_F1 -> ST_SID_F1 [ label = "E_SID_F" ]
- ST_SID_F1 -> ST_SID_U [ label = "E_SID_U" ]
- ST_SID_F1 -> ST_VOICE [ label = "E_VOICE" ]
- ST_SID_F1 -> ST_ONSET_F [ label = "E_FACCH" ]
- ST_SID_F1 -> ST_SID_F2 [ label = "E_COMPL" ]
- ST_SID_F1 -> ST_F1_INH [ label = "E_INHIB" ]
+ ST_SID_F1 -> ST_U_NOINH [ label = "E_SID_U" ]
+ ST_SID_F1 -> ST_F1_INH_F [ label = "E_FACCH" ]
+ ST_SID_F1 -> ST_SID_F2 [ label = "E_FIRST" ]
ST_SID_F1 -> ST_ONSET_V [ label = "E_ONSET" ]
// SID-FIRST P2 (only for AMR HR): actual start of silence period in case of AMR HR
- ST_SID_F2 -> ST_SID_U [ label = "E_SID_U" ]
- ST_SID_F2 -> ST_VOICE [ label = "E_VOICE" ]
+ ST_SID_F2 -> ST_U_NOINH [ label = "E_COMPL" ]
ST_SID_F2 -> ST_ONSET_F [ label = "E_FACCH" ]
ST_SID_F2 -> ST_ONSET_V [ label = "E_ONSET" ]
- // SID-FIRST Inhibited: incoming SPEECH or FACCH (only for AMR HR)
- ST_F1_INH -> ST_VOICE [ label = "E_VOICE" ]
- ST_F1_INH -> ST_FACCH_V [ label = "E_FACCH" ]
+ // SID-FIRST Inhibited: incoming SPEECH (only for AMR HR)
+ ST_F1_INH_V -> ST_F1_INH_V_REC [ label = "E_COMPL" ]
- // SID-UPDATE Inhibited: incoming SPEECH or FACCH (only for AMR HR)
- ST_U_INH -> ST_VOICE [ label = "E_VOICE" ]
- ST_U_INH -> ST_FACCH [ label = "E_FACCH" ]
+ // SID-FIRST Inhibited: incoming FACCH frame (only for AMR HR)
+ ST_F1_INH_F -> ST_F1_INH_F_REC [ label = "E_COMPL" ]
- // Silence period with periodic comfort noise data updates
- ST_SID_U -> ST_ONSET_F [ label = "E_FACCH" ]
+ // SID-UPDATE Inhibited: incoming SPEECH (only for AMR HR)
+ ST_U_INH_V -> ST_U_INH_V_REC [ label = "E_COMPL" ]
+
+ // SID-UPDATE Inhibited: incoming FACCH frame (only for AMR HR)
+ ST_U_INH_F -> ST_U_INH_F_REC [ label = "E_COMPL" ]
+
+ // Silence period with periodic comfort noise data updates (no Inhibition)
+ ST_U_NOINH -> ST_ONSET_F [ label = "E_FACCH" ]
+ ST_U_NOINH -> ST_VOICE [ label = "E_VOICE" ]
+ ST_U_NOINH -> ST_U_NOINH [ label = "E_SID_U" ]
+ ST_U_NOINH -> ST_U_NOINH [ label = "E_SID_F" ]
+ ST_U_NOINH -> ST_ONSET_V [ label = "E_ONSET" ]
+ ST_U_NOINH -> ST_SID_U [ label = "E_COMPL" ]
+
+ // SID-FIRST Inhibition recursion in progress: Inhibit itself was already sent, now have to send the voice that caused it
+ ST_F1_INH_V_REC -> ST_VOICE [ label = "E_COMPL" ]
+ ST_F1_INH_V_REC -> ST_VOICE [ label = "E_VOICE" ]
+
+ // SID-FIRST Inhibition recursion in progress: Inhibit itself was already sent, now have to send the voice that caused it
+ ST_F1_INH_F_REC -> ST_FACCH [ label = "E_COMPL" ]
+ ST_F1_INH_F_REC -> ST_FACCH [ label = "E_VOICE" ]
+
+ // SID-UPDATE Inhibition recursion in progress: Inhibit itself was already sent, now have to send the voice that caused it
+ ST_U_INH_V_REC -> ST_VOICE [ label = "E_COMPL" ]
+ ST_U_INH_V_REC -> ST_VOICE [ label = "E_VOICE" ]
+
+ // SID-UPDATE Inhibition recursion in progress: Inhibit itself was already sent, now have to send the voice that caused it
+ ST_U_INH_F_REC -> ST_FACCH [ label = "E_COMPL" ]
+ ST_U_INH_F_REC -> ST_FACCH [ label = "E_VOICE" ]
+
+ // Silence period with periodic comfort noise data updates (can be inhibited)
+ ST_SID_U -> ST_U_INH_F [ label = "E_FACCH" ]
ST_SID_U -> ST_VOICE [ label = "E_VOICE" ]
- ST_SID_U -> ST_U_INH [ label = "E_INHIB" ]
- ST_SID_U -> ST_SID_U [ label = "E_SID_U" ]
- ST_SID_U -> ST_SID_U [ label = "E_SID_F" ]
- ST_SID_U -> ST_ONSET_V [ label = "E_ONSET" ]
+ ST_SID_U -> ST_U_INH_V [ label = "E_INHIB" ]
+ ST_SID_U -> ST_U_NOINH [ label = "E_SID_U" ]
+ ST_SID_U -> ST_U_NOINH [ label = "E_SID_F" ]
// ONSET - end of silent period due to incoming SPEECH frame
ST_ONSET_V -> ST_ONSET_V_REC [ label = "E_COMPL" ]
@@ -45,21 +70,16 @@ digraph dtx_dl_amr_fsm {
// ONSET - end of silent period due to incoming FACCH frame
ST_ONSET_F -> ST_ONSET_F_REC [ label = "E_COMPL" ]
- // ONSET recursion in progress: ONSET itself was already sent, now have to send the voice that caused it
- ST_ONSET_V_REC -> ST_VOICE [ label = "E_COMPL" ]
-
// ONSET recursion in progress: ONSET itself was already sent, now have to send the data that caused it
ST_ONSET_F_REC -> ST_FACCH [ label = "E_COMPL" ]
- // FACCH sending state: SPEECH was observed before so once we're done FSM should get back to VOICE state
- ST_FACCH_V -> ST_FACCH_V [ label = "E_FACCH" ]
- ST_FACCH_V -> ST_VOICE [ label = "E_VOICE" ]
- ST_FACCH_V -> ST_VOICE [ label = "E_SID_U" ]
- ST_FACCH_V -> ST_SID_F1 [ label = "E_SID_F" ]
+ // ONSET recursion in progress: ONSET itself was already sent, now have to send the voice that caused it
+ ST_ONSET_V_REC -> ST_VOICE [ label = "E_COMPL" ]
- // FACCH sending state: no SPEECH was observed before so once we're done FSM should get back to silent period via SID-FIRST
- ST_FACCH -> ST_FACCH [ label = "E_FACCH" ]
+ // FACCH sending state
ST_FACCH -> ST_VOICE [ label = "E_VOICE" ]
- ST_FACCH -> ST_SID_F1 [ label = "E_SID_U" ]
- ST_FACCH -> ST_SID_F1 [ label = "E_SID_F" ]
+ ST_FACCH -> ST_FACCH [ label = "E_FACCH" ]
+ ST_FACCH -> ST_FACCH [ label = "E_SID_U" ]
+ ST_FACCH -> ST_FACCH [ label = "E_SID_F" ]
+ ST_FACCH -> ST_SID_F1 [ label = "E_COMPL" ]
}
diff --git a/doc/manuals/rtp-amr.adoc b/doc/manuals/rtp-amr.adoc
index f7eda112..982a5af3 100644
--- a/doc/manuals/rtp-amr.adoc
+++ b/doc/manuals/rtp-amr.adoc
@@ -1322,10 +1322,25 @@ There is FSM implementing all the necessary states and transitions for DTX DL.
include::dtx.dot[]
----
-The idea is that each state corresponds to the particular message type which have to be send to L1 while state transition happens on incoming events like FACCH or Voice frames. There are 3 different classes of of events driving this FSM:
+The idea is that each state corresponds to the particular message type which have to be send to L1 next while state transition happens on incoming events like FACCH or Voice frames. There are 3 different classes of of events driving this FSM:
* Voice frame types: E_VOICE, E_SID_U, E_SID_F
* Incoming FACCH: E_FACCH
* Internal: E_ONSET, E_INHIB, E_COMPL
-They represent different types of incoming RTP frames (Voice, SID UPDATE and SID FIRST correspondingly), incoming FACCH events or important events internal to DTX operations. The latter are Onset (interruption of silence period), Inhibition (of currently transmitted SID FIRST or UPDATE) and Completion (of silence initiation). \ No newline at end of file
+They represent different types of incoming RTP frames (Voice, SID UPDATE and SID FIRST correspondingly), incoming FACCH events or important events internal to DTX operations. The latter are Onset (interruption of silence period), Inhibition (of currently transmitted SID FIRST or UPDATE) and Completion (of silence initiation).
+
+The double-circled states are "stationary" meaning that FSM can stay for longer periods in them. Other states are "transient" - the FSM have to switch away during next step. In practice this is implemented using E_COMPL signal which is issued in corresponding RTS handler or internal function (in case of SID First P1 -> P2 transition).
+
+The FSM states are grouped as follows:
+
+* ST_VOICE: talkspurt, normal voice transmission
+* ST_FACCH: transmission of higher-priority FACCH frame, interrupting current DTX state
+* ST_ONSET*: handling of Onset event (interruption of silence period)
+* ST_SID_F*: silence initiation
+* ST_*_REC: sending of 2nd event for L1 during the same FN
+* ST_*_INH: handling of Inhibition event (interruption of transmission of previous event)
+
+The latter are specific to AMR HR where transmission of particular message by L1 takes longer so it can be aborted due to another incoming event. Note that for AMR FR only subset of this FSM is active (ST_SID_F2 and *INH states are never reached). This is implemented by signal emitting functions.
+
+Note that the FSM states describe only the situation when we got to send something to L1, the transmission of Empty frames suppressing the actual radio transmission is done by other code.