diff options
Diffstat (limited to 'src/gprs_bssgp_pcu.c')
-rw-r--r-- | src/gprs_bssgp_pcu.c | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/src/gprs_bssgp_pcu.c b/src/gprs_bssgp_pcu.c index 1fcacdb1..2c5a97a7 100644 --- a/src/gprs_bssgp_pcu.c +++ b/src/gprs_bssgp_pcu.c @@ -12,10 +12,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 <gprs_rlcmac.h> @@ -39,6 +35,8 @@ #include "tbf_dl.h" #include "llc.h" #include "gprs_rlcmac.h" +#include "bts_pch_timer.h" +#include "alloc_algo.h" /* Tuning parameters for BSSGP flow control */ #define FC_DEFAULT_LIFE_TIME_SECS 10 /* experimental value, 10s */ @@ -107,12 +105,8 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) uint8_t egprs_ms_class = 0; int rc; MS_Radio_Access_capability_t rac; - /* TODO: is it really necessary to initialize this as a "000" IMSI? It seems, the function should just return an - * error if no IMSI IE was found. */ - struct osmo_mobile_identity mi_imsi = { - .type = GSM_MI_TYPE_TMSI, - }; - OSMO_STRLCPY_ARRAY(mi_imsi.imsi, "000"); + const char *imsi = NULL; + struct osmo_mobile_identity mi_imsi; budh = (struct bssgp_ud_hdr *)msgb_bssgph(msg); tlli = ntohl(budh->tlli); @@ -143,6 +137,7 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) LOGP(DBSSGP, LOGL_NOTICE, "Failed to parse IMSI IE (rc=%d)\n", rc); return bssgp_tx_status(BSSGP_CAUSE_COND_IE_ERR, NULL, msg); } + imsi = &mi_imsi.imsi[0]; } /* parse ms radio access capability */ @@ -179,10 +174,11 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) "TLLI (old) IE\n"); } - LOGP(DBSSGP, LOGL_INFO, "LLC [SGSN -> PCU] = TLLI: 0x%08x IMSI: %s len: %d\n", tlli, mi_imsi.imsi, len); + LOGP(DBSSGP, LOGL_INFO, "LLC [SGSN -> PCU] = TLLI: 0x%08x IMSI: %s len: %d\n", + tlli, imsi ? : "none", len); - return dl_tbf_handle(the_pcu->bssgp.bts, tlli, tlli_old, mi_imsi.imsi, - ms_class, egprs_ms_class, delay_csec, data, len); + return dl_tbf_handle(the_pcu->bssgp.bts, tlli, tlli_old, imsi, ms_class, + egprs_ms_class, delay_csec, data, len); } /* 3GPP TS 48.018 Table 10.3.2. Returns 0 on success, suggested BSSGP cause otherwise */ @@ -248,9 +244,9 @@ static int gprs_bssgp_pcu_rx_paging_cs(struct msgb *msg, const struct tlv_parsed * target MS is using. */ llist_for_each_entry(bts, &the_pcu->bts_list, list) { /* TODO: Match by TMSI before IMSI if present?! */ - ms = bts_ms_by_tlli(bts, req.tlli, req.tlli); + ms = bts_get_ms_by_tlli(bts, req.tlli, req.tlli); if (!ms && req.mi_imsi_present) - ms = bts_ms_by_imsi(bts, req.mi_imsi.imsi); + ms = bts_get_ms_by_imsi(bts, req.mi_imsi.imsi); bts_add_paging(bts, &req, ms); } @@ -293,7 +289,6 @@ static int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, const struct tlv_parsed struct osmo_mobile_identity mi_imsi; struct osmo_mobile_identity paging_mi; struct gprs_rlcmac_bts *bts; - uint16_t pgroup; int rc; rate_ctr_inc(rate_ctr_group_get_ctr(the_pcu->bssgp.ctrs, SGSN_CTR_RX_PAGING_PS)); @@ -308,18 +303,20 @@ static int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, const struct tlv_parsed LOGP(DBSSGP, LOGL_NOTICE, "Failed to parse IMSI IE (rc=%d)\n", rc); return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); } - pgroup = imsi2paging_group(mi_imsi.imsi); - if (pgroup > 999) { - LOGP(DBSSGP, LOGL_NOTICE, "Failed to compute IMSI %s paging group\n", mi_imsi.imsi); - return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); - } if ((rc = get_paging_ps_mi(&paging_mi, tp)) > 0) return bssgp_tx_status((enum gprs_bssgp_cause) rc, NULL, msg); /* FIXME: look if MS is attached a specific BTS and then only page on that one? */ llist_for_each_entry(bts, &the_pcu->bts_list, list) { - gprs_rlcmac_paging_request(bts, &paging_mi, pgroup); + if (bts_pch_timer_get_by_imsi(bts, mi_imsi.imsi)) { + LOGP(DBSSGP, LOGL_INFO, "PS-Paging request already pending for IMSI=%s\n", mi_imsi.imsi); + bts_do_rate_ctr_inc(bts, CTR_PCH_REQUESTS_ALREADY); + continue; + } + if (gprs_rlcmac_paging_request(bts, &paging_mi, mi_imsi.imsi) < 0) + continue; + bts_pch_timer_start(bts, &paging_mi, mi_imsi.imsi); } return 0; } @@ -780,7 +777,7 @@ static unsigned count_pdch(const struct gprs_rlcmac_bts *bts) for (ts_no = 0; ts_no < ARRAY_SIZE(trx->pdch); ++ts_no) { const struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no]; - if (pdch->m_is_enabled) + if (pdch_is_enabled(pdch)) num_pdch += 1; } } @@ -1118,7 +1115,8 @@ static int ns_configure_nse(struct gprs_rlcmac_bts *bts, if (!(valid & (1 << i))) continue; - if (!gprs_ns2_ip_bind_by_sockaddr(the_pcu->nsi, &local[i])) { + bind[i] = gprs_ns2_ip_bind_by_sockaddr(the_pcu->nsi, &local[i]); + if (!bind[i]) { snprintf(name, sizeof(name), "pcu%u", i); rc = gprs_ns2_ip_bind(the_pcu->nsi, name, &local[i], 0, &bind[i]); if (rc < 0) { |