aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-sysmo
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
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')
-rw-r--r--src/osmo-bts-sysmo/l1_if.c33
-rw-r--r--src/osmo-bts-sysmo/tch.c31
2 files changed, 32 insertions, 32 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;
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index addb2ffb..16c2cf3a 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -403,9 +403,6 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
*payload_type = GsmL1_TchPlType_Amr;
rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
ft);
- /* force STI bit to 0 to make sure resume after FACCH
- works properly */
- l1_payload[6 + 2] &= ~16;
return 0;
case ST_SID_F2:
*payload_type = GsmL1_TchPlType_Amr;
@@ -424,7 +421,6 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
return 1;
case ST_SID_U:
return -EAGAIN;
- case ST_FACCH_V:
case ST_FACCH:
return -EBADMSG;
default:
@@ -598,19 +594,17 @@ struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn)
switch (lchan->tch_mode) {
case GSM48_CMODE_SPEECH_AMR:
if (lchan->type == GSM_LCHAN_TCH_H &&
- lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F1 &&
dtx_dl_amr_enabled(lchan)) {
+ /* we have to explicitly handle sending SID FIRST P2 for
+ AMR HR in here */
*payload_type = GsmL1_TchPlType_Amr_SidFirstP2;
rc = dtx_dl_amr_fsm_step(lchan, NULL, 0, fn, l1_payload,
false, &(msu_param->u8Size),
NULL);
- if (rc < 0) {
- msgb_free(msg);
- return NULL;
- }
- return msg;
- } else
- *payload_type = GsmL1_TchPlType_Amr;
+ if (rc == 0)
+ return msg;
+ }
+ *payload_type = GsmL1_TchPlType_Amr;
break;
case GSM48_CMODE_SPEECH_V1:
if (lchan->type == GSM_LCHAN_TCH_F)
@@ -626,13 +620,12 @@ struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn)
return NULL;
}
- if (dtx_dl_amr_enabled(lchan)) {
- rc = repeat_last_sid(lchan, l1_payload, fn);
- if (!rc) {
- msgb_free(msg);
- return NULL;
- }
- msu_param->u8Size = rc;
+ rc = repeat_last_sid(lchan, l1_payload, fn);
+ if (!rc) {
+ msgb_free(msg);
+ return NULL;
}
+ msu_param->u8Size = rc;
+
return msg;
}