DTX: send AMR voice alongside with ONSET

When ONSET event happens (either via Marker bit or due to unmarked
talkspurt) we should first send Onset event to L1 and than send voice
data in response to the same PH-RTS.ind.

Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347
This commit is contained in:
Max 2016-09-30 11:59:38 +02:00
parent 067ef3f1ce
commit 5f2e2de84f
6 changed files with 32 additions and 20 deletions

View File

@ -441,6 +441,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
uint8_t chan_nr;
GsmL1_Prim_t *l1p;
struct msgb *nmsg = NULL;
int rc = -1;
chan_nr = l1sap->u.tch.chan_nr;
u32Fn = l1sap->u.tch.fn;
@ -464,17 +465,20 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
if (!nmsg)
return -ENOMEM;
l1p = msgb_l1prim(nmsg);
if (!l1if_tch_encode(lchan,
rc = l1if_tch_encode(lchan,
l1p->u.phDataReq.msgUnitParam.u8Buffer,
&l1p->u.phDataReq.msgUnitParam.u8Size,
msg->data, msg->len, u32Fn,
l1sap->u.tch.marker)) {
l1sap->u.tch.marker);
if (rc < 0) {
/* no data encoded for L1: smth will be generated below */
msgb_free(nmsg);
nmsg = NULL;
}
}
/* no message/data, we generate an empty traffic msg */
/* no message/data, we might generate an empty traffic msg or re-send
cached SID in case of DTX */
if (!nmsg)
nmsg = gen_empty_tch_msg(lchan, u32Fn);
@ -502,7 +506,7 @@ 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 */
if (l1sap->u.tch.marker) { /* DTX: send voice after ONSET was sent */
l1sap->u.tch.marker = 0;
return ph_tch_req(trx, l1sap->oph.msg, l1sap);
}

View File

@ -89,7 +89,7 @@ uint32_t l1if_lchan_to_hLayer(struct gsm_lchan *lchan);
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,
int 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,
bool marker);
int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg);

View File

@ -211,7 +211,9 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
* \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
* \returns 0 if encoding result can be sent further to L1 without extra actions
* positive value if data is ready AND extra actions are required
* negative value otherwise
*
* This function prepares a msgb with a L1 PH-DATA.req primitive and
* queues it into lchan->dl_tch_queue.
@ -220,7 +222,7 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
* yet, as things like the frame number, etc. are unknown at the time we
* pre-fill the primtive.
*/
bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
int 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, bool marker)
{
uint8_t *payload_type;
@ -269,7 +271,7 @@ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without"
" Marker: ONSET forced\n",
get_value_string(osmo_amr_type_names, ft));
return true;
return rc;
}
LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n",
get_value_string(osmo_amr_type_names, ft));
@ -289,14 +291,14 @@ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
if (rc < 0) {
LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n",
gsm_lchan_name(lchan));
return false;
return -EBADMSG;
}
*len = rc + 1;
DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan),
osmo_hexdump(data, *len));
return true;
return 0;
}
static int is_recv_only(uint8_t speech_mode)

View File

@ -436,6 +436,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
uint8_t chan_nr;
GsmL1_Prim_t *l1p;
struct msgb *nmsg = NULL;
int rc = -1;
chan_nr = l1sap->u.tch.chan_nr;
u32Fn = l1sap->u.tch.fn;
@ -459,17 +460,20 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
if (!nmsg)
return -ENOMEM;
l1p = msgb_l1prim(nmsg);
if (!l1if_tch_encode(lchan,
rc = l1if_tch_encode(lchan,
l1p->u.phDataReq.msgUnitParam.u8Buffer,
&l1p->u.phDataReq.msgUnitParam.u8Size,
msg->data, msg->len, u32Fn,
l1sap->u.tch.marker)) {
l1sap->u.tch.marker);
if (rc < 0) {
/* no data encoded for L1: smth will be generated below */
msgb_free(nmsg);
nmsg = NULL;
}
}
/* no message/data, we generate an empty traffic msg */
/* no message/data, we might generate an empty traffic msg or re-send
cached SID in case of DTX */
if (!nmsg)
nmsg = gen_empty_tch_msg(lchan, u32Fn);
@ -497,7 +501,7 @@ 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 */
if (l1sap->u.tch.marker) { /* DTX: send voice after ONSET was sent */
l1sap->u.tch.marker = 0;
return ph_tch_req(trx, l1sap->oph.msg, l1sap);
}

View File

@ -109,7 +109,7 @@ uint32_t l1if_lchan_to_hLayer(struct gsm_lchan *lchan);
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,
int 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,
bool marker);
int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg);

View File

@ -307,7 +307,9 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
* \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
* \returns 0 if encoding result can be sent further to L1 without extra actions
* positive value if data is ready AND extra actions are required
* negative value otherwise
*
* This function prepares a msgb with a L1 PH-DATA.req primitive and
* queues it into lchan->dl_tch_queue.
@ -316,7 +318,7 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
* yet, as things like the frame number, etc. are unknown at the time we
* pre-fill the primtive.
*/
bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
int 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, bool marker)
{
uint8_t *payload_type;
@ -367,7 +369,7 @@ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without"
" Marker: ONSET forced\n",
get_value_string(osmo_amr_type_names, ft));
return true;
return rc;
}
LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n",
get_value_string(osmo_amr_type_names, ft));
@ -387,14 +389,14 @@ bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
if (rc < 0) {
LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n",
gsm_lchan_name(lchan));
return false;
return -EBADMSG;
}
*len = rc + 1;
DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan),
osmo_hexdump(data, *len));
return true;
return 0;
}
static int is_recv_only(uint8_t speech_mode)