LCLS, TS 48.008: add GCR IE encoding/decoding

* add functions to encode Global Call. Ref. from TS 29.205 as 3GPP TS
  48.008 §3.2.2.115 information element
* add corresponding tests

Change-Id: I82ce0207dc8de50689a8806c6471ad7fbae6219d
This commit is contained in:
Max 2018-12-10 11:01:10 +01:00
parent 7918f84aeb
commit 969fb2ed84
5 changed files with 123 additions and 0 deletions

View File

@ -27,6 +27,7 @@ struct sockaddr_storage;
#include <osmocom/gsm/protocol/gsm_08_08.h> #include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/gsm29205.h>
#include <osmocom/gsm/gsm23003.h> #include <osmocom/gsm/gsm23003.h>
#include <osmocom/gsm/gsm_utils.h> #include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/tlv.h> #include <osmocom/gsm/tlv.h>
@ -82,6 +83,10 @@ uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg,
const struct sockaddr_storage *ss); const struct sockaddr_storage *ss);
int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss, int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss,
const uint8_t *elem, uint8_t len); const uint8_t *elem, uint8_t len);
uint8_t gsm0808_enc_gcr(struct msgb *msg, const struct osmo_gcr_parsed *g);
int gsm0808_dec_gcr(struct osmo_gcr_parsed *g, const struct tlv_parsed *tp);
uint8_t gsm0808_enc_speech_codec(struct msgb *msg, uint8_t gsm0808_enc_speech_codec(struct msgb *msg,
const struct gsm0808_speech_codec *sc); const struct gsm0808_speech_codec *sc);
int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc, int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc,

View File

@ -508,6 +508,41 @@ int gsm0808_dec_channel_type(struct gsm0808_channel_type *ct,
return (int)(elem - old_elem); return (int)(elem - old_elem);
} }
/*! Create BSSMAP Global Call Reference, 3GPP TS 48.008 §3.2.2.115.
* \param[out] msg Message Buffer for appending IE
* \param[in] g Global Call Reference, 3GPP TS 29.205 Table B 2.1.9.1
* \returns number of bytes added to \a msg or 0 on error */
uint8_t gsm0808_enc_gcr(struct msgb *msg, const struct osmo_gcr_parsed *g)
{
uint8_t enc, *len = msgb_tl_put(msg, GSM0808_IE_GLOBAL_CALL_REF);
enc = osmo_enc_gcr(msg, g);
if (!enc)
return 0;
*len = enc;
return enc + 2; /* type (1 byte) + length (1 byte) */
}
/*! Decode BSSMAP Global Call Reference, 3GPP TS 29.205 Table B 2.1.9.1.
* \param[out] gcr Caller-provided memory to store Global Call Reference
* \param[in] elem IE value to be decoded
* \param[in] len Length of \a elem in bytes
* \returns number of bytes parsed; negative on error */
int gsm0808_dec_gcr(struct osmo_gcr_parsed *gcr, const struct tlv_parsed *tp)
{
int ret;
const uint8_t *buf = TLVP_VAL_MINLEN(tp, GSM0808_IE_GLOBAL_CALL_REF, OSMO_GCR_MIN_LEN);
if (!buf)
return -EINVAL;
ret = osmo_dec_gcr(gcr, buf, TLVP_LEN(tp, GSM0808_IE_GLOBAL_CALL_REF));
if (ret < 0)
return -ENOENT;
return 2 + ret;
}
/*! Encode TS 08.08 Encryption Information IE /*! Encode TS 08.08 Encryption Information IE
* \param[out] msg Message Buffer to which IE is to be appended * \param[out] msg Message Buffer to which IE is to be appended
* \param[in] ei Encryption Information to be encoded * \param[in] ei Encryption Information to be encoded

View File

@ -219,6 +219,8 @@ gsm0808_channel_type_name;
gsm0808_lcls_config_names; gsm0808_lcls_config_names;
gsm0808_lcls_control_names; gsm0808_lcls_control_names;
gsm0808_lcls_status_names; gsm0808_lcls_status_names;
gsm0808_enc_gcr;
gsm0808_dec_gcr;
gsm29118_msgb_alloc; gsm29118_msgb_alloc;
gsm29118_create_alert_req; gsm29118_create_alert_req;

View File

@ -22,6 +22,8 @@
#include <osmocom/gsm/gsm0808_utils.h> #include <osmocom/gsm/gsm0808_utils.h>
#include <osmocom/gsm/protocol/gsm_08_08.h> #include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/protocol/gsm_08_58.h> #include <osmocom/gsm/protocol/gsm_08_58.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -597,6 +599,75 @@ static void test_prepend_dtap()
msgb_free(in_msg); msgb_free(in_msg);
} }
static void test_enc_dec_gcr()
{
static const uint8_t res[] = {
GSM0808_IE_GLOBAL_CALL_REF,
0x0d, /* GCR length */
0x03, /* .net_len */
0xf1, 0xf2, 0xf3, /* .net */
0x02, /* .node length */
0xde, 0xad, /* .node */
0x05, /* length of Call. Ref. */
0x41, 0x42, 0x43, 0x44, 0x45 /* .cr - Call. Ref. */
};
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;
msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "global call reference");
if (!msg)
return;
len = gsm0808_enc_gcr(msg, &g);
printf("Testing Global Call Reference IE encoder...\n\t%d bytes added: %s\n",
len, len == ARRAY_SIZE(res) ? "OK" : "FAIL");
if (!msgb_eq_data_print(msg, res, ARRAY_SIZE(res)))
abort();
rc = osmo_bssap_tlv_parse(&tp, msgb_data(msg), msgb_length(msg));
if (rc < 0) {
printf("parsing failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg));
abort();
}
rc = gsm0808_dec_gcr(&p, &tp);
if (rc < 0) {
printf("decoding failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg));
abort();
}
if (p.net_len != g.net_len) {
printf("Network ID length parsed wrong: %u != %u\n", p.net_len, g.net_len);
abort();
}
if (p.node != g.node) {
printf("Node ID parsed wrong: 0x%X != 0x%X\n", p.node, g.node);
abort();
}
if (memcmp(p.net, g.net, g.net_len) != 0) {
printf("Network ID parsed wrong: %s\n", osmo_hexdump(p.net, p.net_len));
abort();
}
if (memcmp(p.cr, g.cr, 5) != 0) {
printf("Call ref. ID parsed wrong: %s\n", osmo_hexdump(p.cr, 5));
abort();
}
printf("\tdecoded %d bytes: %s\n", rc, rc == len ? "OK" : "FAIL");
msgb_free(msg);
}
static void test_enc_dec_aoip_trasp_addr_v4() static void test_enc_dec_aoip_trasp_addr_v4()
{ {
struct sockaddr_storage enc_addr; struct sockaddr_storage enc_addr;
@ -1790,6 +1861,10 @@ void test_gsm48_mr_cfg_from_gsm0808_sc_cfg()
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
void *ctx = talloc_named_const(NULL, 0, "gsm0808 test");
msgb_talloc_ctx_init(ctx, 0);
osmo_init_logging2(ctx, NULL);
printf("Testing generation of GSM0808 messages\n"); printf("Testing generation of GSM0808 messages\n");
test_gsm0808_enc_cause(); test_gsm0808_enc_cause();
test_create_layer3(); test_create_layer3();
@ -1813,6 +1888,9 @@ int main(int argc, char **argv)
test_create_paging(); test_create_paging();
test_create_dtap(); test_create_dtap();
test_prepend_dtap(); test_prepend_dtap();
test_enc_dec_gcr();
test_enc_dec_aoip_trasp_addr_v4(); test_enc_dec_aoip_trasp_addr_v4();
test_enc_dec_aoip_trasp_addr_v6(); test_enc_dec_aoip_trasp_addr_v6();
test_gsm0808_enc_dec_speech_codec(); test_gsm0808_enc_dec_speech_codec();

View File

@ -22,6 +22,9 @@ Testing creating Clear Request
Testing creating Paging Request Testing creating Paging Request
Testing creating DTAP Testing creating DTAP
Testing prepend DTAP Testing prepend DTAP
Testing Global Call Reference IE encoder...
15 bytes added: OK
decoded 15 bytes: OK
test_gsm0808_enc_dec_cell_id_list_lac: encoded: 1a 07 05 01 24 ab cd 56 78 (rc = 9) test_gsm0808_enc_dec_cell_id_list_lac: encoded: 1a 07 05 01 24 ab cd 56 78 (rc = 9)
------- test_cell_id_list_add ------- test_cell_id_list_add
cell_id_list == CGI[0]:{} cell_id_list == CGI[0]:{}