Review at https://gerrit.osmocom.org/2181
gsm0808: Add utils for Cell Identifier List The planned support for true A over IP requires the encoding of the a Cell Identifier List element (see also BSS_MAP_MSG_PAGING). This commt adds encoding/decoding functionality and tests for the element mentioned above, however, it is not yet actively used. Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 --- M include/osmocom/gsm/gsm0808_utils.h M include/osmocom/gsm/protocol/gsm_08_08.h M src/gsm/gsm0808_utils.c M src/gsm/libosmogsm.map M tests/gsm0808/gsm0808_test.c 5 files changed, 195 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/81/2181/1 diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index 2196f94..c9fd124 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -57,3 +57,10 @@ /* Decode Encryption Information element */ struct gsm0808_encrypt_info *gsm0808_dec_encrypt_info(const void *ctx, struct msgb *msg); + +/* Encode Cell Identifier List element */ +struct msgb *gsm0808_enc_cell_id_list(struct gsm0808_cell_id_list *cil); + +/* Decode Cell Identifier List element */ +struct gsm0808_cell_id_list *gsm0808_dec_cell_id_list(const void *ctx, + struct msgb *msg); diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h index d52af9f..ad7f8eb 100644 --- a/include/osmocom/gsm/protocol/gsm_08_08.h +++ b/include/osmocom/gsm/protocol/gsm_08_08.h @@ -452,3 +452,17 @@ uint8_t key[ENCRY_INFO_KEY_MAXLEN]; unsigned int key_len; }; + +/* 3GPP TS 48.008 3.2.2.10 Cell Identifier List */ +struct gsm0808_cell_id_list { + uint8_t id_discr; + struct llist_head id_list; +}; + +/* 3GPP TS 48.008 3.2.2.10 Cell Identifier List + * (Coding of i-th Cell Identification for Cell + * identification discriminator = 0101) */ +struct gsm0808_cell_id_lac { + struct llist_head list; + uint16_t lac; +}; diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 7dfe2e9..564f171 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -426,3 +426,87 @@ return ei; } + +/* Encode Cell Identifier List element */ +struct msgb *gsm0808_enc_cell_id_list(struct gsm0808_cell_id_list *cil) +{ + struct msgb *msg; + struct gsm0808_cell_id_lac *lac; + + OSMO_ASSERT(cil); + + /* FIXME: Implement support for all identifier list elements */ + OSMO_ASSERT(cil->id_discr == CELL_IDENT_LAC + || cil->id_discr == CELL_IDENT_BSS) + + msg = msgb_alloc(ELEMENT_MSGB_MAXLEN, "Cell-ID list Element"); + if (!msg) + return NULL; + + msgb_put_u8(msg, cil->id_discr & 0x0f); + + switch (cil->id_discr) { + case CELL_IDENT_LAC: + llist_for_each_entry(lac, &cil->id_list, list) { + msgb_put_u16(msg, lac->lac); + } + break; + + case CELL_IDENT_BSS: + /* Does not have any list items */ + break; + + default: + /* Unspported encoding */ + OSMO_ASSERT(false); + } + + return msg; +} + +/* Decode Cell Identifier List element */ +struct gsm0808_cell_id_list *gsm0808_dec_cell_id_list(const void *ctx, + struct msgb *msg) +{ + uint8_t id_discr; + struct gsm0808_cell_id_list *cil; + struct gsm0808_cell_id_lac *lac; + + if (!msg) + return NULL; + + id_discr = msgb_pull_u8(msg) & 0x0f; + + /* FIXME: Implement support for all identifier list elements */ + if (id_discr != CELL_IDENT_LAC && id_discr != CELL_IDENT_BSS) + return NULL; + + cil = talloc_zero(ctx, struct gsm0808_cell_id_list); + if (!cil) + return NULL; + INIT_LLIST_HEAD(&cil->id_list); + + cil->id_discr = id_discr; + + switch (id_discr) { + case CELL_IDENT_LAC: + while (msg->len >= 2) { + lac = talloc_zero(cil, struct gsm0808_cell_id_lac); + if (!lac) { + talloc_free(cil); + return NULL; + } + lac->lac = msgb_pull_u16(msg); + llist_add(&lac->list, &cil->id_list); + } + + case CELL_IDENT_BSS: + /* Does not have any list items */ + break; + default: + /* Unspported encoding */ + OSMO_ASSERT(false); + } + + return cil; +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index e64fdd9..ac8d467 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -150,6 +150,8 @@ gsm0808_dec_channel_type; gsm0808_enc_encrypt_info; gsm0808_dec_encrypt_info; +gsm0808_enc_cell_id_list; +gsm0808_dec_cell_id_list; gsm0858_rsl_ul_meas_enc; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index e52cba7..c7e0d18 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -619,7 +619,6 @@ msgb_free(ct_enc); } - static void test_gsm0808_enc_dec_encrypt_info(const void *ctx) { struct gsm0808_encrypt_info ei; @@ -655,6 +654,91 @@ msgb_free(ei_enc); } +static void test_gsm0808_enc_dec_cell_id_list_lac(const void *ctx) +{ + struct gsm0808_cell_id_lac lac1; + struct gsm0808_cell_id_lac lac2; + struct gsm0808_cell_id_lac lac3; + struct msgb *msg; + struct gsm0808_cell_id_list cil; + struct gsm0808_cell_id_list *cil_decoded; + struct gsm0808_cell_id_lac *lac; + + cil.id_discr = CELL_IDENT_LAC; + INIT_LLIST_HEAD(&cil.id_list); + lac1.lac = 0x1111; + lac2.lac = 0x2222; + lac3.lac = 0x3333; + llist_add(&lac1.list, &cil.id_list); + llist_add(&lac2.list, &cil.id_list); + llist_add(&lac3.list, &cil.id_list); + + msg = gsm0808_enc_cell_id_list(&cil); + OSMO_ASSERT(msg); + cil_decoded = gsm0808_dec_cell_id_list(ctx, msg); + OSMO_ASSERT(cil_decoded); + OSMO_ASSERT(msg->len == 0); + OSMO_ASSERT(cil_decoded->id_discr == cil.id_discr); + + llist_for_each_entry(lac, &cil_decoded->id_list, list) { + OSMO_ASSERT((lac->lac == lac1.lac) || (lac->lac == lac2.lac) + || (lac->lac == lac3.lac)) + } + + talloc_free(cil_decoded); + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_cell_id_list_single_lac(const void *ctx) +{ + struct gsm0808_cell_id_lac lac_enc; + struct msgb *msg; + struct gsm0808_cell_id_list cil; + struct gsm0808_cell_id_list *cil_decoded; + struct gsm0808_cell_id_lac *lac; + uint8_t cil_enc_expected[] = {0x05, 0x23, 0x42}; + cil.id_discr = CELL_IDENT_LAC; + INIT_LLIST_HEAD(&cil.id_list); + lac_enc.lac = 0x2342; + llist_add(&lac_enc.list, &cil.id_list); + + msg = gsm0808_enc_cell_id_list(&cil); + OSMO_ASSERT(msg); + OSMO_ASSERT(memcmp(cil_enc_expected,msg->data,msg->len) == 0); + + cil_decoded = gsm0808_dec_cell_id_list(ctx, msg); + OSMO_ASSERT(cil_decoded); + OSMO_ASSERT(msg->len == 0); + OSMO_ASSERT(cil_decoded->id_discr == cil.id_discr); + + llist_for_each_entry(lac, &cil_decoded->id_list, list) { + OSMO_ASSERT(lac->lac == lac_enc.lac) + } + + talloc_free(cil_decoded); + msgb_free(msg); +} + +static void test_gsm0808_enc_dec_cell_id_list_bss(const void *ctx) +{ + struct msgb *msg; + struct gsm0808_cell_id_list cil; + struct gsm0808_cell_id_list *cil_decoded; + + cil.id_discr = CELL_IDENT_BSS; + + msg = gsm0808_enc_cell_id_list(&cil); + OSMO_ASSERT(msg); + + cil_decoded = gsm0808_dec_cell_id_list(ctx, msg); + OSMO_ASSERT(cil_decoded); + OSMO_ASSERT(msg->len == 0); + OSMO_ASSERT(cil_decoded->id_discr == cil.id_discr); + + talloc_free(cil_decoded); + msgb_free(msg); +} + int main(int argc, char **argv) { void *ctx; @@ -686,6 +770,9 @@ test_gsm0808_enc_dec_speech_codec_list(ctx); test_gsm0808_enc_dec_channel_type(ctx); test_gsm0808_enc_dec_encrypt_info(ctx); + test_gsm0808_enc_dec_cell_id_list_lac(ctx); + test_gsm0808_enc_dec_cell_id_list_single_lac(ctx); + test_gsm0808_enc_dec_cell_id_list_bss(ctx); printf("Done\n"); -- To view, visit https://gerrit.osmocom.org/2181 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I625245dd1dd396fc2bc189e8cd2c444a33042528 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: dexter <pma...@sysmocom.de>