This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Max gerrit-no-reply at lists.osmocom.orgMax has uploaded this change for review. ( https://gerrit.osmocom.org/11827 Change subject: Add GCR routines ...................................................................... Add GCR routines Add functions to create and decode Global Call Reference as per 3GPP TS 29.205 Table B 2.1.9.1, add corresponding tests Change-Id: Iee95aa4e5c056645b6cb5667e4a067097d52dfbf Related: OS#2487 --- M include/osmocom/gsm/gsm0808.h M include/osmocom/gsm/gsm0808_utils.h M src/gsm/gsm0808.c M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c M tests/gsm0808/gsm0808_test.ok 7 files changed, 119 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/27/11827/1 diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 9b19d69..7777c23 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -52,6 +52,9 @@ struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id); struct msgb *gsm0808_create_cipher_reject(enum gsm0808_cause cause); struct msgb *gsm0808_create_cipher_reject_ext(enum gsm0808_cause_class class, uint8_t ext); + +struct msgb *gsm0808_create_gcr(const struct gsm0808_gcr *g); + struct msgb *gsm0808_create_classmark_request(); struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len); diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index c5bf280..59d8985 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -66,6 +66,16 @@ bool corr_needed; /* §3.2.2.118 Correlation-Not-Needed */ }; +/*! Parsed representation of Global Call Reference, 3GPP TS 29.205 Table B 2.1.9.1 */ +struct gsm0808_gcr { + uint8_t *net; /* Network ID, ITU-T Q.1902.3 */ + uint8_t net_len; /* length (3-5 octets) of \a net */ + uint16_t node; /* Node ID */ + uint8_t *cr; /* Call Reference ID (5 octets) */ +}; + +int gsm0808_dec_gcr(struct gsm0808_gcr *gcr, const struct msgb *m); + extern const struct value_string gsm0808_cell_id_discr_names[]; static inline const char *gsm0808_cell_id_discr_name(enum CELL_IDENT id_discr) { return get_value_string(gsm0808_cell_id_discr_names, id_discr); } diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index a84e717..3a2c551 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -405,6 +405,30 @@ return msg; } +/*! Create BSSMAP Global Call Reference + * \param[in] g Global Call Reference, 3GPP TS 29.205 Table B 2.1.9.1 + * \returns callee-allocated msgb with GCR */ +struct msgb *gsm0808_create_gcr(const struct gsm0808_gcr *g) +{ + uint8_t buf[2]; + struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "global call reference"); + if (!msg || !g) + return NULL; + + if (g->net_len < 3 || g->net_len > 5) + return NULL; + + msgb_lv_put(msg, g->net_len, g->net); + + osmo_store16be(g->node, &buf); + msgb_lv_put(msg, 2, buf); + + msgb_lv_put(msg, 5, g->cr); + + return msg; +} + /*! Create BSSMAP SAPI N Reject message * \param[in] link_id Link Identifier * \returns callee-allocated msgb with BSSMAP SAPI N Reject message */ diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index c58d828..c73114d 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -28,6 +28,7 @@ #include <errno.h> #include <osmocom/gsm/protocol/gsm_08_08.h> #include <osmocom/gsm/gsm48.h> +#include <osmocom/gsm/gsm0808.h> #include <osmocom/gsm/gsm0808_utils.h> #define IP_V4_ADDR_LEN 4 @@ -667,6 +668,43 @@ return *tlv_len + 2; } +/*! 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] m message buffer to be decoded + * \returns number of bytes parsed; negative on error */ +int gsm0808_dec_gcr(struct gsm0808_gcr *gcr, const struct msgb *msg) +{ + struct tlv_parsed tp; + const uint8_t *buf; + uint16_t len, point = 1; + int rc = osmo_bssap_tlv_parse(&tp, msgb_data(msg), msgb_length(msg)); + if (rc < 0) + return -EINVAL; + + buf = TLVP_VAL_MINLEN(&tp, GSM0808_IE_GLOBAL_CALL_REF, 13); + if (!buf) + return -EBADMSG; + + len = TLVP_LEN(&tp, GSM0808_IE_GLOBAL_CALL_REF); + + gcr->net_len = buf[0]; + if (gcr->net_len < 3 || gcr->net_len > 5) + return -E2BIG; + + memcpy(gcr->net, buf + point, gcr->net_len); + point += (gcr->net_len + 1); + + gcr->node = osmo_load16be(buf + point); + point += 2; + + if (buf[point] != 5) /* see Table B 2.1.9.2 */ + return -EBADSLT; + + memcpy(gcr->cr, buf + point + 1, 5); + + return len; +} + /* Decode 5-byte LAI list element data (see TS 08.08 3.2.2.27) into MCC/MNC/LAC. */ static void decode_lai(const uint8_t *data, struct osmo_location_area_id *decoded) { diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 217dcc3..85739b6 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -154,6 +154,8 @@ gsm0808_create_ass_compl; gsm0808_create_assignment_failure; gsm0808_create_ass_fail; +gsm0808_create_gcr; +gsm0808_dec_gcr; gsm0808_create_cipher; gsm0808_create_cipher_complete; gsm0808_create_cipher_reject; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 197ec06..d2f7250 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -130,6 +130,46 @@ msgb_free(in_msg); } +static void test_create_gcr() +{ + static const uint8_t res[] = { 0x89, 0x0d, 0x03, 0x55, 0x55, 0x55, 0x02, 0xde, 0xad, 0x05, 0x46, 0x46, 0x46, 0x46, 0x46 }; + struct msgb *msg; + struct gsm0808_gcr g = { .net_len = 3, .node = 0xDEAD }, p; + uint8_t net[g.net_len], pnet[g.net_len], cr[5], pcr[5] = { 0 }; + int rc; + + g.net = net; + g.cr = cr; + p.net = pnet; + p.cr = pcr; + memset(pcr, 0, 5); + memset(cr, 'F', 5); + memset(net, 'U', g.net_len); + + printf("Testing creating Global Call Reference\n"); + msg = gsm0808_create_gcr(&g); + msg->l3h = msgb_wrap_with_TL(msg, GSM0808_IE_GLOBAL_CALL_REF); + VERIFY(msg, res, ARRAY_SIZE(res)); + + rc = gsm0808_dec_gcr(&p, msg); + if (rc < 0) + printf("parsing failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg)); + + if (p.net_len != g.net_len) + printf("Network ID length parsed wrong: %u != %u\n", p.net_len, g.net_len); + + if (p.node != g.node) + printf("Node ID parsed wrong: 0x%X != 0x%X\n", p.node, g.node); + + if (memcmp(p.net, g.net, g.net_len) != 0) + printf("Network ID parsed wrong: %s\n", osmo_hexdump(p.net, p.net_len)); + + if (memcmp(p.cr, g.cr, 5) != 0) + printf("Call ref. ID parsed wrong: %s\n", osmo_hexdump(p.cr, 5)); + + msgb_free(msg); +} + static void test_create_reset() { static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 }; @@ -1774,6 +1814,7 @@ test_create_layer3_aoip(); test_create_reset(); test_create_reset_ack(); + test_create_gcr(); test_create_clear_command(); test_create_clear_complete(); test_create_cipher(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index a48cf1d..db36594 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -3,6 +3,7 @@ Testing creating Layer3 (AoIP) Testing creating Reset Testing creating Reset Ack +Testing creating Global Call Reference Testing creating Clear Command Testing creating Clear Complete Testing creating Chipher Mode Command -- To view, visit https://gerrit.osmocom.org/11827 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: Iee95aa4e5c056645b6cb5667e4a067097d52dfbf Gerrit-Change-Number: 11827 Gerrit-PatchSet: 1 Gerrit-Owner: Max <msuraev at sysmocom.de> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20181119/b142ebcb/attachment.htm>