DTXd and SID logic is broken for non-AMR codecs
For non-AMR codecs the rules for SID transmission on the downlink are given in TS 46.031 for FR1 and GSM 06.81 for EFR, chapter 5 in both specs, particular emphasis on section 5.1.2. The desired behavior is as follows:
1. If the source feeding codec frames in RTP packets to the GSM RAN sends a new SID frame every 20 ms for the entire duration of every speech pause, mimicking the behavior of TDM-based TRAUs, the BTS needs to select which of these SIDs to transmit and drop the others, following the rules of section 5.1.2: transmit the first SID after non-SID speech frames, and transmit those SIDs which happen to fall into SACCH-aligned frame number positions.
2. If the RTP source sends a SID followed by gaps (no RTP transmission or BFI packets), as is expected to happen when this RTP stream comes from the UL of another GSM call (TrFO), the BTS needs to transmit the first received SID if it comes after a non-SID speech frame, but it also needs to remember this SID so it can be retransmitted if no new SID arrives in the SACCH-aligned frame number slot.
3. Rules 1 and 2 above need to be combined if the RTP source is a mixture of SID frames and frame gaps, but with source SID frames not aligning with the downlink SACCH multiframe. The most sensible way to combine these rules would be to first replace RTP Rx frame gaps with copies of the last SID if they do follow a valid SID (copy this last SID into immediately following frame gaps), and then apply the "filtering" rules of section 5.1.2 when deciding which frames should actually be transmitted on the air.
Furthermore, we need to consider what should be done when the RTP stream hitting the BTS contains SID frames even though DTXd is disabled. Per classic GSM specs this condition is a "should never happen", but actually making this condition not-happen (by implementing the logic of TS 28.062 section C.22.214.171.124) would be extremely difficult for EFR and HR1 (though easy for FR1), hence I propose that we cheat a little: have the BTS apply exactly the same logic in the presence of SID frames in its RTP input irrespective of whether DTXd is enabled or disabled, and in the case of DTXd being disabled, do a "fake DTXd" by transmitting dummy FACCH (an L2 fill frame) during those times when Tx would be physically turned off if DTXd were possible and enabled.
The present code fails to do most of the above:
1. osmo-bts-sysmo implements a SID catcher in the DL, repeating the last captured SID in the SACCH-aligned frame number position, but this logic is disabled when DTXd is disabled, resulting in the PHY getting an empty message instead of SID transmission in those SACCH-aligned positions, and resulting in the MS receiving a BFI there, causing its "lost SID" logic to kick in prematurely.
2. Even if one were to enable DTXd in osmo-bts-sysmo, that DL SID catcher logic is broken for non-AMR codecs: it will only save the first 20 bytes of the SID frame (out of 33 for FR or 31 for EFR), and then try to retransmit (send to the PHY) a truncated 20-byte SID frame in the SACCH-aligned position. It is unknown what the proprietary PHY will do with such an invalid, truncated FR or EFR SID frame.
3. osmo-bts-trx has no DTXd support at all, but more importantly, it has no DL SID handling logic, which is needed even in the absence of DTXd. The end effect on the shape of the transmitted DL and on the GSM MS will be the same as with problem point 1 above, osmo-bts-sysmo with DTXd disabled.
4. If the RTP source sends a new SID every 20 ms throughout pause periods and DTXd is enabled and supported by the BTS model, this DTXd will be defeated (radio Tx will never be cut) because the SID "filtering" logic of TS 46.031 section 5.1.2 is missing.
5. Like the previous point, but with DTXd disabled: having SID transmitted in every frame position, instead of having dummy FACCH inserted as "fake DTXd" in those frame positions where section 5.1.2 says "no Tx", will mess up the spec-compliant Rx DTX handler in the MS, particularly its SID update and interpolation logic.
I have a plan in mind for how to fix this bug and implement all desired functionality as outlined here, but it is currently blocked waiting for resolution of this libosmocodec patch and its prerequisites:
- Status changed from New to In Progress
- Assignee set to falconia
- % Done changed from 0 to 30
I have a partial fix for this bug on branch falconia/os5996. This fix should be correct and complete for osmo-bts-trx, but I don't have a solution yet for osmo-bts-sysmo. For the sysmo version, my difficulty is that I don't understand how the proprietary PHY handles the step of combining TCH with FACCH on the DL. With osmo-bts-trx it is obvious: we have code in tch_dl_dequeue() that explicitly prioritizes FACCH over speech traffic, we know when we are transmitting one or the other, and we can handle any corner cases that may arise. But in the sysmo version I can only assume that this combining must be happening in the PHY - is that the case? Does that femtobts PHY likewise prioritize FACCH over speech traffic? Does it mean that some TCH frames sent to the PHY won't actually be transmitted on the air because the PHY decides to schedule FACCH there instead?
Why does this FACCH business matter? The rules of section 5.1.2 in GSM 06.31 & 06.81 say that only one SID frame is to be transmitted after a talkspurt (after speech frames), plus one SID frame in each SACCH-aligned position every 480 ms. But what if that position (whether SACCH-aligned or right after a talkspurt) is taken up by FACCH? In that case the specs say that the next SID frame should be transmitted in the place of the FACCH-stolen one. Implementing this logic requires knowing when a FACCH frame has been transmitted - easy for osmo-bts-trx - but how would we implement the same logic in the sysmo version? Help and ideas will be appreciated.
- Status changed from In Progress to Feedback
- % Done changed from 30 to 80
I have a new solution for this bug:
Unlike my previous solution on falconia/os5996 branch, this new solution is fully contained in the common part and thus independent of BTS model. It works as intended on my sysmoBTS.
- Status changed from Feedback to Resolved
- % Done changed from 80 to 100
A complete fix has now been merged into osmo-bts master: