Fix AMR HR DTX FSM logic.
Fix SID_FIRST_INH detection during speech and when SID_FIRST is interrupted by FACCH. Fix SID_UPDATE_INH detection during silence and when SID_UPDATE is interrupted by FACCH. Add a delay for SID_FIRST to appear at the right time after FACCH. Fix extra byte sent in downlink for SID_FIRST and SID_UPDATE. Change-Id: Ia811305e15541f2376005df736bd610e8b0d2f69
This commit is contained in:
parent
16b4179fbe
commit
a760a043c4
|
@ -12,11 +12,15 @@ enum dtx_dl_amr_fsm_states {
|
|||
ST_VOICE,
|
||||
ST_SID_F1,
|
||||
ST_SID_F2,
|
||||
ST_F1_INH,
|
||||
ST_U_INH,
|
||||
ST_F1_INH_V,
|
||||
ST_F1_INH_F,
|
||||
ST_U_INH_V,
|
||||
ST_U_INH_F,
|
||||
ST_U_NOINH,
|
||||
ST_F1_INH_REC,
|
||||
ST_U_INH_REC,
|
||||
ST_F1_INH_V_REC,
|
||||
ST_F1_INH_F_REC,
|
||||
ST_U_INH_V_REC,
|
||||
ST_U_INH_F_REC,
|
||||
ST_SID_U,
|
||||
ST_ONSET_V,
|
||||
ST_ONSET_F,
|
||||
|
|
|
@ -13,6 +13,7 @@ enum {
|
|||
};
|
||||
|
||||
#define LCHAN_FN_DUMMY 0xFFFFFFFF
|
||||
#define LCHAN_FN_WAIT 0xFFFFFFFE
|
||||
|
||||
int msgb_queue_flush(struct llist_head *list);
|
||||
|
||||
|
|
|
@ -29,9 +29,14 @@ void dtx_fsm_voice(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
case E_FACCH:
|
||||
break;
|
||||
case E_SID_F:
|
||||
case E_SID_U:
|
||||
osmo_fsm_inst_state_chg(fi, ST_SID_F1, 0, 0);
|
||||
break;
|
||||
case E_SID_U:
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
|
||||
break;
|
||||
case E_INHIB:
|
||||
osmo_fsm_inst_state_chg(fi, ST_F1_INH_V, 0, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DL1P, LOGL_ERROR, "Inexpected event %d\n", event);
|
||||
OSMO_ASSERT(0);
|
||||
|
@ -49,18 +54,12 @@ void dtx_fsm_sid_f1(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
case E_SID_U:
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
|
||||
break;
|
||||
case E_VOICE:
|
||||
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
|
||||
break;
|
||||
case E_FACCH:
|
||||
osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0);
|
||||
osmo_fsm_inst_state_chg(fi, ST_F1_INH_F, 0, 0);
|
||||
break;
|
||||
case E_FIRST:
|
||||
osmo_fsm_inst_state_chg(fi, ST_SID_F2, 0, 0);
|
||||
break;
|
||||
case E_INHIB:
|
||||
osmo_fsm_inst_state_chg(fi, ST_F1_INH, 0, 0);
|
||||
break;
|
||||
case E_ONSET:
|
||||
osmo_fsm_inst_state_chg(fi, ST_ONSET_V, 0, 0);
|
||||
break;
|
||||
|
@ -75,10 +74,7 @@ void dtx_fsm_sid_f2(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
{
|
||||
switch (event) {
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_SID_U, 0, 0);
|
||||
break;
|
||||
case E_VOICE:
|
||||
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
|
||||
break;
|
||||
case E_FACCH:
|
||||
osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0);
|
||||
|
@ -93,11 +89,11 @@ void dtx_fsm_sid_f2(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_f1_inh(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
void dtx_fsm_f1_inh_v(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_F1_INH_REC, 0, 0);
|
||||
osmo_fsm_inst_state_chg(fi, ST_F1_INH_V_REC, 0, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
|
||||
|
@ -106,11 +102,11 @@ void dtx_fsm_f1_inh(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_u_inh(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
void dtx_fsm_f1_inh_f(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_INH_REC, 0, 0);
|
||||
osmo_fsm_inst_state_chg(fi, ST_F1_INH_F_REC, 0, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
|
||||
|
@ -119,9 +115,36 @@ void dtx_fsm_u_inh(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_f1_inh_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
void dtx_fsm_u_inh_v(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_INH_V_REC, 0, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
|
||||
OSMO_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_u_inh_f(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_INH_F_REC, 0, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
|
||||
OSMO_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_f1_inh_v_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
case E_VOICE:
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
|
||||
break;
|
||||
|
@ -132,9 +155,24 @@ void dtx_fsm_f1_inh_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_u_inh_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
void dtx_fsm_f1_inh_f_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
case E_FACCH:
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
|
||||
OSMO_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_u_inh_v_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
case E_VOICE:
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
|
||||
break;
|
||||
|
@ -145,6 +183,20 @@ void dtx_fsm_u_inh_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_u_inh_f_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
case E_FACCH:
|
||||
case E_COMPL:
|
||||
osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0);
|
||||
break;
|
||||
default:
|
||||
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
|
||||
OSMO_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dtx_fsm_u_noinh(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
switch (event) {
|
||||
|
@ -176,13 +228,13 @@ void dtx_fsm_sid_upd(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
{
|
||||
switch (event) {
|
||||
case E_FACCH:
|
||||
osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0);
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_INH_F, 0, 0);
|
||||
break;
|
||||
case E_VOICE:
|
||||
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
|
||||
break;
|
||||
case E_INHIB:
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_INH, 0, 0);
|
||||
osmo_fsm_inst_state_chg(fi, ST_U_INH_V, 0, 0);
|
||||
break;
|
||||
case E_SID_U:
|
||||
case E_SID_F:
|
||||
|
@ -270,40 +322,54 @@ void dtx_fsm_facch(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||
static struct osmo_fsm_state dtx_dl_amr_fsm_states[] = {
|
||||
/* default state for non-DTX and DTX when SPEECH is in progress */
|
||||
[ST_VOICE] = {
|
||||
.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_VOICE) | X(E_FACCH),
|
||||
.out_state_mask = X(ST_SID_F1),
|
||||
.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_VOICE) | X(E_FACCH) | X(E_INHIB),
|
||||
.out_state_mask = X(ST_SID_F1) | X(ST_U_NOINH) | X(ST_F1_INH_V),
|
||||
.name = "Voice",
|
||||
.action = dtx_fsm_voice,
|
||||
},
|
||||
/* 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]= {
|
||||
.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_VOICE) | X(E_FACCH) | X(E_FIRST) | X(E_INHIB) | X(E_ONSET),
|
||||
.out_state_mask = X(ST_U_NOINH) | X(ST_VOICE) | X(ST_ONSET_F) | X(ST_SID_F2) | X(ST_F1_INH) | X(ST_ONSET_V),
|
||||
.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_FACCH) | X(E_FIRST) | X(E_ONSET),
|
||||
.out_state_mask = X(ST_U_NOINH) | X(ST_ONSET_F) | X(ST_SID_F2) | X(ST_ONSET_V),
|
||||
.name = "SID-FIRST (P1)",
|
||||
.action = dtx_fsm_sid_f1,
|
||||
},
|
||||
/* SID-FIRST P2 (only for AMR HR):
|
||||
actual start of silence period in case of AMR HR */
|
||||
[ST_SID_F2]= {
|
||||
.in_event_mask = X(E_COMPL) | X(E_VOICE) | X(E_FACCH) | X(E_ONSET),
|
||||
.out_state_mask = X(ST_SID_U) | X(ST_VOICE) | X(ST_ONSET_F) | X(ST_ONSET_V),
|
||||
.in_event_mask = X(E_COMPL) | X(E_FACCH) | X(E_ONSET),
|
||||
.out_state_mask = X(ST_U_NOINH) | X(ST_ONSET_F) | X(ST_ONSET_V),
|
||||
.name = "SID-FIRST (P2)",
|
||||
.action = dtx_fsm_sid_f2,
|
||||
},
|
||||
/* SID-FIRST Inhibited: incoming SPEECH (only for AMR HR) */
|
||||
[ST_F1_INH]= {
|
||||
[ST_F1_INH_V]= {
|
||||
.in_event_mask = X(E_COMPL),
|
||||
.out_state_mask = X(ST_F1_INH_REC),
|
||||
.name = "SID-FIRST (Inh)",
|
||||
.action = dtx_fsm_f1_inh,
|
||||
.out_state_mask = X(ST_F1_INH_V_REC),
|
||||
.name = "SID-FIRST (Inh, SPEECH)",
|
||||
.action = dtx_fsm_f1_inh_v,
|
||||
},
|
||||
/* SID-FIRST Inhibited: incoming FACCH frame (only for AMR HR) */
|
||||
[ST_F1_INH_F]= {
|
||||
.in_event_mask = X(E_COMPL),
|
||||
.out_state_mask = X(ST_F1_INH_F_REC),
|
||||
.name = "SID-FIRST (Inh, FACCH)",
|
||||
.action = dtx_fsm_f1_inh_f,
|
||||
},
|
||||
/* SID-UPDATE Inhibited: incoming SPEECH (only for AMR HR) */
|
||||
[ST_U_INH]= {
|
||||
[ST_U_INH_V]= {
|
||||
.in_event_mask = X(E_COMPL),
|
||||
.out_state_mask = X(ST_U_INH_REC),
|
||||
.name = "SID-UPDATE (Inh)",
|
||||
.action = dtx_fsm_u_inh,
|
||||
.out_state_mask = X(ST_U_INH_V_REC),
|
||||
.name = "SID-UPDATE (Inh, SPEECH)",
|
||||
.action = dtx_fsm_u_inh_v,
|
||||
},
|
||||
/* SID-UPDATE Inhibited: incoming FACCH frame (only for AMR HR) */
|
||||
[ST_U_INH_F]= {
|
||||
.in_event_mask = X(E_COMPL),
|
||||
.out_state_mask = X(ST_U_INH_F_REC),
|
||||
.name = "SID-UPDATE (Inh, FACCH)",
|
||||
.action = dtx_fsm_u_inh_f,
|
||||
},
|
||||
/* SID-UPDATE: Inhibited not allowed (only for AMR HR) */
|
||||
[ST_U_NOINH]= {
|
||||
|
@ -314,24 +380,40 @@ static struct osmo_fsm_state dtx_dl_amr_fsm_states[] = {
|
|||
},
|
||||
/* SID-FIRST Inhibition recursion in progress:
|
||||
Inhibit itself was already sent, now have to send the voice that caused it */
|
||||
[ST_F1_INH_REC]= {
|
||||
.in_event_mask = X(E_COMPL),
|
||||
[ST_F1_INH_V_REC]= {
|
||||
.in_event_mask = X(E_COMPL) | X(E_VOICE),
|
||||
.out_state_mask = X(ST_VOICE),
|
||||
.name = "SID-FIRST (Inh, Rec)",
|
||||
.action = dtx_fsm_f1_inh_rec,
|
||||
.name = "SID-FIRST (Inh, SPEECH, Rec)",
|
||||
.action = dtx_fsm_f1_inh_v_rec,
|
||||
},
|
||||
/* SID-FIRST Inhibition recursion in progress:
|
||||
Inhibit itself was already sent, now have to send the data that caused it */
|
||||
[ST_F1_INH_F_REC]= {
|
||||
.in_event_mask = X(E_COMPL) | X(E_FACCH),
|
||||
.out_state_mask = X(ST_FACCH),
|
||||
.name = "SID-FIRST (Inh, FACCH, Rec)",
|
||||
.action = dtx_fsm_f1_inh_f_rec,
|
||||
},
|
||||
/* SID-UPDATE Inhibition recursion in progress:
|
||||
Inhibit itself was already sent, now have to send the voice that caused it */
|
||||
[ST_U_INH_REC]= {
|
||||
.in_event_mask = X(E_COMPL),
|
||||
[ST_U_INH_V_REC]= {
|
||||
.in_event_mask = X(E_COMPL) | X(E_VOICE),
|
||||
.out_state_mask = X(ST_VOICE),
|
||||
.name = "SID-UPDATE (Inh, Rec)",
|
||||
.action = dtx_fsm_u_inh_rec,
|
||||
.name = "SID-UPDATE (Inh, SPEECH, Rec)",
|
||||
.action = dtx_fsm_u_inh_v_rec,
|
||||
},
|
||||
/* SID-UPDATE Inhibition recursion in progress:
|
||||
Inhibit itself was already sent, now have to send the data that caused it */
|
||||
[ST_U_INH_F_REC]= {
|
||||
.in_event_mask = X(E_COMPL) | X(E_FACCH),
|
||||
.out_state_mask = X(ST_FACCH),
|
||||
.name = "SID-UPDATE (Inh, FACCH, Rec)",
|
||||
.action = dtx_fsm_u_inh_f_rec,
|
||||
},
|
||||
/* Silence period with periodic comfort noise data updates */
|
||||
[ST_SID_U]= {
|
||||
.in_event_mask = X(E_FACCH) | X(E_VOICE) | X(E_INHIB) | X(E_SID_U) | X(E_SID_F),
|
||||
.out_state_mask = X(ST_ONSET_F) | X(ST_VOICE) | X(ST_U_INH) | X(ST_U_NOINH),
|
||||
.out_state_mask = X(ST_ONSET_F) | X(ST_VOICE) | X(ST_U_INH_V) | X(ST_U_INH_F) | X(ST_U_NOINH),
|
||||
.name = "SID-UPDATE (AMR/HR)",
|
||||
.action = dtx_fsm_sid_upd,
|
||||
},
|
||||
|
@ -365,8 +447,7 @@ static struct osmo_fsm_state dtx_dl_amr_fsm_states[] = {
|
|||
.name = "ONSET (FACCH, Rec)",
|
||||
.action = dtx_fsm_onset_f_rec,
|
||||
},
|
||||
/* FACCH sending state: no SPEECH was observed before so once we're done
|
||||
FSM should get back to silent period via SID-FIRST */
|
||||
/* FACCH sending state */
|
||||
[ST_FACCH]= {
|
||||
.in_event_mask = X(E_FACCH) | X(E_VOICE) | X(E_COMPL) | X(E_SID_U) | X(E_SID_F),
|
||||
.out_state_mask = X(ST_VOICE) | X(ST_SID_F1),
|
||||
|
|
|
@ -137,7 +137,7 @@ void dtx_cache_payload(struct gsm_lchan *lchan, const uint8_t *l1_payload,
|
|||
size_t length, uint32_t fn, int update)
|
||||
{
|
||||
size_t amr = (update < 0) ? 0 : 2,
|
||||
copy_len = OSMO_MIN(length + 1,
|
||||
copy_len = OSMO_MIN(length,
|
||||
ARRAY_SIZE(lchan->tch.dtx.cache) - amr);
|
||||
|
||||
lchan->tch.dtx.len = copy_len + amr;
|
||||
|
@ -230,7 +230,7 @@ int dtx_dl_amr_fsm_step(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
|
|||
|
||||
if (osmo_amr_is_speech(ft)) {
|
||||
/* AMR HR - SID-FIRST_P1 Inhibition */
|
||||
if (marker && dtx_is_first_p1(lchan))
|
||||
if (marker && lchan->tch.dtx.dl_amr_fsm->state == ST_VOICE)
|
||||
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
|
||||
E_INHIB, (void *)lchan);
|
||||
|
||||
|
@ -261,7 +261,8 @@ int dtx_dl_amr_fsm_step(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
|
|||
as FIRST regardless of actually decoded type */
|
||||
dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, false);
|
||||
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
|
||||
E_SID_F, (void *)lchan);
|
||||
sti ? E_SID_U : E_SID_F,
|
||||
(void *)lchan);
|
||||
} else if (lchan->tch.dtx.dl_amr_fsm->state != ST_FACCH)
|
||||
dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, sti);
|
||||
if (lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F2)
|
||||
|
@ -319,12 +320,24 @@ static inline bool dtx_amr_sid_optional(struct gsm_lchan *lchan, uint32_t fn)
|
|||
already: we rely here on the order of RTS arrival from L1 - we
|
||||
expect that PH-DATA.req ALWAYS comes before PH-TCH.req for the
|
||||
same FN */
|
||||
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY) {
|
||||
/* FACCH interruption is over */
|
||||
dtx_dispatch(lchan, E_COMPL);
|
||||
return false;
|
||||
} else
|
||||
lchan->tch.dtx.fn = fn;
|
||||
if(lchan->type == GSM_LCHAN_TCH_H) {
|
||||
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY &&
|
||||
lchan->tch.dtx.fn != LCHAN_FN_WAIT) {
|
||||
/* FACCH interruption is over */
|
||||
dtx_dispatch(lchan, E_COMPL);
|
||||
return false;
|
||||
} else if(lchan->tch.dtx.fn == LCHAN_FN_DUMMY) {
|
||||
lchan->tch.dtx.fn = LCHAN_FN_WAIT;
|
||||
} else
|
||||
lchan->tch.dtx.fn = fn;
|
||||
} else if(lchan->type == GSM_LCHAN_TCH_F) {
|
||||
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY) {
|
||||
/* FACCH interruption is over */
|
||||
dtx_dispatch(lchan, E_COMPL);
|
||||
return false;
|
||||
} else
|
||||
lchan->tch.dtx.fn = fn;
|
||||
}
|
||||
/* this FN was already used for FACCH or ONSET message so we just
|
||||
prepare things for next one */
|
||||
return true;
|
||||
|
@ -401,9 +414,14 @@ bool dtx_recursion(const struct gsm_lchan *lchan)
|
|||
if (!dtx_dl_amr_enabled(lchan))
|
||||
return false;
|
||||
|
||||
if (lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_REC ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH ||
|
||||
if (lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_V ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_V_REC ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F_REC ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_V ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_V_REC ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F_REC ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_V ||
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F_REC ||
|
||||
|
|
|
@ -410,7 +410,9 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||
memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
||||
lchan->tch.dtx.facch, msgb_l2len(msg));
|
||||
else if (dtx_dl_amr_enabled(lchan) &&
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) {
|
||||
((lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) ||
|
||||
(lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F) ||
|
||||
(lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F))) {
|
||||
if (sapi == GsmL1_Sapi_FacchF) {
|
||||
sapi = GsmL1_Sapi_TchF;
|
||||
}
|
||||
|
@ -424,9 +426,16 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||
/* cache FACCH data */
|
||||
memcpy(lchan->tch.dtx.facch, msg->l2h,
|
||||
msgb_l2len(msg));
|
||||
/* prepare ONSET message */
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
|
||||
GsmL1_TchPlType_Amr_Onset;
|
||||
/* prepare ONSET or INH message */
|
||||
if(lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F)
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
|
||||
GsmL1_TchPlType_Amr_Onset;
|
||||
else if(lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F)
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
|
||||
GsmL1_TchPlType_Amr_SidUpdateInH;
|
||||
else if(lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F)
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
|
||||
GsmL1_TchPlType_Amr_SidFirstInH;
|
||||
/* ignored CMR/CMI pair */
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[1] = 0;
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[2] = 0;
|
||||
|
|
|
@ -311,12 +311,12 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
|
|||
rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
|
||||
ft);
|
||||
return 0;
|
||||
case ST_F1_INH:
|
||||
case ST_F1_INH_V:
|
||||
*payload_type = GsmL1_TchPlType_Amr_SidFirstInH;
|
||||
*len = 3;
|
||||
dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
|
||||
return 1;
|
||||
case ST_U_INH:
|
||||
case ST_U_INH_V:
|
||||
*payload_type = GsmL1_TchPlType_Amr_SidUpdateInH;
|
||||
*len = 3;
|
||||
dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
|
||||
|
|
|
@ -405,7 +405,9 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||
memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
||||
lchan->tch.dtx.facch, msgb_l2len(msg));
|
||||
else if (dtx_dl_amr_enabled(lchan) &&
|
||||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) {
|
||||
((lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) ||
|
||||
(lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F) ||
|
||||
(lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F))) {
|
||||
if (sapi == GsmL1_Sapi_FacchF) {
|
||||
sapi = GsmL1_Sapi_TchF;
|
||||
}
|
||||
|
@ -419,9 +421,16 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||
/* cache FACCH data */
|
||||
memcpy(lchan->tch.dtx.facch, msg->l2h,
|
||||
msgb_l2len(msg));
|
||||
/* prepare ONSET message */
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
|
||||
GsmL1_TchPlType_Amr_Onset;
|
||||
/* prepare ONSET or INH message */
|
||||
if(lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F)
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
|
||||
GsmL1_TchPlType_Amr_Onset;
|
||||
else if(lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F)
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
|
||||
GsmL1_TchPlType_Amr_SidUpdateInH;
|
||||
else if(lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F)
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
|
||||
GsmL1_TchPlType_Amr_SidFirstInH;
|
||||
/* ignored CMR/CMI pair */
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[1] = 0;
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer[2] = 0;
|
||||
|
|
|
@ -409,12 +409,12 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
|
|||
rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
|
||||
ft);
|
||||
return 0;
|
||||
case ST_F1_INH:
|
||||
case ST_F1_INH_V:
|
||||
*payload_type = GsmL1_TchPlType_Amr_SidFirstInH;
|
||||
*len = 3;
|
||||
dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
|
||||
return 1;
|
||||
case ST_U_INH:
|
||||
case ST_U_INH_V:
|
||||
*payload_type = GsmL1_TchPlType_Amr_SidUpdateInH;
|
||||
*len = 3;
|
||||
dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
|
||||
|
|
Loading…
Reference in New Issue