<p>osmith has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13347">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Forward GPRS SUSPEND REQ from DCCH to PCU socket<br><br>As specified in 3GPP TS 03.60 Section 16.2.1 and 44.018 Section 3.4.15,<br>a Class B MS is sending a "RR GPRS SUSPEND REQ" via a DCCH to the BTS if<br>it wants to suspend GPRS services.  The BSS is now responsible to<br>somehow forward this to the SGSN.  As the Gs interface between BSC and<br>SGSN is both optional and doesn't have any provision to forward this<br>message, we have to send it over to the PCU so it can use regular BSSGP<br>signaling to inform the SGSN of the SUSPEND REQUEST.<br><br>This patch requires libosmocore Change-Id<br>I90113044460a6c511ced14f588876c4280d1cac7 for the related definition of<br>struct gsm48_gprs_susp_req.<br><br>Change-Id: I3c1af662c8f0d3d22da200638480f6ef05c3ed1f<br>Closes: OS#2249<br>---<br>M include/osmo-bts/pcu_if.h<br>M include/osmo-bts/pcuif_proto.h<br>M src/common/pcu_sock.c<br>M src/common/rsl.c<br>4 files changed, 87 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/47/13347/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmo-bts/pcu_if.h b/include/osmo-bts/pcu_if.h</span><br><span>index 98efb57..6253c84 100644</span><br><span>--- a/include/osmo-bts/pcu_if.h</span><br><span>+++ b/include/osmo-bts/pcu_if.h</span><br><span>@@ -15,6 +15,7 @@</span><br><span> int pcu_tx_time_ind(uint32_t fn);</span><br><span> int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed);</span><br><span> int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause);</span><br><span> </span><br><span> int pcu_sock_init(const char *path);</span><br><span> void pcu_sock_exit(void);</span><br><span>diff --git a/include/osmo-bts/pcuif_proto.h b/include/osmo-bts/pcuif_proto.h</span><br><span>index b06077c..5a85859 100644</span><br><span>--- a/include/osmo-bts/pcuif_proto.h</span><br><span>+++ b/include/osmo-bts/pcuif_proto.h</span><br><span>@@ -11,7 +11,8 @@</span><br><span> /* msg_type */</span><br><span> #define PCU_IF_MSG_DATA_REQ    0x00    /* send data to given channel */</span><br><span> #define PCU_IF_MSG_DATA_CNF 0x01    /* confirm (e.g. transmission on PCH) */</span><br><span style="color: hsl(0, 100%, 40%);">-#define PCU_IF_MSG_DATA_IND     0x02    /* receive data from given channel */</span><br><span style="color: hsl(120, 100%, 40%);">+#define PCU_IF_MSG_DATA_IND      0x02    /* receive data from given channel */   </span><br><span style="color: hsl(120, 100%, 40%);">+#define PCU_IF_MSG_SUSP_REQ   0x03    /* BTS forwards GPRS SUSP REQ to PCU */</span><br><span> #define PCU_IF_MSG_RTS_REQ   0x10    /* ready to send request */</span><br><span> #define PCU_IF_MSG_DATA_CNF_DT   0x11    /* confirm (with direct tlli) */</span><br><span> #define PCU_IF_MSG_RACH_IND 0x22    /* receive RACH */</span><br><span>@@ -171,6 +172,13 @@</span><br><span>    uint8_t         identity_lv[9];</span><br><span> } __attribute__ ((packed));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* BTS tells PCU about a GPRS SUSPENSION REQUEST received on DCCH */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_pcu_if_susp_req {</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t        tlli;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t         ra_id[6];</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t         cause;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct gsm_pcu_if {</span><br><span>         /* context based information */</span><br><span>      uint8_t         msg_type;       /* message type */</span><br><span>@@ -182,6 +190,7 @@</span><br><span>             struct gsm_pcu_if_data          data_cnf;</span><br><span>            struct gsm_pcu_if_data_cnf_dt   data_cnf_dt;</span><br><span>                 struct gsm_pcu_if_data          data_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+             struct gsm_pcu_if_susp_req      susp_req;</span><br><span>            struct gsm_pcu_if_rts_req       rts_req;</span><br><span>             struct gsm_pcu_if_rach_ind      rach_ind;</span><br><span>            struct gsm_pcu_if_txt_ind       txt_ind;</span><br><span>diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c</span><br><span>index 2c7028e..48efe51 100644</span><br><span>--- a/src/common/pcu_sock.c</span><br><span>+++ b/src/common/pcu_sock.c</span><br><span>@@ -465,6 +465,23 @@</span><br><span>     return pcu_sock_send(&bts_gsmnet, msg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* forward data from a RR GPRS SUSPEND REQ towards PCU */</span><br><span style="color: hsl(120, 100%, 40%);">+int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_pcu_if *pcu_prim;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        msg = pcu_msgb_alloc(PCU_IF_MSG_SUSP_REQ, lchan->ts->trx->bts->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+       pcu_prim = (struct gsm_pcu_if *) msg->data;</span><br><span style="color: hsl(120, 100%, 40%);">+        pcu_prim->u.susp_req.tlli = tlli;</span><br><span style="color: hsl(120, 100%, 40%);">+  memcpy(pcu_prim->u.susp_req.ra_id, ra_id, sizeof(pcu_prim->u.susp_req.ra_id));</span><br><span style="color: hsl(120, 100%, 40%);">+  pcu_prim->u.susp_req.cause = cause;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return pcu_sock_send(&bts_gsmnet, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,</span><br><span>        const struct gsm_pcu_if_data *data_req)</span><br><span> {</span><br><span>diff --git a/src/common/rsl.c b/src/common/rsl.c</span><br><span>index fce3495..cac4abd 100644</span><br><span>--- a/src/common/rsl.c</span><br><span>+++ b/src/common/rsl.c</span><br><span>@@ -29,12 +29,14 @@</span><br><span> #include <sys/types.h></span><br><span> #include <arpa/inet.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/byteswap.h></span><br><span> #include <osmocom/core/msgb.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/gsm/rsl.h></span><br><span> #include <osmocom/gsm/lapdm.h></span><br><span> #include <osmocom/gsm/protocol/gsm_12_21.h></span><br><span> #include <osmocom/gsm/protocol/gsm_08_58.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/protocol/gsm_04_08.h></span><br><span> #include <osmocom/gsm/protocol/ipaccess.h></span><br><span> #include <osmocom/trau/osmo_ortp.h></span><br><span> </span><br><span>@@ -2587,6 +2589,61 @@</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int rslms_is_gprs_susp_req(struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct abis_rsl_common_hdr *rh = msgb_l2(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+        struct abis_rsl_rll_hdr *rllh;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm48_hdr *gh;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((rh->msg_discr & 0xfe) != ABIS_RSL_MDISC_RLL)</span><br><span style="color: hsl(120, 100%, 40%);">+              return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rh->msg_type != RSL_MT_UNIT_DATA_IND)</span><br><span style="color: hsl(120, 100%, 40%);">+          return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   rllh = msgb_l2(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rsl_link_id_is_sacch(rllh->link_id))</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   gh = msgb_l3(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (gh->proto_discr != GSM48_PDISC_RR)</span><br><span style="color: hsl(120, 100%, 40%);">+             return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (gh->msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case GSM48_MT_RR_GPRS_SUSP_REQ:</span><br><span style="color: hsl(120, 100%, 40%);">+               return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* TS 44.018 9.1.13b GPRS suspension request */</span><br><span style="color: hsl(120, 100%, 40%);">+static int handle_gprs_susp_req(struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm48_hdr *gh = msgb_l3(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm48_gprs_susp_req *gsr;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t tlli;</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!gh || msgb_l3len(msg) < sizeof(*gh)+sizeof(*gsr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DRSL, LOGL_NOTICE, "%s Short GPRS SUSPEND REQ received, ignoring\n", gsm_lchan_name(msg->lchan));</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   gsr = (struct gsm48_gprs_susp_req *) gh->data;</span><br><span style="color: hsl(120, 100%, 40%);">+     tlli = osmo_htonl(gsr->tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGP(DRSL, LOGL_INFO, "%s Fwd GPRS SUSPEND REQ for TLLI=0x%08x to PCU\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           gsm_lchan_name(msg->lchan), tlli);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = pcu_tx_susp_req(msg->lchan, tlli, gsr->ra_id, gsr->cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, const struct lapdm_entity *le)</span><br><span> {</span><br><span>        return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - le->ta);</span><br><span>@@ -2727,6 +2784,8 @@</span><br><span>                 rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), le);</span><br><span>              msgb_free(msg);</span><br><span>              return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    } else if (rslms_is_gprs_susp_req(msg)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             return handle_gprs_susp_req(msg);</span><br><span>    } else {</span><br><span>             LOGP(DRSL, LOGL_INFO, "%s Fwd RLL msg %s from LAPDm to A-bis\n",</span><br><span>                   gsm_lchan_name(lchan), rsl_msg_name(rh->msg_type));</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13347">change 13347</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13347"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bts </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I3c1af662c8f0d3d22da200638480f6ef05c3ed1f </div>
<div style="display:none"> Gerrit-Change-Number: 13347 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: osmith <osmith@sysmocom.de> </div>