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:
Mychaela N. Falconia 2023-05-29 21:04:07 +00:00
parent 1dd710944f
commit 405368b697
4 changed files with 24 additions and 10 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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: