diff options
-rw-r--r-- | src/bts.cpp | 4 | ||||
-rw-r--r-- | src/bts.h | 2 | ||||
-rw-r--r-- | src/gprs_bssgp_pcu.cpp | 10 | ||||
-rw-r--r-- | src/gprs_rlcmac.cpp | 4 | ||||
-rw-r--r-- | src/gprs_rlcmac.h | 4 | ||||
-rw-r--r-- | src/pcu_l1_if.cpp | 37 | ||||
-rw-r--r-- | src/pcu_l1_if.h | 4 | ||||
-rw-r--r-- | src/tbf.cpp | 5 | ||||
-rw-r--r-- | src/tbf_dl.cpp | 5 |
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); @@ -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; } } |