aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-07-24 21:24:29 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-07-25 09:22:29 +0200
commit3674645e20d23d37269ee9226363f94bbde4b5c6 (patch)
tree712207c7fdbfbbf2d1ff062bf2ecbcfa6a5b61ba
parenta2b806c375dc6b3e3b7df0496e06b34b1520bd1b (diff)
amr: Avoid toggling the CMR from none and a set one
For LCR and other systems without out-of-band information we need to indicate the CMR. Not every air message will include the mode and we sent a stream that had the CMR set and not-set. This lead to the AudioCodes MGW only playing every second frame. Remember the last used mode and initialize it to _NONE when we receive the multirate config. In case of a real error we will still use AMR_CMR_NONE. The initial patch is from Harald. I have added the initialization and moving of the defines to amr.h. Manually verified by enabling AMR5.9 and looking at two RTP packages in sequence. In both cases the CMR was 2. I have looked at "amr.nb.cmr != 2" in wireshark and only found the MGCP dummy packet.
-rw-r--r--include/osmo-bts/amr.h3
-rw-r--r--src/common/rsl.c2
-rw-r--r--src/osmo-bts-sysmo/tch.c18
3 files changed, 14 insertions, 9 deletions
diff --git a/include/osmo-bts/amr.h b/include/osmo-bts/amr.h
index 059f2e0..ba66e4d 100644
--- a/include/osmo-bts/amr.h
+++ b/include/osmo-bts/amr.h
@@ -3,6 +3,9 @@
#include <osmo-bts/gsm_data.h>
+#define AMR_TOC_QBIT 0x04
+#define AMR_CMR_NONE 0xF
+
void amr_log_mr_conf(int ss, int logl, const char *pfx,
struct amr_multirate_conf *amr_mrc);
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 6b683bd..bc7fddb 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -811,6 +811,7 @@ static int rsl_rx_chan_activ(struct msgb *msg)
TLVP_LEN(&tp, RSL_IE_MR_CONFIG));
amr_log_mr_conf(DRTP, LOGL_DEBUG, gsm_lchan_name(lchan),
&lchan->tch.amr_mr);
+ lchan->tch.last_cmr = AMR_CMR_NONE;
}
/* 9.3.53 MultiRate Control */
/* 9.3.54 Supported Codec Types */
@@ -1067,6 +1068,7 @@ static int rsl_rx_mode_modif(struct msgb *msg)
TLVP_LEN(&tp, RSL_IE_MR_CONFIG));
amr_log_mr_conf(DRTP, LOGL_DEBUG, gsm_lchan_name(lchan),
&lchan->tch.amr_mr);
+ lchan->tch.last_cmr = AMR_CMR_NONE;
}
/* 9.3.53 MultiRate Control */
/* 9.3.54 Supported Codec Types */
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index 88c0754..c3c6ca3 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -39,6 +39,7 @@
#include <osmo-bts/bts.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/measurement.h>
+#include <osmo-bts/amr.h>
#include <sysmocom/femtobts/superfemto.h>
#include <sysmocom/femtobts/gsml1prim.h>
@@ -240,12 +241,10 @@ static int rtppayload_to_l1_hr(uint8_t *l1_payload, const uint8_t *rtp_payload,
return GSM_HR_BYTES;
}
-#define AMR_TOC_QBIT 0x04
-#define AMR_CMR_NONE 0xF
-
static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_len,
- struct amr_multirate_conf *amr_mrc)
+ struct gsm_lchan *lchan)
{
+ struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr;
struct msgb *msg;
uint8_t amr_if2_len = payload_len - 2;
uint8_t *cur;
@@ -262,14 +261,16 @@ static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_le
uint8_t ft = l1_payload[2] & 0xF;
uint8_t cmr_idx = l1_payload[1];
/* CMR == Unset means CMR was not transmitted at this TDMA */
- if (cmr_idx >= GsmL1_AmrCodecMode_Unset)
- cmr = AMR_CMR_NONE;
- else if (cmr_idx >= amr_mrc->num_modes) {
+ if (cmr_idx == GsmL1_AmrCodecMode_Unset)
+ cmr = lchan->tch.last_cmr;
+ else if (cmr_idx >= amr_mrc->num_modes ||
+ cmr_idx > GsmL1_AmrCodecMode_Unset) {
/* Make sure the CMR of the phone is in the active codec set */
LOGP(DL1C, LOGL_NOTICE, "L1->RTP: overriding CMR IDX %u\n", cmr_idx);
cmr = AMR_CMR_NONE;
} else {
cmr = amr_mrc->mode[cmr_idx].mode;
+ lchan->tch.last_cmr = cmr;
}
/* RFC 3267 4.4.1 Payload Header */
@@ -606,8 +607,7 @@ int l1if_tch_rx(struct gsm_lchan *lchan, struct msgb *l1p_msg)
break;
#endif
case GsmL1_TchPlType_Amr:
- rmsg = l1_to_rtppayload_amr(payload, payload_len,
- &lchan->tch.amr_mr);
+ rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
break;
}