aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-11-17 20:54:47 +0100
committerHarald Welte <laforge@gnumonks.org>2017-05-25 14:04:08 +0200
commit854bcc2b7b36c4b9fc965cd8104006705d09edb7 (patch)
tree2e2b5efb6a67e60b4272aade620802495908c89f /openbsc/src
parente586f41692f1e7d2386c52ae9caa81b6d9a2de08 (diff)
pcu_sock: Forward paging request from PCU via RSL to BTS
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/libbsc/pcu_sock.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/openbsc/src/libbsc/pcu_sock.c b/openbsc/src/libbsc/pcu_sock.c
index e713b086e..4555b31a4 100644
--- a/openbsc/src/libbsc/pcu_sock.c
+++ b/openbsc/src/libbsc/pcu_sock.c
@@ -284,6 +284,39 @@ int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
return pcu_sock_send(bts, msg);
}
+/* we need to decode the raw RR paging messsage (see PCU code
+ * Encoding::write_paging_request) and extract the mobile identity
+ * (P-TMSI) from it */
+static int pcu_rx_rr_paging(struct gsm_bts *bts, uint8_t paging_group,
+ const uint8_t *raw_rr_msg)
+{
+ struct gsm48_hdr *gsmh = (struct gsm48_hdr *) raw_rr_msg;
+ struct gsm48_paging1 *p1 = (struct gsm48_paging1 *) gsmh;
+ uint8_t chan_needed;
+ unsigned int mi_len;
+ uint8_t *mi;
+ int rc;
+
+ switch (gsmh->msg_type) {
+ case GSM48_MT_RR_PAG_REQ_1:
+ chan_needed = (p1->cneed2 << 2) | p1->cneed1;
+ mi_len = p1->data[0];
+ mi = p1->data+1;
+ /* FIXME: why does rsl_paging_cmd add 2 to mi? */
+ rc = rsl_paging_cmd(bts, paging_group, mi_len, mi,
+ chan_needed, true);
+ break;
+ case GSM48_MT_RR_PAG_REQ_2:
+ case GSM48_MT_RR_PAG_REQ_3:
+ LOGP(DPCU, LOGL_ERROR, "PCU Sends unsupported paging "
+ "request type\n");
+ rc = -EINVAL;
+ break;
+ }
+
+ return rc;
+}
+
static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
struct gsm_pcu_if_data *data_req)
{
@@ -291,6 +324,8 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
struct msgb *msg;
+ char imsi_digit_buf[4];
+ uint8_t pag_grp;
int rc = 0;
LOGP(DPCU, LOGL_DEBUG, "Data request received: sapi=%s arfcn=%d "
@@ -300,15 +335,15 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
switch (data_req->sapi) {
case PCU_IF_SAPI_PCH:
- if (msg_type == PCU_IF_MSG_PAG_REQ) {
- /* FIXME: Add function to schedule paging request.
- * This might not be required, if PCU_IF_MSG_DATA_REQ
- * is used instead. */
- } else {
- struct gsm_bts_role_bts *btsb = bts->role;
-
- printf("paging_add_imm_ass(btsb->paging_state, data_req->data,data_req->len);\n");
- }
+ /* the first three bytes are the last three digits of
+ * the IMSI, which we need to compute the paging group */
+ imsi_digit_buf[0] = data_req->data[0];
+ imsi_digit_buf[1] = data_req->data[1];
+ imsi_digit_buf[2] = data_req->data[2];
+ imsi_digit_buf[3] = '\0';
+ pag_grp = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
+ str_to_imsi(imsi_digit_buf));
+ pcu_rx_rr_paging(bts, pag_grp, data_req->data+3);
break;
case PCU_IF_SAPI_AGCH:
msg = msgb_alloc(data_req->len, "pcu_agch");