aboutsummaryrefslogtreecommitdiffstats
path: root/tests/gsm0408/gsm0408_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/gsm0408/gsm0408_test.c')
-rw-r--r--tests/gsm0408/gsm0408_test.c563
1 files changed, 524 insertions, 39 deletions
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index d2ae6f6c..8a89357c 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -35,40 +31,96 @@
#include <osmocom/core/msgb.h>
-static const uint8_t csd_9600_v110_lv[] = { 0x07, 0xa1, 0xb8, 0x89, 0x21, 0x15, 0x63, 0x80 };
+static const uint8_t csd_9600_v110_lv[] = { 0x07, 0xa1, 0x88, 0x89, 0x21, 0x15, 0x63, 0x80 };
static const struct gsm_mncc_bearer_cap bcap_csd_9600_v110 = {
- .transfer = GSM48_BCAP_ITCAP_UNR_DIG_INF,
- .mode = GSM48_BCAP_TMOD_CIRCUIT,
- .coding = GSM48_BCAP_CODING_GSM_STD,
- .radio = GSM48_BCAP_RRQ_FR_ONLY,
- .speech_ver[0]= -1,
+ .transfer = GSM48_BCAP_ITCAP_UNR_DIG_INF,
+ .mode = GSM48_BCAP_TMOD_CIRCUIT,
+ .coding = GSM48_BCAP_CODING_GSM_STD,
+ .radio = GSM48_BCAP_RRQ_FR_ONLY,
+ .speech_ver[0] = -1,
.data = {
- .rate_adaption = GSM48_BCAP_RA_V110_X30,
- .sig_access = GSM48_BCAP_SA_I440_I450,
- .async = 1,
- .nr_stop_bits = 1,
- .nr_data_bits = 8,
- .user_rate = GSM48_BCAP_UR_9600,
- .parity = GSM48_BCAP_PAR_NONE,
- .interm_rate = GSM48_BCAP_IR_16k,
- .transp = GSM48_BCAP_TR_TRANSP,
- .modem_type = GSM48_BCAP_MT_NONE,
+ .rate_adaption = GSM48_BCAP_RA_V110_X30,
+ .sig_access = GSM48_BCAP_SA_I440_I450,
+ .async = 1,
+ .nr_stop_bits = 1,
+ .nr_data_bits = 8,
+ .user_rate = GSM48_BCAP_UR_9600,
+ .parity = GSM48_BCAP_PAR_NONE,
+ .interm_rate = GSM48_BCAP_IR_16k,
+ .transp = GSM48_BCAP_TR_TRANSP,
+ .modem_type = GSM48_BCAP_MT_NONE,
+ },
+};
+
+static const uint8_t csd_4800_rlp_lv[] = { 0x07, 0xa1, 0x88, 0x89, 0x21, 0x14, 0x63, 0xa0 };
+
+static const struct gsm_mncc_bearer_cap bcap_csd_4800_rlp = {
+ .transfer = GSM48_BCAP_ITCAP_UNR_DIG_INF,
+ .mode = GSM48_BCAP_TMOD_CIRCUIT,
+ .coding = GSM48_BCAP_CODING_GSM_STD,
+ .radio = GSM48_BCAP_RRQ_FR_ONLY,
+ .speech_ver[0] = -1,
+ .data = {
+ .rate_adaption = GSM48_BCAP_RA_V110_X30,
+ .sig_access = GSM48_BCAP_SA_I440_I450,
+ .async = 1,
+ .nr_stop_bits = 1,
+ .nr_data_bits = 8,
+ .user_rate = GSM48_BCAP_UR_4800,
+ .parity = GSM48_BCAP_PAR_NONE,
+ .interm_rate = GSM48_BCAP_IR_16k,
+ .transp = GSM48_BCAP_TR_RLP,
+ .modem_type = GSM48_BCAP_MT_NONE,
+ },
+};
+
+static const uint8_t csd_2400_v22bis_lv[] = { 0x07, 0xa2, 0xb8, 0x81, 0x21, 0x13, 0x43, 0x83 };
+
+static const struct gsm_mncc_bearer_cap bcap_csd_2400_v22bis = {
+ .transfer = GSM48_BCAP_ITCAP_3k1_AUDIO,
+ .mode = GSM48_BCAP_TMOD_CIRCUIT,
+ .coding = GSM48_BCAP_CODING_GSM_STD,
+ .radio = GSM48_BCAP_RRQ_FR_ONLY,
+ .speech_ver[0] = -1,
+ .data = {
+ .rate_adaption = GSM48_BCAP_RA_NONE,
+ .sig_access = GSM48_BCAP_SA_I440_I450,
+ .async = 1,
+ .nr_stop_bits = 1,
+ .nr_data_bits = 8,
+ .user_rate = GSM48_BCAP_UR_2400,
+ .parity = GSM48_BCAP_PAR_NONE,
+ .interm_rate = GSM48_BCAP_IR_8k,
+ .transp = GSM48_BCAP_TR_TRANSP,
+ .modem_type = GSM48_BCAP_MT_V22bis,
},
};
static const uint8_t speech_all_lv[] = { 0x06, 0x60, 0x04, 0x02, 0x00, 0x05, 0x81 };
static const struct gsm_mncc_bearer_cap bcap_speech_all = {
- .transfer = GSM48_BCAP_ITCAP_SPEECH,
- .mode = GSM48_BCAP_TMOD_CIRCUIT,
- .coding = GSM48_BCAP_CODING_GSM_STD,
- .radio = GSM48_BCAP_RRQ_DUAL_FR,
+ .transfer = GSM48_BCAP_ITCAP_SPEECH,
+ .mode = GSM48_BCAP_TMOD_CIRCUIT,
+ .coding = GSM48_BCAP_CODING_GSM_STD,
+ .radio = GSM48_BCAP_RRQ_DUAL_FR,
.speech_ver = {
4, 2, 0, 5, 1, -1,
},
};
+static const uint8_t speech_no3a_lv[] = { 0x01, 0xa0 };
+
+static const struct gsm_mncc_bearer_cap bcap_speech_no3a = {
+ .transfer = GSM48_BCAP_ITCAP_SPEECH,
+ .mode = GSM48_BCAP_TMOD_CIRCUIT,
+ .coding = GSM48_BCAP_CODING_GSM_STD,
+ .radio = GSM48_BCAP_RRQ_FR_ONLY,
+ .speech_ver = {
+ 0, -1,
+ },
+};
+
struct bcap_test {
const uint8_t *lv;
@@ -78,16 +130,22 @@ struct bcap_test {
static const struct bcap_test bcap_tests[] = {
{ csd_9600_v110_lv, &bcap_csd_9600_v110, "CSD 9600/V.110/transparent" },
+ { csd_4800_rlp_lv, &bcap_csd_4800_rlp, "CSD 4800/RLP/non-transparent" },
+ { /* XXX: this testcase is expected to fail because octet 4 is not represented in
+ * 'struct gsm_mncc_bearer_cap' and the encoder unconditionally hard-codes it to 0x88. */
+ csd_2400_v22bis_lv, &bcap_csd_2400_v22bis, "CSD 2400/V.22bis/transparent" },
{ speech_all_lv, &bcap_speech_all, "Speech, all codecs" },
+ { speech_no3a_lv, &bcap_speech_no3a, "Speech, without octet 3a" },
};
-static int test_bearer_cap()
+static int test_bearer_cap(void)
{
struct gsm_mncc_bearer_cap bc;
int i, rc;
for (i = 0; i < ARRAY_SIZE(bcap_tests); i++) {
struct msgb *msg = msgb_alloc(100, "test");
+ bool pass = false;
int lv_len;
memset(&bc, 0, sizeof(bc));
@@ -97,7 +155,7 @@ static int test_bearer_cap()
if (rc < 0) {
fprintf(stderr, "Error decoding %s\n",
bcap_tests[i].name);
- return rc;
+ goto verdict;
}
if (memcmp(&bc, bcap_tests[i].bc, sizeof(bc))) {
fprintf(stderr, "Incorrect decoded result of %s:\n",
@@ -106,7 +164,7 @@ static int test_bearer_cap()
osmo_hexdump((uint8_t *) bcap_tests[i].bc, sizeof(bc)));
fprintf(stderr, " is: %s\n",
osmo_hexdump((uint8_t *) &bc, sizeof(bc)));
- return -1;
+ goto verdict;
}
/* also test re-encode? */
@@ -114,7 +172,7 @@ static int test_bearer_cap()
if (rc < 0) {
fprintf(stderr, "Error encoding %s\n",
bcap_tests[i].name);
- return rc;
+ goto verdict;
}
lv_len = bcap_tests[i].lv[0]+1;
if (memcmp(msg->data, bcap_tests[i].lv, lv_len)) {
@@ -124,10 +182,14 @@ static int test_bearer_cap()
osmo_hexdump(bcap_tests[i].lv, lv_len));
fprintf(stderr, " is: %s\n",
osmo_hexdump(msg->data, msg->len));
- return -1;
+ goto verdict;
}
- printf("Test `%s' passed\n", bcap_tests[i].name);
+ /* all checks passed */
+ pass = true;
+
+verdict:
+ printf("Test `%s' %sed\n", bcap_tests[i].name, pass ? "pass" : "fail");
msgb_free(msg);
}
@@ -327,6 +389,368 @@ static void test_lai_encode_decode(void)
}
}
+static struct osmo_routing_area_id test_osmo_routing_area_id_items[] = {
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 77,
+ .mnc = 121,
+ },
+ .lac = 666,
+ },
+ .rac = 5,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 84,
+ .mnc = 98,
+ },
+ .lac = 11,
+ },
+ .rac = 89,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 0,
+ .mnc = 0,
+ .mnc_3_digits = false,
+ /* expecting 000-00, BCD = 00 f0 00 */
+ },
+ .lac = 0,
+ },
+ .rac = 0,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 0,
+ .mnc = 0,
+ .mnc_3_digits = true,
+ /* expecting 000-000, BCD = 00 00 00 */
+ },
+ .lac = 0,
+ },
+ .rac = 0,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 999,
+ .mnc = 999,
+ },
+ .lac = 65535,
+ },
+ .rac = 255,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 1,
+ .mnc = 2,
+ .mnc_3_digits = false,
+ /* expecting 001-02, BCD = 00 f1 20 */
+ },
+ .lac = 23,
+ },
+ .rac = 42,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 1,
+ .mnc = 2,
+ .mnc_3_digits = true,
+ /* expecting 001-002, BCD = 00 21 00 */
+ },
+ .lac = 23,
+ },
+ .rac = 42,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 12,
+ .mnc = 34,
+ .mnc_3_digits = false,
+ /* expecting 012-34, BCD = 10 f2 43 */
+ },
+ .lac = 56,
+ },
+ .rac = 78,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 12,
+ .mnc = 34,
+ .mnc_3_digits = true,
+ /* expecting 012-034, BCD = 10 42 30 */
+ },
+ .lac = 23,
+ },
+ .rac = 42,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 123,
+ .mnc = 456,
+ .mnc_3_digits = false,
+ /* expecting 123-456, BCD = 21 63 54 (false flag has no effect) */
+ },
+ .lac = 23,
+ },
+ .rac = 42,
+ },
+ {
+ .lac = {
+ .plmn = {
+ .mcc = 123,
+ .mnc = 456,
+ .mnc_3_digits = true,
+ /* expecting 123-456, BCD = 21 63 54 (same) */
+ },
+ .lac = 23,
+ },
+ .rac = 42,
+ },
+};
+
+static inline void dump_osmo_routing_area_id(const struct osmo_routing_area_id *raid)
+{
+ printf("%s%s", osmo_rai_name2(raid), raid->lac.plmn.mnc_3_digits ? " (3-digit MNC)" : "");
+}
+
+static inline void check_osmo_routing_area_id(const struct osmo_routing_area_id *raid)
+{
+ uint8_t buf[sizeof(struct gsm48_ra_id)] = {};
+ struct osmo_routing_area_id raid0 = {};
+ int rc;
+
+ printf("RA ID: ");
+ dump_osmo_routing_area_id(raid);
+
+ rc = osmo_routing_area_id_encode_buf(buf, sizeof(buf), raid);
+ printf("osmo_routing_area_id_encode_buf(): %src=%d\n", osmo_hexdump(buf, sizeof(buf)), rc);
+
+ rc = osmo_routing_area_id_decode(&raid0, buf, sizeof(buf));
+ printf("osmo_routing_area_id_decode(): ");
+ dump_osmo_routing_area_id(&raid0);
+ printf(" rc=%d\n", rc);
+
+ if (osmo_rai_cmp(raid, &raid0))
+ printf("FAIL\n");
+ else
+ printf("ok\n");
+}
+
+static void test_osmo_routing_area_id(void)
+{
+ int i;
+ printf("==%s()==\n", __func__);
+ for (i = 0; i < ARRAY_SIZE(test_osmo_routing_area_id_items); i++)
+ check_osmo_routing_area_id(&test_osmo_routing_area_id_items[i]);
+}
+
+static void dump_cm3(struct gsm48_classmark3 *cm3)
+{
+ printf("mult_band_supp=%02x\n", cm3->mult_band_supp);
+ printf("a5_bits=%02x\n", cm3->a5_bits);
+ printf("assoc_radio_cap_1=%02x\n", cm3->assoc_radio_cap_1);
+ printf("assoc_radio_cap_2=%02x\n", cm3->assoc_radio_cap_2);
+ printf("\n");
+ printf("r_support.present=%u\n", cm3->r_support.present);
+ printf("r_support.r_gsm_assoc_radio_cap=%02x\n",
+ cm3->r_support.r_gsm_assoc_radio_cap);
+ printf("\n");
+ printf("hscsd_mult_slot_cap.present=%u\n",
+ cm3->hscsd_mult_slot_cap.present);
+ printf("hscsd_mult_slot_cap.mslot_class=%02x\n",
+ cm3->hscsd_mult_slot_cap.mslot_class);
+ printf("\n");
+ printf("ucs2_treatment=%u\n", cm3->ucs2_treatment);
+ printf("extended_meas_cap=%u\n", cm3->extended_meas_cap);
+ printf("\n");
+ printf("ms_meas_cap.present=%u\n", cm3->ms_meas_cap.present);
+ printf("ms_meas_cap.sms_value=%02x\n", cm3->ms_meas_cap.sms_value);
+ printf("ms_meas_cap.sm_value=%02x\n", cm3->ms_meas_cap.sm_value);
+ printf("\n");
+ printf("ms_pos_method_cap.present=%u\n",
+ cm3->ms_pos_method_cap.present);
+ printf("ms_pos_method_cap.method=%02x\n",
+ cm3->ms_pos_method_cap.method);
+ printf("\n");
+ printf("ecsd_multislot_cap.present=%u\n",
+ cm3->ecsd_multislot_cap.present);
+ printf("ecsd_multislot_cap.mslot_class=%02x\n",
+ cm3->ecsd_multislot_cap.mslot_class);
+ printf("\n");
+ printf("psk8_struct.present=%u\n", cm3->psk8_struct.present);
+ printf("psk8_struct.mod_cap=%u\n", cm3->psk8_struct.mod_cap);
+ printf("psk8_struct.rf_pwr_cap_1.present=%u\n",
+ cm3->psk8_struct.rf_pwr_cap_1.present);
+ printf("psk8_struct.rf_pwr_cap_1.value=%02x\n",
+ cm3->psk8_struct.rf_pwr_cap_1.value);
+ printf("psk8_struct.rf_pwr_cap_2.present=%u\n",
+ cm3->psk8_struct.rf_pwr_cap_2.present);
+ printf("psk8_struct.rf_pwr_cap_2.value=%02x\n",
+ cm3->psk8_struct.rf_pwr_cap_2.value);
+ printf("\n");
+ printf("gsm_400_bands_supp.present=%u\n",
+ cm3->gsm_400_bands_supp.present);
+ printf("gsm_400_bands_supp.value=%02x\n",
+ cm3->gsm_400_bands_supp.value);
+ printf("gsm_400_bands_supp.assoc_radio_cap=%02x\n",
+ cm3->gsm_400_bands_supp.assoc_radio_cap);
+ printf("\n");
+ printf("gsm_850_assoc_radio_cap.present=%u\n",
+ cm3->gsm_850_assoc_radio_cap.present);
+ printf("gsm_850_assoc_radio_cap.value=%02x\n",
+ cm3->gsm_850_assoc_radio_cap.value);
+ printf("\n");
+ printf("gsm_1900_assoc_radio_cap.present=%u\n",
+ cm3->gsm_1900_assoc_radio_cap.present);
+ printf("gsm_1900_assoc_radio_cap.value=%02x\n",
+ cm3->gsm_1900_assoc_radio_cap.value);
+ printf("\n");
+ printf("umts_fdd_rat_cap=%u\n", cm3->umts_fdd_rat_cap);
+ printf("umts_tdd_rat_cap=%u\n", cm3->umts_tdd_rat_cap);
+ printf("cdma200_rat_cap=%u\n", cm3->cdma200_rat_cap);
+ printf("\n");
+ printf("dtm_gprs_multislot_cap.present=%u\n",
+ cm3->dtm_gprs_multislot_cap.present);
+ printf("dtm_gprs_multislot_cap.mslot_class=%02x\n",
+ cm3->dtm_gprs_multislot_cap.mslot_class);
+ printf("dtm_gprs_multislot_cap.single_slot_dtm=%u\n",
+ cm3->dtm_gprs_multislot_cap.single_slot_dtm);
+ printf("dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=%u\n",
+ cm3->dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present);
+ printf("dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=%02x\n",
+ cm3->dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class);
+ printf("\n");
+ printf("single_band_supp.present=%u\n", cm3->single_band_supp.present);
+ printf("single_band_supp.value=%u\n", cm3->single_band_supp.value);
+ printf("\n");
+ printf("gsm_750_assoc_radio_cap.present=%u\n",
+ cm3->gsm_750_assoc_radio_cap.present);
+ printf("gsm_750_assoc_radio_cap.value=%02x\n",
+ cm3->gsm_750_assoc_radio_cap.value);
+ printf("\n");
+ printf("umts_1_28_mcps_tdd_rat_cap=%u\n",
+ cm3->umts_1_28_mcps_tdd_rat_cap);
+ printf("geran_feature_package=%u\n", cm3->geran_feature_package);
+ printf("\n");
+ printf("extended_dtm_gprs_multislot_cap.present=%u\n",
+ cm3->extended_dtm_gprs_multislot_cap.present);
+ printf("extended_dtm_gprs_multislot_cap.mslot_class=%02x\n",
+ cm3->extended_dtm_gprs_multislot_cap.mslot_class);
+ printf
+ ("extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.present=%u\n",
+ cm3->extended_dtm_gprs_multislot_cap.
+ extended_dtm_egprs_multislot_cap.present);
+ printf
+ ("extended_dtm_gprs_multislot_cap.dtm_egprs_multislot_cap.mslot_class=%02x\n",
+ cm3->extended_dtm_gprs_multislot_cap.
+ extended_dtm_egprs_multislot_cap.mslot_class);
+ printf("\n");
+ printf("high_multislot_cap.present=%u\n",
+ cm3->high_multislot_cap.present);
+ printf("high_multislot_cap.value=%02x\n",
+ cm3->high_multislot_cap.value);
+ printf("\n");
+ printf("geran_feature_package_2=%u\n", cm3->geran_feature_package_2);
+ printf("gmsk_multislot_power_prof=%02x\n",
+ cm3->gmsk_multislot_power_prof);
+ printf("psk8_multislot_power_prof=%02x\n",
+ cm3->psk8_multislot_power_prof);
+ printf("\n");
+ printf("t_gsm_400_bands_supp.present=%u\n",
+ cm3->t_gsm_400_bands_supp.present);
+ printf("t_gsm_400_bands_supp.value=%02x\n",
+ cm3->t_gsm_400_bands_supp.value);
+ printf("t_gsm_400_bands_supp.assoc_radio_cap=%02x\n",
+ cm3->t_gsm_400_bands_supp.assoc_radio_cap);
+ printf("\n");
+ printf("dl_advanced_rx_perf=%02x\n", cm3->dl_advanced_rx_perf);
+ printf("dtm_enhancements_cap=%u\n", cm3->dtm_enhancements_cap);
+ printf("\n");
+ printf("dtm_gprs_high_multislot_cap.present=%u\n",
+ cm3->dtm_gprs_high_multislot_cap.present);
+ printf("dtm_gprs_high_multislot_cap.mslot_class=%02x\n",
+ cm3->dtm_gprs_high_multislot_cap.mslot_class);
+ printf("dtm_gprs_high_multislot_cap.offset_required=%u\n",
+ cm3->dtm_gprs_high_multislot_cap.offset_required);
+ printf
+ ("dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.present=%u\n",
+ cm3->dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.
+ present);
+ printf
+ ("dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.mslot_class=%02x\n",
+ cm3->dtm_gprs_high_multislot_cap.dtm_egprs_high_multislot_cap.
+ mslot_class);
+ printf("\n");
+ printf("repeated_acch_capability=%u\n", cm3->repeated_acch_capability);
+ printf("\n");
+ printf("gsm_710_assoc_radio_cap.present=%u\n",
+ cm3->gsm_710_assoc_radio_cap.present);
+ printf("gsm_710_assoc_radio_cap.value=%02x\n",
+ cm3->gsm_710_assoc_radio_cap.value);
+ printf("\n");
+ printf("t_gsm_810_assoc_radio_cap.present=%u\n",
+ cm3->t_gsm_810_assoc_radio_cap.present);
+ printf("t_gsm_810_assoc_radio_cap.value=%02x\n",
+ cm3->t_gsm_810_assoc_radio_cap.value);
+ printf("\n");
+ printf("ciphering_mode_setting_cap=%u\n",
+ cm3->ciphering_mode_setting_cap);
+ printf("add_pos_cap=%u\n", cm3->add_pos_cap);
+ printf("e_utra_fdd_supp=%u\n", cm3->e_utra_fdd_supp);
+ printf("e_utra_tdd_supp=%u\n", cm3->e_utra_tdd_supp);
+ printf("e_utra_meas_rep_supp=%u\n", cm3->e_utra_meas_rep_supp);
+ printf("prio_resel_supp=%u\n", cm3->prio_resel_supp);
+ printf("utra_csg_cells_rep=%u\n", cm3->utra_csg_cells_rep);
+ printf("vamos_level=%02x\n", cm3->vamos_level);
+ printf("tighter_capability=%02x\n", cm3->tighter_capability);
+ printf("sel_ciph_dl_sacch=%u\n", cm3->sel_ciph_dl_sacch);
+ printf("cs_ps_srvcc_geran_utra=%02x\n", cm3->cs_ps_srvcc_geran_utra);
+ printf("cs_ps_srvcc_geran_eutra=%02x\n", cm3->cs_ps_srvcc_geran_eutra);
+ printf("geran_net_sharing=%u\n", cm3->geran_net_sharing);
+ printf("e_utra_wb_rsrq_meas_supp=%u\n", cm3->e_utra_wb_rsrq_meas_supp);
+ printf("er_band_support=%u\n", cm3->er_band_support);
+ printf("utra_mult_band_ind_supp=%u\n", cm3->utra_mult_band_ind_supp);
+ printf("e_utra_mult_band_ind_supp=%u\n",
+ cm3->e_utra_mult_band_ind_supp);
+ printf("extended_tsc_set_cap_supp=%u\n",
+ cm3->extended_tsc_set_cap_supp);
+ printf("extended_earfcn_val_range=%u\n",
+ cm3->extended_earfcn_val_range);
+}
+
+static void test_decode_classmark3(void)
+{
+ struct gsm48_classmark3 cm3;
+ const uint8_t cm3_1[] = { 0x60, 0x14, 0x04, 0x2f, 0x65, 0x00, 0x20, 0x03, 0x40, 0x4a };
+ const uint8_t cm3_2[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
+ const uint8_t cm3_3[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
+
+ printf("=====cm3_1=====\n");
+ gsm48_decode_classmark3(&cm3, cm3_1, sizeof(cm3_1));
+ dump_cm3(&cm3);
+ printf("\n");
+
+ printf("=====cm3_2=====\n");
+ gsm48_decode_classmark3(&cm3, cm3_2, sizeof(cm3_2));
+ dump_cm3(&cm3);
+ printf("\n");
+
+ printf("=====cm3_3=====\n");
+ gsm48_decode_classmark3(&cm3, cm3_3, sizeof(cm3_3));
+ dump_cm3(&cm3);
+ printf("\n");
+}
+
static void test_mid_from_tmsi(void)
{
static const uint8_t res[] = { 0x17, 0x05, 0xf4, 0xaa, 0xbb, 0xcc, 0xdd };
@@ -943,7 +1367,7 @@ struct mobile_identity_tc mobile_identity_tests[] = {
},
};
-void test_struct_mobile_identity()
+void test_struct_mobile_identity(void)
{
struct mobile_identity_tc *t;
printf("%s()\n", __func__);
@@ -957,7 +1381,7 @@ void test_struct_mobile_identity()
rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false);
msgb_free(msg);
- printf("%s: rc = %d", t->label, rc);
+ printf("%s: %s", t->label, rc ? "rc != 0" : "rc == 0");
if (!rc) {
printf(", mi = %s", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
}
@@ -966,7 +1390,7 @@ void test_struct_mobile_identity()
&& ((rc != 0) || !osmo_mobile_identity_cmp(&mi, &t->expect_mi))) {
printf(" ok");
} else {
- printf(" ERROR: Expected rc = %d", t->expect_rc);
+ printf(" ERROR: Got rc = %d, expected rc = %d", rc, t->expect_rc);
if (!t->expect_rc)
printf(", mi = %s", osmo_mobile_identity_to_str_c(OTC_SELECT, &t->expect_mi));
}
@@ -1105,7 +1529,7 @@ static const struct bcd_number_test {
},
};
-static void test_bcd_number_encode_decode()
+static void test_bcd_number_encode_decode(void)
{
const struct bcd_number_test *test;
uint8_t buf_enc[0xff] = { 0xff };
@@ -1339,7 +1763,7 @@ static void test_random_range_encoding(int range, int max_arfcn_num)
}
}
-static void test_range_encoding()
+static void test_range_encoding(void)
{
int *arfcns;
int arfcns_num = 0;
@@ -1400,7 +1824,7 @@ static int range512[] = {
__FILE__, __LINE__, (int) res, # cmp, (int) wanted); \
}
-static void test_arfcn_filter()
+static void test_arfcn_filter(void)
{
int arfcns[50], i, res, f0_included;
for (i = 0; i < ARRAY_SIZE(arfcns); ++i)
@@ -1433,7 +1857,7 @@ static void test_arfcn_filter()
VERIFY(arfcns[i], ==, ((i + 1) * 2) - 1);
}
-static void test_print_encoding()
+static void test_print_encoding(void)
{
int rc;
int w[17];
@@ -1458,7 +1882,7 @@ static void test_print_encoding()
printf("Range512: %s\n", osmo_hexdump(chan_list, ARRAY_SIZE(chan_list)));
}
-static void test_si_range_helpers()
+static void test_si_range_helpers(void)
{
int ws[(sizeof(freqs1)/sizeof(freqs1[0]))];
int i, f0 = 0xFFFFFF;
@@ -1497,7 +1921,7 @@ static void test_si_range_helpers()
VERIFY(f0, ==, 1);
}
-static void test_power_ctrl()
+static void test_power_ctrl(void)
{
int8_t rc8;
int rc;
@@ -1539,6 +1963,62 @@ static void test_power_ctrl()
VERIFY(rc, <, 0);
}
+static void test_rach_tx_integer_raw2val(void)
+{
+ unsigned int raw;
+ for (raw = 0; raw <= 0x0f; raw++) {
+ unsigned int val = rach_tx_integer_raw2val(raw);
+ printf("rach_tx_integer_raw2val(0x0%x): %u slots used to spread transmission\n",
+ raw, val);
+ }
+}
+
+static void test_gsm_gsmtime2fn(void)
+{
+ struct gsm_time gsm_time;
+ uint32_t fn;
+ uint32_t fn_recovered;
+
+ for (fn = 0; fn < 42432; fn++) {
+ gsm_time.t1 = (fn / 1326) % 32;
+ gsm_time.t2 = fn % 26;
+ gsm_time.t3 = fn % 51;
+
+ fn_recovered = gsm_gsmtime2fn(&gsm_time);
+
+ if (fn_recovered != fn) {
+ printf(" Wrong frame number computed! t1=%d, t2=%d, t3=%d ==> fn=%d, expected fn=%d\n",
+ gsm_time.t1, gsm_time.t2, gsm_time.t3, fn_recovered, fn);
+ OSMO_ASSERT(false);
+ }
+ }
+}
+
+static void test_gsm_rfn2fn(void)
+{
+ unsigned int i;
+ struct {
+ uint32_t curr_fn;
+ uint16_t rfn;
+ uint32_t exp_fn;
+ } input[] = {
+ { .curr_fn = 0, .rfn = 0, .exp_fn = 0 },
+ { .curr_fn = 0, .rfn = 4, .exp_fn = 4 },
+ { .curr_fn = 2229729, .rfn = 23322, .exp_fn = 2229786 },
+ { .curr_fn = 2229777, .rfn = 23322, .exp_fn = 2229786 },
+ { .curr_fn = 1320458, .rfn = 5070, .exp_fn = 1320462 },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(input); i++) {
+ uint32_t fn = gsm_rfn2fn(input[i].rfn, input[i].curr_fn);
+ if (fn != input[i].exp_fn) {
+ printf("Wrong frame number computed! curr_fn=%u, rfn=%u ==> fn=%u, expected fn=%u\n",
+ input[i].curr_fn, input[i].rfn, fn, input[i].exp_fn);
+ OSMO_ASSERT(false);
+ }
+ }
+}
+
int main(int argc, char **argv)
{
test_bearer_cap();
@@ -1550,12 +2030,17 @@ int main(int argc, char **argv)
test_bcd_number_encode_decode();
test_ra_cap();
test_lai_encode_decode();
+ test_osmo_routing_area_id();
+ test_decode_classmark3();
test_si_range_helpers();
test_arfcn_filter();
test_print_encoding();
test_range_encoding();
test_power_ctrl();
+ test_rach_tx_integer_raw2val();
+ test_gsm_gsmtime2fn();
+ test_gsm_rfn2fn();
return EXIT_SUCCESS;
}