diff --git a/TODO-RELEASE b/TODO-RELEASE index 8ccfa491e..d5bde1a65 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -7,3 +7,5 @@ # 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 gsm0808_sc_cfg_from_gsm48_mr_cfg() Deprecate; replacement is gsm0808_sc_cfg_from_modes(). +libosmogsm gsm48_mr_cfg_from_gsm0808_sc_cfg() Deprecate; replacement is gsm0808_sc_cfg_get_best_modes(). diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 6abfeecc4..42d42cced 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -144,8 +144,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_modes(uint8_t modes, bool full_rate); +uint8_t gsm0808_sc_cfg_get_all_modes(uint16_t s15_s0, bool full_rate); +uint8_t gsm0808_sc_cfg_get_best_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_gsm48_mr_cfg2() with fixed behavior"); +int gsm48_mr_cfg_from_gsm0808_sc_cfg(struct gsm48_multi_rate_conf *cfg, uint16_t s15_s0) + OSMO_DEPRECATED("use gsm48_mr_cfg_from_gsm0808_sc_cfg_all() or gsm48_mr_cfg_from_gsm0808_sc_cfg_four"); /*! \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 ea77e764b..1c446d9ac 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_modes(const struct gsm48_multi_rate_conf *cfg) +{ + return ((uint8_t *)cfg)[1]; +} + +static inline void gsm48_multi_rate_conf_set_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 f1569c90c..e963313e5 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -1588,8 +1588,96 @@ 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_modes(my_cfg); + * uint16_t s15_s0 = gsm0808_sc_cfg_from_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_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 cfg_modes, add this configuration to s15_s0. */ + 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_modes(s15_s0, full_rate); + * gsm48_multi_rate_conf_set_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_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 & 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 modes to send in the MR CFG IE during GSM channel activation. + * + * "The best choice": return the modes for the highest bit present in s15_s0 (that is supported / is non-empty), with + * the exception: favor S1 over S0, S2..S9 -- S1 has a more favorable variety of rates than the latter ones. + * + * Apply limitations of GSM, according to full_rate; see gsm0808_amr_modes_from_cfg for an explanation. + * + * Example: + * uint8_t modes = gsm0808_sc_cfg_get_four_modes(s15_s0, full_rate); + * gsm48_multi_rate_conf_set_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). + */ +uint8_t gsm0808_sc_cfg_get_best_modes(uint16_t s15_s0, bool full_rate) +{ + 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_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_modes(gsm48_multi_rate_conf_get_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_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) */ @@ -1641,7 +1729,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_modes(); The following code is an equivalent replacement for a call to + * gsm0808_sc_cfg_get_best_modes(cfg, s15_s0): + * + * *cfg = (struct gsm48_multi_rate_conf){ .ver = 1, .icmi = 1 }; + * gsm48_multi_rate_conf_set_modes(cfg, gsm0808_sc_cfg_get_best_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 aa5df90b8..91db8016b 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -244,6 +244,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_modes; +gsm0808_sc_cfg_get_all_modes; +gsm0808_sc_cfg_get_best_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 1ab836d1d..193027c35 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -1940,11 +1940,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_modes(gsm48_multi_rate_conf_get_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_modes(gsm48_multi_rate_conf_get_modes(cfg), false); printf("Result (hr):\n"); print_s15_s0(s15_s0, false); @@ -1955,7 +1955,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_modes():\n"); memset(&cfg, 0, sizeof(cfg)); @@ -2144,25 +2144,21 @@ 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; 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_modes(&cfg, gsm0808_sc_cfg_get_best_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() { - printf("Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():\n"); + printf("Testing gsm0808_sc_cfg_get_best_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 74baacac4..dd1387b9b 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_modes(): Input: cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0 m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=0 @@ -98,19 +98,11 @@ Input: cfg.smod=0 spare=0 icmi=0 nscb=0 ver=0 m4_75=1 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=0 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 m4_75=0 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=0 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 m4_75=0 m5_15=0 m5_90=0 m6_70=1 m7_40=0 m7_95=0 m10_2=0 m12_2=0 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 m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=0 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 m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=1 m10_2=0 m12_2=0 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 m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=1 m12_2=0 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 m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=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 m7_40=0 m7_95=0 m10_2=0 m12_2=0 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 m4_75=0 m5_15=0 m5_90=0 m6_70=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 m4_75=0 m5_15=0 m5_90=1 m6_70=1 m7_40=0 m7_95=0 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 m5_90=0 m6_70=0 m7_40=1 m7_95=1 m10_2=0 m12_2=0 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 m4_75=0 m5_15=1 m5_90=0 m6_70=1 m7_40=0 m7_95=1 m10_2=0 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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=1 m12_2=0 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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=0 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_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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=1 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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=1 m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=1 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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 - m4_75=0 m5_15=0 m5_90=0 m6_70=1 m7_40=0 m7_95=0 m10_2=0 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=1 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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 - m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=1 m10_2=0 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=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 - m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=1 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=1 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=1 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 m12_2=1 Input: S15-S0 = 0x0004 = 0b0000000000000100 S2 5.90 Output: - cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1 - m4_75=0 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 m12_2=1 Input: S15-S0 = 0x0008 = 0b0000000000001000 S3 6.70 Output: - cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1 - m4_75=0 m5_15=0 m5_90=0 m6_70=1 m7_40=0 m7_95=0 m10_2=0 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 m12_2=1 Input: S15-S0 = 0x0010 = 0b0000000000010000 S4 7.40 Output: - cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1 - m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=0 Input: S15-S0 = 0x0020 = 0b0000000000100000 S5 7.95 Output: - cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1 - m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=1 m10_2=0 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=0 Input: S15-S0 = 0x0040 = 0b0000000001000000 S6 10.2 Output: - cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1 - m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=1 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=0 Input: S15-S0 = 0x0080 = 0b0000000010000000 S7 12.2 Output: - cfg.smod=0 spare=0 icmi=1 nscb=0 ver=1 - m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=1 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=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 - m4_75=0 m5_15=0 m5_90=0 m6_70=1 m7_40=1 m7_95=0 m10_2=1 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=1 m10_2=0 m12_2=0 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 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 - m4_75=0 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=1 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=1 + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=1 - Result invalid! + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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 m5_15=0 m5_90=0 m6_70=1 m7_40=1 m7_95=1 m10_2=0 m12_2=0 - Result invalid! + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 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=1 m4_75=0 m5_15=0 m5_90=0 m6_70=0 m7_40=0 m7_95=0 m10_2=0 m12_2=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_15=0 m5_90=1 m6_70=0 m7_40=1 m7_95=0 m10_2=0 m12_2=1 - Result invalid! + cfg.smod=0 spare=0 icmi=0 nscb=0 ver=1 + m4_75=1 m5_15=0 m5_90=1 m6_70=0 m7_40=0 m7_95=1 m10_2=0 m12_2=1 test_cell_id_matching