diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 4a2233e70..7c6f70702 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -63,7 +63,8 @@ struct gsm0808_cell_id_list2 { struct osmo_lcls { enum gsm0808_lcls_config config; /**< §3.2.2.116 Configuration */ enum gsm0808_lcls_control control; /**< §3.2.2.117 Connection Status Control */ - struct osmo_gcr_parsed *gcr; /**< §3.2.2.115 Global Call Reference */ + struct osmo_gcr_parsed gcr; /**< §3.2.2.115 Global Call Reference */ + bool gcr_available; bool corr_needed; /**< §3.2.2.118 Correlation-Not-Needed */ }; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 2a458c388..9fcccaec6 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -551,8 +551,8 @@ uint8_t gsm0808_enc_lcls(struct msgb *msg, const struct osmo_lcls *lcls) uint8_t enc = 0; /* LCLS: §3.2.2.115 Global Call Reference */ - if (lcls->gcr) - enc = gsm0808_enc_gcr(msg, lcls->gcr); + if (lcls->gcr_available) + enc = gsm0808_enc_gcr(msg, &lcls->gcr); /* LCLS: §3.2.2.116 Configuration */ if (lcls->config != GSM0808_LCLS_CFG_NA) { @@ -581,10 +581,9 @@ uint8_t gsm0808_enc_lcls(struct msgb *msg, const struct osmo_lcls *lcls) * \returns GCR size or negative on error */ int gsm0808_dec_lcls(struct osmo_lcls *lcls, const struct tlv_parsed *tp) { - int ret = gsm0808_dec_gcr(lcls->gcr, tp); - if (ret < 0) - return ret; + int ret = gsm0808_dec_gcr(&lcls->gcr, tp); + lcls->gcr_available = (ret < 0) ? false : true; lcls->config = tlvp_val8(tp, GSM0808_IE_LCLS_CONFIG, GSM0808_LCLS_CFG_NA); lcls->control = tlvp_val8(tp, GSM0808_IE_LCLS_CONN_STATUS_CTRL, GSM0808_LCLS_CSC_NA); lcls->corr_needed = TLVP_PRESENT(tp, GSM0808_IE_LCLS_CORR_NOT_NEEDED) ? false : true; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index e5c1fd373..90bef21fc 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -445,17 +445,17 @@ static void test_create_ass2() struct sockaddr_in sin; struct gsm0808_speech_codec_list sc_list; uint32_t call_id = 0xDEADFACE; - struct osmo_gcr_parsed gcr = { .net_len = 3, .node = 0xFEED }; uint8_t Kc[16]; struct osmo_lcls lcls = { .config = GSM0808_LCLS_CFG_BOTH_WAY, .control = GSM0808_LCLS_CSC_CONNECT, - .gcr = &gcr, + .gcr = { .net_len = 3, .node = 0xFEED }, + .gcr_available = true, .corr_needed = false }; - memset(gcr.cr, 'A', 5); - memset(gcr.net, 'D', gcr.net_len); + memset(lcls.gcr.cr, 'A', 5); + memset(lcls.gcr.net, 'D', lcls.gcr.net_len); memset(Kc, 'E', 16); memset(&ct, 0, sizeof(ct)); @@ -683,16 +683,16 @@ static void test_enc_dec_lcls() }; uint8_t len; struct msgb *msg; - struct osmo_gcr_parsed p = { 0 }, g = { - .net_len = 3, - .net = { 0xf1, 0xf2, 0xf3 }, - .node = 0xDEAD, - .cr = { 0x41, 0x42, 0x43, 0x44, 0x45 }, - }; int rc; struct tlv_parsed tp; - struct osmo_lcls lcls_out = { .gcr = &p }, lcls_in = { - .gcr = &g, + struct osmo_lcls *lcls_out, lcls_in = { + .gcr = { + .net_len = 3, + .net = { 0xf1, 0xf2, 0xf3 }, + .node = 0xDEAD, + .cr = { 0x41, 0x42, 0x43, 0x44, 0x45 }, + }, + .gcr_available = true, .config = GSM0808_LCLS_CFG_NA, .control = GSM0808_LCLS_CSC_NA, .corr_needed = true, @@ -702,6 +702,10 @@ static void test_enc_dec_lcls() if (!msg) return; + lcls_out = talloc_zero(msg, struct osmo_lcls); + if (!lcls_out) + return; + len = gsm0808_enc_lcls(msg, &lcls_in); printf("Testing Global Call Reference IE encoder...\n\t%d bytes added: %s\n", len, len == ARRAY_SIZE(res) ? "OK" : "FAIL"); @@ -715,25 +719,25 @@ static void test_enc_dec_lcls() abort(); } - rc = gsm0808_dec_lcls(&lcls_out, &tp); + rc = gsm0808_dec_lcls(lcls_out, &tp); if (rc < 0) { printf("decoding failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg)); abort(); } - if (lcls_out.config != lcls_in.config) { + if (lcls_out->config != lcls_in.config) { printf("LCLS Config parsed wrong: %s != %s\n", - gsm0808_lcls_config_name(lcls_out.config), gsm0808_lcls_config_name(lcls_in.config)); + gsm0808_lcls_config_name(lcls_out->config), gsm0808_lcls_config_name(lcls_in.config)); abort(); } - if (lcls_out.control != lcls_in.control) { + if (lcls_out->control != lcls_in.control) { printf("LCLS Control parsed wrong: %s != %s\n", - gsm0808_lcls_control_name(lcls_out.control), gsm0808_lcls_control_name(lcls_in.control)); + gsm0808_lcls_control_name(lcls_out->control), gsm0808_lcls_control_name(lcls_in.control)); abort(); } - if (!osmo_gcr_eq(lcls_out.gcr, lcls_in.gcr)) { + if (!osmo_gcr_eq(&lcls_out->gcr, &lcls_in.gcr)) { printf("GCR parsed wrong.\n"); abort(); }