aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2016-09-17 14:15:03 +0200
committerMax <msuraev@sysmocom.de>2016-09-24 15:09:31 +0200
commit654175f33bd412671e3ef8cdd65c0689d10f278c (patch)
tree9861adb1bf44de4ff5edf02025e7fc7795f33218
parenteb08a87be52bf55a78c12689f1e5c7cff627cbbc (diff)
DTX: check Marker bit to send ONSET to L1
If Marker bit is set than it's a talkspurt which we have to explicitly indicate to L1 by first sending ONSET message and than actual voice data in a separate message. This change affect sysmobts and LC15 hw. Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6 Related: OS#1750
-rw-r--r--include/osmo-bts/l1sap.h2
-rw-r--r--include/osmo-bts/msg_utils.h3
-rw-r--r--src/common/l1sap.c13
-rw-r--r--src/osmo-bts-litecell15/l1_if.c11
-rw-r--r--src/osmo-bts-litecell15/l1_if.h3
-rw-r--r--src/osmo-bts-litecell15/tch.c33
-rw-r--r--src/osmo-bts-sysmo/l1_if.c8
-rw-r--r--src/osmo-bts-sysmo/l1_if.h3
-rw-r--r--src/osmo-bts-sysmo/tch.c31
9 files changed, 83 insertions, 24 deletions
diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h
index 27355747..981cd756 100644
--- a/include/osmo-bts/l1sap.h
+++ b/include/osmo-bts/l1sap.h
@@ -55,7 +55,7 @@ int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn,
/* call-back function for incoming RTP */
void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
- unsigned int rtp_pl_len);
+ unsigned int rtp_pl_len, bool marker);
/* channel control */
int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp);
diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h
index cde7a93b..f03eb438 100644
--- a/include/osmo-bts/msg_utils.h
+++ b/include/osmo-bts/msg_utils.h
@@ -10,6 +10,9 @@
struct msgb;
+/* Access 1st byte of msgb control buffer */
+#define rtpmsg_marker_bit(x) ((x)->cb[0])
+
/**
* Classification of OML message. ETSI for plain GSM 12.21
* messages and IPA/Osmo for manufacturer messages.
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index 7eb0b623..943bdfe2 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -24,7 +24,7 @@
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
-
+#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -46,6 +46,7 @@
#include <osmo-bts/bts_model.h>
#include <osmo-bts/handover.h>
#include <osmo-bts/power_control.h>
+#include <osmo-bts/msg_utils.h>
struct gsm_lchan *get_lchan_by_chan_nr(struct gsm_bts_trx *trx,
unsigned int chan_nr)
@@ -659,7 +660,7 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx,
struct osmo_phsap_prim *resp_l1sap, empty_l1sap;
struct gsm_time g_time;
struct gsm_lchan *lchan;
- uint8_t chan_nr;
+ uint8_t chan_nr, marker = 0;
uint32_t fn;
chan_nr = rts_ind->chan_nr;
@@ -691,6 +692,9 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx,
gsm_lchan_name(lchan));
resp_l1sap = &empty_l1sap;
} else {
+ /* Obtain RTP header Marker bit from control buffer */
+ marker = rtpmsg_marker_bit(resp_msg);
+
resp_msg->l2h = resp_msg->data;
msgb_push(resp_msg, sizeof(*resp_l1sap));
resp_msg->l1h = resp_msg->data;
@@ -702,6 +706,7 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx,
resp_msg);
resp_l1sap->u.tch.chan_nr = chan_nr;
resp_l1sap->u.tch.fn = fn;
+ resp_l1sap->u.tch.marker = marker;
DEBUGP(DL1P, "Tx TCH.req %02u/%02u/%02u chan_nr=%d\n",
g_time.t1, g_time.t2, g_time.t3, chan_nr);
@@ -1050,7 +1055,7 @@ int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn,
/*! \brief call-back function for incoming RTP */
void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
- unsigned int rtp_pl_len)
+ unsigned int rtp_pl_len, bool marker)
{
struct gsm_lchan *lchan = rs->priv;
struct msgb *msg, *tmp;
@@ -1063,6 +1068,8 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len);
msgb_pull(msg, sizeof(*l1sap));
+ /* Store RTP header Marker bit in control buffer */
+ rtpmsg_marker_bit(msg) = marker;
/* make sure the queue doesn't get too long */
llist_for_each_entry(tmp, &lchan->dl_tch_queue, list)
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index 21d047a5..0779dacc 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -469,7 +469,8 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
if (!l1if_tch_encode(lchan,
l1p->u.phDataReq.msgUnitParam.u8Buffer,
&l1p->u.phDataReq.msgUnitParam.u8Size,
- msg->data, msg->len, u32Fn)) {
+ msg->data, msg->len, u32Fn,
+ l1sap->u.tch.marker)) {
msgb_free(nmsg);
nmsg = NULL;
}
@@ -503,7 +504,13 @@ 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);
- msgb_free(msg);
+ if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */
+ l1sap->u.tch.marker = 0;
+ return ph_tch_req(trx, l1sap->oph.msg, l1sap);
+ }
+
+ if (msg)
+ msgb_free(msg);
return 0;
}
diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h
index f01fdc2b..88d71bf0 100644
--- a/src/osmo-bts-litecell15/l1_if.h
+++ b/src/osmo-bts-litecell15/l1_if.h
@@ -90,7 +90,8 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer)
/* tch.c */
bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
- const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn);
+ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn,
+ bool marker);
int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg);
int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer);
struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn);
diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c
index 3c6ee25f..e06c4cf8 100644
--- a/src/osmo-bts-litecell15/tch.c
+++ b/src/osmo-bts-litecell15/tch.c
@@ -26,7 +26,7 @@
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
-
+#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -222,6 +222,9 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
cmi = ft;
LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi);
break;
+ case AMR_NO_DATA:
+ LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n");
+ break;
case AMR_SID:
LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n",
sti ? "UPDATE" : "FIRST", cmi);
@@ -283,6 +286,7 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
/*! \brief function for incoming RTP via TCH.req
* \param[in] rtp_pl buffer containing RTP payload
* \param[in] rtp_pl_len length of \a rtp_pl
+ * \param[in] marker RTP header Marker bit (indicates speech onset)
* \returns true if encoding result can be sent further to L1, false otherwise
*
* This function prepares a msgb with a L1 PH-DATA.req primitive and
@@ -293,10 +297,13 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
* pre-fill the primtive.
*/
bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
- const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn)
+ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker)
{
uint8_t *payload_type;
- uint8_t *l1_payload;
+ uint8_t *l1_payload, cmr;
+ enum osmo_amr_type ft;
+ enum osmo_amr_quality bfi;
+ int8_t sti, cmi;
int rc;
DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan),
@@ -323,11 +330,21 @@ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
rtp_pl_len);
break;
case GSM48_CMODE_SPEECH_AMR:
- *payload_type = GsmL1_TchPlType_Amr;
- rc = rtppayload_to_l1_amr(l1_payload, rtp_pl,
- rtp_pl_len, lchan, fn);
- if (-EALREADY == rc)
- return false;
+ if (marker) {
+ *payload_type = GsmL1_TchPlType_Amr_Onset;
+ rc = 0;
+ osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft,
+ &bfi, &sti);
+ LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n",
+ get_value_string(osmo_amr_type_names, ft));
+ }
+ else {
+ *payload_type = GsmL1_TchPlType_Amr;
+ rc = rtppayload_to_l1_amr(l1_payload, rtp_pl,
+ rtp_pl_len, lchan, fn);
+ if (-EALREADY == rc)
+ return false;
+ }
break;
default:
/* we don't support CSD modes */
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 41b09a1c..3c6db43d 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -462,7 +462,8 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
if (!l1if_tch_encode(lchan,
l1p->u.phDataReq.msgUnitParam.u8Buffer,
&l1p->u.phDataReq.msgUnitParam.u8Size,
- msg->data, msg->len, u32Fn)) {
+ msg->data, msg->len, u32Fn,
+ l1sap->u.tch.marker)) {
msgb_free(nmsg);
nmsg = NULL;
}
@@ -496,6 +497,11 @@ 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);
+ if (l1sap->u.tch.marker) { /* Send voice after ONSET was sent */
+ l1sap->u.tch.marker = 0;
+ return ph_tch_req(trx, l1sap->oph.msg, l1sap);
+ }
+
return 0;
}
diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h
index 49b7e677..a90c39b2 100644
--- a/src/osmo-bts-sysmo/l1_if.h
+++ b/src/osmo-bts-sysmo/l1_if.h
@@ -110,7 +110,8 @@ struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer)
/* tch.c */
bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
- const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn);
+ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn,
+ bool marker);
int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg);
int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer);
struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn);
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index 745923c0..b1ab0866 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -319,6 +319,9 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
cmi = ft;
LOGP(DRTP, LOGL_DEBUG, "SPEECH frame with CMI %u\n", cmi);
break;
+ case AMR_NO_DATA:
+ LOGP(DRTP, LOGL_DEBUG, "SPEECH frame AMR NO_DATA\n");
+ break;
case AMR_SID:
LOGP(DRTP, LOGL_DEBUG, "SID %s frame with CMI %u\n",
sti ? "UPDATE" : "FIRST", cmi);
@@ -380,6 +383,7 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
/*! \brief function for incoming RTP via TCH.req
* \param[in] rtp_pl buffer containing RTP payload
* \param[in] rtp_pl_len length of \a rtp_pl
+ * \param[in] marker RTP header Marker bit (indicates speech onset)
* \returns true if encoding result can be sent further to L1, false otherwise
*
* This function prepares a msgb with a L1 PH-DATA.req primitive and
@@ -390,10 +394,13 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
* pre-fill the primtive.
*/
bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
- const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn)
+ const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker)
{
uint8_t *payload_type;
- uint8_t *l1_payload;
+ uint8_t *l1_payload, cmr;
+ enum osmo_amr_type ft;
+ enum osmo_amr_quality bfi;
+ int8_t sti, cmi;
int rc;
DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan),
@@ -422,11 +429,21 @@ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
break;
#endif
case GSM48_CMODE_SPEECH_AMR:
- *payload_type = GsmL1_TchPlType_Amr;
- rc = rtppayload_to_l1_amr(l1_payload, rtp_pl,
- rtp_pl_len, lchan, fn);
- if (-EALREADY == rc)
- return false;
+ if (marker) {
+ *payload_type = GsmL1_TchPlType_Amr_Onset;
+ rc = 0;
+ osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft,
+ &bfi, &sti);
+ LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n",
+ get_value_string(osmo_amr_type_names, ft));
+ }
+ else {
+ *payload_type = GsmL1_TchPlType_Amr;
+ rc = rtppayload_to_l1_amr(l1_payload, rtp_pl,
+ rtp_pl_len, lchan, fn);
+ if (-EALREADY == rc)
+ return false;
+ }
break;
default:
/* we don't support CSD modes */