aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bts.cpp4
-rw-r--r--src/bts.h2
-rw-r--r--src/gprs_bssgp_pcu.cpp10
-rw-r--r--src/gprs_rlcmac.cpp4
-rw-r--r--src/gprs_rlcmac.h4
-rw-r--r--src/pcu_l1_if.cpp37
-rw-r--r--src/pcu_l1_if.h4
-rw-r--r--src/tbf.cpp5
-rw-r--r--src/tbf_dl.cpp5
9 files changed, 54 insertions, 21 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 71a2f06d..5e1725c1 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -890,7 +890,7 @@ int BTS::rcv_ptcch_rach(uint8_t trx_nr, uint8_t ts_nr, uint32_t fn, int16_t qta)
return 0;
}
-void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, const char *imsi)
+void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup)
{
int plen;
unsigned int ts = tbf->first_ts;
@@ -910,7 +910,7 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, const char *imsi)
GSM_L1_BURST_TYPE_ACCESS_0);
if (plen >= 0) {
immediate_assignment_dl_tbf();
- pcu_l1if_tx_pch(immediate_assignment, plen, imsi);
+ pcu_l1if_tx_pch(immediate_assignment, plen, pgroup);
}
bitvec_free(immediate_assignment);
diff --git a/src/bts.h b/src/bts.h
index 0eaab854..823138bb 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -306,7 +306,7 @@ public:
enum ph_burst_type burst_type);
int rcv_ptcch_rach(uint8_t trx_nr, uint8_t ts_nr, uint32_t fn, int16_t qta);
- void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, const char *imsi);
+ void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup);
GprsMsStorage &ms_store();
GprsMs *ms_by_tlli(uint32_t tlli, uint32_t old_tlli = 0);
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp
index 6435d99a..54927f59 100644
--- a/src/gprs_bssgp_pcu.cpp
+++ b/src/gprs_bssgp_pcu.cpp
@@ -174,6 +174,7 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp)
static int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, struct tlv_parsed *tp)
{
char imsi[16];
+ uint16_t pgroup;
uint8_t *ptmsi = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_TMSI);
uint16_t ptmsi_len = TLVP_LEN(tp, BSSGP_IE_TMSI);
int rc;
@@ -195,10 +196,15 @@ static int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, struct tlv_parsed *tp)
TLVP_LEN(tp, BSSGP_IE_IMSI));
if (rc != GSM23003_IMSI_MAX_DIGITS + 1) {
LOGP(DBSSGP, LOGL_NOTICE, "Failed to parse IMSI IE (rc=%d)\n", rc);
- return bssgp_tx_status(BSSGP_CAUSE_COND_IE_ERR, NULL, msg);
+ return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
+ }
+ pgroup = imsi2paging_group(imsi);
+ if (pgroup > 999) {
+ LOGP(DBSSGP, LOGL_NOTICE, "Failed to compute IMSI %s paging group\n", imsi);
+ return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
}
- return gprs_rlcmac_paging_request(ptmsi, ptmsi_len, imsi);
+ return gprs_rlcmac_paging_request(ptmsi, ptmsi_len, pgroup);
}
/* Receive a BSSGP PDU from a BSS on a PTP BVCI */
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp
index e381b113..cbfc87f4 100644
--- a/src/gprs_rlcmac.cpp
+++ b/src/gprs_rlcmac.cpp
@@ -29,13 +29,13 @@
extern void *tall_pcu_ctx;
int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len,
- const char *imsi)
+ uint16_t pgroup)
{
LOGP(DRLCMAC, LOGL_NOTICE, "TX: [PCU -> BTS] Paging Request (CCCH)\n");
bitvec *paging_request = bitvec_alloc(22, tall_pcu_ctx);
bitvec_unhex(paging_request, DUMMY_VEC);
int plen = Encoding::write_paging_request(paging_request, ptmsi, ptmsi_len);
- pcu_l1if_tx_pch(paging_request, plen, (char *)imsi);
+ pcu_l1if_tx_pch(paging_request, plen, pgroup);
bitvec_free(paging_request);
return 0;
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index 5361a1cc..6f3418c5 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -26,6 +26,7 @@
#ifdef __cplusplus
#include <gsm_rlcmac.h>
#include <gsm_timer.h>
+#include <pcu_l1_if.h>
extern "C" {
#include <osmocom/core/linuxlist.h>
@@ -92,8 +93,7 @@ enum gprs_rlcmac_block_type {
int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf);
-int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len,
- const char *imsi);
+int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len, uint16_t pgroup);
struct msgb *gprs_rlcmac_app_info_msg(const struct gsm_pcu_if_app_info_req *req);
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index bac0e56a..1f23c25e 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -60,6 +60,28 @@ int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn,
extern void *tall_pcu_ctx;
+#define PAGING_GROUP_LEN 3
+
+/* returns [0,999] on success, > 999 on error */
+uint16_t imsi2paging_group(const char* imsi)
+{
+ uint16_t pgroup = 0;
+ size_t len = strlen(imsi);
+
+ if (!imsi || len < PAGING_GROUP_LEN)
+ return 0xFFFF;
+ imsi += len - PAGING_GROUP_LEN;
+
+ while (*imsi != '\0') {
+ if (!isdigit(*imsi))
+ return 0xFFFF;
+ pgroup *= 10;
+ pgroup += *imsi - '0';
+ imsi++;
+ }
+ return pgroup;
+}
+
/*
* PCU messages
*/
@@ -218,19 +240,18 @@ void pcu_l1if_tx_agch(bitvec * block, int plen)
pcu_tx_data_req(0, 0, PCU_IF_SAPI_AGCH, 0, 0, 0, data, GSM_MACBLOCK_LEN);
}
-#define PAGING_GROUP_LEN 3
-void pcu_l1if_tx_pch(bitvec * block, int plen, const char *imsi)
+void pcu_l1if_tx_pch(bitvec * block, int plen, uint16_t pgroup)
{
struct gprs_rlcmac_bts *bts = bts_main_data();
uint8_t data[PAGING_GROUP_LEN + GSM_MACBLOCK_LEN];
+ int i;
/* prepend paging group */
- if (!imsi || strlen(imsi) < PAGING_GROUP_LEN)
- return;
- imsi += strlen(imsi) - PAGING_GROUP_LEN;
- data[0] = imsi[0];
- data[1] = imsi[1];
- data[2] = imsi[2];
+ for (i = 0; i < PAGING_GROUP_LEN; i++) {
+ data[PAGING_GROUP_LEN - 1 - i] = '0' + (char)(pgroup % 10);
+ pgroup = pgroup / 10;
+ }
+ OSMO_ASSERT(pgroup == 0);
/* block provided by upper layer comes without first byte (plen),
* prepend it manually:
diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h
index a77a6c87..35643da1 100644
--- a/src/pcu_l1_if.h
+++ b/src/pcu_l1_if.h
@@ -159,7 +159,7 @@ void pcu_l1if_tx_ptcch(uint8_t trx, uint8_t ts, uint16_t arfcn,
uint8_t *data, size_t data_len);
void pcu_l1if_tx_agch(bitvec * block, int len);
-void pcu_l1if_tx_pch(bitvec * block, int plen, const char *imsi);
+void pcu_l1if_tx_pch(bitvec * block, int plen, uint16_t pgroup);
int pcu_tx_txt_ind(enum gsm_pcu_if_text_type t, const char *fmt, ...);
@@ -184,7 +184,7 @@ int pcu_rx_data_ind_pdtch(uint8_t trx, uint8_t ts, uint8_t *data,
void pcu_rx_block_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no);
void pcu_rx_ra_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no);
-
+uint16_t imsi2paging_group(const char* imsi);
#ifdef __cplusplus
}
#endif
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 389b1864..61d8d583 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -803,6 +803,7 @@ void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts, enum gprs_rl
void gprs_rlcmac_tbf::poll_timeout()
{
+ uint16_t pgroup;
gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this);
LOGPTBF(this, LOGL_NOTICE, "poll timeout for FN=%d, TS=%d (curr FN %d)\n",
@@ -902,7 +903,9 @@ void gprs_rlcmac_tbf::poll_timeout()
LOGPTBF(dl_tbf, LOGL_DEBUG, "Re-send dowlink assignment on PCH (IMSI=%s)\n",
imsi());
/* send immediate assignment */
- dl_tbf->bts->snd_dl_ass(dl_tbf, false, imsi());
+ if ((pgroup = imsi2paging_group(imsi())) > 999)
+ LOGPTBF(dl_tbf, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi());
+ dl_tbf->bts->snd_dl_ass(dl_tbf, false, pgroup);
dl_tbf->m_wait_confirm = 1;
}
} else
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index e3c1ff4e..7113d65a 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -507,6 +507,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(uint32_t fn, uint8_t ts)
/* depending on the current TBF, we assign on PACCH or AGCH */
void gprs_rlcmac_dl_tbf::trigger_ass(struct gprs_rlcmac_tbf *old_tbf)
{
+ uint16_t pgroup;
/* stop pending timer */
stop_timers("assignment (DL-TBF)");
@@ -530,7 +531,9 @@ void gprs_rlcmac_dl_tbf::trigger_ass(struct gprs_rlcmac_tbf *old_tbf)
TBF_SET_ASS_ON(this, GPRS_RLCMAC_FLAG_CCCH, false);
/* send immediate assignment */
- bts->snd_dl_ass(this, false, imsi());
+ if ((pgroup = imsi2paging_group(imsi())) > 999)
+ LOGPTBFDL(this, LOGL_ERROR, "IMSI to paging group failed! (%s)\n", imsi());
+ bts->snd_dl_ass(this, false, pgroup);
m_wait_confirm = 1;
}
}