aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2022-09-06 04:55:39 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-03-09 04:08:58 +0100
commitd2d44883ac1a588b5d158f284e2b1503dd460c4a (patch)
tree90df5479141b5ce8561f6c1bf78078a130314152
parenta41bd22349416e60b826a7398716201809311675 (diff)
fix gsm0808_sc_cfg <-> gsm48_mr_cfg conversionneels/codecs
Deprecate gsm0808_sc_cfg_from_gsm48_mr_cfg() and gsm48_mr_cfg_from_gsm0808_sc_cfg(), and add new functions gsm0808_sc_cfg_from_amr_modes() and gsm0808_sc_cfg_get_best_amr_modes() to fix the behavior as follows: When the mr_cfg enables a specific rate, do not include all AMR configurations that feature this rate. Instead, enable only those configurations that are a subset of the mr_cfg. For example, in the old functions, setting only m4_75 = 1 would result in enabling all of S0, S8, S9, S10, S12, S14. S14 would allow all of 4.75k, 5.9k, 7.95k, 12.2k, instead of limiting to 4.75k only. In the new functions, do not modify the .version and .icmi members, act only on the AMR rates. Changes from old behavior to new behavior is clearly shown in tests/gsm0808/gsm0808_test.ok. Keep the deprecated functions unchanged, yielding incorrect behavior, and let the API users decide when and how to upgrade to the more sane behavior. For example, changing the behavior of existing functions in-place would have repercussions on osmo-bsc installations, where now only those AMR modes listed in the config would be used -- we are becoming stricter. Possibly this would deteriorate or break sites alone from upgrading libosmocore -- i.e. those sites that fail to list an essential AMR rate for matching with peers, but where that essential AMR rate was erratically allowed by the old behavior. The old behavior, by example of osmo-bsc: - Picking rates in osmo-bsc.cfg has non-obvious effects, often including rates that are configured as 'forbidden'. - If any of 4.75, 5.90, 7.40, 12.2 is enabled in osmo-bsc.cfg, the configuration S1 ends up enabled in s15_s0 (gsm0808_sc_cfg_from_gsm48_mr_cfg()). - In gsm48_mr_cfg_from_gsm0808_sc_cfg() used during channel activation, if S1 is present, the four rates from S1 are returned. - In summary, in the vast majority of cases, the S1 set will be used -- even if only one of its AMR rates is originally present in mr_cfg. - Configurations above S7 are ignored. The new behavior, assuming osmo-bsc moved to the more sane implementation introduced in this patch: - Only one of the rate combinations defined by S0..S15 is going to be used. This is mainly because AMR rate selections are sent to the MSC and back from the MSC in the somewhat limited S0..S15 bit form. Enabling one or more of these combinations of rates in osmo-bsc.cfg makes sense: - 4.75, 5.90, 7.40, 12.2 (S1) - 4.75, 5.90 (S8) - 4.75, 5.90, 6.70 (S9) - 4.75, 5.90, 6.70, 7.40 (S10) - 4.75, 5.90, 6.70, 10.2 (S12) - 4.75, 5.90, 7.95, 12.2 (S14) - e.g. if only 4.75 is enabled, only 4.75 is used (S0). - e.g. in case of 6.70=allowed + 7.75=allowed + 10.2=allowed, we have to choose between "only 6.70", "only 7.75", "only 10.2". On FR we'd pick S6 = "only 10.2", because it is the highest rate. So osmo-bsc.cfg should rather choose rates exactly matching a specific Sn bit, e.g. all rates of S12, to obtain a flexible variety of AMR rates. 3GPP TS 48.008 3.2.2.103 'Speech Codec List' says to this: NOTE: One of these Codec Configurations, "Config-NB-Code 1" = S1, is recommended for TrFO [Transcoder Free Operation]. S14 also seems a good choice, it is like S1 but with 7k95 instead of 7k40; 7k95 is the highest possible AMR-HR rate. It is not clear at this point why S1 seems to be preferred over S14. Ironically, the old behavior would usually end up selecting exactly S1 in almost every case, which is what 3GPP TS 48.008 3.2.2.103 recommends. This is, however, not obvious to the caller / the site admin. Related: SYS#5066 Change-Id: I900fda192742fa8f6dd54e9131ef1704b14cc41a
-rw-r--r--TODO-RELEASE4
-rw-r--r--include/osmocom/gsm/gsm0808_utils.h11
-rw-r--r--include/osmocom/gsm/protocol/gsm_04_08.h10
-rw-r--r--src/gsm/gsm0808_utils.c108
-rw-r--r--src/gsm/libosmogsm.map3
-rw-r--r--tests/gsm0808/gsm0808_test.c16
-rw-r--r--tests/gsm0808/gsm0808_test.ok229
7 files changed, 211 insertions, 170 deletions
diff --git a/TODO-RELEASE b/TODO-RELEASE
index 8ecd7a69..4002e412 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,4 +7,6 @@
# If any interfaces have been added since the last public release: c:r:a + 1.
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
-libosmogsm new header osmocom/gsm/protocol/gsm_44_060.h \ No newline at end of file
+libosmogsm new header osmocom/gsm/protocol/gsm_44_060.h
+libosmogsm gsm0808_sc_cfg_from_gsm48_mr_cfg() Deprecate; replacement is gsm0808_sc_cfg_from_amr_modes().
+libosmogsm gsm48_mr_cfg_from_gsm0808_sc_cfg() Deprecate; replacement is gsm0808_sc_cfg_get_best_amr_modes().
diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h
index 18f3ebe5..cbf42c46 100644
--- a/include/osmocom/gsm/gsm0808_utils.h
+++ b/include/osmocom/gsm/gsm0808_utils.h
@@ -149,8 +149,15 @@ int gsm0808_dec_cell_id(struct gsm0808_cell_id *ci, const uint8_t *elem, uint8_t
int gsm0808_chan_type_to_speech_codec(uint8_t perm_spch);
int gsm0808_speech_codec_from_chan_type(struct gsm0808_speech_codec *sc,
uint8_t perm_spch);
-uint16_t gsm0808_sc_cfg_from_gsm48_mr_cfg(const struct gsm48_multi_rate_conf *cfg, bool fr);
-int gsm48_mr_cfg_from_gsm0808_sc_cfg(struct gsm48_multi_rate_conf *cfg, uint16_t s15_s0);
+
+uint16_t gsm0808_sc_cfg_from_amr_modes(uint8_t modes, bool full_rate);
+uint8_t gsm0808_sc_cfg_get_all_amr_modes(uint16_t s15_s0, bool full_rate);
+uint8_t gsm0808_sc_cfg_get_best_amr_modes(uint16_t s15_s0, bool full_rate);
+
+uint16_t gsm0808_sc_cfg_from_gsm48_mr_cfg(const struct gsm48_multi_rate_conf *cfg, bool fr)
+ OSMO_DEPRECATED("use gsm0808_sc_cfg_from_amr_modes() with fixed behavior");
+int gsm48_mr_cfg_from_gsm0808_sc_cfg(struct gsm48_multi_rate_conf *cfg, uint16_t s15_s0)
+ OSMO_DEPRECATED("use gsm0808_sc_cfg_get_best_amr_modes() or gsm0808_sc_cfg_get_all_amr_modes()");
/*! \returns 3GPP TS 08.08 ยง3.2.2.5 Class of a given Cause */
static inline enum gsm0808_cause_class gsm0808_cause_class(enum gsm0808_cause cause)
diff --git a/include/osmocom/gsm/protocol/gsm_04_08.h b/include/osmocom/gsm/protocol/gsm_04_08.h
index 66aa135c..4db3e9dc 100644
--- a/include/osmocom/gsm/protocol/gsm_04_08.h
+++ b/include/osmocom/gsm/protocol/gsm_04_08.h
@@ -622,6 +622,16 @@ struct gsm48_multi_rate_conf {
#endif
} __attribute__((packed));
+static inline uint8_t gsm48_multi_rate_conf_get_amr_modes(const struct gsm48_multi_rate_conf *cfg)
+{
+ return ((uint8_t *)cfg)[1];
+}
+
+static inline void gsm48_multi_rate_conf_set_amr_modes(struct gsm48_multi_rate_conf *cfg, uint8_t modes)
+{
+ ((uint8_t *)cfg)[1] = modes;
+}
+
/* Chapter 10.5.2.28(a) */
struct gsm48_power_cmd {
#if OSMO_IS_LITTLE_ENDIAN
diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c
index efa9305f..c8037ebd 100644
--- a/src/gsm/gsm0808_utils.c
+++ b/src/gsm/gsm0808_utils.c
@@ -1657,8 +1657,104 @@ int gsm0808_speech_codec_from_chan_type(struct gsm0808_speech_codec *sc,
return 0;
}
-/*! Determine a set of AMR speech codec configuration bits (S0-S15) from a
- * given GSM 04.08 AMR configuration struct.
+/*! Determine a set of AMR speech codec configuration bits (S0-S15) from a given set of AMR modes.
+ * Enable each of the S0..S15 bits that is a subset of the given modes.
+ * In other words, there must be no S0..S15 bit enabled that includes a mode that is disabled in modes.
+ * See 3GPP TS 28.062 Table 7.11.3.1.3-2, where each column defines one of the S0..S15 bits.
+ * The bits in 'modes' are a binary match for the mX_XX flags in struct gsm48_multi_rate_conf.mX_XX.
+ *
+ * Example:
+ * uint8_t modes = gsm48_multi_rate_conf_get_amr_modes(my_cfg);
+ * uint16_t s15_s0 = gsm0808_sc_cfg_from_amr_modes(modes, full_rate);
+ *
+ * \param[in] modes Set of modes, bitmask of (1 << GSM0808_AMR_MODE_4_75) | (1 << GSM0808_AMR_MODE_5_90) | ...
+ * \param[in] full_rate When false, apply special HR AMR exceptions.
+ * \returns configuration bits (S0-S15) */
+uint16_t gsm0808_sc_cfg_from_amr_modes(uint8_t modes, bool full_rate)
+{
+ uint16_t s15_s0 = 0;
+ int s_bit;
+
+ for (s_bit = 0; s_bit < 16; s_bit++) {
+ uint8_t s_modes = gsm0808_amr_modes_from_cfg[full_rate ? 1 : 0][s_bit];
+ /* When s_modes is a non-zero subset of the input modes, add this configuration to s15_s0.
+ * Some Sn are empty, because they are not supported for HR, or not at all in GSM. */
+ if (s_modes && ((s_modes & modes) == s_modes))
+ s15_s0 |= (1 << s_bit);
+ }
+ return s15_s0;
+}
+
+/*! Return all AMR modes present in any of the given s15_s0 configurations.
+ * The returned bits are a binary match for the mX_XX flags in struct gsm48_multi_rate_conf.mX_XX.
+ *
+ * Example:
+ * uint8_t modes = gsm0808_sc_cfg_get_all_amr_modes(s15_s0, full_rate);
+ * gsm48_multi_rate_conf_set_amr_modes(&my_cfg, modes);
+ *
+ * \param[in] s15_s0 S15-S0 configuration bits, see gsm0808_amr_modes_from_cfg.
+ * \param[in] full_rate When false, return only modes compatible with HR AMR, and only observe Sn bits marked as
+ * supported by HR AMR, as in gsm0808_amr_modes_from_cfg.
+ * \return Bitmask of modes present in s15_s0, as in (1 << GSM0808_AMR_MODE_X_XX).
+ */
+uint8_t gsm0808_sc_cfg_get_all_amr_modes(uint16_t s15_s0, bool full_rate)
+{
+ uint8_t modes = 0;
+ int s_bit;
+ for (s_bit = 0; s_bit < 16; s_bit++) {
+ if (!(s15_s0 & (1 << s_bit)))
+ continue;
+ modes |= gsm0808_amr_modes_from_cfg[full_rate ? 1 : 0][s_bit];
+ }
+ return modes;
+}
+
+/*! Return "the best choice" of at most four AMR modes present in the given s15_s0 configurations.
+ * This is useful to determine which four or less modes to send in the MR CFG IE during GSM channel activation.
+ *
+ * "The best choice": return the modes for the highest Sn present in s15_s0, with these exceptions:
+ * - Skip any Sn that is not supported; e.g. HR does not support S6, and GSM never supports S11. See API doc of
+ * gsm0808_amr_modes_from_cfg for an explanation.
+ * - S1 ranks higher than S2..S9 -- S1 has a more favorable variety of rates than the latter ones.
+ *
+ * For example:
+ * - if S8 and S9 are set, return the modes for S9.
+ * - if S0 thru S9 are set, return the modes for S1 (because S1 ranks higher than S9).
+ * - if S0 thru S11 are set, return the modes for S10 (because S11 is not supported).
+ *
+ * Code example:
+ * uint8_t modes = gsm0808_sc_cfg_get_best_amr_modes(s15_s0, full_rate);
+ * gsm48_multi_rate_conf_set_amr_modes(&my_cfg, modes);
+ *
+ * \param[in] s15_s0 S15-S0 configuration bits, see gsm0808_amr_modes_from_cfg.
+ * \param[in] full_rate When false, return only modes compatible with HR AMR, and only observe Sn bits marked as
+ * supported by HR AMR, as in gsm0808_amr_modes_from_cfg.
+ * \return Bitmask of modes chosen from s15_s0, as in (1 << GSM0808_AMR_MODE_X_XX) | (1 << ...), or 0 if no modes are
+ * viable.
+ */
+uint8_t gsm0808_sc_cfg_get_best_amr_modes(uint16_t s15_s0, bool full_rate)
+{
+ /* Could skip S15, S13, S11 here, but let's rather rely on the definition of gsm0808_amr_modes_from_cfg. */
+ const int s_bit_preference[] = { 15, 14, 13, 12, 11, 10, 1, 9, 8, 7, 6, 5, 4, 3, 2, 0 };
+ int i;
+ uint8_t modes = 0;
+ for (i = 0; (!modes) && (i < ARRAY_SIZE(s_bit_preference)); i++) {
+ int s_bit = s_bit_preference[i];
+ if (!(s15_s0 & s_bit))
+ continue;
+ modes = gsm0808_amr_modes_from_cfg[full_rate ? 1 : 0][s_bit];
+ }
+ return modes;
+}
+
+/*! Deprecated, use gsm0808_sc_cfg_from_amr_modes(); The following code is an equivalent replacement for a call to
+ * s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, fr):
+ *
+ * s15_s0 = gsm0808_sc_cfg_from_amr_modes(gsm48_multi_rate_conf_get_amr_modes(cfg), fr);
+ *
+ * Determine a set of AMR speech codec configuration bits (S0-S15) from a given GSM 04.08 AMR configuration struct.
+ * Enable all those AMR configurations where at least one of its AMR rates is enabled in cfg.
+ * This is usually undesired behavior, use gsm0808_sc_cfg_from_amr_modes() instead.
* \param[in] cfg AMR configuration in GSM 04.08 format.
* \param[in] hint if the resulting configuration shall be used with a FR or HR TCH.
* \returns configuration bits (S0-S15) */
@@ -1710,7 +1806,13 @@ uint16_t gsm0808_sc_cfg_from_gsm48_mr_cfg(const struct gsm48_multi_rate_conf *cf
return s15_s0;
}
-/*! Determine a GSM 04.08 AMR configuration struct from a set of speech codec
+/*! Deprecated, use gsm0808_sc_cfg_get_best_amr_modes(); The following code is an equivalent replacement for a call to
+ * gsm48_mr_cfg_from_gsm0808_sc_cfg(cfg, s15_s0):
+ *
+ * *cfg = (struct gsm48_multi_rate_conf){ .ver = 1, .icmi = 1 };
+ * gsm48_multi_rate_conf_set_amr_modes(cfg, gsm0808_sc_cfg_get_best_amr_modes(s15_s0, true));
+ *
+ * Determine a GSM 04.08 AMR configuration struct from a set of speech codec
* configuration bits (S0-S15)
* \param[out] cfg AMR configuration in GSM 04.08 format.
* \param[in] s15_s0 configuration bits (S15-S0, non-ambiguous).
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 6795c578..74b54248 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -250,6 +250,9 @@ gsm0808_cell_ids_match;
gsm0808_cell_id_matches_list;
gsm0808_chan_type_to_speech_codec;
gsm0808_speech_codec_from_chan_type;
+gsm0808_sc_cfg_from_amr_modes;
+gsm0808_sc_cfg_get_all_amr_modes;
+gsm0808_sc_cfg_get_best_amr_modes;
gsm0808_sc_cfg_from_gsm48_mr_cfg;
gsm48_mr_cfg_from_gsm0808_sc_cfg;
gsm0808_amr_modes_from_cfg;
diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c
index aa086a23..22a126cc 100644
--- a/tests/gsm0808/gsm0808_test.c
+++ b/tests/gsm0808/gsm0808_test.c
@@ -2094,11 +2094,11 @@ static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(struct gsm48_multi_rate
printf("Input:\n");
print_mr_cfg(cfg);
- s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, true);
+ s15_s0 = gsm0808_sc_cfg_from_amr_modes(gsm48_multi_rate_conf_get_amr_modes(cfg), true);
printf("Result (fr):\n");
print_s15_s0(s15_s0, true);
- s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, false);
+ s15_s0 = gsm0808_sc_cfg_from_amr_modes(gsm48_multi_rate_conf_get_amr_modes(cfg), false);
printf("Result (hr):\n");
print_s15_s0(s15_s0, false);
@@ -2109,7 +2109,7 @@ static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg(void)
{
struct gsm48_multi_rate_conf cfg;
- printf("Testing gsm0808_sc_cfg_from_gsm48_mr_cfg():\n");
+ printf("Testing gsm0808_sc_cfg_from_amr_modes():\n");
memset(&cfg, 0, sizeof(cfg));
@@ -2297,26 +2297,22 @@ static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg(void)
static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0)
{
- struct gsm48_multi_rate_conf cfg;
- int rc;
+ struct gsm48_multi_rate_conf cfg = {};
printf("Input:\n");
print_s15_s0(s15_s0, true);
- rc = gsm48_mr_cfg_from_gsm0808_sc_cfg(&cfg, s15_s0);
+ gsm48_multi_rate_conf_set_amr_modes(&cfg, gsm0808_sc_cfg_get_best_amr_modes(s15_s0, true));
printf("Output:\n");
print_mr_cfg(&cfg);
- if (rc != 0)
- printf(" Result invalid!\n");
-
printf("\n");
}
void test_gsm48_mr_cfg_from_gsm0808_sc_cfg(void)
{
- printf("Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():\n");
+ printf("Testing gsm0808_sc_cfg_get_best_amr_modes():\n");
/* Test with settings as defined in 3GPP TS 28.062, Table 7.11.3.1.3-2,
* (up to four codecs may become selected) */
diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok
index 2329fcdc..1f862ade 100644
--- a/tests/gsm0808/gsm0808_test.ok
+++ b/tests/gsm0808/gsm0808_test.ok
@@ -85,7 +85,7 @@ test_gsm0808_enc_dec_cell_id_lai_and_lac: encoded: 05 06 04 21 63 54 23 42 (rc =
test_gsm0808_enc_dec_cell_id_ci: encoded: 05 03 02 04 23 (rc = 5)
test_gsm0808_enc_dec_cell_id_lac_and_ci: encoded: 05 05 01 04 23 02 35 (rc = 7)
test_gsm0808_enc_dec_cell_id_global: encoded: 05 08 00 21 63 54 23 42 04 23 (rc = 10)
-Testing gsm0808_sc_cfg_from_gsm48_mr_cfg():
+Testing gsm0808_sc_cfg_from_amr_modes():
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- ------- ------- ------- ------- -------
@@ -98,19 +98,11 @@ Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
m4_75=1 ------- ------- ------- ------- ------- ------- -------
Result (fr):
- S15-S0 = 0x5701 = 0b0101011100000001
+ S15-S0 = 0x0001 = 0b0000000000000001
S0 4.75
- S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x0701 = 0b0000011100000001
+ S15-S0 = 0x0001 = 0b0000000000000001
S0 4.75
- S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
@@ -124,54 +116,38 @@ Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- m5_90=1 ------- ------- ------- ------- -------
Result (fr):
- S15-S0 = 0x5704 = 0b0101011100000100
+ S15-S0 = 0x0004 = 0b0000000000000100
S2 5.90
- S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x0704 = 0b0000011100000100
+ S15-S0 = 0x0004 = 0b0000000000000100
S2 5.90
- S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- m6_70=1 ------- ------- ------- -------
Result (fr):
- S15-S0 = 0x1608 = 0b0001011000001000
+ S15-S0 = 0x0008 = 0b0000000000001000
S3 6.70
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
Result (hr):
- S15-S0 = 0x0608 = 0b0000011000001000
+ S15-S0 = 0x0008 = 0b0000000000001000
S3 6.70
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- ------- m7_40=1 ------- ------- -------
Result (fr):
- S15-S0 = 0x0410 = 0b0000010000010000
+ S15-S0 = 0x0010 = 0b0000000000010000
S4 7.40
- S10 4.75 5.90 6.70 7.40
Result (hr):
- S15-S0 = 0x0410 = 0b0000010000010000
+ S15-S0 = 0x0010 = 0b0000000000010000
S4 7.40
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- ------- ------- m7_95=1 ------- -------
Result (fr):
- S15-S0 = 0x4020 = 0b0100000000100000
+ S15-S0 = 0x0020 = 0b0000000000100000
S5 7.95
- S14 4.75 5.90 7.95 12.2
Result (hr):
S15-S0 = 0x0020 = 0b0000000000100000
S5 7.95
@@ -180,9 +156,8 @@ Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- ------- ------- ------- m10_2=1 -------
Result (fr):
- S15-S0 = 0x1040 = 0b0001000001000000
+ S15-S0 = 0x0040 = 0b0000000001000000
S6 10.2
- S12 4.75 5.90 6.70 10.2
Result (hr):
S15-S0 = 0x0000 = 0b0000000000000000
@@ -190,9 +165,8 @@ Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- ------- ------- ------- ------- m12_2=1
Result (fr):
- S15-S0 = 0x4080 = 0b0100000010000000
+ S15-S0 = 0x0080 = 0b0000000010000000
S7 12.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
S15-S0 = 0x0000 = 0b0000000000000000
@@ -200,128 +174,92 @@ Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
m4_75=1 m5_15=1 m5_90=1 m6_70=1 ------- ------- ------- -------
Result (fr):
- S15-S0 = 0x570d = 0b0101011100001101
+ S15-S0 = 0x030d = 0b0000001100001101
S0 4.75
S2 5.90
S3 6.70
S8 4.75 5.90
S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x070d = 0b0000011100001101
+ S15-S0 = 0x030d = 0b0000001100001101
S0 4.75
S2 5.90
S3 6.70
S8 4.75 5.90
S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- ------- m7_40=1 m7_95=1 m10_2=1 m12_2=1
Result (fr):
- S15-S0 = 0x54f0 = 0b0101010011110000
+ S15-S0 = 0x00f0 = 0b0000000011110000
S4 7.40
S5 7.95
S6 10.2
S7 12.2
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x0430 = 0b0000010000110000
+ S15-S0 = 0x0030 = 0b0000000000110000
S4 7.40
S5 7.95
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- m5_90=1 m6_70=1 ------- ------- m10_2=1 m12_2=1
Result (fr):
- S15-S0 = 0x57cc = 0b0101011111001100
+ S15-S0 = 0x00cc = 0b0000000011001100
S2 5.90
S3 6.70
S6 10.2
S7 12.2
- S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x070c = 0b0000011100001100
+ S15-S0 = 0x000c = 0b0000000000001100
S2 5.90
S3 6.70
- S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
m4_75=1 m5_15=1 ------- ------- m7_40=1 m7_95=1 ------- -------
Result (fr):
- S15-S0 = 0x5731 = 0b0101011100110001
+ S15-S0 = 0x0031 = 0b0000000000110001
S0 4.75
S4 7.40
S5 7.95
- S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x0731 = 0b0000011100110001
+ S15-S0 = 0x0031 = 0b0000000000110001
S0 4.75
S4 7.40
S5 7.95
- S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- m5_15=1 ------- m6_70=1 ------- m7_95=1 ------- m12_2=1
Result (fr):
- S15-S0 = 0x56a8 = 0b0101011010101000
+ S15-S0 = 0x00a8 = 0b0000000010101000
S3 6.70
S5 7.95
S7 12.2
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x0628 = 0b0000011000101000
+ S15-S0 = 0x0028 = 0b0000000000101000
S3 6.70
S5 7.95
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- m10_2=1 -------
Result (fr):
- S15-S0 = 0x5755 = 0b0101011101010101
+ S15-S0 = 0x0155 = 0b0000000101010101
S0 4.75
S2 5.90
S4 7.40
S6 10.2
S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x0717 = 0b0000011100010111
+ S15-S0 = 0x0117 = 0b0000000100010111
S0 4.75
S1 4.75 5.90 7.40
S2 5.90
S4 7.40
S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
@@ -357,51 +295,39 @@ Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Result (fr):
- S15-S0 = 0x5797 = 0b0101011110010111
+ S15-S0 = 0x0197 = 0b0000000110010111
S0 4.75
S1 4.75 5.90 7.40 12.2
S2 5.90
S4 7.40
S7 12.2
S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x0717 = 0b0000011100010111
+ S15-S0 = 0x0117 = 0b0000000100010111
S0 4.75
S1 4.75 5.90 7.40
S2 5.90
S4 7.40
S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
Input:
cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- -------
Result (fr):
- S15-S0 = 0x5715 = 0b0101011100010101
+ S15-S0 = 0x0115 = 0b0000000100010101
S0 4.75
S2 5.90
S4 7.40
S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
- S12 4.75 5.90 6.70 10.2
- S14 4.75 5.90 7.95 12.2
Result (hr):
- S15-S0 = 0x0717 = 0b0000011100010111
+ S15-S0 = 0x0117 = 0b0000000100010111
S0 4.75
S1 4.75 5.90 7.40
S2 5.90
S4 7.40
S8 4.75 5.90
- S9 4.75 5.90 6.70
- S10 4.75 5.90 6.70 7.40
-Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():
+Testing gsm0808_sc_cfg_get_best_amr_modes():
Input:
S15-S0 = 0xff03 = 0b1111111100000011
S0 4.75
@@ -415,15 +341,14 @@ Input:
S14 4.75 5.90 7.95 12.2
S15 (empty)
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0000 = 0b0000000000000000
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- ------- ------- ------- ------- -------
- Result invalid!
Input:
S15-S0 = 0xff06 = 0b1111111100000110
@@ -438,8 +363,8 @@ Input:
S14 4.75 5.90 7.95 12.2
S15 (empty)
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x3e08 = 0b0011111000001000
@@ -450,8 +375,8 @@ Input:
S12 4.75 5.90 6.70 10.2
S13 (empty)
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- m6_70=1 ------- ------- ------- -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0c12 = 0b0000110000010010
@@ -460,8 +385,8 @@ Input:
S10 4.75 5.90 6.70 7.40
S11 (empty)
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0xc020 = 0b1100000000100000
@@ -469,8 +394,8 @@ Input:
S14 4.75 5.90 7.95 12.2
S15 (empty)
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- ------- ------- m7_95=1 ------- -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- ------- -------
Input:
S15-S0 = 0x3040 = 0b0011000001000000
@@ -478,8 +403,8 @@ Input:
S12 4.75 5.90 6.70 10.2
S13 (empty)
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- ------- ------- ------- m10_2=1 -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- ------- -------
Input:
S15-S0 = 0xc082 = 0b1100000010000010
@@ -488,64 +413,64 @@ Input:
S14 4.75 5.90 7.95 12.2
S15 (empty)
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0001 = 0b0000000000000001
S0 4.75
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- ------- ------- ------- ------- ------- -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Input:
S15-S0 = 0x0002 = 0b0000000000000010
S1 4.75 5.90 7.40 12.2
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0004 = 0b0000000000000100
S2 5.90
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- m5_90=1 ------- ------- ------- ------- -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0008 = 0b0000000000001000
S3 6.70
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- m6_70=1 ------- ------- ------- -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0010 = 0b0000000000010000
S4 7.40
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- ------- m7_40=1 ------- ------- -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- ------- -------
Input:
S15-S0 = 0x0020 = 0b0000000000100000
S5 7.95
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- ------- ------- m7_95=1 ------- -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- ------- -------
Input:
S15-S0 = 0x0040 = 0b0000000001000000
S6 10.2
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- ------- ------- ------- m10_2=1 -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- ------- -------
Input:
S15-S0 = 0x0080 = 0b0000000010000000
S7 12.2
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- ------- ------- ------- ------- m12_2=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ ------- ------- ------- ------- ------- ------- ------- -------
Input:
S15-S0 = 0x0058 = 0b0000000001011000
@@ -553,24 +478,24 @@ Input:
S4 7.40
S6 10.2
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- ------- m6_70=1 m7_40=1 ------- m10_2=1 -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0021 = 0b0000000000100001
S0 4.75
S5 7.95
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- ------- ------- ------- m7_95=1 ------- -------
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
Input:
S15-S0 = 0x0084 = 0b0000000010000100
S2 5.90
S7 12.2
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- ------- ------- m5_90=1 ------- ------- ------- ------- m12_2=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0086 = 0b0000000010000110
@@ -578,17 +503,16 @@ Input:
S2 5.90
S7 12.2
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x000a = 0b0000000000001010
S1 4.75 5.90 7.40 12.2
S3 6.70
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
- Result invalid!
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0079 = 0b0000000001111001
@@ -598,16 +522,14 @@ Input:
S5 7.95
S6 10.2
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- ------- m6_70=1 m7_40=1 m7_95=1 ------- -------
- Result invalid!
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
Input:
S15-S0 = 0x0000 = 0b0000000000000000
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
------- ------- ------- ------- ------- ------- ------- -------
- Result invalid!
Input:
S15-S0 = 0xffff = 0b1111111111111111
@@ -628,9 +550,8 @@ Input:
S14 4.75 5.90 7.95 12.2
S15 (empty)
Output:
- cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1
- m4_75=1 ------- m5_90=1 ------- m7_40=1 ------- ------- m12_2=1
- Result invalid!
+ cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0
+ m4_75=1 ------- m5_90=1 ------- ------- m7_95=1 ------- m12_2=1
test_cell_id_matching