mirror of https://gerrit.osmocom.org/libosmocore
add gsm0808_cell_id_from_cgi(), gsm0808_cell_id_to_cgi()
CGI to Cell ID: for example, for Paging, osmo-msc has a CGI for a subscriber and needs to send out a Cell Identifier IE. Makes sense to add this conversion here. Cell ID to CGI: for a Layer 3 Complete, a subscriber sends the current cell in the form of a Cell Identifier, which we store as a CGI, if necessary enriched with the local PLMN. Add enum with bitmask values to identify parts of a CGI, for the return value of gsm0808_cell_id_to_cgi(). Can't use enum CELL_IDENT for that, because it doesn't have a value for just a PLMN (and is not a bitmask). Change-Id: Ib9af67b100c4583342a2103669732dab2e577b04
This commit is contained in:
parent
d4b79c8772
commit
3a5045302f
|
@ -84,6 +84,9 @@ int gsm0808_cell_id_u_name(char *buf, size_t buflen,
|
|||
bool gsm0808_cell_ids_match(const struct gsm0808_cell_id *id1, const struct gsm0808_cell_id *id2, bool exact_match);
|
||||
int gsm0808_cell_id_matches_list(const struct gsm0808_cell_id *id, const struct gsm0808_cell_id_list2 *list,
|
||||
unsigned int match_nr, bool exact_match);
|
||||
void gsm0808_cell_id_from_cgi(struct gsm0808_cell_id *cid, enum CELL_IDENT id_discr,
|
||||
const struct osmo_cell_global_id *cgi);
|
||||
int gsm0808_cell_id_to_cgi(struct osmo_cell_global_id *cgi, const struct gsm0808_cell_id *cid);
|
||||
|
||||
uint8_t gsm0808_enc_cause(struct msgb *msg, uint16_t cause);
|
||||
uint8_t gsm0808_enc_aoip_trasp_addr(struct msgb *msg,
|
||||
|
|
|
@ -30,6 +30,15 @@ struct osmo_cell_global_id {
|
|||
uint16_t cell_identity;
|
||||
};
|
||||
|
||||
/*! Bitmask of items contained in a struct osmo_cell_global_id.
|
||||
* See also gsm0808_cell_id_to_cgi().
|
||||
*/
|
||||
enum osmo_cgi_part {
|
||||
OSMO_CGI_PART_PLMN = 1,
|
||||
OSMO_CGI_PART_LAC = 2,
|
||||
OSMO_CGI_PART_CI = 4,
|
||||
};
|
||||
|
||||
/* Actually defined in 3GPP TS 48.008 3.2.2.27 Cell Identifier List,
|
||||
* but conceptually belongs with the above structures. */
|
||||
struct osmo_lac_and_ci_id {
|
||||
|
|
|
@ -1577,6 +1577,93 @@ int gsm0808_cell_id_matches_list(const struct gsm0808_cell_id *id, const struct
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*! Copy information from a CGI to form a Cell Identifier of the specified kind.
|
||||
* \param [out] cid Compose new Cell Identifier here.
|
||||
* \param [in] id_discr Which kind of Cell Identifier to compose.
|
||||
* \param [in] cgi Cell Global Identifier to form the Cell Identifier from.
|
||||
*/
|
||||
void gsm0808_cell_id_from_cgi(struct gsm0808_cell_id *cid, enum CELL_IDENT id_discr,
|
||||
const struct osmo_cell_global_id *cgi)
|
||||
{
|
||||
*cid = (struct gsm0808_cell_id){
|
||||
.id_discr = id_discr,
|
||||
};
|
||||
|
||||
switch (id_discr) {
|
||||
case CELL_IDENT_WHOLE_GLOBAL:
|
||||
cid->id.global = *cgi;
|
||||
return;
|
||||
|
||||
case CELL_IDENT_LAC_AND_CI:
|
||||
cid->id.lac_and_ci = (struct osmo_lac_and_ci_id){
|
||||
.lac = cgi->lai.lac,
|
||||
.ci = cgi->cell_identity,
|
||||
};
|
||||
return;
|
||||
|
||||
case CELL_IDENT_CI:
|
||||
cid->id.ci = cgi->cell_identity;
|
||||
return;
|
||||
|
||||
case CELL_IDENT_LAI:
|
||||
cid->id.lai_and_lac = cgi->lai;
|
||||
return;
|
||||
|
||||
case CELL_IDENT_LAC:
|
||||
cid->id.lac = cgi->lai.lac;
|
||||
return;
|
||||
|
||||
case CELL_IDENT_NO_CELL:
|
||||
case CELL_IDENT_BSS:
|
||||
case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
|
||||
case CELL_IDENT_UTRAN_RNC:
|
||||
case CELL_IDENT_UTRAN_LAC_RNC:
|
||||
default:
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
/*! Overwrite parts of cgi with values from a Cell Identifier.
|
||||
* Place only those items given in cid into cgi, leaving other values unchanged.
|
||||
* \param[out] cgi Cell Global Identity to write to.
|
||||
* \param[in] cid Cell Identity to read from.
|
||||
* \return a bitmask of items that were set: OSMO_CGI_PART_PLMN | OSMO_CGI_PART_LAC | OSMO_CGI_PART_CI; 0 if nothing was
|
||||
* written to cgi.
|
||||
*/
|
||||
int gsm0808_cell_id_to_cgi(struct osmo_cell_global_id *cgi, const struct gsm0808_cell_id *cid)
|
||||
{
|
||||
switch (cid->id_discr) {
|
||||
case CELL_IDENT_WHOLE_GLOBAL:
|
||||
*cgi = cid->id.global;
|
||||
return OSMO_CGI_PART_PLMN | OSMO_CGI_PART_LAC | OSMO_CGI_PART_CI;
|
||||
|
||||
case CELL_IDENT_LAC_AND_CI:
|
||||
cgi->lai.lac = cid->id.lac_and_ci.lac;
|
||||
cgi->cell_identity = cid->id.lac_and_ci.ci;
|
||||
return OSMO_CGI_PART_LAC | OSMO_CGI_PART_CI;
|
||||
|
||||
case CELL_IDENT_CI:
|
||||
cgi->cell_identity = cid->id.ci;
|
||||
return OSMO_CGI_PART_CI;
|
||||
|
||||
case CELL_IDENT_LAI:
|
||||
cgi->lai = cid->id.lai_and_lac;
|
||||
return OSMO_CGI_PART_PLMN | OSMO_CGI_PART_LAC;
|
||||
|
||||
case CELL_IDENT_LAC:
|
||||
cgi->lai.lac = cid->id.lac;
|
||||
return OSMO_CGI_PART_LAC;
|
||||
|
||||
case CELL_IDENT_NO_CELL:
|
||||
case CELL_IDENT_BSS:
|
||||
case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
|
||||
case CELL_IDENT_UTRAN_RNC:
|
||||
case CELL_IDENT_UTRAN_LAC_RNC:
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
/*! value_string[] for enum CELL_IDENT. */
|
||||
const struct value_string gsm0808_cell_id_discr_names[] = {
|
||||
{ CELL_IDENT_WHOLE_GLOBAL, "CGI" },
|
||||
|
|
|
@ -205,6 +205,8 @@ gsm0808_dec_cell_id_list;
|
|||
gsm0808_dec_cell_id_list2;
|
||||
gsm0808_cell_id_list_add;
|
||||
gsm0808_cell_id_to_list;
|
||||
gsm0808_cell_id_to_cgi;
|
||||
gsm0808_cell_id_from_cgi;
|
||||
gsm0808_enc_cell_id;
|
||||
gsm0808_dec_cell_id;
|
||||
gsm0808_cell_id_name;
|
||||
|
|
|
@ -2206,29 +2206,96 @@ static bool test_cell_id_list_matching_discrs(bool test_match,
|
|||
return true;
|
||||
}
|
||||
|
||||
const enum CELL_IDENT cell_ident_discrs[] = {
|
||||
CELL_IDENT_LAC, CELL_IDENT_CI, CELL_IDENT_LAC_AND_CI, CELL_IDENT_LAI_AND_LAC,
|
||||
CELL_IDENT_WHOLE_GLOBAL,
|
||||
};
|
||||
|
||||
|
||||
static void test_cell_id_list_matching(bool test_match)
|
||||
{
|
||||
int i, j;
|
||||
bool ok = true;
|
||||
|
||||
const enum CELL_IDENT discrs[] = {
|
||||
CELL_IDENT_LAC, CELL_IDENT_CI, CELL_IDENT_LAC_AND_CI, CELL_IDENT_LAI_AND_LAC,
|
||||
CELL_IDENT_WHOLE_GLOBAL,
|
||||
};
|
||||
|
||||
printf("\n%s(%s)\n", __func__, test_match ? "test match" : "test mismatch");
|
||||
|
||||
/* Autogenerate Cell ID lists from above dataset, which should match / not match. */
|
||||
for (i = 0; i < ARRAY_SIZE(discrs); i++) {
|
||||
for (j = 0; j < ARRAY_SIZE(discrs); j++)
|
||||
for (i = 0; i < ARRAY_SIZE(cell_ident_discrs); i++) {
|
||||
for (j = 0; j < ARRAY_SIZE(cell_ident_discrs); j++)
|
||||
if (!test_cell_id_list_matching_discrs(test_match,
|
||||
discrs[i], discrs[j]))
|
||||
cell_ident_discrs[i], cell_ident_discrs[j]))
|
||||
ok = false;
|
||||
}
|
||||
|
||||
OSMO_ASSERT(ok);
|
||||
}
|
||||
|
||||
|
||||
static const struct gsm0808_cell_id test_gsm0808_cell_id_to_from_cgi_data[] = {
|
||||
lac_23,
|
||||
lac_42,
|
||||
ci_5,
|
||||
ci_6,
|
||||
lac_ci_23_5,
|
||||
lac_ci_42_6,
|
||||
lai_23_042_23,
|
||||
lai_23_042_42,
|
||||
lai_23_99_23,
|
||||
lai_23_42_23,
|
||||
cgi_23_042_23_5,
|
||||
cgi_23_042_42_6,
|
||||
cgi_23_99_23_5,
|
||||
{ .id_discr = CELL_IDENT_NO_CELL },
|
||||
{ .id_discr = 423 },
|
||||
};
|
||||
|
||||
static void test_gsm0808_cell_id_to_from_cgi()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
printf("\n%s()\n", __func__);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_gsm0808_cell_id_to_from_cgi_data); i++) {
|
||||
const struct gsm0808_cell_id *from_cid = &test_gsm0808_cell_id_to_from_cgi_data[i];
|
||||
struct osmo_cell_global_id cgi = {
|
||||
.lai = {
|
||||
.plmn = {
|
||||
.mcc = 777,
|
||||
.mnc = 7,
|
||||
.mnc_3_digits = true,
|
||||
},
|
||||
.lac = 7777,
|
||||
},
|
||||
.cell_identity = 7777,
|
||||
};
|
||||
struct gsm0808_cell_id cid = {};
|
||||
int rc;
|
||||
|
||||
rc = gsm0808_cell_id_to_cgi(&cgi, from_cid);
|
||||
printf("cid %s -> cgi %s", gsm0808_cell_id_name(from_cid), osmo_cgi_name(&cgi));
|
||||
|
||||
if (rc & OSMO_CGI_PART_PLMN)
|
||||
printf(" PLMN");
|
||||
if (rc & OSMO_CGI_PART_LAC)
|
||||
printf(" LAC");
|
||||
if (rc & OSMO_CGI_PART_CI)
|
||||
printf(" CI");
|
||||
|
||||
gsm0808_cell_id_from_cgi(&cid, from_cid->id_discr, &cgi);
|
||||
printf(" -> cid %s\n", gsm0808_cell_id_name(&cid));
|
||||
if (!gsm0808_cell_ids_match(from_cid, &cid, true))
|
||||
printf(" MISMATCH!\n");
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(cell_ident_discrs); j++) {
|
||||
enum CELL_IDENT discr = cell_ident_discrs[j];
|
||||
|
||||
gsm0808_cell_id_from_cgi(&cid, discr, &cgi);
|
||||
printf(" --> gsm0808_cell_id{%s} = %s\n", gsm0808_cell_id_discr_name(discr), gsm0808_cell_id_name(&cid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *ctx = talloc_named_const(NULL, 0, "gsm0808 test");
|
||||
|
@ -2300,6 +2367,8 @@ int main(int argc, char **argv)
|
|||
test_cell_id_list_matching(true);
|
||||
test_cell_id_list_matching(false);
|
||||
|
||||
test_gsm0808_cell_id_to_from_cgi();
|
||||
|
||||
printf("Done\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -629,4 +629,96 @@ CGI:023-042-23-5 and CI[1]:{6}: mismatch
|
|||
CGI:023-042-23-5 and LAC-CI[1]:{42-6}: mismatch
|
||||
CGI:023-042-23-5 and LAI[3]:{023-042-42, 023-99-23, 023-42-23}: mismatch
|
||||
CGI:023-042-23-5 and CGI[2]:{023-042-42-6, 023-99-23-5}: mismatch
|
||||
|
||||
test_gsm0808_cell_id_to_from_cgi()
|
||||
cid LAC:23 -> cgi 777-007-23-7777 LAC -> cid LAC:23
|
||||
--> gsm0808_cell_id{LAC} = LAC:23
|
||||
--> gsm0808_cell_id{CI} = CI:7777
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:23-7777
|
||||
--> gsm0808_cell_id{LAI} = LAI:777-007-23
|
||||
--> gsm0808_cell_id{CGI} = CGI:777-007-23-7777
|
||||
cid LAC:42 -> cgi 777-007-42-7777 LAC -> cid LAC:42
|
||||
--> gsm0808_cell_id{LAC} = LAC:42
|
||||
--> gsm0808_cell_id{CI} = CI:7777
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:42-7777
|
||||
--> gsm0808_cell_id{LAI} = LAI:777-007-42
|
||||
--> gsm0808_cell_id{CGI} = CGI:777-007-42-7777
|
||||
cid CI:5 -> cgi 777-007-7777-5 CI -> cid CI:5
|
||||
--> gsm0808_cell_id{LAC} = LAC:7777
|
||||
--> gsm0808_cell_id{CI} = CI:5
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-5
|
||||
--> gsm0808_cell_id{LAI} = LAI:777-007-7777
|
||||
--> gsm0808_cell_id{CGI} = CGI:777-007-7777-5
|
||||
cid CI:6 -> cgi 777-007-7777-6 CI -> cid CI:6
|
||||
--> gsm0808_cell_id{LAC} = LAC:7777
|
||||
--> gsm0808_cell_id{CI} = CI:6
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-6
|
||||
--> gsm0808_cell_id{LAI} = LAI:777-007-7777
|
||||
--> gsm0808_cell_id{CGI} = CGI:777-007-7777-6
|
||||
cid LAC-CI:23-5 -> cgi 777-007-23-5 LAC CI -> cid LAC-CI:23-5
|
||||
--> gsm0808_cell_id{LAC} = LAC:23
|
||||
--> gsm0808_cell_id{CI} = CI:5
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:23-5
|
||||
--> gsm0808_cell_id{LAI} = LAI:777-007-23
|
||||
--> gsm0808_cell_id{CGI} = CGI:777-007-23-5
|
||||
cid LAC-CI:42-6 -> cgi 777-007-42-6 LAC CI -> cid LAC-CI:42-6
|
||||
--> gsm0808_cell_id{LAC} = LAC:42
|
||||
--> gsm0808_cell_id{CI} = CI:6
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:42-6
|
||||
--> gsm0808_cell_id{LAI} = LAI:777-007-42
|
||||
--> gsm0808_cell_id{CGI} = CGI:777-007-42-6
|
||||
cid LAI:023-042-23 -> cgi 023-042-23-7777 PLMN LAC -> cid LAI:023-042-23
|
||||
--> gsm0808_cell_id{LAC} = LAC:23
|
||||
--> gsm0808_cell_id{CI} = CI:7777
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:23-7777
|
||||
--> gsm0808_cell_id{LAI} = LAI:023-042-23
|
||||
--> gsm0808_cell_id{CGI} = CGI:023-042-23-7777
|
||||
cid LAI:023-042-42 -> cgi 023-042-42-7777 PLMN LAC -> cid LAI:023-042-42
|
||||
--> gsm0808_cell_id{LAC} = LAC:42
|
||||
--> gsm0808_cell_id{CI} = CI:7777
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:42-7777
|
||||
--> gsm0808_cell_id{LAI} = LAI:023-042-42
|
||||
--> gsm0808_cell_id{CGI} = CGI:023-042-42-7777
|
||||
cid LAI:023-99-23 -> cgi 023-99-23-7777 PLMN LAC -> cid LAI:023-99-23
|
||||
--> gsm0808_cell_id{LAC} = LAC:23
|
||||
--> gsm0808_cell_id{CI} = CI:7777
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:23-7777
|
||||
--> gsm0808_cell_id{LAI} = LAI:023-99-23
|
||||
--> gsm0808_cell_id{CGI} = CGI:023-99-23-7777
|
||||
cid LAI:023-42-23 -> cgi 023-42-23-7777 PLMN LAC -> cid LAI:023-42-23
|
||||
--> gsm0808_cell_id{LAC} = LAC:23
|
||||
--> gsm0808_cell_id{CI} = CI:7777
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:23-7777
|
||||
--> gsm0808_cell_id{LAI} = LAI:023-42-23
|
||||
--> gsm0808_cell_id{CGI} = CGI:023-42-23-7777
|
||||
cid CGI:023-042-23-5 -> cgi 023-042-23-5 PLMN LAC CI -> cid CGI:023-042-23-5
|
||||
--> gsm0808_cell_id{LAC} = LAC:23
|
||||
--> gsm0808_cell_id{CI} = CI:5
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:23-5
|
||||
--> gsm0808_cell_id{LAI} = LAI:023-042-23
|
||||
--> gsm0808_cell_id{CGI} = CGI:023-042-23-5
|
||||
cid CGI:023-042-42-6 -> cgi 023-042-42-6 PLMN LAC CI -> cid CGI:023-042-42-6
|
||||
--> gsm0808_cell_id{LAC} = LAC:42
|
||||
--> gsm0808_cell_id{CI} = CI:6
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:42-6
|
||||
--> gsm0808_cell_id{LAI} = LAI:023-042-42
|
||||
--> gsm0808_cell_id{CGI} = CGI:023-042-42-6
|
||||
cid CGI:023-99-23-5 -> cgi 023-99-23-5 PLMN LAC CI -> cid CGI:023-99-23-5
|
||||
--> gsm0808_cell_id{LAC} = LAC:23
|
||||
--> gsm0808_cell_id{CI} = CI:5
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:23-5
|
||||
--> gsm0808_cell_id{LAI} = LAI:023-99-23
|
||||
--> gsm0808_cell_id{CGI} = CGI:023-99-23-5
|
||||
cid NO-CELL:NO-CELL -> cgi 777-007-7777-7777 -> cid NO-CELL:NO-CELL
|
||||
--> gsm0808_cell_id{LAC} = LAC:7777
|
||||
--> gsm0808_cell_id{CI} = CI:7777
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-7777
|
||||
--> gsm0808_cell_id{LAI} = LAI:777-007-7777
|
||||
--> gsm0808_cell_id{CGI} = CGI:777-007-7777-7777
|
||||
cid unknown 0x1a7:unknown 0x1a7 -> cgi 777-007-7777-7777 -> cid unknown 0x1a7:unknown 0x1a7
|
||||
--> gsm0808_cell_id{LAC} = LAC:7777
|
||||
--> gsm0808_cell_id{CI} = CI:7777
|
||||
--> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-7777
|
||||
--> gsm0808_cell_id{LAI} = LAI:777-007-7777
|
||||
--> gsm0808_cell_id{CGI} = CGI:777-007-7777-7777
|
||||
Done
|
||||
|
|
Loading…
Reference in New Issue