HR1 codec: act on SID indication in RFC5993 RTP input
Suppose we receive RTP from the uplink of another BTS, and the UL-handling BTS has channel-decoded an HR1 frame which it deems (per GSM 06.41 section 6.1.1) to be a valid SID, even though it is not a perfect, error-free SID. How will this SID frame be represented in RFC 5993 transport? My reading of the RFC tells me that the UL-handling BTS will need to apply an operation like our osmo_hr_sid_reset() to the payload before sending it out in RTP - but because the text of the RFC does not explicitly address this scenario, others may have interpreted it differently. If we receive an RFC 5993 RTP payload in which FT is set to 2, indicating good SID, but the actual HR payload is not a perfect SID (the SID field is not all 1s), the only reasonable interpretation of such occurrence is that the sender of this payload was another BTS whose implementors interpreted the RFC as not requiring them to rejuvenate the SID codeword prior to RTP output. Therefore, let's treat such payloads as valid SID for our DTXd logic, and rejuvenate the SID codeword ourselves. Change-Id: Ife00de6220a8ca7cc180a61734497f1acb7f5b83
This commit is contained in:
parent
1dd710944f
commit
405368b697
|
@ -22,6 +22,9 @@ struct msgb;
|
|||
/* Access 3rd part of msgb control buffer */
|
||||
#define rtpmsg_ts(x) ((x)->cb[2])
|
||||
|
||||
/* Access 4th part of msgb control buffer */
|
||||
#define rtpmsg_is_rfc5993_sid(x) ((x)->cb[3])
|
||||
|
||||
/**
|
||||
* Classification of OML message. ETSI for plain GSM 12.21
|
||||
* messages and IPA/Osmo for manufacturer messages.
|
||||
|
|
|
@ -17,4 +17,4 @@ enum pl_input_decision {
|
|||
|
||||
enum pl_input_decision
|
||||
rtp_payload_input_preen(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
|
||||
unsigned rtp_pl_len);
|
||||
unsigned rtp_pl_len, bool *rfc5993_sid_flag);
|
||||
|
|
|
@ -1314,9 +1314,17 @@ static bool fr_hr_efr_dtxd_input(struct gsm_lchan *lchan, struct msgb *resp_msg,
|
|||
* directly coupled to the GSM 05.03 channel decoder,
|
||||
* and cannot be reconstructed downstream from frame
|
||||
* payload bits. The only kind of SID we can detect
|
||||
* here is the perfect, error-free kind. */
|
||||
is_sid = osmo_hr_check_sid(msgb_l2(resp_msg),
|
||||
msgb_l2len(resp_msg));
|
||||
* here is the perfect, error-free kind. However,
|
||||
* if we received RFC 5993 payload and the sender
|
||||
* told us it is valid SID, honor that indication
|
||||
* and rejuvenate the SID codeword. */
|
||||
if (rtpmsg_is_rfc5993_sid(resp_msg)) {
|
||||
is_sid = true;
|
||||
osmo_hr_sid_reset(msgb_l2(resp_msg));
|
||||
} else {
|
||||
is_sid = osmo_hr_check_sid(msgb_l2(resp_msg),
|
||||
msgb_l2len(resp_msg));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GSM48_CMODE_SPEECH_EFR:
|
||||
|
@ -2152,6 +2160,7 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
|
|||
{
|
||||
struct gsm_lchan *lchan = rs->priv;
|
||||
struct msgb *msg;
|
||||
bool rfc5993_sid = false;
|
||||
|
||||
/* if we're in loopback mode, we don't accept frames from the
|
||||
* RTP socket anymore */
|
||||
|
@ -2159,7 +2168,7 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
|
|||
return;
|
||||
|
||||
/* initial preen */
|
||||
switch (rtp_payload_input_preen(lchan, rtp_pl, rtp_pl_len)) {
|
||||
switch (rtp_payload_input_preen(lchan, rtp_pl, rtp_pl_len, &rfc5993_sid)) {
|
||||
case PL_DECISION_DROP:
|
||||
return;
|
||||
case PL_DECISION_ACCEPT:
|
||||
|
@ -2184,6 +2193,8 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
|
|||
rtpmsg_seq(msg) = seq_number;
|
||||
/* Store RTP header Timestamp in control buffer */
|
||||
rtpmsg_ts(msg) = timestamp;
|
||||
/* Store RFC 5993 SID flag likewise */
|
||||
rtpmsg_is_rfc5993_sid(msg) = rfc5993_sid;
|
||||
|
||||
/* make sure the queue doesn't get too long */
|
||||
lchan_dl_tch_queue_enqueue(lchan, msg, 1);
|
||||
|
|
|
@ -82,7 +82,8 @@ input_preen_efr(const uint8_t *rtp_pl, unsigned rtp_pl_len)
|
|||
}
|
||||
|
||||
static enum pl_input_decision
|
||||
input_preen_hr(const uint8_t *rtp_pl, unsigned rtp_pl_len)
|
||||
input_preen_hr(const uint8_t *rtp_pl, unsigned rtp_pl_len,
|
||||
bool *rfc5993_sid_flag)
|
||||
{
|
||||
switch (rtp_pl_len) {
|
||||
case GSM_HR_BYTES:
|
||||
|
@ -96,8 +97,7 @@ input_preen_hr(const uint8_t *rtp_pl, unsigned rtp_pl_len)
|
|||
case 0x00:
|
||||
break;
|
||||
case 0x20:
|
||||
/* TODO (next patch): signal this SID to the
|
||||
* fr_hr_efr_dtxd_input() handler in l1sap. */
|
||||
*rfc5993_sid_flag = true;
|
||||
break;
|
||||
default:
|
||||
/* invalid payload */
|
||||
|
@ -113,7 +113,7 @@ input_preen_hr(const uint8_t *rtp_pl, unsigned rtp_pl_len)
|
|||
|
||||
enum pl_input_decision
|
||||
rtp_payload_input_preen(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
|
||||
unsigned rtp_pl_len)
|
||||
unsigned rtp_pl_len, bool *rfc5993_sid_flag)
|
||||
{
|
||||
/* If rtp continuous-streaming is enabled, we shall emit RTP packets
|
||||
* with zero-length payloads as BFI markers. In a TrFO scenario such
|
||||
|
@ -132,7 +132,7 @@ rtp_payload_input_preen(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
|
|||
if (lchan->type == GSM_LCHAN_TCH_F)
|
||||
return input_preen_fr(rtp_pl, rtp_pl_len);
|
||||
else
|
||||
return input_preen_hr(rtp_pl, rtp_pl_len);
|
||||
return input_preen_hr(rtp_pl, rtp_pl_len, rfc5993_sid_flag);
|
||||
case GSM48_CMODE_SPEECH_EFR:
|
||||
return input_preen_efr(rtp_pl, rtp_pl_len);
|
||||
case GSM48_CMODE_SPEECH_AMR:
|
||||
|
|
Loading…
Reference in New Issue