diff options
Diffstat (limited to 'src/gprs_bssgp_rim.c')
-rw-r--r-- | src/gprs_bssgp_rim.c | 134 |
1 files changed, 62 insertions, 72 deletions
diff --git a/src/gprs_bssgp_rim.c b/src/gprs_bssgp_rim.c index 5f6f7505..aa636b66 100644 --- a/src/gprs_bssgp_rim.c +++ b/src/gprs_bssgp_rim.c @@ -11,10 +11,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <osmocom/gprs/gprs_bssgp.h> @@ -87,10 +83,18 @@ static void fill_app_cont_nacc(struct bssgp_ran_inf_app_cont_nacc *app_cont, con /* 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 */ + + if (!bts->si1_is_set || !bts->si3_is_set || !bts->si13_is_set) + LOGP(DNACC, LOGL_INFO, "TX RAN INFO RESPONSE (NACC) %s: Some SI are missing:%s%s%s\n", + osmo_cgi_ps_name(&app_cont->reprt_cell), + bts->si1_is_set ? "" : " SI1", + bts->si3_is_set ? "" : " SI3", + bts->si13_is_set ? "" : " SI13"); } /* 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, +static void format_response_pdu(struct bssgp_ran_information_pdu *resp_pdu, + const struct bssgp_ran_information_pdu *req_pdu, const struct gprs_rlcmac_bts *bts) { memset(resp_pdu, 0, sizeof(*resp_pdu)); @@ -128,34 +132,6 @@ static void format_response_pdu_err(struct bssgp_ran_information_pdu *resp_pdu, resp_pdu->rim_cont_iei = BSSGP_IE_RI_ERROR_RIM_COINTAINER; } -/* Check if the application ID in the request PDU is actually BSSGP_RAN_INF_APP_ID_NACC */ -static const enum bssgp_ran_inf_app_id *get_app_id(const struct bssgp_ran_information_pdu *pdu) -{ - switch (pdu->rim_cont_iei) { - case BSSGP_IE_RI_REQ_RIM_CONTAINER: - return &pdu->decoded.req_rim_cont.app_id; - case BSSGP_IE_RI_RIM_CONTAINER: - return &pdu->decoded.rim_cont.app_id; - case BSSGP_IE_RI_APP_ERROR_RIM_CONT: - return &pdu->decoded.app_err_rim_cont.app_id; - case BSSGP_IE_RI_ACK_RIM_CONTAINER: - return &pdu->decoded.ack_rim_cont.app_id; - case BSSGP_IE_RI_ERROR_RIM_COINTAINER: - return &pdu->decoded.err_rim_cont.app_id; - default: - return NULL; - } -} - -/* Check if the application ID in the request PDU is of a certain type */ -static bool match_app_id(const struct bssgp_ran_information_pdu *pdu, enum bssgp_ran_inf_app_id exp_app_id) -{ - const enum bssgp_ran_inf_app_id *app_id = get_app_id(pdu); - if (app_id && *app_id == exp_app_id) - return true; - return false; -} - static int handle_ran_info_response_nacc(const struct bssgp_ran_inf_app_cont_nacc *nacc, struct gprs_rlcmac_bts *bts) { struct si_cache_value val; @@ -176,24 +152,64 @@ static int handle_ran_info_response_nacc(const struct bssgp_ran_inf_app_cont_nac } entry = si_cache_add(bts->pcu->si_cache, &nacc->reprt_cell, &val); - llist_for_each(tmp, bts_ms_list(bts)) { + llist_for_each(tmp, &bts->ms_list) { struct GprsMs *ms = llist_entry(tmp, typeof(*ms), list); - if (!ms->nacc) - continue; - if (ms->nacc->fi->state != NACC_ST_WAIT_REQUEST_SI) - continue; - if (osmo_cgi_ps_cmp(&nacc->reprt_cell, &ms->nacc->cgi_ps) != 0) - continue; - osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_SI, entry); + if (ms->nacc && nacc_fsm_is_waiting_si_resolution(ms->nacc, &nacc->reprt_cell)) + osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_SI, entry); } return 0; } +static int handle_ran_info_request(const struct bssgp_ran_information_pdu *pdu, + struct gprs_rlcmac_bts *bts, uint16_t nsei) +{ + const struct bssgp_ran_inf_req_rim_cont *ri_req = &pdu->decoded.req_rim_cont; + const struct bssgp_ran_inf_req_app_cont_nacc *nacc_req; + struct bssgp_ran_information_pdu resp_pdu; + int rc; + + /* Check if we support the application ID */ + if (ri_req->app_id != BSSGP_RAN_INF_APP_ID_NACC) { + LOGPRIM(nsei, LOGL_ERROR, + "Rx RAN-INFO-REQ for cell %s with unknown/wrong application ID %s -- reject.\n", + osmo_cgi_ps_name(&bts->cgi_ps), bssgp_ran_inf_app_id_str(ri_req->app_id)); + format_response_pdu_err(&resp_pdu, pdu); + rc = -ENOTSUP; + goto tx_ret; + } + + nacc_req = &ri_req->u.app_cont_nacc; + rc = osmo_cgi_ps_cmp(&bts->cgi_ps, &nacc_req->reprt_cell); + if (rc != 0) { + LOGPRIM(nsei, LOGL_ERROR, "reporting cell in RIM application container %s " + "does not match destination cell in RIM routing info %s -- rejected.\n", + osmo_cgi_ps_name(&nacc_req->reprt_cell), + osmo_cgi_ps_name2(&bts->cgi_ps)); + format_response_pdu_err(&resp_pdu, pdu); + } else { + LOGPRIM(nsei, LOGL_INFO, "Responding to RAN INFORMATION REQUEST %s ...\n", + osmo_cgi_ps_name(&nacc_req->reprt_cell)); + format_response_pdu(&resp_pdu, pdu, bts); + } + +tx_ret: + bssgp_tx_rim(&resp_pdu, nsei); + return rc; +} + static int handle_ran_info_response(const struct bssgp_ran_information_pdu *pdu, struct gprs_rlcmac_bts *bts) { const struct bssgp_ran_inf_rim_cont *ran_info = &pdu->decoded.rim_cont; char ri_src_str[64]; + /* Check if we support the application ID */ + if (ran_info->app_id != BSSGP_RAN_INF_APP_ID_NACC) { + LOGP(DRIM, LOGL_ERROR, + "Rx RAN-INFO for cell %s with unknown/wrong application ID %s received -- reject.\n", + osmo_cgi_ps_name(&bts->cgi_ps), bssgp_ran_inf_app_id_str(ran_info->app_id)); + return -1; + } + if (ran_info->app_err) { LOGP(DRIM, LOGL_ERROR, "%s Rx RAN-INFO with an app error! cause: %s\n", @@ -202,16 +218,7 @@ static int handle_ran_info_response(const struct bssgp_ran_information_pdu *pdu, return -1; } - switch (pdu->decoded.rim_cont.app_id) { - case BSSGP_RAN_INF_APP_ID_NACC: - handle_ran_info_response_nacc(&ran_info->u.app_cont_nacc, bts); - break; - default: - LOGP(DRIM, LOGL_ERROR, "%s Rx RAN-INFO with unknown/wrong application ID %s received\n", - bssgp_rim_ri_name_buf(ri_src_str, sizeof(ri_src_str), &pdu->routing_info_src), - bssgp_ran_inf_app_id_str(pdu->decoded.rim_cont.app_id)); - return -1; - } + handle_ran_info_response_nacc(&ran_info->u.app_cont_nacc, bts); return 0; } @@ -223,7 +230,6 @@ 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); @@ -243,7 +249,7 @@ int handle_rim(struct osmo_bssgp_prim *bp) pdu->routing_info_dest.geran.cid); bts = gprs_pcu_get_bts_by_cgi_ps(the_pcu, &dst_addr); if (!bts) { - LOGPRIM(nsei, LOGL_ERROR, "Cell %s unknown to this pcu\n", + LOGPRIM(nsei, LOGL_ERROR, "Destination cell %s unknown to this pcu\n", osmo_cgi_ps_name(&dst_addr)); return bssgp_tx_status(BSSGP_CAUSE_UNKN_DST, NULL, msg); } @@ -251,15 +257,8 @@ int handle_rim(struct osmo_bssgp_prim *bp) /* Check if the incoming RIM PDU is parseable, if not we must report * an error to the controlling BSS 3GPP TS 48.018, 8c.3.4 and 8c.3.4.2 */ if (!pdu->decoded_present) { - LOGPRIM(nsei, LOGL_ERROR, "Errornous RIM PDU received -- rejected.\n"); - format_response_pdu_err(&resp_pdu, pdu); - return 0; - } - - /* Check if the RIM container inside the incoming RIM PDU has the correct - * application ID */ - if (!match_app_id(pdu, BSSGP_RAN_INF_APP_ID_NACC)) { - LOGPRIM(nsei, LOGL_ERROR, "RIM PDU with unknown/wrong application ID received -- rejected.\n"); + LOGPRIM(nsei, LOGL_ERROR, "Erroneous RIM PDU received for cell %s -- reject.\n", + osmo_cgi_ps_name(&dst_addr)); format_response_pdu_err(&resp_pdu, pdu); return 0; } @@ -267,16 +266,7 @@ int handle_rim(struct osmo_bssgp_prim *bp) /* Handle incoming RIM container */ switch (pdu->rim_cont_iei) { case BSSGP_IE_RI_REQ_RIM_CONTAINER: - 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; + return handle_ran_info_request(pdu, bts, nsei); case BSSGP_IE_RI_RIM_CONTAINER: return handle_ran_info_response(pdu, bts); case BSSGP_IE_RI_APP_ERROR_RIM_CONT: |