aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-sysmo/l1_if.c
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2016-11-04 17:19:52 +0100
committerHarald Welte <laforge@gnumonks.org>2016-12-01 14:49:43 +0000
commitaabeb2eae40bd8d5fc713fcf39e96ff14ad991b2 (patch)
treefbe549153c93d9cbf524ef012c1c4ededcdfe2d2 /src/osmo-bts-sysmo/l1_if.c
parentf4b238f91efddbfc3bc8456bdfef9a2354103c99 (diff)
DTX DL AMR: rewrite FSM recursion
Add explicit state for recursion (sending the different payload data in response to the RTS request for same FN) and corresponding transition. Remove ST_FACCH_V as with new explicit recursion handling it becomes unreacheable. This makes it easier to maintain preemption (interruption of current procedure due to FACCH or Inhibition). This also reduces the number of possible transitions out of each state thus reducing graph's cyclomatic complexity. Change-Id: If39b68083d23a4a35f468a5d75f54eb733ebfd14
Diffstat (limited to 'src/osmo-bts-sysmo/l1_if.c')
-rw-r--r--src/osmo-bts-sysmo/l1_if.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 61ffe395..ed643fcf 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -49,6 +49,7 @@
#include <osmo-bts/cbch.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/l1sap.h>
+#include <osmo-bts/msg_utils.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <sysmocom/femtobts/superfemto.h>
@@ -334,7 +335,6 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
uint32_t u32Fn;
uint8_t u8Tn, subCh, u8BlockNbr = 0, sapi = 0;
uint8_t chan_nr, link_id;
- bool rec = false;
int len;
if (!msg) {
@@ -350,6 +350,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
u32Fn = l1sap->u.data.fn;
u8Tn = L1SAP_CHAN2TS(chan_nr);
subCh = 0x1f;
+ lchan = get_lchan_by_chan_nr(trx, chan_nr);
if (L1SAP_IS_LINK_SACCH(link_id)) {
sapi = GsmL1_Sapi_Sacch;
if (!L1SAP_IS_CHAN_TCHF(chan_nr))
@@ -399,8 +400,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
if (len) {
/* data request */
GsmL1_Prim_t *l1p = msgb_l1prim(l1msg);
- lchan = get_lchan_by_chan_nr(trx, chan_nr);
-
+ data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr, len);
if (use_cache)
memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer,
lchan->tch.dtx.facch, msgb_l2len(msg));
@@ -418,20 +418,25 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
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;
+ /* update length */
+ data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi,
+ subCh, u8BlockNbr, 3);
+ /* update FN so it can be checked by TCH silence
+ resume handler */
+ lchan->tch.dtx.fn = LCHAN_FN_DUMMY;
}
+ } else if (dtx_dl_amr_enabled(lchan) &&
+ lchan->tch.dtx.dl_amr_fsm->state == ST_FACCH) {
+ /* update FN so it can be checked by TCH silence
+ resume handler */
+ lchan->tch.dtx.fn = LCHAN_FN_DUMMY;
}
-
- data_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr, len);
-
- if (!rec && !use_cache) {
+ else {
OSMO_ASSERT(msgb_l2len(msg) <= sizeof(l1p->u.phDataReq.msgUnitParam.u8Buffer));
memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h,
msgb_l2len(msg));
@@ -450,9 +455,10 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], l1msg) != 0) {
LOGP(DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n");
msgb_free(l1msg);
- }
+ } else
+ dtx_int_signal(lchan);
- if (rec)
+ if (dtx_recursion(lchan))
ph_data_req(trx, msg, l1sap, true);
return 0;
}
@@ -531,8 +537,9 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
}
/* send message to DSP's queue */
osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg);
+ dtx_int_signal(lchan);
- if (rc > 0 && trx->bts->dtxd) /* DTX: send voice after ONSET was sent */
+ if (dtx_recursion(lchan)) /* DTX: send voice after ONSET was sent */
return ph_tch_req(trx, l1sap->oph.msg, l1sap, true, false);
return 0;