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