aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2021-01-25 23:43:52 +0100
committerPhilipp Maier <pmaier@sysmocom.de>2021-02-02 21:57:09 +0100
commita58ec615147e34a3860bdf92e067943499d21300 (patch)
treecde38695cd82b0be86c1ce37e0f2e30821eb637b
parent1aef113bb7d5f45a2d49c6c982b77899a9c291ff (diff)
gprs_bssgp_rim: add serving BSS NACC application
Answer an incoming RAN INFORMATION REQUEST RIM PDU with RAN INFORMATION PDU that contains system information type 1, 3 and 13 Depends: osmo-bts I5138ab183793e7eee4dc494318d984e9f1f56932 Change-Id: Id72118120c14984d2fb1b918b41fac4868150d41 Related: SYS#5103
-rw-r--r--src/bts.h4
-rw-r--r--src/gprs_bssgp_rim.c67
-rw-r--r--src/pcu_l1_if.cpp73
3 files changed, 131 insertions, 13 deletions
diff --git a/src/bts.h b/src/bts.h
index ea15caf4..e67668c3 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -219,6 +219,10 @@ struct gprs_rlcmac_bts {
uint8_t n3105;
struct gprs_rlcmac_trx trx[8];
+ uint8_t si1[GSM_MACBLOCK_LEN];
+ bool si1_is_set;
+ uint8_t si3[GSM_MACBLOCK_LEN];
+ bool si3_is_set;
uint8_t si13[GSM_MACBLOCK_LEN];
bool si13_is_set;
diff --git a/src/gprs_bssgp_rim.c b/src/gprs_bssgp_rim.c
index a191fffc..5f6f7505 100644
--- a/src/gprs_bssgp_rim.c
+++ b/src/gprs_bssgp_rim.c
@@ -23,6 +23,9 @@
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/core/prim.h>
+#include <pcu_l1_if.h>
+#include <gprs_rlcmac.h>
+#include <bts.h>
#include "gprs_debug.h"
#include "gprs_pcu.h"
@@ -54,6 +57,59 @@ static void mirror_rim_routing_info(struct bssgp_ran_information_pdu *to_pdu,
memcpy(&to_pdu->routing_info_src, &from_pdu->routing_info_dest, sizeof(to_pdu->routing_info_src));
}
+/* Fill NACC application container with data (cell identifier, sysinfo) */
+#define SI_HDR_LEN 2
+static void fill_app_cont_nacc(struct bssgp_ran_inf_app_cont_nacc *app_cont, const struct gprs_rlcmac_bts *bts)
+{
+ struct bssgp_bvc_ctx *bctx = the_pcu->bssgp.bctx;
+
+ gprs_ra_id_ci_to_cgi_ps(&app_cont->reprt_cell, &bctx->ra_id, bctx->cell_id);
+ app_cont->num_si = 0;
+
+ /* Note: The BTS struct stores the system information including its pseudo header. The RIM application
+ * container defines the system information without pseudo header, so we need to chop it off. */
+
+ if (bts->si1_is_set) {
+ app_cont->si[app_cont->num_si] = bts->si1 + SI_HDR_LEN;
+ app_cont->num_si++;
+ }
+
+ if (bts->si3_is_set) {
+ app_cont->si[app_cont->num_si] = bts->si3 + SI_HDR_LEN;
+ app_cont->num_si++;
+ }
+
+ if (bts->si13_is_set) {
+ app_cont->si[app_cont->num_si] = bts->si13 + SI_HDR_LEN;
+ app_cont->num_si++;
+ }
+
+ /* Note: It is possible that the resulting PDU will not contain any system information, even if this is
+ * an unlikely case since the BTS immediately updates the system information after startup. The
+ * specification permits to send zero system information, see also: 3GPP TS 48.018 section 11.3.63.2.1 */
+}
+
+/* Format a RAN INFORMATION PDU that contains the requested system information */
+static void format_response_pdu(struct bssgp_ran_information_pdu *resp_pdu, struct bssgp_ran_information_pdu *req_pdu,
+ const struct gprs_rlcmac_bts *bts)
+{
+ memset(resp_pdu, 0, sizeof(*resp_pdu));
+ mirror_rim_routing_info(resp_pdu, req_pdu);
+
+ resp_pdu->decoded.rim_cont = (struct bssgp_ran_inf_rim_cont) {
+ .app_id = BSSGP_RAN_INF_APP_ID_NACC,
+ .seq_num = 1, /* single report has only one message in response */
+ .pdu_ind = {
+ .pdu_type_ext = RIM_PDU_TYPE_SING_REP,
+ },
+ .prot_ver = 1,
+ };
+
+ fill_app_cont_nacc(&resp_pdu->decoded.rim_cont.u.app_cont_nacc, bts);
+ resp_pdu->decoded_present = true;
+ resp_pdu->rim_cont_iei = BSSGP_IE_RI_RIM_CONTAINER;
+}
+
/* Format a RAN INFORMATION ERROR PDU */
static void format_response_pdu_err(struct bssgp_ran_information_pdu *resp_pdu,
const struct bssgp_ran_information_pdu *req_pdu)
@@ -167,6 +223,7 @@ int handle_rim(struct osmo_bssgp_prim *bp)
struct bssgp_ran_information_pdu resp_pdu;
struct osmo_cell_global_id_ps dst_addr;
struct gprs_rlcmac_bts *bts;
+ int rc;
OSMO_ASSERT (bp->oph.sap == SAP_BSSGP_RIM);
@@ -210,7 +267,15 @@ int handle_rim(struct osmo_bssgp_prim *bp)
/* Handle incoming RIM container */
switch (pdu->rim_cont_iei) {
case BSSGP_IE_RI_REQ_RIM_CONTAINER:
- LOGPRIM(nsei, LOGL_NOTICE, "Responding to RAN INFORMATION REQUEST not yet implemented!\n");
+ rc = osmo_cgi_ps_cmp(&dst_addr, &pdu->decoded.req_rim_cont.u.app_cont_nacc.reprt_cell);
+ if (rc != 0) {
+ LOGPRIM(nsei, LOGL_ERROR, "reporting cell in RIM application container does not match destination cell in RIM routing info -- rejected.\n");
+ format_response_pdu_err(&resp_pdu, pdu);
+ } else {
+ LOGPRIM(nsei, LOGL_INFO, "Responding to RAN INFORMATION REQUEST ...\n");
+ format_response_pdu(&resp_pdu, pdu, bts);
+ }
+ bssgp_tx_rim(&resp_pdu, nsei);
break;
case BSSGP_IE_RI_RIM_CONTAINER:
return handle_ran_info_response(pdu, bts);
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index d7590e1f..98734698 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -42,6 +42,7 @@ extern "C" {
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gsm/l1sap.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/sysinfo.h>
}
#include <gprs_rlcmac.h>
@@ -290,21 +291,69 @@ int pcu_rx_data_ind_pdtch(struct gprs_rlcmac_bts *bts, uint8_t trx_no, uint8_t t
static int pcu_rx_data_ind_bcch(struct gprs_rlcmac_bts *bts, uint8_t *data, uint8_t len)
{
- if (len == 0) {
+ switch (len) {
+ case 0:
+ /* Due to historical reasons also accept a completely empty message as
+ * revoke command for SI13. */
+ LOGP(DL1IF, LOGL_ERROR,
+ "Received PCU data indication that contains no data -- Revoked SI13.\n");
bts->si13_is_set = false;
- LOGP(DL1IF, LOGL_INFO, "Received PCU data indication with empty SI13: cache cleaned\n");
- return 0;
- }
- if (len != GSM_MACBLOCK_LEN) {
- LOGP(DL1IF, LOGL_ERROR, "Received PCU data indication with SI13 with unexpected length %u\n", len);
+ return 0;
+ case 1:
+ /* Revoke SI, type is identified by a single byte which is coded after
+ * enum osmo_sysinfo_type. */
+ switch (data[0]) {
+ case SYSINFO_TYPE_1:
+ bts->si1_is_set = false;
+ break;
+ case SYSINFO_TYPE_3:
+ bts->si3_is_set = false;
+ break;
+ case SYSINFO_TYPE_13:
+ bts->si13_is_set = false;
+ break;
+ default:
+ LOGP(DL1IF, LOGL_ERROR,
+ "Received PCU data indication that contains an unsupported system information identifier (%02x,OSMO) -- ignored.\n", data[0]);
+ return -EINVAL;
+ }
+ LOGP(DPCU, LOGL_DEBUG,
+ "Received PCU data indication: Revoked SI%s\n",
+ get_value_string(osmo_sitype_strs, data[0]));
+ return 0;
+ case GSM_MACBLOCK_LEN:
+ /* Update SI, type is identified by the RR sysinfo type, which is the
+ * 3rd byte in the buffer. */
+ switch (data[2]) {
+ case GSM48_MT_RR_SYSINFO_1:
+ memcpy(bts->si1, data, GSM_MACBLOCK_LEN);
+ bts->si1_is_set = true;
+ break;
+ case GSM48_MT_RR_SYSINFO_3:
+ memcpy(bts->si3, data, GSM_MACBLOCK_LEN);
+ bts->si3_is_set = true;
+ break;
+ case GSM48_MT_RR_SYSINFO_13:
+ memcpy(bts->si13, data, GSM_MACBLOCK_LEN);
+ bts->si13_is_set = true;
+ break;
+ default:
+ LOGP(DL1IF, LOGL_ERROR,
+ "Received PCU data indication that contains an unsupported system information identifier (%02x,RR) -- ignored.\n", data[2]);
+ return -EINVAL;
+ }
+ LOGP(DPCU, LOGL_DEBUG,
+ "Received PCU data indication: Updated %s: %s\n",
+ gsm48_pdisc_msgtype_name(data[1], data[2]),
+ osmo_hexdump_nospc(data + 1, GSM_MACBLOCK_LEN));
+ return 0;
+ default:
+ LOGP(DL1IF, LOGL_ERROR,
+ "Received PCU data indication with unexpected data length: %u -- ignored.\n",
+ len);
return -EINVAL;
}
-
- memcpy(bts->si13, data, GSM_MACBLOCK_LEN);
- bts->si13_is_set = true;
-
- return 0;
}
static int pcu_rx_data_ind(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_data *data_ind)
@@ -782,7 +831,7 @@ static int pcu_rx_pag_req(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_pag_req
static int pcu_rx_susp_req(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_susp_req *susp_req)
{
- struct bssgp_bvc_ctx *bctx = bts->pcu->bssgp.bctx;
+ struct bssgp_bvc_ctx *bctx = the_pcu->bssgp.bctx;
GprsMs *ms;
struct gprs_rlcmac_dl_tbf *dl_tbf;
struct gprs_rlcmac_ul_tbf *ul_tbf;