Stefan Sperling has submitted this change and it was merged.

Change subject: use libosmocore to parse cell identifiers in osmo-bsc
......................................................................


use libosmocore to parse cell identifiers in osmo-bsc

This replaces custom cell identifier parsing in the paging code with
calls to the new cell identifier parser implementation in libosmocore
(which was derived from the code that is now being replaced here).

The bssap tests will fail unless this other change is merged to
libosmocore as well: https://gerrit.osmocom.org/#/c/7288/

Related: OS#2847
Change-Id: I9e2002fbbe135287e9ce09caa3f0a85a84529463
Depends: I7f3e8ace26176e9cbfe2542961d2a95662aa4d97
---
M src/osmo-bsc/osmo_bsc_bssap.c
1 file changed, 49 insertions(+), 86 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index db749a3..176a413 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -260,18 +260,6 @@
        return ret;
 }
 
-/* Decode 5-byte LAI list element data (see TS 08.08 3.2.2.27) into 
MCC/MNC/LAC.
- * Return 0 if successful, negative on error. */
-static void
-decode_lai(const uint8_t *data, struct osmo_location_area_id *laid)
-{
-       struct gsm48_loc_area_id lai;
-
-       /* Copy data to stack to prevent unaligned access in 
gsm48_decode_lai(). */
-       memcpy(&lai, data, sizeof(lai)); /* don't byte swap yet */
-       gsm48_decode_lai2(&lai, laid);
-}
-
 static void
 page_all_bts(struct bsc_msc_data *msc, uint32_t tmsi, const char *mi_string, 
uint8_t chan_needed)
 {
@@ -283,83 +271,71 @@
 }
 
 static void
-page_cgi(struct bsc_msc_data *msc, const uint8_t *data, uint8_t data_length, 
size_t remain,
+page_cgi(struct bsc_msc_data *msc, struct gsm0808_cell_id_list2 *cil,
         uint32_t tmsi, const char *mi_string, uint8_t chan_needed)
 {
-       uint16_t ci;
-       int i = 0;
-       while (remain >= sizeof(struct gsm48_loc_area_id) + sizeof(ci)) {
-               struct osmo_location_area_id lai;
-               uint16_t *ci_be;
-               size_t lai_offset = 1 + i * (sizeof(struct gsm48_loc_area_id) + 
sizeof(ci));
-               decode_lai(&data[lai_offset], &lai);
-               ci_be = (uint16_t *)(&data[lai_offset + sizeof(struct 
gsm48_loc_area_id)]);
-               ci = osmo_load16be(ci_be);
-               if (!osmo_plmn_cmp(&lai.plmn, &msc->network->plmn)) {
+       int i;
+       for (i = 0; i < cil->id_list_len; i++) {
+               struct osmo_cell_global_id *id = &cil->id_list[i].global;
+               if (!osmo_plmn_cmp(&id->lai.plmn, &msc->network->plmn)) {
                        int paged = 0;
                        struct gsm_bts *bts;
                        llist_for_each_entry(bts, &msc->network->bts_list, 
list) {
-                               if (bts->location_area_code != lai.lac)
+                               if (bts->location_area_code != id->lai.lac)
                                        continue;
-                               if (bts->cell_identity != ci)
+                               if (bts->cell_identity != id->cell_identity)
                                        continue;
                                /* ignore errors from page_subscriber(); keep 
trying other BTS */
-                               page_subscriber(msc, bts, tmsi, lai.lac, 
mi_string, chan_needed);
+                               page_subscriber(msc, bts, tmsi, id->lai.lac, 
mi_string, chan_needed);
                                paged = 1;
                        }
                        if (!paged) {
                                LOGP(DMSC, LOGL_NOTICE, "Paging IMSI %s: BTS 
with LAC %d and CI %d not found\n",
-                                    mi_string, lai.lac, ci);
+                                    mi_string, id->lai.lac, id->cell_identity);
                        }
                } else {
                        LOGP(DMSC, LOGL_DEBUG, "Paging IMSI %s: MCC-MNC in Cell 
Identifier List "
                             "(%s) do not match our network (%s)\n",
-                            mi_string, osmo_plmn_name(&lai.plmn),
+                            mi_string, osmo_plmn_name(&id->lai.plmn),
                             osmo_plmn_name2(&msc->network->plmn));
                }
-               remain -= sizeof(struct gsm48_loc_area_id) + sizeof(ci);
-               i++;
        }
 }
 
 static void
-page_lac_and_ci(struct bsc_msc_data *msc, const uint8_t *data, size_t remain,
+page_lac_and_ci(struct bsc_msc_data *msc, struct gsm0808_cell_id_list2 *cil,
         uint32_t tmsi, const char *mi_string, uint8_t chan_needed)
 {
-       uint16_t *lacp_be, *ci_be;
-       lacp_be = (uint16_t *)(&data[1]);
-       ci_be = (uint16_t *)(&data[3]);
-       while (remain >= sizeof(*lacp_be) + sizeof(*ci_be)) {
-               uint16_t lac = osmo_load16be(lacp_be);
-               uint16_t ci = osmo_load16be(ci_be);
+       int i;
+
+       for (i = 0; i < cil->id_list_len; i++) {
+               struct osmo_lac_and_ci_id *id = &cil->id_list[i].lac_and_ci;
                int paged = 0;
                struct gsm_bts *bts;
                llist_for_each_entry(bts, &msc->network->bts_list, list) {
-                       if (bts->location_area_code != lac)
+                       if (bts->location_area_code != id->lac)
                                continue;
-                       if (bts->cell_identity != ci)
+                       if (bts->cell_identity != id->ci)
                                continue;
                        /* ignore errors from page_subscriber(); keep trying 
other BTS */
-                       page_subscriber(msc, bts, tmsi, lac, mi_string, 
chan_needed);
+                       page_subscriber(msc, bts, tmsi, id->lac, mi_string, 
chan_needed);
                        paged = 1;
                }
                if (!paged) {
                        LOGP(DMSC, LOGL_NOTICE, "Paging IMSI %s: BTS with LAC 
%d and CI %d not found\n",
-                            mi_string, lac, ci);
+                            mi_string, id->lac, id->ci);
                }
-               remain -= sizeof(*lacp_be) + sizeof(*ci_be);
-               lacp_be++;
-               ci_be++;
        }
 }
 
 static void
-page_ci(struct bsc_msc_data *msc, const uint8_t *data, size_t remain,
+page_ci(struct bsc_msc_data *msc, struct gsm0808_cell_id_list2 *cil,
         uint32_t tmsi, const char *mi_string, uint8_t chan_needed)
 {
-       uint16_t *ci_be = (uint16_t *)(&data[1]);
-       while (remain >= sizeof(*ci_be)) {
-               uint16_t ci = osmo_load16be(ci_be);
+       int i;
+
+       for (i = 0; i < cil->id_list_len; i++) {
+               uint16_t ci = cil->id_list[i].ci;
                int paged = 0;
                struct gsm_bts *bts;
                llist_for_each_entry(bts, &msc->network->bts_list, list) {
@@ -373,51 +349,48 @@
                        LOGP(DMSC, LOGL_NOTICE, "Paging IMSI %s: BTS with CI %d 
not found\n",
                             mi_string, ci);
                }
-               remain -= sizeof(*ci_be);
-               ci_be++;
        }
 }
 
 static void
-page_lai_and_lac(struct bsc_msc_data *msc, const uint8_t *data, size_t 
data_length, size_t remain,
+page_lai_and_lac(struct bsc_msc_data *msc, struct gsm0808_cell_id_list2 *cil,
         uint32_t tmsi, const char *mi_string, uint8_t chan_needed)
 {
-       int i = 0;
-       while (remain >= sizeof(struct gsm48_loc_area_id)) {
-               struct osmo_location_area_id lai;
-               decode_lai(&data[1 + i * sizeof(struct gsm48_loc_area_id)], 
&lai);
-               if (!osmo_plmn_cmp(&lai.plmn, &msc->network->plmn)) {
+       int i;
+
+       for (i = 0; i < cil->id_list_len; i++) {
+               struct osmo_location_area_id *id = &cil->id_list[i].lai_and_lac;
+               if (!osmo_plmn_cmp(&id->plmn, &msc->network->plmn)) {
                        int paged = 0;
                        struct gsm_bts *bts;
                        llist_for_each_entry(bts, &msc->network->bts_list, 
list) {
-                               if (bts->location_area_code != lai.lac)
+                               if (bts->location_area_code != id->lac)
                                        continue;
                                /* ignore errors from page_subscriber(); keep 
trying other BTS */
-                               page_subscriber(msc, bts, tmsi, lai.lac, 
mi_string, chan_needed);
+                               page_subscriber(msc, bts, tmsi, id->lac, 
mi_string, chan_needed);
                                paged = 1;
                        }
                        if (!paged) {
                                LOGP(DMSC, LOGL_NOTICE, "Paging IMSI %s: BTS 
with LAC %d not found\n",
-                                    mi_string, lai.lac);
+                                    mi_string, id->lac);
                        }
                } else {
                        LOGP(DMSC, LOGL_DEBUG, "Paging IMSI %s: MCC-MNC in Cell 
Identifier List "
                             "(%s) do not match our network (%s)\n",
-                            mi_string, osmo_plmn_name(&lai.plmn),
+                            mi_string, osmo_plmn_name(&id->plmn),
                             osmo_plmn_name2(&msc->network->plmn));
                }
-               remain -= sizeof(struct gsm48_loc_area_id);
-               i++;
        }
 }
 
 static void
-page_lac(struct bsc_msc_data *msc, const uint8_t *data, size_t remain,
+page_lac(struct bsc_msc_data *msc, struct gsm0808_cell_id_list2 *cil,
         uint32_t tmsi, const char *mi_string, uint8_t chan_needed)
 {
-       uint16_t *lacp_be = (uint16_t *)(&data[1]);
-       while (remain >= sizeof(*lacp_be)) {
-               uint16_t lac = osmo_load16be(lacp_be);
+       int i;
+
+       for (i = 0; i < cil->id_list_len; i++) {
+               uint16_t lac = cil->id_list[i].lac;
                int paged = 0;
                struct gsm_bts *bts;
                llist_for_each_entry(bts, &msc->network->bts_list, list) {
@@ -431,8 +404,6 @@
                        LOGP(DMSC, LOGL_NOTICE, "Paging IMSI %s: BTS with LAC 
%d not found\n",
                             mi_string, lac);
                }
-               remain -= sizeof(*lacp_be);
-               lacp_be++;
        }
 }
 
@@ -447,7 +418,7 @@
        int remain;
        const uint8_t *data;
        uint8_t chan_needed = RSL_CHANNEED_ANY;
-       uint8_t cell_ident;
+       struct gsm0808_cell_id_list2 cil;
 
        tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, payload_length - 1, 
0, 0);
        remain = payload_length - 1;
@@ -490,17 +461,12 @@
         */
        data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
        data = TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
-
-       if (data_length < 1) {
-               LOGP(DMSC, LOGL_ERROR, "Paging IMSI %s: Zero length Cell 
Identifier List\n",
-                    mi_string);
-               return -1;
-       } else if (data_length > remain) {
+       if (gsm0808_dec_cell_id_list2(&cil, data, data_length) < 0) {
                LOGP(DMSC, LOGL_ERROR, "Paging IMSI %s: Bogus Cell Identifier 
List length\n",
                     mi_string);
                return -1;
        }
-       remain = data_length; /* ignore payload padding data beyond data_length 
*/
+       remain = 0;
 
        if (TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_NEEDED) && TLVP_LEN(&tp, 
GSM0808_IE_CHANNEL_NEEDED) == 1)
                chan_needed = TLVP_VAL(&tp, GSM0808_IE_CHANNEL_NEEDED)[0] & 
0x03;
@@ -509,34 +475,31 @@
                LOGP(DMSC, LOGL_ERROR, "eMLPP is not handled\n");
        }
 
-       cell_ident = data[0] & 0xf;
-       remain -= 1; /* cell ident consumed */
-
        rate_ctr_inc(&msc->network->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED]);
 
-       switch (cell_ident) {
+       switch (cil.id_discr) {
        case CELL_IDENT_NO_CELL:
                page_all_bts(msc, tmsi, mi_string, chan_needed);
                break;
 
        case CELL_IDENT_WHOLE_GLOBAL:
-               page_cgi(msc, data, data_length, remain, tmsi, mi_string, 
chan_needed);
+               page_cgi(msc, &cil, tmsi, mi_string, chan_needed);
                break;
 
        case CELL_IDENT_LAC_AND_CI:
-               page_lac_and_ci(msc, data, remain, tmsi, mi_string, 
chan_needed);
+               page_lac_and_ci(msc, &cil, tmsi, mi_string, chan_needed);
                break;
 
        case CELL_IDENT_CI:
-               page_ci(msc, data, remain, tmsi, mi_string, chan_needed);
+               page_ci(msc, &cil, tmsi, mi_string, chan_needed);
                break;
 
        case CELL_IDENT_LAI_AND_LAC:
-               page_lai_and_lac(msc, data, data_length, remain, tmsi, 
mi_string, chan_needed);
+               page_lai_and_lac(msc, &cil, tmsi, mi_string, chan_needed);
                break;
 
        case CELL_IDENT_LAC:
-               page_lac(msc, data, remain, tmsi, mi_string, chan_needed);
+               page_lac(msc, &cil, tmsi, mi_string, chan_needed);
                break;
 
        case CELL_IDENT_BSS:
@@ -551,7 +514,7 @@
        default:
                LOGP(DMSC, LOGL_NOTICE, "Paging IMSI %s: unimplemented Cell 
Identifier List (0x%x),"
                     " paging entire BSS instead (%s)\n",
-                    mi_string, cell_ident, osmo_hexdump(data, data_length));
+                    mi_string, cil.id_discr, osmo_hexdump(data, data_length));
                page_all_bts(msc, tmsi, mi_string, chan_needed);
                break;
        }

-- 
To view, visit https://gerrit.osmocom.org/7289
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I9e2002fbbe135287e9ce09caa3f0a85a84529463
Gerrit-PatchSet: 3
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Owner: Stefan Sperling <ssperl...@sysmocom.de>
Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Stefan Sperling <ssperl...@sysmocom.de>

Reply via email to