aboutsummaryrefslogtreecommitdiffstats
path: root/src/gprs_bssgp_pcu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gprs_bssgp_pcu.c')
-rw-r--r--src/gprs_bssgp_pcu.c46
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) {