aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2021-02-15 16:26:37 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2021-02-15 16:42:46 +0100
commit524898504af2251b740be9621d184db1b9b875ee (patch)
tree9ce979f530a3e1febcd6dc7b355517afe8ec566d
parent85a0f1143d0e2bb9ad34c675bcca384e8e84badf (diff)
gsm: Fix encoding of gsm0808_cell_id_list2 with CGI-PS types
CGI-PS type doesn't exist in GSM 08.08 Cell Id lists. That type of cell id is osmocom-specific and used internally. In here CGI-PS is automatically converted to CGI (since the later is an extension of this one). The encode/decode_cell_id_u are left intact (comment added) since those can still be used (and are used by RIM code) to encode/decode TS 48.018 Cell Identifiers. Related: SYS#4909 Change-Id: Id74f4577c397c1ba696f00395858311bd82cb2c8
-rw-r--r--src/gsm/gsm0808_utils.c23
-rw-r--r--tests/gsm0808/gsm0808_test.c43
2 files changed, 63 insertions, 3 deletions
diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c
index e0f0c28b..dda73adb 100644
--- a/src/gsm/gsm0808_utils.c
+++ b/src/gsm/gsm0808_utils.c
@@ -877,6 +877,7 @@ int gsm0808_decode_cell_id_u(union gsm0808_cell_id_u *out, enum CELL_IDENT discr
/* Does not have any list items */
break;
case CELL_IDENT_WHOLE_GLOBAL_PS:
+ /* 3GPP TS 48.018 sec 11.3.9 "Cell Identifier" */
if (len < 8)
return -EINVAL;
decode_lai(buf, (struct osmo_location_area_id *)&out->global_ps.rai); /* rai contains lai + non-decoded rac */
@@ -925,6 +926,7 @@ void gsm0808_msgb_put_cell_id_u(struct msgb *msg, enum CELL_IDENT id_discr, cons
/* Does not have any list items */
break;
case CELL_IDENT_WHOLE_GLOBAL_PS: {
+ /* 3GPP TS 48.018 sec 11.3.9 "Cell Identifier" */
const struct osmo_cell_global_id_ps *id = &u->global_ps;
struct gsm48_loc_area_id lai;
gsm48_generate_lai2(&lai, &id->rai.lac);
@@ -949,6 +951,7 @@ uint8_t gsm0808_enc_cell_id_list2(struct msgb *msg,
uint8_t *old_tail;
uint8_t *tlv_len;
unsigned int i;
+ uint8_t id_discr;
OSMO_ASSERT(msg);
OSMO_ASSERT(cil);
@@ -957,11 +960,25 @@ uint8_t gsm0808_enc_cell_id_list2(struct msgb *msg,
tlv_len = msgb_put(msg, 1);
old_tail = msg->tail;
- msgb_put_u8(msg, cil->id_discr & 0x0f);
+ /* CGI-PS is an osmocom-specific type. In here we don't care about the
+ * PS part, only the CS one. */
+ if (cil->id_discr == CELL_IDENT_WHOLE_GLOBAL_PS)
+ id_discr = CELL_IDENT_WHOLE_GLOBAL;
+ else
+ id_discr = cil->id_discr & 0x0f;
+
+ msgb_put_u8(msg, id_discr);
OSMO_ASSERT(cil->id_list_len <= GSM0808_CELL_ID_LIST2_MAXLEN);
- for (i = 0; i < cil->id_list_len; i++)
- gsm0808_msgb_put_cell_id_u(msg, cil->id_discr, &cil->id_list[i]);
+ for (i = 0; i < cil->id_list_len; i++) {
+ if (cil->id_discr == CELL_IDENT_WHOLE_GLOBAL_PS) {
+ union gsm0808_cell_id_u u;
+ cell_id_to_cgi(&u.global, cil->id_discr, &cil->id_list[i]);
+ gsm0808_msgb_put_cell_id_u(msg, CELL_IDENT_WHOLE_GLOBAL, &u);
+ } else {
+ gsm0808_msgb_put_cell_id_u(msg, cil->id_discr, &cil->id_list[i]);
+ }
+ }
*tlv_len = (uint8_t) (msg->tail - old_tail);
return *tlv_len + 2;
diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c
index 7eb53c2b..04b3b727 100644
--- a/tests/gsm0808/gsm0808_test.c
+++ b/tests/gsm0808/gsm0808_test.c
@@ -1760,6 +1760,48 @@ static void test_gsm0808_enc_dec_cell_id_global()
msgb_free(msg);
}
+static void test_gsm0808_enc_dec_cell_id_global_ps()
+{
+ struct gsm0808_cell_id enc_cgi = {
+ .id_discr = CELL_IDENT_WHOLE_GLOBAL,
+ .id.global = {
+ .lai = {
+ .plmn = { .mcc = 123, .mnc = 456 },
+ .lac = 0x2342
+ },
+ .cell_identity = 0x423,
+ }
+ };
+ struct gsm0808_cell_id enc_cgi_ps = {
+ .id_discr = CELL_IDENT_WHOLE_GLOBAL_PS,
+ .id.global_ps = {
+ .rai = {
+ .lac = {
+ .plmn = { .mcc = 123, .mnc = 456 },
+ .lac = 0x2342
+ },
+ .rac = 0xcc,
+ },
+ .cell_identity = 0x423,
+ }
+ };
+ struct msgb *msg_cgi, *msg_cgi_ps;
+ uint8_t rc_enc;
+
+ msg_cgi = msgb_alloc(1024, "output buffer (CGI)");
+ rc_enc = gsm0808_enc_cell_id(msg_cgi, &enc_cgi);
+ OSMO_ASSERT(rc_enc > 0);
+
+ msg_cgi_ps = msgb_alloc(1024, "output buffer (CGI-PS)");
+ rc_enc = gsm0808_enc_cell_id(msg_cgi_ps, &enc_cgi_ps);
+ OSMO_ASSERT(rc_enc > 0);
+
+ OSMO_ASSERT(msgb_eq(msg_cgi, msg_cgi_ps));
+
+ msgb_free(msg_cgi);
+ msgb_free(msg_cgi_ps);
+}
+
static void test_gsm0808_sc_cfg_from_gsm48_mr_cfg_single(struct gsm48_multi_rate_conf *cfg)
{
uint16_t s15_s0;
@@ -2462,6 +2504,7 @@ int main(int argc, char **argv)
test_gsm0808_enc_dec_cell_id_ci();
test_gsm0808_enc_dec_cell_id_lac_and_ci();
test_gsm0808_enc_dec_cell_id_global();
+ test_gsm0808_enc_dec_cell_id_global_ps();
test_gsm0808_sc_cfg_from_gsm48_mr_cfg();
test_gsm48_mr_cfg_from_gsm0808_sc_cfg();