aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-07-11 09:50:29 +0200
committerHarald Welte <laforge@gnumonks.org>2017-07-11 12:57:17 +0200
commitb900a4c412318cdd3447840884d5f9403a9e4575 (patch)
tree57b8e51876dc53a4a23efc17d23aca45def1e618
parent63c780c51e13394756338394bee3852dbc2c33ed (diff)
pcu_sock: Forward incoming RR GPRS SUSPEND REQ to PCU socketlaforge/gprs-suspend
s specified in 3GPP TS 03.60 Section 16.2.1 and 44.018 Section 3.4.15, a Class B MS is sending a "RR GPRS SUSPEND REQ" via a DCCH to the BTS if it wants to suspend GPRS services. The BSS is now responsible to somehow forward this to the SGSN. As the Gs interface between BSC and SGSN is both optional and doesn't have any provision to forward this message, we have to send it over to the PCU so it can use regular BSSGP signaling to inform the SGSN of the SUSPEND REQUEST. This patch requires libosmocore Change-Id I90113044460a6c511ced14f588876c4280d1cac7 for the related definition of struct gsm48_gprs_susp_req. This patch follows the same logic of whatwas introdiced in osmo-bts as Change-Id I3c1af662c8f0d3d22da200638480f6ef05c3ed1f. Change-Id: I05ac5de16c9d5122c179b3f9b273a0c9c7661e29 Closes: OS#2249
-rw-r--r--openbsc/include/openbsc/pcu_if.h3
-rw-r--r--openbsc/src/libbsc/bsc_api.c31
-rw-r--r--openbsc/src/libbsc/pcu_sock.c20
3 files changed, 50 insertions, 4 deletions
diff --git a/openbsc/include/openbsc/pcu_if.h b/openbsc/include/openbsc/pcu_if.h
index 1f398b4aa..2d85a88d7 100644
--- a/openbsc/include/openbsc/pcu_if.h
+++ b/openbsc/include/openbsc/pcu_if.h
@@ -26,6 +26,9 @@ int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli);
/* Confirm the sending of an immediate assignment to the pcu */
int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli);
+/* forward data from a RR GPRS SUSPEND REQ towards PCU */
+int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause);
+
/* Open connection to PCU */
int pcu_sock_init(const char *path, struct gsm_bts *bts);
diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index 7613cac90..a7675fbab 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -2,7 +2,7 @@
/* (C) 2010-2011 by Holger Hans Peter Freyther
* (C) 2010-2011 by On-Waves
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009-2017 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
@@ -32,11 +32,13 @@
#include <openbsc/debug.h>
#include <openbsc/gsm_04_08.h>
#include <openbsc/trau_mux.h>
+#include <openbsc/pcu_if.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/core/talloc.h>
+#include <osmocom/core/byteswap.h>
#define GSM0808_T10_VALUE 6, 0
@@ -570,6 +572,30 @@ static void handle_rr_ho_fail(struct msgb *msg)
/* FIXME: release allocated new channel */
}
+/* TS 44.018 9.1.13b GPRS suspension request */
+static int handle_gprs_susp_req(struct msgb *msg)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ struct gsm48_gprs_susp_req *gsr;
+ uint32_t tlli;
+ int rc;
+
+ if (!gh || msgb_l3len(msg) < sizeof(*gh)+sizeof(*gsr)) {
+ LOGP(DRSL, LOGL_NOTICE, "%s Short GPRS SUSPEND REQ received, ignoring\n", gsm_lchan_name(msg->lchan));
+ return -EINVAL;
+ }
+
+ gsr = (struct gsm48_gprs_susp_req *) gh->data;
+ tlli = osmo_ntohl(gsr->tlli);
+
+ LOGP(DRSL, LOGL_INFO, "%s Fwd GPRS SUSPEND REQ for TLLI=0x%08x to PCU\n",
+ gsm_lchan_name(msg->lchan), tlli);
+ rc = pcu_tx_susp_req(msg->lchan, tlli, gsr->ra_id, gsr->cause);
+
+ msgb_free(msg);
+
+ return rc;
+}
static void dispatch_dtap(struct gsm_subscriber_connection *conn,
uint8_t link_id, struct msgb *msg)
@@ -599,8 +625,7 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn,
case GSM48_PDISC_RR:
switch (msg_type) {
case GSM48_MT_RR_GPRS_SUSP_REQ:
- DEBUGP(DRR, "%s\n",
- gsm48_rr_msg_name(GSM48_MT_RR_GPRS_SUSP_REQ));
+ handle_gprs_susp_req(msg);
break;
case GSM48_MT_RR_STATUS:
LOGP(DRR, LOGL_NOTICE, "%s (cause: %s)\n",
diff --git a/openbsc/src/libbsc/pcu_sock.c b/openbsc/src/libbsc/pcu_sock.c
index 98e12fad4..637e4c6a3 100644
--- a/openbsc/src/libbsc/pcu_sock.c
+++ b/openbsc/src/libbsc/pcu_sock.c
@@ -1,6 +1,6 @@
/* pcu_sock.c: Connect from PCU via unix domain socket */
-/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
+/* (C) 2008-2017 by Harald Welte <laforge@gnumonks.org>
* (C) 2009-2012 by Andreas Eversberg <jolly@eversberg.eu>
* (C) 2012 by Holger Hans Peter Freyther
* All Rights Reserved
@@ -307,6 +307,24 @@ int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli)
return pcu_sock_send(bts, msg);
}
+/* forward data from a RR GPRS SUSPEND REQ towards PCU */
+int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause)
+{
+ struct gsm_bts *bts = lchan->ts->trx->bts;
+ struct msgb *msg;
+ struct gsm_pcu_if *pcu_prim;
+
+ msg = pcu_msgb_alloc(PCU_IF_MSG_SUSP_REQ, bts->nr);
+ if (!msg)
+ return -ENOMEM;
+ pcu_prim = (struct gsm_pcu_if *) msg->data;
+ pcu_prim->u.susp_req.tlli = tlli;
+ memcpy(pcu_prim->u.susp_req.ra_id, ra_id, sizeof(pcu_prim->u.susp_req.ra_id));
+ pcu_prim->u.susp_req.cause = cause;
+
+ 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 */