falconia has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmocore/+/33059 )

Change subject: codec: new functions osmo_{fr,efr}_sid_reset()
......................................................................

codec: new functions osmo_{fr,efr}_sid_reset()

In Iec5c1f2619a82499f61cb3e5a7cd03ff0f020ad8 we added
osmo_{fr,efr}_sid_preen() functions that apply SID classification
of GSM 06.31/06.81 section 6.1.1 (osmo_{fr,efr}_sid_classify()),
reject invalid SID, and "rejuvenate" deemed-valid SID frames by
resetting their SID code word, correcting the one bit error that
may be present in a deemed-valid SID frame.  However, the last
operation (rejuvenation of a SID frame by resetting its SID field)
should also be made available as its own function, as it may be
more efficient in some applications: for example, an application
may need to call osmo_{fr,efr}_sid_classify(), apply the rejuvenation
to valid SID, but also use the classification result to drive other
logic.  Factor out these functions.

Change-Id: I1d6dd867a358bdda8850cd8c959d0f361c0a5b6d
---
M include/osmocom/codec/codec.h
M src/codec/gsm610.c
M src/codec/gsm660.c
3 files changed, 94 insertions(+), 32 deletions(-)

Approvals:
  laforge: Looks good to me, but someone else must approve
  fixeria: Looks good to me, approved
  Jenkins Builder: Verified




diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h
index 731f169..4dbe129 100644
--- a/include/osmocom/codec/codec.h
+++ b/include/osmocom/codec/codec.h
@@ -130,6 +130,9 @@
 bool osmo_fr_sid_preen(uint8_t *rtp_payload);
 bool osmo_efr_sid_preen(uint8_t *rtp_payload);

+void osmo_fr_sid_reset(uint8_t *rtp_payload);
+void osmo_efr_sid_reset(uint8_t *rtp_payload);
+
 int osmo_amr_rtp_enc(uint8_t *payload, uint8_t cmr, enum osmo_amr_type ft,
                     enum osmo_amr_quality bfi);
 int osmo_amr_rtp_dec(const uint8_t *payload, int payload_len, uint8_t *cmr,
diff --git a/src/codec/gsm610.c b/src/codec/gsm610.c
index 19c7aa4..5cc4f14 100644
--- a/src/codec/gsm610.c
+++ b/src/codec/gsm610.c
@@ -404,6 +404,35 @@
                return OSMO_GSM631_SID_CLASS_VALID;
 }

+/*! Reset the SID field and the unused bits of a potentially corrupted,
+ *  but still valid GSM-FR SID frame in RTP encoding to their pristine state.
+ *  \param[in] rtp_payload Buffer with RTP payload - must be writable!
+ *
+ *  Per GSM 06.12 section 5.2, a freshly minted SID frame carries 60 bits
+ *  of comfort noise parameters (LARc and 4 times Xmaxc), while the remaining
+ *  200 bits are all zeros; the latter 200 all-0 bits further break down into
+ *  95 bits of SID field (checked by receivers to detect SID) and 105 unused
+ *  bits which receivers are told to ignore.  Network elements that receive
+ *  SID frames from call leg A uplink and need to retransmit them on leg B
+ *  downlink should "rejuvenate" received SID frames prior to retransmission;
+ *  this function does the job.
+ */
+void osmo_fr_sid_reset(uint8_t *rtp_payload)
+{
+       uint8_t *p, sub;
+
+       p = rtp_payload + 5;    /* skip magic+LARc */
+       for (sub = 0; sub < 4; sub++) {
+               *p++ = 0;
+               *p++ &= 0x1F;   /* upper 5 bits of Xmaxc field */
+               *p++ &= 0x80;   /* and the lsb spilling into the next byte */
+               *p++ = 0;
+               *p++ = 0;
+               *p++ = 0;
+               *p++ = 0;
+       }
+}
+
 /*! Preen potentially-SID FR codec frame in RTP format, ensuring that it is
  *  either a speech frame or a valid SID, and if the latter, making it a
  *  perfect, error-free SID frame.
@@ -413,7 +442,6 @@
 bool osmo_fr_sid_preen(uint8_t *rtp_payload)
 {
        enum osmo_gsm631_sid_class sidc;
-       uint8_t *p, sub;

        sidc = osmo_fr_sid_classify(rtp_payload);
        switch (sidc) {
@@ -422,20 +450,8 @@
        case OSMO_GSM631_SID_CLASS_INVALID:
                return false;
        case OSMO_GSM631_SID_CLASS_VALID:
-               /* "Rejuvenate" this SID frame, correcting any errors:
-                * zero out all bits that aren't LARc or Xmaxc, thereby
-                * clearing all SID code word bits and all unused/reserved
-                * bits. */
-               p = rtp_payload + 5;    /* skip magic+LARc */
-               for (sub = 0; sub < 4; sub++) {
-                       *p++ = 0;
-                       *p++ &= 0x1F;
-                       *p++ &= 0x80;
-                       *p++ = 0;
-                       *p++ = 0;
-                       *p++ = 0;
-                       *p++ = 0;
-               }
+               /* "Rejuvenate" this SID frame, correcting any errors */
+               osmo_fr_sid_reset(rtp_payload);
                return true;
        default:
                /* There are only 3 possible SID classifications per GSM 06.31
diff --git a/src/codec/gsm660.c b/src/codec/gsm660.c
index 9b5c55a..b15bdf3 100644
--- a/src/codec/gsm660.c
+++ b/src/codec/gsm660.c
@@ -352,6 +352,42 @@
                return OSMO_GSM631_SID_CLASS_VALID;
 }

+/*! Reset the SID field of a potentially corrupted, but still valid GSM-EFR
+ *  SID frame in RTP encoding to its pristine state (full SID code word).
+ *  \param[in] rtp_payload Buffer with RTP payload - must be writable!
+ *
+ *  Per GSM 06.62 section 5.3, a freshly minted SID frame consists of 58 bits
+ *  of comfort noise parameters (LSF and 4 times fixed codebook gain), 95 bits
+ *  of SID code word (all 1s) and 91 unused bits (all 0s).  Network elements
+ *  that receive SID frames from call leg A uplink and need to retransmit them
+ *  on leg B downlink should "rejuvenate" received SID frames prior to
+ *  retransmission by resetting the SID field to its pristine state of all 1s;
+ *  this function does the job.
+ *
+ *  Potential TODO: it would be nice to also zero out the remaining 91 bits
+ *  which the spec leaves as reserved, clearing out leg A radio bit errors -
+ *  but do we really need to?
+ */
+void osmo_efr_sid_reset(uint8_t *rtp_payload)
+{
+       /* set all 95 SID code word bits to 1 */
+       rtp_payload[6]  |= 0x6F;
+       rtp_payload[7]   = 0xFF;
+       rtp_payload[8]   = 0xFF;
+       rtp_payload[9]  |= 0x80;
+       rtp_payload[12] |= 0x3B;
+       rtp_payload[13]  = 0xFF;
+       rtp_payload[14]  = 0xFF;
+       rtp_payload[15] |= 0xE0;
+       rtp_payload[19]  = 0xFF;
+       rtp_payload[20]  = 0xFF;
+       rtp_payload[21]  = 0xFF;
+       rtp_payload[25]  = 0xFF;
+       rtp_payload[26] |= 0xFC;
+       rtp_payload[27]  = 0xFF;
+       rtp_payload[28] |= 0xC0;
+}
+
 /*! Preen potentially-SID EFR codec frame in RTP format, ensuring that it is
  *  either a speech frame or a valid SID, and if the latter, making it a
  *  perfect, error-free SID frame.
@@ -369,23 +405,8 @@
        case OSMO_GSM631_SID_CLASS_INVALID:
                return false;
        case OSMO_GSM631_SID_CLASS_VALID:
-               /* "Rejuvenate" this SID frame, correcting any errors:
-                * set all 95 SID code word bits to 1. */
-               rtp_payload[6]  |= 0x6F;
-               rtp_payload[7]   = 0xFF;
-               rtp_payload[8]   = 0xFF;
-               rtp_payload[9]  |= 0x80;
-               rtp_payload[12] |= 0x3B;
-               rtp_payload[13]  = 0xFF;
-               rtp_payload[14]  = 0xFF;
-               rtp_payload[15] |= 0xE0;
-               rtp_payload[19]  = 0xFF;
-               rtp_payload[20]  = 0xFF;
-               rtp_payload[21]  = 0xFF;
-               rtp_payload[25]  = 0xFF;
-               rtp_payload[26] |= 0xFC;
-               rtp_payload[27]  = 0xFF;
-               rtp_payload[28] |= 0xC0;
+               /* "Rejuvenate" this SID frame, correcting any errors */
+               osmo_efr_sid_reset(rtp_payload);
                return true;
        default:
                /* There are only 3 possible SID classifications per GSM 06.81

--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/33059
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I1d6dd867a358bdda8850cd8c959d0f361c0a5b6d
Gerrit-Change-Number: 33059
Gerrit-PatchSet: 2
Gerrit-Owner: falconia <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: falconia <[email protected]>
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-MessageType: merged

Reply via email to