DTX: fix SID logic

Previously receiving SID via RTP always caused it's transmission to L1
regardless of the time which might have resulted in excess traffic. Fix
this by only saving SID data and transmitting it later on as necessary
according to 3GPP TS 26.093 A.5.1.1.

Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090
Fixes: OS#1801
This commit is contained in:
Max 2016-09-16 19:46:00 +02:00
parent 527dd402c7
commit 70460814ce
6 changed files with 38 additions and 18 deletions

View File

@ -466,10 +466,13 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
if (!nmsg)
return -ENOMEM;
l1p = msgb_l1prim(nmsg);
l1if_tch_encode(lchan,
l1p->u.phDataReq.msgUnitParam.u8Buffer,
&l1p->u.phDataReq.msgUnitParam.u8Size,
msg->data, msg->len, u32Fn);
if (!l1if_tch_encode(lchan,
l1p->u.phDataReq.msgUnitParam.u8Buffer,
&l1p->u.phDataReq.msgUnitParam.u8Size,
msg->data, msg->len, u32Fn)) {
msgb_free(nmsg);
nmsg = NULL;
}
}
/* no message/data, we generate an empty traffic msg */

View File

@ -11,6 +11,8 @@
#include <nrw/litecell15/gsml1prim.h>
#include <stdbool.h>
enum {
MQ_SYS_READ,
MQ_L1_READ,
@ -87,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 */
void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
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);
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);

View File

@ -270,8 +270,10 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
}
#endif
if (ft == AMR_SID)
if (ft == AMR_SID) {
save_last_sid(lchan, l1_payload, payload_len, fn, sti);
return -EALREADY;
}
return payload_len+1;
}
@ -279,9 +281,9 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
#define RTP_MSGB_ALLOC_SIZE 512
/*! \brief function for incoming RTP via TCH.req
* \param rs RTP Socket
* \param[in] rtp_pl buffer containing RTP payload
* \param[in] rtp_pl_len length of \a rtp_pl
* \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
* queues it into lchan->dl_tch_queue.
@ -290,7 +292,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.
*/
void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
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)
{
uint8_t *payload_type;
@ -324,6 +326,8 @@ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
*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 */
@ -334,13 +338,14 @@ void 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;
return false;
}
*len = rc + 1;
DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan),
osmo_hexdump(data, *len));
return true;
}
static int is_recv_only(uint8_t speech_mode)

View File

@ -459,10 +459,13 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
if (!nmsg)
return -ENOMEM;
l1p = msgb_l1prim(nmsg);
l1if_tch_encode(lchan,
l1p->u.phDataReq.msgUnitParam.u8Buffer,
&l1p->u.phDataReq.msgUnitParam.u8Size,
msg->data, msg->len, u32Fn);
if (!l1if_tch_encode(lchan,
l1p->u.phDataReq.msgUnitParam.u8Buffer,
&l1p->u.phDataReq.msgUnitParam.u8Size,
msg->data, msg->len, u32Fn)) {
msgb_free(nmsg);
nmsg = NULL;
}
}
/* no message/data, we generate an empty traffic msg */

View File

@ -11,6 +11,8 @@
#include <sysmocom/femtobts/gsml1prim.h>
#include <stdbool.h>
enum {
MQ_SYS_READ,
MQ_L1_READ,
@ -107,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 */
void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
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);
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);

View File

@ -367,8 +367,10 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
}
#endif
if (ft == AMR_SID)
if (ft == AMR_SID) {
save_last_sid(lchan, l1_payload, payload_len, fn, sti);
return -EALREADY;
}
return payload_len+1;
}
@ -376,9 +378,9 @@ static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
#define RTP_MSGB_ALLOC_SIZE 512
/*! \brief function for incoming RTP via TCH.req
* \param rs RTP Socket
* \param[in] rtp_pl buffer containing RTP payload
* \param[in] rtp_pl_len length of \a rtp_pl
* \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
* queues it into lchan->dl_tch_queue.
@ -387,7 +389,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.
*/
void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
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)
{
uint8_t *payload_type;
@ -423,6 +425,8 @@ void l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
*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 */
@ -433,13 +437,14 @@ void 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;
return false;
}
*len = rc + 1;
DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan),
osmo_hexdump(data, *len));
return true;
}
static int is_recv_only(uint8_t speech_mode)