diff options
Diffstat (limited to 'tests/gsm0808/gsm0808_test.c')
-rw-r--r-- | tests/gsm0808/gsm0808_test.c | 447 |
1 files changed, 361 insertions, 86 deletions
diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 04b3b727..ed99245c 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_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. - * */ #include <osmocom/gsm/gsm0808.h> @@ -115,7 +111,7 @@ static void test_create_layer3(void) msgb_free(in_msg); } -static void test_create_layer3_aoip() +static void test_create_layer3_aoip(void) { static const uint8_t res[] = { 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62, @@ -152,7 +148,7 @@ static void test_create_layer3_aoip() msgb_free(in_msg); } -static void test_create_reset() +static void test_create_reset(void) { static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 }; struct msgb *msg; @@ -163,7 +159,7 @@ static void test_create_reset() msgb_free(msg); } -static void test_create_reset_ack() +static void test_create_reset_ack(void) { static const uint8_t res[] = { 0x00, 0x01, 0x31 }; struct msgb *msg; @@ -175,7 +171,7 @@ static void test_create_reset_ack() } -static void test_create_clear_command() +static void test_create_clear_command(void) { static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 }; struct msgb *msg; @@ -186,7 +182,7 @@ static void test_create_clear_command() msgb_free(msg); } -static void test_create_clear_command2() +static void test_create_clear_command2(void) { static const uint8_t res[] = { 0x00, 0x04, 0x20, 0x04, 0x01, 0x23 }; struct msgb *msg; @@ -197,7 +193,7 @@ static void test_create_clear_command2() msgb_free(msg); } -static void test_create_clear_command2_csfb() +static void test_create_clear_command2_csfb(void) { static const uint8_t res[] = { 0x00, 0x05, 0x20, 0x04, 0x01, 0x23, 0x8F }; struct msgb *msg; @@ -208,7 +204,7 @@ static void test_create_clear_command2_csfb() msgb_free(msg); } -static void test_create_clear_complete() +static void test_create_clear_complete(void) { static const uint8_t res[] = { 0x00, 0x01, 0x21 }; struct msgb *msg; @@ -219,7 +215,7 @@ static void test_create_clear_complete() msgb_free(msg); } -static void test_create_cipher() +static void test_create_cipher(void) { static const uint8_t res[] = { 0x00, 0x0c, 0x53, 0x0a, 0x09, 0x03, 0xaa, @@ -259,7 +255,7 @@ static void test_create_cipher() msgb_free(msg); } -static void test_create_cipher_complete() +static void test_create_cipher_complete(void) { static const uint8_t res1[] = { 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 }; @@ -316,7 +312,7 @@ static inline void parse_cipher_reject(struct msgb *msg, uint8_t exp) rc, exp, OSMO_BIT_PRINT(exp), msgb_hexdump(msg)); } -static void test_create_cipher_reject() +static void test_create_cipher_reject(void) { static const uint8_t res[] = { 0x00, 0x04, 0x59, 0x04, 0x01, 0x23 }; enum gsm0808_cause cause = GSM0808_CAUSE_CCCH_OVERLOAD; @@ -331,7 +327,7 @@ static void test_create_cipher_reject() msgb_free(msg); } -static void test_create_cipher_reject_ext() +static void test_create_cipher_reject_ext(void) { static const uint8_t res[] = { 0x00, 0x05, 0x59, 0x04, 0x02, 0xd0, 0xFA }; uint8_t cause = 0xFA; @@ -346,7 +342,7 @@ static void test_create_cipher_reject_ext() msgb_free(msg); } -static void test_create_cm_u() +static void test_create_cm_u(void) { static const uint8_t res[] = { 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 }; @@ -368,7 +364,7 @@ static void test_create_cm_u() msgb_free(msg); } -static void test_create_sapi_reject() +static void test_create_sapi_reject(void) { static const uint8_t res[] = { 0x00, 0x06, 0x25, 0x18, 0x03, 0x04, 0x01, 0x25 }; struct msgb *msg; @@ -379,7 +375,7 @@ static void test_create_sapi_reject() msgb_free(msg); } -static void test_dec_confusion() +static void test_dec_confusion(void) { static const uint8_t hex[] = { 0x26, 0x04, 0x01, 0x52, 0x1f, 0x07, 0x00, 0xff, 0x00, 0x03, 0x25, 0x03, 0x25 }; @@ -428,7 +424,60 @@ static void test_dec_confusion() osmo_hexdump(diag->msg, diag_len-2)); } -static void test_create_ass() +/* Test Perform Location Report SYS#5891 */ +static void test_dec_perform_location_report_sys5891(void) +{ +/* Message Type Perform Location Request + Location Type + Element ID: 0x44 + Length: 1 + Location Information: current geographic location (0x00) + Cell Identifier/CI (25911) + Element ID: 0x05 + Length: 8 + 0000 .... = Spare bit(s): 0x00 + .... 0000 = Cell identification discriminator: The whole Cell Global Identification, CGI, is used to identify the cells. (0) + Mobile Country Code (MCC): (removed)) + Mobile Network Code (MNC): (removed)) + Cell LAC: 0x001e (30) + Cell CI: 0x6537 (25911) + LCS Client Type + Element ID: 0x48 + Length: 1 + 0011 .... = Client Category: Emergency Services (0x03) + .... 0000 = Client Subtype: unspecified (0x00) + LCS Priority + Element ID: 0x43 + Length: 1 + Periodicity: highest (0) + LCS QoS + Element ID: 0x3e + Length: 4 + 0000 00.. = Spare: 0x00 + .... ..0. = Velocity Requested: do not report velocity (0x00) + .... ...0 = Vertical Coordinate Indicator: vertical coordinate not requested (0x00) + 1... .... = Horizontal Accuracy Indicator: horizontal accuracy is specified (0x01) + .001 0010 = Horizontal Accuracy: 0x12 + 0... .... = Vertical Accuracy Indicator: vertical accuracy is not specified (0x00) + .000 0000 = Spare: 0x00 + 00.. .... = Response Time Category: Response Time is not specified (0x00) +*/ + const uint8_t hex[] = { + 0x2b, 0x44, 0x01, 0x00, 0x05, 0x08, 0x00, 0xab, 0xbc, 0xcd, 0x00, 0x1e, + 0x65, 0x37, 0x48, 0x01, 0x30, 0x43, 0x01, 0x00, 0x3e, 0x04, 0x00, 0x92, + 0x00, 0x00 + }; + + struct tlv_parsed tp; + int rc; + + printf("Testing decoding Perform Location Report SYS#5891\n"); + + rc = tlv_parse(&tp, gsm0808_att_tlvdef(), hex+1, sizeof(hex)-1, 0, 0); + OSMO_ASSERT(rc == 5); +} + +static void test_create_ass(void) { static const uint8_t res1[] = { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, @@ -478,7 +527,7 @@ static void test_create_ass() msgb_free(msg); } -static void test_create_ass2() +static void test_create_ass2(void) { static const uint8_t res[] = { BSSAP_MSG_BSS_MANAGEMENT, @@ -555,7 +604,7 @@ static void test_create_ass2() msgb_free(msg); } -static void test_create_ass_compl() +static void test_create_ass_compl(void) { static const uint8_t res1[] = { 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, @@ -574,7 +623,7 @@ static void test_create_ass_compl() msgb_free(msg); } -static void test_create_ass_compl_aoip() +static void test_create_ass_compl_aoip(void) { struct sockaddr_storage ss; struct sockaddr_in sin; @@ -611,7 +660,7 @@ static void test_create_ass_compl_aoip() msgb_free(msg); } -static void test_create_ass_fail() +static void test_create_ass_fail(void) { static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 }; static const uint8_t res2[] = { @@ -629,7 +678,7 @@ static void test_create_ass_fail() msgb_free(msg); } -static void test_create_ass_fail_aoip() +static void test_create_ass_fail_aoip(void) { static const uint8_t res1[] = { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST, @@ -655,7 +704,7 @@ static void test_create_ass_fail_aoip() msgb_free(msg); } -static void test_create_clear_rqst() +static void test_create_clear_rqst(void) { static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 }; struct msgb *msg; @@ -666,7 +715,7 @@ static void test_create_clear_rqst() msgb_free(msg); } -static void test_create_paging() +static void test_create_paging(void) { static const uint8_t res[] = { 0x00, 0x10, 0x52, 0x08, 0x08, 0x09, 0x10, 0x10, 0x00, 0x00, 0x00, @@ -706,7 +755,7 @@ static void test_create_paging() msgb_free(msg); } -static void test_create_dtap() +static void test_create_dtap(void) { static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 }; struct msgb *msg, *l3; @@ -723,7 +772,7 @@ static void test_create_dtap() msgb_free(l3); } -static void test_prepend_dtap() +static void test_prepend_dtap(void) { static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 }; struct msgb *in_msg; @@ -740,7 +789,7 @@ static void test_prepend_dtap() msgb_free(in_msg); } -static void test_enc_dec_lcls() +static void test_enc_dec_lcls(void) { static const uint8_t res[] = { GSM0808_IE_GLOBAL_CALL_REF, @@ -818,7 +867,7 @@ static void test_enc_dec_lcls() msgb_free(msg); } -static void test_enc_dec_aoip_trasp_addr_v4() +static void test_enc_dec_aoip_trasp_addr_v4(void) { struct sockaddr_storage enc_addr; struct sockaddr_storage dec_addr; @@ -846,7 +895,7 @@ static void test_enc_dec_aoip_trasp_addr_v4() msgb_free(msg); } -static void test_enc_dec_aoip_trasp_addr_v6() +static void test_enc_dec_aoip_trasp_addr_v6(void) { struct sockaddr_storage enc_addr; struct sockaddr_storage dec_addr; @@ -875,7 +924,29 @@ static void test_enc_dec_aoip_trasp_addr_v6() msgb_free(msg); } -static void test_gsm0808_enc_dec_speech_codec() +static void test_enc_aoip_trasp_addr_msg_too_small(void) +{ + struct msgb *msg; + struct sockaddr_storage enc_addr; + struct sockaddr_in enc_addr_in; + uint8_t rc_enc; + + memset(&enc_addr_in, 0, sizeof(enc_addr_in)); + enc_addr_in.sin_family = AF_INET; + enc_addr_in.sin_port = htons(1234); + inet_aton("255.0.255.255", &enc_addr_in.sin_addr); + + memset(&enc_addr, 0, sizeof(enc_addr)); + memcpy(&enc_addr, &enc_addr_in, sizeof(enc_addr_in)); + + msg = msgb_alloc(7, "output buffer"); + rc_enc = gsm0808_enc_aoip_trasp_addr(msg, &enc_addr); + OSMO_ASSERT(rc_enc == 0); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_speech_codec(void) { struct gsm0808_speech_codec enc_sc = { .pi = true, @@ -888,7 +959,7 @@ static void test_gsm0808_enc_dec_speech_codec() int rc_dec; msg = msgb_alloc(1024, "output buffer"); - rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + rc_enc = gsm0808_enc_speech_codec2(msg, &enc_sc); OSMO_ASSERT(rc_enc == 3); rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); @@ -900,7 +971,7 @@ static void test_gsm0808_enc_dec_speech_codec() } -static void test_gsm0808_enc_dec_speech_codec_with_cfg() +static void test_gsm0808_enc_dec_speech_codec_with_cfg(void) { struct gsm0808_speech_codec enc_sc = { .pi = true, @@ -914,7 +985,7 @@ static void test_gsm0808_enc_dec_speech_codec_with_cfg() int rc_dec; msg = msgb_alloc(1024, "output buffer"); - rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + rc_enc = gsm0808_enc_speech_codec2(msg, &enc_sc); OSMO_ASSERT(rc_enc == 5); rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); @@ -925,7 +996,7 @@ static void test_gsm0808_enc_dec_speech_codec_with_cfg() msgb_free(msg); } -static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg() +static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg(void) { struct gsm0808_speech_codec enc_sc = { .pi = true, @@ -939,7 +1010,7 @@ static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg() int rc_dec; msg = msgb_alloc(1024, "output buffer"); - rc_enc = gsm0808_enc_speech_codec(msg, &enc_sc); + rc_enc = gsm0808_enc_speech_codec2(msg, &enc_sc); OSMO_ASSERT(rc_enc == 5); rc_dec = gsm0808_dec_speech_codec(&dec_sc, msg->data + 2, msg->len - 2); @@ -950,7 +1021,7 @@ static void test_gsm0808_enc_dec_speech_codec_ext_with_cfg() msgb_free(msg); } -static void test_gsm0808_enc_dec_speech_codec_list() +static void test_gsm0808_enc_dec_speech_codec_list(void) { struct gsm0808_speech_codec_list enc_scl = { .codec = { @@ -982,7 +1053,7 @@ static void test_gsm0808_enc_dec_speech_codec_list() int rc_dec; msg = msgb_alloc(1024, "output buffer"); - rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl); + rc_enc = gsm0808_enc_speech_codec_list2(msg, &enc_scl); OSMO_ASSERT(rc_enc == 9); rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2); @@ -993,7 +1064,7 @@ static void test_gsm0808_enc_dec_speech_codec_list() msgb_free(msg); } -static void test_gsm0808_enc_dec_empty_speech_codec_list() +static void test_gsm0808_enc_dec_empty_speech_codec_list(void) { struct gsm0808_speech_codec_list enc_scl = { .len = 0, @@ -1004,7 +1075,7 @@ static void test_gsm0808_enc_dec_empty_speech_codec_list() int rc_dec; msg = msgb_alloc(1024, "output buffer"); - rc_enc = gsm0808_enc_speech_codec_list(msg, &enc_scl); + rc_enc = gsm0808_enc_speech_codec_list2(msg, &enc_scl); OSMO_ASSERT(rc_enc == 2); rc_dec = gsm0808_dec_speech_codec_list(&dec_scl, msg->data + 2, msg->len - 2); @@ -1015,7 +1086,89 @@ static void test_gsm0808_enc_dec_empty_speech_codec_list() msgb_free(msg); } -static void test_gsm0808_enc_dec_channel_type() +static void test_gsm0808_enc_dec_channel_type_data(void) +{ + struct gsm0808_channel_type enc_ct = { + .ch_indctr = GSM0808_CHAN_DATA, + .ch_rate_type = GSM0808_DATA_HALF_PREF, + + .data_transparent = true, + .data_rate = GSM0808_DATA_RATE_TRANSP_4k8, + }; + struct gsm0808_channel_type dec_ct = {}; + struct msgb *msg; + uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE, + 0x03, 0x02, 0x0b, 0x11, + }; + uint8_t rc_enc; + int rc_dec; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_channel_type(msg, &enc_ct); + OSMO_ASSERT(rc_enc == 5); + if (memcmp(ct_enc_expected, msg->data, msg->len)) { + printf(" got: %s\n", osmo_hexdump(msg->data, msg->len)); + printf("expect: %s\n", osmo_hexdump(ct_enc_expected, sizeof(ct_enc_expected))); + OSMO_ASSERT(false); + } + + rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 3); + OSMO_ASSERT(dec_ct.ch_indctr == enc_ct.ch_indctr); + OSMO_ASSERT(dec_ct.ch_rate_type == enc_ct.ch_rate_type); + OSMO_ASSERT(dec_ct.data_transparent == enc_ct.data_transparent); + OSMO_ASSERT(dec_ct.data_rate == enc_ct.data_rate); + OSMO_ASSERT(dec_ct.data_rate_allowed_is_set == enc_ct.data_rate_allowed_is_set); + OSMO_ASSERT(dec_ct.data_asym_pref_is_set == enc_ct.data_asym_pref_is_set); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_channel_type_data_asym_pref(void) +{ + struct gsm0808_channel_type enc_ct = { + .ch_indctr = GSM0808_CHAN_DATA, + .ch_rate_type = GSM0808_DATA_HALF_PREF, + + .data_transparent = false, + .data_rate = GSM0808_DATA_RATE_NON_TRANSP_6k0, + .data_rate_allowed_is_set = true, + .data_rate_allowed = GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_6k0 + | GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_12k0 + | GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_14k5, + .data_asym_pref_is_set = true, + .data_asym_pref = GSM0808_CT_ASYM_PREF_UL, + }; + struct gsm0808_channel_type dec_ct = {}; + struct msgb *msg; + uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE, + 0x05, 0x02, 0x0b, 0xd1, 0x8b, 0x20, + }; + uint8_t rc_enc; + int rc_dec; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_channel_type(msg, &enc_ct); + OSMO_ASSERT(rc_enc == 7); + if (memcmp(ct_enc_expected, msg->data, msg->len)) { + printf(" got: %s\n", osmo_hexdump(msg->data, msg->len)); + printf("expect: %s\n", osmo_hexdump(ct_enc_expected, sizeof(ct_enc_expected))); + OSMO_ASSERT(false); + } + + rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 5); + OSMO_ASSERT(dec_ct.ch_indctr == enc_ct.ch_indctr); + OSMO_ASSERT(dec_ct.ch_rate_type == enc_ct.ch_rate_type); + OSMO_ASSERT(dec_ct.data_transparent == enc_ct.data_transparent); + OSMO_ASSERT(dec_ct.data_rate == enc_ct.data_rate); + OSMO_ASSERT(dec_ct.data_rate_allowed_is_set == enc_ct.data_rate_allowed_is_set); + OSMO_ASSERT(dec_ct.data_asym_pref_is_set == enc_ct.data_asym_pref_is_set); + + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_channel_type_speech(void) { struct gsm0808_channel_type enc_ct = { .ch_indctr = GSM0808_CHAN_SPEECH, @@ -1046,7 +1199,65 @@ static void test_gsm0808_enc_dec_channel_type() msgb_free(msg); } -static void test_gsm0808_enc_dec_encrypt_info() +static void test_gsm0808_enc_dec_channel_type_sign(void) +{ + struct gsm0808_channel_type enc_ct = { + .ch_indctr = GSM0808_CHAN_SIGN, + .ch_rate_type = GSM0808_SIGN_FULL_PREF_NO_CHANGE, + }; + struct gsm0808_channel_type dec_ct = {}; + struct msgb *msg; + uint8_t ct_enc_expected[] = { GSM0808_IE_CHANNEL_TYPE, + 0x03, 0x03, 0x1a, 0x00 + }; + uint8_t rc_enc; + int rc_dec; + + msg = msgb_alloc(1024, "output buffer"); + rc_enc = gsm0808_enc_channel_type(msg, &enc_ct); + OSMO_ASSERT(rc_enc == 5); + OSMO_ASSERT(memcmp(ct_enc_expected, msg->data, msg->len) == 0); + + rc_dec = gsm0808_dec_channel_type(&dec_ct, msg->data + 2, msg->len - 2); + OSMO_ASSERT(rc_dec == 2); + OSMO_ASSERT(enc_ct.ch_indctr == dec_ct.ch_indctr); + OSMO_ASSERT(enc_ct.ch_rate_type == dec_ct.ch_rate_type); + + msgb_free(msg); +} + +static void test_gsm0808_dec_channel_type_err(void) +{ + struct gsm0808_channel_type ct; + int rc; + + /* Unknown channel indicator */ + const uint8_t hex1[] = { 0x05, 0x0b, 0xa1, 0x25 }; + rc = gsm0808_dec_channel_type(&ct, hex1, sizeof(hex1)); + OSMO_ASSERT(rc == -ENOTSUP); + + /* Data: ext in Octet 5 with transparent service */ + const uint8_t hex2[] = { 0x02, 0x0b, 0x80, 0x00 }; + rc = gsm0808_dec_channel_type(&ct, hex2, sizeof(hex2)); + OSMO_ASSERT(rc == -EINVAL); + + /* Data: ext in Octet 5, but too short */ + const uint8_t hex3[] = { 0x02, 0x0b, 0xc0 }; + rc = gsm0808_dec_channel_type(&ct, hex3, sizeof(hex3)); + OSMO_ASSERT(rc == -EOVERFLOW); + + /* Data: ext in Octet 5a, but too short */ + const uint8_t hex4[] = { 0x02, 0x0b, 0xc0, 0x80 }; + rc = gsm0808_dec_channel_type(&ct, hex4, sizeof(hex4)); + OSMO_ASSERT(rc == -EOVERFLOW); + + /* Speech: extension bit is set in last byte */ + const uint8_t hex5[] = { 0x01, 0x0b, 0xa1, 0xa5 }; + rc = gsm0808_dec_channel_type(&ct, hex5, sizeof(hex5)); + OSMO_ASSERT(rc == -EOVERFLOW); +} + +static void test_gsm0808_enc_dec_encrypt_info(void) { struct gsm0808_encrypt_info enc_ei = { .perm_algo = { GSM0808_ALG_ID_A5_0, GSM0808_ALG_ID_A5_1 }, @@ -1076,7 +1287,20 @@ static void test_gsm0808_enc_dec_encrypt_info() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_list_lac() +static void test_gsm0808_dec_cell_id_list_srvcc(void) +{ + /* taken from a pcap file of a real-world 3rd party MSC (SYS#5838) */ + const uint8_t enc_cil[] = { 0x0b, 0x2, 0xf2, 0x10, 0x4e, 0x20, 0x15, 0xbe}; + struct gsm0808_cell_id_list2 dec_cil; + int rc; + + rc = gsm0808_dec_cell_id_list2(&dec_cil, enc_cil, sizeof(enc_cil)); + OSMO_ASSERT(rc == sizeof(enc_cil)); + OSMO_ASSERT(dec_cil.id_discr == CELL_IDENT_SAI); + OSMO_ASSERT(dec_cil.id_list_len == 1); +} + +static void test_gsm0808_enc_dec_cell_id_list_lac(void) { struct gsm0808_cell_id_list2 enc_cil; struct gsm0808_cell_id_list2 dec_cil; @@ -1103,7 +1327,7 @@ static void test_gsm0808_enc_dec_cell_id_list_lac() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_list_single_lac() +static void test_gsm0808_enc_dec_cell_id_list_single_lac(void) { struct gsm0808_cell_id_list2 enc_cil; struct gsm0808_cell_id_list2 dec_cil; @@ -1132,7 +1356,7 @@ static void test_gsm0808_enc_dec_cell_id_list_single_lac() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_list_multi_lac() +static void test_gsm0808_enc_dec_cell_id_list_multi_lac(void) { struct gsm0808_cell_id_list2 enc_cil; struct gsm0808_cell_id_list2 dec_cil; @@ -1168,7 +1392,7 @@ static void test_gsm0808_enc_dec_cell_id_list_multi_lac() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_list_bss() +static void test_gsm0808_enc_dec_cell_id_list_bss(void) { struct gsm0808_cell_id_list2 enc_cil; struct gsm0808_cell_id_list2 dec_cil; @@ -1191,7 +1415,7 @@ static void test_gsm0808_enc_dec_cell_id_list_bss() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac() +static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac(void) { struct gsm0808_cell_id_list2 enc_cil; struct gsm0808_cell_id_list2 dec_cil; @@ -1247,7 +1471,7 @@ static void test_gsm0808_enc_dec_cell_id_list_multi_lai_and_lac() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_list_multi_ci() +static void test_gsm0808_enc_dec_cell_id_list_multi_ci(void) { struct gsm0808_cell_id_list2 enc_cil; struct gsm0808_cell_id_list2 dec_cil; @@ -1281,7 +1505,7 @@ static void test_gsm0808_enc_dec_cell_id_list_multi_ci() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci() +static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci(void) { struct gsm0808_cell_id_list2 enc_cil; struct gsm0808_cell_id_list2 dec_cil; @@ -1322,7 +1546,7 @@ static void test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_list_multi_global() +static void test_gsm0808_enc_dec_cell_id_list_multi_global(void) { struct gsm0808_cell_id_list2 enc_cil; struct gsm0808_cell_id_list2 dec_cil; @@ -1395,7 +1619,7 @@ static void print_cil(const struct gsm0808_cell_id_list2 *cil) printf(" cell_id_list == %s\n", gsm0808_cell_id_list_name(cil)); } -void test_cell_id_list_add() { +void test_cell_id_list_add(void) { size_t zu; const struct gsm0808_cell_id_list2 cgi1 = { @@ -1577,7 +1801,7 @@ void test_cell_id_list_add() { printf("------- %s done\n", __func__); } -static void test_gsm0808_enc_dec_cell_id_lac() +static void test_gsm0808_enc_dec_cell_id_lac(void) { struct gsm0808_cell_id enc_ci = { .id_discr = CELL_IDENT_LAC, @@ -1603,7 +1827,7 @@ static void test_gsm0808_enc_dec_cell_id_lac() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_bss() +static void test_gsm0808_enc_dec_cell_id_bss(void) { struct gsm0808_cell_id enc_ci = { .id_discr = CELL_IDENT_BSS, @@ -1625,7 +1849,7 @@ static void test_gsm0808_enc_dec_cell_id_bss() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_no_cell() +static void test_gsm0808_enc_dec_cell_id_no_cell(void) { struct gsm0808_cell_id enc_ci = { .id_discr = CELL_IDENT_NO_CELL, @@ -1647,7 +1871,7 @@ static void test_gsm0808_enc_dec_cell_id_no_cell() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_lai_and_lac() +static void test_gsm0808_enc_dec_cell_id_lai_and_lac(void) { struct gsm0808_cell_id enc_ci = { .id_discr = CELL_IDENT_LAI_AND_LAC, @@ -1678,7 +1902,7 @@ static void test_gsm0808_enc_dec_cell_id_lai_and_lac() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_ci() +static void test_gsm0808_enc_dec_cell_id_ci(void) { struct gsm0808_cell_id enc_ci = { .id_discr = CELL_IDENT_CI, @@ -1701,7 +1925,7 @@ static void test_gsm0808_enc_dec_cell_id_ci() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_lac_and_ci() +static void test_gsm0808_enc_dec_cell_id_lac_and_ci(void) { struct gsm0808_cell_id enc_ci = { .id_discr = CELL_IDENT_LAC_AND_CI, @@ -1728,7 +1952,7 @@ static void test_gsm0808_enc_dec_cell_id_lac_and_ci() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_global() +static void test_gsm0808_enc_dec_cell_id_global(void) { struct gsm0808_cell_id enc_ci = { .id_discr = CELL_IDENT_WHOLE_GLOBAL, @@ -1760,7 +1984,7 @@ static void test_gsm0808_enc_dec_cell_id_global() msgb_free(msg); } -static void test_gsm0808_enc_dec_cell_id_global_ps() +static void test_gsm0808_enc_dec_cell_id_global_ps(void) { struct gsm0808_cell_id enc_cgi = { .id_discr = CELL_IDENT_WHOLE_GLOBAL, @@ -1802,29 +2026,81 @@ static void test_gsm0808_enc_dec_cell_id_global_ps() msgb_free(msg_cgi_ps); } +static void print_s15_s0(uint16_t s15_s0, bool full_rate) +{ + int i; + printf(" S15-S0 = 0x%04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0, + OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0)); + for (i = 0; i < 16; i++) { + uint8_t modes; + int m; + int space; + + if (!(s15_s0 & (1 << i))) + continue; + + space = 6; + if (i < 10) + space++; + + printf(" S%d", i); + + modes = gsm0808_amr_modes_from_cfg[full_rate ? 1 : 0][i]; + if (!modes) { + printf(" (empty)\n"); + continue; + } + + for (m = 0; m < 8; m++) { + if (!(modes & (1 << m))) { + /* avoid whitespace at line ends -- accumulate whitespace width until there is + * non-whitespace to actually be printed.*/ + space += 8; + continue; + } + printf("%*s", space, gsm0808_amr_mode_name(m)); + space = 8; + } + printf("\n"); + } +} + +static void print_mr_cfg(const struct gsm48_multi_rate_conf *cfg) +{ + printf(" cfg.smod=%u spare=%u icmi=%u nscb=%u ver=%u\n", + cfg->smod, cfg->spare, cfg->icmi, cfg->nscb, cfg->ver); + printf(" "); +#define PRINT_MODE_BIT(NAME) do { \ + if (cfg->NAME) \ + printf(" " #NAME "=1"); \ + else \ + printf(" -------"); \ + } while (0) + PRINT_MODE_BIT(m4_75); + PRINT_MODE_BIT(m5_15); + PRINT_MODE_BIT(m5_90); + PRINT_MODE_BIT(m6_70); + PRINT_MODE_BIT(m7_40); + PRINT_MODE_BIT(m7_95); + PRINT_MODE_BIT(m10_2); + PRINT_MODE_BIT(m12_2); + printf("\n"); +} + static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(struct gsm48_multi_rate_conf *cfg) { uint16_t s15_s0; printf("Input:\n"); - printf(" m4_75= %u smod= %u\n", cfg->m4_75, cfg->smod); - printf(" m5_15= %u spare= %u\n", cfg->m5_15, cfg->spare); - printf(" m5_90= %u icmi= %u\n", cfg->m5_90, cfg->icmi); - printf(" m6_70= %u nscb= %u\n", cfg->m6_70, cfg->nscb); - printf(" m7_40= %u ver= %u\n", cfg->m7_40, cfg->ver); - printf(" m7_95= %u\n", cfg->m7_95); - printf(" m10_2= %u\n", cfg->m10_2); - printf(" m12_2= %u\n", cfg->m12_2); + print_mr_cfg(cfg); s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, true); printf("Result (fr):\n"); - printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0, - OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0)); + print_s15_s0(s15_s0, true); s15_s0 = gsm0808_sc_cfg_from_gsm48_mr_cfg(cfg, false); printf("Result (hr):\n"); - printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0, - OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0)); + print_s15_s0(s15_s0, false); printf("\n"); } @@ -2025,20 +2301,12 @@ static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0) int rc; printf("Input:\n"); - printf(" S15-S0 = %04x = 0b" OSMO_BIN_SPEC OSMO_BIN_SPEC "\n", s15_s0, - OSMO_BIN_PRINT(s15_s0 >> 8), OSMO_BIN_PRINT(s15_s0)); + print_s15_s0(s15_s0, true); rc = gsm48_mr_cfg_from_gsm0808_sc_cfg(&cfg, s15_s0); printf("Output:\n"); - printf(" m4_75= %u smod= %u\n", cfg.m4_75, cfg.smod); - printf(" m5_15= %u spare= %u\n", cfg.m5_15, cfg.spare); - printf(" m5_90= %u icmi= %u\n", cfg.m5_90, cfg.icmi); - printf(" m6_70= %u nscb= %u\n", cfg.m6_70, cfg.nscb); - printf(" m7_40= %u ver= %u\n", cfg.m7_40, cfg.ver); - printf(" m7_95= %u\n", cfg.m7_95); - printf(" m10_2= %u\n", cfg.m10_2); - printf(" m12_2= %u\n", cfg.m12_2); + print_mr_cfg(&cfg); if (rc != 0) printf(" Result invalid!\n"); @@ -2046,7 +2314,7 @@ static void test_gsm48_mr_cfg_from_gsm0808_sc_cfg_single(uint16_t s15_s0) printf("\n"); } -void test_gsm48_mr_cfg_from_gsm0808_sc_cfg() +void test_gsm48_mr_cfg_from_gsm0808_sc_cfg(void) { printf("Testing gsm48_mr_cfg_from_gsm0808_sc_cfg():\n"); @@ -2231,7 +2499,7 @@ static const struct test_cell_id_matching_data test_cell_id_matching_tests[] = { { .id = cgi_23_042_23_5, .match_id = cgi_23_99_23_5, .expect_match = false, .expect_exact_match = false }, }; -static void test_cell_id_matching() +static void test_cell_id_matching(void) { int i; bool ok = true; @@ -2394,7 +2662,7 @@ static const struct gsm0808_cell_id test_gsm0808_cell_id_to_from_cgi_data[] = { { .id_discr = 423 }, }; -static void test_gsm0808_cell_id_to_from_cgi() +static void test_gsm0808_cell_id_to_from_cgi(void) { int i; int j; @@ -2478,12 +2746,17 @@ int main(int argc, char **argv) test_enc_dec_aoip_trasp_addr_v4(); test_enc_dec_aoip_trasp_addr_v6(); + test_enc_aoip_trasp_addr_msg_too_small(); test_gsm0808_enc_dec_speech_codec(); test_gsm0808_enc_dec_speech_codec_ext_with_cfg(); test_gsm0808_enc_dec_speech_codec_with_cfg(); test_gsm0808_enc_dec_speech_codec_list(); test_gsm0808_enc_dec_empty_speech_codec_list(); - test_gsm0808_enc_dec_channel_type(); + test_gsm0808_enc_dec_channel_type_data(); + test_gsm0808_enc_dec_channel_type_data_asym_pref(); + test_gsm0808_enc_dec_channel_type_speech(); + test_gsm0808_enc_dec_channel_type_sign(); + test_gsm0808_dec_channel_type_err(); test_gsm0808_enc_dec_encrypt_info(); test_gsm0808_enc_dec_cell_id_list_lac(); @@ -2494,6 +2767,7 @@ int main(int argc, char **argv) test_gsm0808_enc_dec_cell_id_list_multi_ci(); test_gsm0808_enc_dec_cell_id_list_multi_lac_and_ci(); test_gsm0808_enc_dec_cell_id_list_multi_global(); + test_gsm0808_dec_cell_id_list_srvcc(); test_cell_id_list_add(); @@ -2515,6 +2789,7 @@ int main(int argc, char **argv) test_gsm0808_cell_id_to_from_cgi(); test_dec_confusion(); + test_dec_perform_location_report_sys5891(); printf("Done\n"); return EXIT_SUCCESS; |