This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Max gerrit-no-reply at lists.osmocom.orgHello Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/1145 to look at the new patch set (#4). DTX DL: split ONSET state handling Handle ONSET cause by Voice and FACCH separately. In case of Voice we have RTP payload which we have to cache and send later on in next response to L1 RTS. FACCH have higher priority so it preempts both voice and silence alike - hence we can send ONSET immediately but still have to track previous state in order to get back to it gracefully. This affects lc15 and sysmo hw as there's no FSM-based DTX implementation for other models yet. Change-Id: Idba14dcd0cb12cd7aee86391fcc152c49fcd7052 Related: OS#1801 --- M include/osmo-bts/dtx_dl_amr_fsm.h M src/common/dtx_dl_amr_fsm.c M src/osmo-bts-litecell15/l1_if.c M src/osmo-bts-litecell15/tch.c M src/osmo-bts-sysmo/l1_if.c M src/osmo-bts-sysmo/tch.c 6 files changed, 84 insertions(+), 31 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/45/1145/4 diff --git a/include/osmo-bts/dtx_dl_amr_fsm.h b/include/osmo-bts/dtx_dl_amr_fsm.h index 8b19595..5c13c19 100644 --- a/include/osmo-bts/dtx_dl_amr_fsm.h +++ b/include/osmo-bts/dtx_dl_amr_fsm.h @@ -16,7 +16,6 @@ ST_U_INH, ST_SID_U, ST_ONSET_V, - ST_ONSET_F, ST_FACCH_V, ST_FACCH, }; diff --git a/src/common/dtx_dl_amr_fsm.c b/src/common/dtx_dl_amr_fsm.c index b110cf2..a75fd00 100644 --- a/src/common/dtx_dl_amr_fsm.c +++ b/src/common/dtx_dl_amr_fsm.c @@ -53,7 +53,7 @@ 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_FACCH, 0, 0); break; case E_COMPL: osmo_fsm_inst_state_chg(fi, ST_SID_F2, 0, 0); @@ -81,7 +81,7 @@ 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_FACCH, 0, 0); break; default: LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event); @@ -97,7 +97,7 @@ osmo_fsm_inst_state_chg(fi, ST_ONSET_V, 0, 0); break; case E_FACCH: - osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0); + osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0); break; default: LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event); @@ -113,7 +113,7 @@ osmo_fsm_inst_state_chg(fi, ST_ONSET_V, 0, 0); break; case E_FACCH: - osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0); + osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0); break; default: LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event); @@ -126,7 +126,7 @@ { switch (event) { case E_FACCH: - osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0); + osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0); break; case E_VOICE: osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0); @@ -234,7 +234,7 @@ 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_COMPL) | X(E_INHIB) | X(E_ONSET), - .out_state_mask = X(ST_SID_U) | X(ST_VOICE) | X(ST_ONSET_F) | X(ST_SID_F2) | X(ST_F1_INH) | X(ST_ONSET_V), + .out_state_mask = X(ST_SID_U) | X(ST_VOICE) | X(ST_FACCH) | X(ST_SID_F2) | X(ST_F1_INH) | X(ST_ONSET_V), .name = "SID-FIRST (P1)", .action = dtx_fsm_sid_f1, }, @@ -242,7 +242,7 @@ actual start of silence period in case of AMR HR*/ [ST_SID_F2]= { .in_event_mask = X(E_SID_U) | X(E_VOICE) | X(E_FACCH), - .out_state_mask = X(ST_SID_U) | X(ST_VOICE) | X(ST_ONSET_F), + .out_state_mask = X(ST_SID_U) | X(ST_VOICE) | X(ST_FACCH), .name = "SID-FIRST (P2)", .action = dtx_fsm_sid_f2, }, @@ -265,7 +265,7 @@ /* 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) | X(E_ONSET), - .out_state_mask = X(ST_ONSET_F) | X(ST_VOICE) | X(ST_U_INH) | X(ST_SID_U) | X(ST_ONSET_V), + .out_state_mask = X(ST_FACCH) | X(ST_VOICE) | X(ST_U_INH) | X(ST_SID_U) | X(ST_ONSET_V), .name = "SID-UPDATE", .action = dtx_fsm_sid_upd, }, @@ -275,13 +275,6 @@ .out_state_mask = X(ST_VOICE) | X(ST_FACCH_V), .name = "ONSET (SPEECH)", .action = dtx_fsm_onset_v, - }, - /* ONSET - end of silent period due to incoming FACCH frame */ - [ST_ONSET_F]= { - .in_event_mask = X(E_VOICE) | X(E_FACCH) | X(E_SID_U), - .out_state_mask = X(ST_VOICE) | X(ST_FACCH), - .name = "ONSET (FACCH)", - .action = dtx_fsm_onset_f, }, /* FACCH sending state: SPEECH was observed before so once we're done FSM should get back to VOICE state */ diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c index f47634e..b98e95a 100644 --- a/src/osmo-bts-litecell15/l1_if.c +++ b/src/osmo-bts-litecell15/l1_if.c @@ -53,6 +53,7 @@ #include <osmo-bts/cbch.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/l1sap.h> +#include <osmo-bts/dtx_dl_amr_fsm.h> #include <nrw/litecell15/litecell15.h> #include <nrw/litecell15/gsml1prim.h> @@ -330,13 +331,15 @@ } static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, - struct osmo_phsap_prim *l1sap) + struct osmo_phsap_prim *l1sap, bool use_cache) { struct lc15l1_hdl *fl1 = trx_lc15l1_hdl(trx); struct msgb *l1msg = l1p_msgb_alloc(); + struct gsm_lchan *lchan; uint32_t u32Fn; uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi = 0; uint8_t chan_nr, link_id; + bool rec = false; int len; if (!msg) { @@ -401,14 +404,41 @@ if (len) { /* data request */ GsmL1_Prim_t *l1p = msgb_l1prim(l1msg); + lchan = get_lchan_by_chan_nr(trx, chan_nr); + + if (use_cache) + memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, + lchan->tch.dtx.facch, msgb_l2len(msg)); + else if (trx->bts->dtxd && // FIXME: separate FACCH/H? + (sapi == GsmL1_Sapi_FacchF || + sapi == GsmL1_Sapi_FacchH)) { + if (lchan->tch.dtx.dl_amr_fsm->state == ST_FACCH) { + /* FACCH interruption of DTX silence */ + /* cache FACCH data */ + memcpy(lchan->tch.dtx.facch, msg->l2h, + msgb_l2len(msg)); + /* prepare ONSET message */ + len = 3; + l1p->u.phDataReq.msgUnitParam.u8Buffer[0] = + GsmL1_TchPlType_Amr_Onset; + /* ignored CMR/CMI pair */ + l1p->u.phDataReq.msgUnitParam.u8Buffer[1] = 0; + l1p->u.phDataReq.msgUnitParam.u8Buffer[2] = 0; + /* ONSET is ready, recursive call is necessary */ + rec = true; + } + } data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr, len); - OSMO_ASSERT(msgb_l2len(msg) <= sizeof(l1p->u.phDataReq.msgUnitParam.u8Buffer)); - memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h, msgb_l2len(msg)); + if (!rec && !use_cache) { + OSMO_ASSERT(msgb_l2len(msg) <= sizeof(l1p->u.phDataReq.msgUnitParam.u8Buffer)); + memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h, + msgb_l2len(msg)); + } LOGP(DL1P, LOGL_DEBUG, "PH-DATA.req(%s)\n", - osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, - l1p->u.phDataReq.msgUnitParam.u8Size)); + osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, + l1p->u.phDataReq.msgUnitParam.u8Size)); } else { /* empty frame */ GsmL1_Prim_t *l1p = msgb_l1prim(l1msg); @@ -422,6 +452,8 @@ msgb_free(l1msg); } + if (rec) + ph_data_req(trx, msg, l1sap, true); return 0; } @@ -566,7 +598,7 @@ * free()d below */ switch (OSMO_PRIM_HDR(&l1sap->oph)) { case OSMO_PRIM(PRIM_PH_DATA, PRIM_OP_REQUEST): - rc = ph_data_req(trx, msg, l1sap); + rc = ph_data_req(trx, msg, l1sap, false); break; case OSMO_PRIM(PRIM_TCH, PRIM_OP_REQUEST): rc = ph_tch_req(trx, msg, l1sap, false, l1sap->u.tch.marker); diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index b251388..2565e23 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -285,10 +285,9 @@ /* DTX DL-specific logic below: */ switch (lchan->tch.dtx.dl_amr_fsm->state) { case ST_ONSET_V: - case ST_ONSET_F: *payload_type = GsmL1_TchPlType_Amr_Onset; dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0); - *len = 1; + *len = 3; return 1; case ST_VOICE: *payload_type = GsmL1_TchPlType_Amr; diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index bef2d30..eefcdaf 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -325,13 +325,15 @@ } static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, - struct osmo_phsap_prim *l1sap) + struct osmo_phsap_prim *l1sap, bool use_cache) { struct femtol1_hdl *fl1 = trx_femtol1_hdl(trx); struct msgb *l1msg = l1p_msgb_alloc(); + struct gsm_lchan *lchan; uint32_t u32Fn; uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi = 0; uint8_t chan_nr, link_id; + bool rec = false; int len; if (!msg) { @@ -396,14 +398,41 @@ if (len) { /* data request */ GsmL1_Prim_t *l1p = msgb_l1prim(l1msg); + lchan = get_lchan_by_chan_nr(trx, chan_nr); + + if (use_cache) + memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, + lchan->tch.dtx.facch, msgb_l2len(msg)); + else if (trx->bts->dtxd && // FIXME: separate FACCH/H? + (sapi == GsmL1_Sapi_FacchF || + sapi == GsmL1_Sapi_FacchH)) { + if (lchan->tch.dtx.dl_amr_fsm->state == ST_FACCH) { + /* FACCH interruption of DTX silence */ + /* cache FACCH data */ + memcpy(lchan->tch.dtx.facch, msg->l2h, + msgb_l2len(msg)); + /* prepare ONSET message */ + len = 3; + l1p->u.phDataReq.msgUnitParam.u8Buffer[0] = + GsmL1_TchPlType_Amr_Onset; + /* ignored CMR/CMI pair */ + l1p->u.phDataReq.msgUnitParam.u8Buffer[1] = 0; + l1p->u.phDataReq.msgUnitParam.u8Buffer[2] = 0; + /* ONSET is ready, recursive call is necessary */ + rec = true; + } + } data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr, len); - OSMO_ASSERT(msgb_l2len(msg) <= sizeof(l1p->u.phDataReq.msgUnitParam.u8Buffer)); - memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h, msgb_l2len(msg)); + if (!rec && !use_cache) { + OSMO_ASSERT(msgb_l2len(msg) <= sizeof(l1p->u.phDataReq.msgUnitParam.u8Buffer)); + memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h, + msgb_l2len(msg)); + } LOGP(DL1P, LOGL_DEBUG, "PH-DATA.req(%s)\n", - osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, - l1p->u.phDataReq.msgUnitParam.u8Size)); + osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, + l1p->u.phDataReq.msgUnitParam.u8Size)); } else { /* empty frame */ GsmL1_Prim_t *l1p = msgb_l1prim(l1msg); @@ -417,6 +446,8 @@ msgb_free(l1msg); } + if (rec) + ph_data_req(trx, msg, l1sap, true); return 0; } diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index b08ba7e..5e517e9 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -383,10 +383,9 @@ /* DTX DL-specific logic below: */ switch (lchan->tch.dtx.dl_amr_fsm->state) { case ST_ONSET_V: - case ST_ONSET_F: *payload_type = GsmL1_TchPlType_Amr_Onset; dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0); - *len = 1; + *len = 3; return 1; case ST_VOICE: *payload_type = GsmL1_TchPlType_Amr; -- To view, visit https://gerrit.osmocom.org/1145 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: Idba14dcd0cb12cd7aee86391fcc152c49fcd7052 Gerrit-PatchSet: 4 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: Max <msuraev at sysmocom.de> Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max <msuraev at sysmocom.de>