<p>Vadim Yanitskiy <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/11920">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

Objections:
  Max: I would prefer this is not merged as is

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">libmsc/gsm_04_11.c: accept MT SMS messages over GSUP<br><br>Change-Id: I57357982ca0e51f6722c24a4aa1d0fb3e6caef88<br>Depends-on: (core) Ibe325c64ae2d6c626b232533bb4cbc65fc2b5d71<br>Depends-on: (OsmoHLR) I0589ff27933e9bca2bcf93b8259004935778db8f<br>Related Change-Id: (TTCN) I63a25c8366cce0852df6b628365151661a22a25f<br>Related: OS#3587<br>---<br>M include/osmocom/msc/gsm_04_11.h<br>M include/osmocom/msc/gsm_04_11_gsup.h<br>M src/libmsc/gsm_04_08.c<br>M src/libmsc/gsm_04_11.c<br>M src/libmsc/gsm_04_11_gsup.c<br>5 files changed, 164 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/msc/gsm_04_11.h b/include/osmocom/msc/gsm_04_11.h</span><br><span>index b739918..4297cdb 100644</span><br><span>--- a/include/osmocom/msc/gsm_04_11.h</span><br><span>+++ b/include/osmocom/msc/gsm_04_11.h</span><br><span>@@ -42,6 +42,10 @@</span><br><span> int gsm411_send_sms(struct gsm_network *net,</span><br><span>                 struct vlr_subscr *vsub,</span><br><span>                     struct gsm_sms *sms);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,</span><br><span style="color: hsl(120, 100%, 40%);">+                  size_t sm_rp_oa_len, const uint8_t *sm_rp_oa,</span><br><span style="color: hsl(120, 100%, 40%);">+                 size_t sm_rp_ud_len, const uint8_t *sm_rp_ud);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void gsm411_sapi_n_reject(struct ran_conn *conn);</span><br><span> </span><br><span> int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref);</span><br><span>diff --git a/include/osmocom/msc/gsm_04_11_gsup.h b/include/osmocom/msc/gsm_04_11_gsup.h</span><br><span>index 94ff8f6..969eaba 100644</span><br><span>--- a/include/osmocom/msc/gsm_04_11_gsup.h</span><br><span>+++ b/include/osmocom/msc/gsm_04_11_gsup.h</span><br><span>@@ -12,3 +12,9 @@</span><br><span>      uint8_t sm_rp_mr, uint8_t *sm_rp_da, uint8_t sm_rp_da_len);</span><br><span> int gsm411_gsup_mo_handler(struct vlr_subscr *vsub,</span><br><span>   struct osmo_gsup_message *gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm411_gsup_mt_fwd_sm_res(struct gsm_trans *trans, uint8_t sm_rp_mr);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm411_gsup_mt_fwd_sm_err(struct gsm_trans *trans,</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t sm_rp_mr, uint8_t cause);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm411_gsup_mt_handler(struct vlr_subscr *vsub,</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_gsup_message *gsup_msg);</span><br><span>diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c</span><br><span>index 7ff8681..686194f 100644</span><br><span>--- a/src/libmsc/gsm_04_08.c</span><br><span>+++ b/src/libmsc/gsm_04_08.c</span><br><span>@@ -1810,6 +1810,11 @@</span><br><span>           DEBUGP(DMSC, "Routed to GSM 04.11 MO handler\n");</span><br><span>          return gsm411_gsup_mo_handler(vsub, gsup_msg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    /* GSM 04.11 code implementing MT SMS */</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:</span><br><span style="color: hsl(120, 100%, 40%);">+            DEBUGP(DMSC, "Routed to GSM 04.11 MT handler\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return gsm411_gsup_mt_handler(vsub, gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     default:</span><br><span>             LOGP(DMM, LOGL_ERROR, "No handler found for %s, dropping message...\n",</span><br><span>                    osmo_gsup_message_type_name(gsup_msg->message_type));</span><br><span>diff --git a/src/libmsc/gsm_04_11.c b/src/libmsc/gsm_04_11.c</span><br><span>index 788a0a9..15a92d4 100644</span><br><span>--- a/src/libmsc/gsm_04_11.c</span><br><span>+++ b/src/libmsc/gsm_04_11.c</span><br><span>@@ -158,10 +158,13 @@</span><br><span>                gsm411_smc_recv(&trans->sms.smc_inst,</span><br><span>                         GSM411_MMSMS_REL_IND, NULL, 0);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             /* Notify the SMSqueue and free stored SMS */</span><br><span style="color: hsl(0, 100%, 40%);">-           send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, event);</span><br><span style="color: hsl(0, 100%, 40%);">-             trans->sms.sms = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-               sms_free(sms);</span><br><span style="color: hsl(120, 100%, 40%);">+                /* gsm411_send_rp_data() doesn't set trans->sms.sms */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (sms != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* Notify the SMSqueue and free stored SMS */</span><br><span style="color: hsl(120, 100%, 40%);">+                 send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, event);</span><br><span style="color: hsl(120, 100%, 40%);">+                   trans->sms.sms = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+                     sms_free(sms);</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span> </span><br><span>                /* Destroy this transaction */</span><br><span>               trans_free(trans);</span><br><span>@@ -794,6 +797,11 @@</span><br><span>     * successfully received a SMS.  We can now safely mark it as</span><br><span>         * transmitted */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (trans->net->sms_over_gsup) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Forward towards SMSC via GSUP */</span><br><span style="color: hsl(120, 100%, 40%);">+           return gsm411_gsup_mt_fwd_sm_res(trans, rph->msg_ref);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if (!sms) {</span><br><span>          LOGP(DLSMS, LOGL_ERROR, "RX RP-ACK but no sms in transaction?!?\n");</span><br><span>               return gsm411_send_rp_error(trans, rph->msg_ref,</span><br><span>@@ -830,6 +838,11 @@</span><br><span>        vlr_subscr_name(trans->conn->vsub), cause_len, cause,</span><br><span>          get_value_string(gsm411_rp_cause_strs, cause));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      if (trans->net->sms_over_gsup) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Forward towards SMSC via GSUP */</span><br><span style="color: hsl(120, 100%, 40%);">+           return gsm411_gsup_mt_fwd_sm_err(trans, rph->msg_ref, cause);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if (!sms) {</span><br><span>          LOGP(DLSMS, LOGL_ERROR,</span><br><span>                      "RX RP-ERR, but no sms in transaction?!?\n");</span><br><span>@@ -1112,6 +1125,42 @@</span><br><span>             GSM411_SM_RL_DATA_REQ);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Low-level function to send raw RP-DATA to a given subscriber */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,</span><br><span style="color: hsl(120, 100%, 40%);">+                       size_t sm_rp_oa_len, const uint8_t *sm_rp_oa,</span><br><span style="color: hsl(120, 100%, 40%);">+                 size_t sm_rp_ud_len, const uint8_t *sm_rp_ud)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_trans *trans;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Allocate a new transaction for MT SMS */</span><br><span style="color: hsl(120, 100%, 40%);">+   trans = gsm411_alloc_mt_trans(net, vsub);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!trans)</span><br><span style="color: hsl(120, 100%, 40%);">+           return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Allocate a message buffer for to be encoded SMS */</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = gsm411_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!msg) {</span><br><span style="color: hsl(120, 100%, 40%);">+           trans_free(trans);</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOMEM;</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%);">+   /* Encode SM-RP-OA (SMSC address) */</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_lv_put(msg, sm_rp_oa_len, sm_rp_oa);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Encode SM-RP-DA (shall be empty, len=0) */</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_v_put(msg, 0x00);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Encode RP-UD itself (SM TPDU) */</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_lv_put(msg, sm_rp_ud_len, sm_rp_ud);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,</span><br><span style="color: hsl(120, 100%, 40%);">+            GSM411_MT_RP_DATA_MT, trans->sms.sm_rp_mr,</span><br><span style="color: hsl(120, 100%, 40%);">+         GSM411_SM_RL_DATA_REQ);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Entry point for incoming GSM48_PDISC_SMS from abis_rsl.c */</span><br><span> int gsm0411_rcv_sms(struct ran_conn *conn,</span><br><span>                     struct msgb *msg)</span><br><span>diff --git a/src/libmsc/gsm_04_11_gsup.c b/src/libmsc/gsm_04_11_gsup.c</span><br><span>index 5c01072..f2de95f 100644</span><br><span>--- a/src/libmsc/gsm_04_11_gsup.c</span><br><span>+++ b/src/libmsc/gsm_04_11_gsup.c</span><br><span>@@ -201,3 +201,99 @@</span><br><span>                msg_name, msg_is_err ? "Err" : "Res");</span><br><span>   return -EINVAL;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm411_gsup_mt_fwd_sm_res(struct gsm_trans *trans, uint8_t sm_rp_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_gsup_message gsup_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Associate logging messages with this subscriber */</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        LOGP(DLSMS, LOGL_DEBUG, "TX MT-forwardSM-Res\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize a new GSUP message */</span><br><span style="color: hsl(120, 100%, 40%);">+   gsup_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT,</span><br><span style="color: hsl(120, 100%, 40%);">+          trans->vsub->imsi, &sm_rp_mr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return osmo_gsup_client_enc_send(trans->net->vlr->gsup_client, &gsup_msg);</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%);">+int gsm411_gsup_mt_fwd_sm_err(struct gsm_trans *trans,</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t sm_rp_mr, uint8_t cause)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_gsup_message gsup_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Associate logging messages with this subscriber */</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        LOGP(DLSMS, LOGL_DEBUG, "TX MT-forwardSM-Err\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize a new GSUP message */</span><br><span style="color: hsl(120, 100%, 40%);">+   gsup_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+           trans->vsub->imsi, &sm_rp_mr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* SM-RP-Cause value */</span><br><span style="color: hsl(120, 100%, 40%);">+       gsup_msg.sm_rp_cause = &cause;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* TODO: include optional SM-RP-UI field if present */</span><br><span style="color: hsl(120, 100%, 40%);">+        return osmo_gsup_client_enc_send(trans->net->vlr->gsup_client, &gsup_msg);</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%);">+/* Handles MT SMS (and triggers Paging Request if required) */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm411_gsup_mt_handler(struct vlr_subscr *vsub,</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_gsup_message *gsup_msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct vlr_instance *vlr;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_network *net;</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%);">+     /* Obtain required pointers */</span><br><span style="color: hsl(120, 100%, 40%);">+        vlr = vsub->vlr;</span><br><span style="color: hsl(120, 100%, 40%);">+   net = (struct gsm_network *) vlr->user_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Associate logging messages with this subscriber */</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_context(LOG_CTX_VLR_SUBSCR, vsub);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  LOGP(DLSMS, LOGL_DEBUG, "RX MT-forwardSM-Req\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Make sure that 'SMS over GSUP' is expected */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!net->sms_over_gsup) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOGP(DLSMS, LOGL_NOTICE, "Unexpected MT SMS over GSUP, "</span><br><span style="color: hsl(120, 100%, 40%);">+                    "ignoring message...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           /* TODO: notify sender about that? */</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EIO;</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%);">+   /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * Verify GSUP message</span><br><span style="color: hsl(120, 100%, 40%);">+         *</span><br><span style="color: hsl(120, 100%, 40%);">+     * FIXME: SM-RP-MR is not known yet (to be assigned by MSC)</span><br><span style="color: hsl(120, 100%, 40%);">+    * NOTE: SM-RP-DA is out of our interest</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!gsup_msg->sm_rp_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+           goto msg_error;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!gsup_msg->sm_rp_ui)</span><br><span style="color: hsl(120, 100%, 40%);">+           goto msg_error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* SM-RP-OA shall contain SMSC address */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (gsup_msg->sm_rp_oa_type != OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR)</span><br><span style="color: hsl(120, 100%, 40%);">+          goto msg_error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Send RP-DATA */</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = gsm411_send_rp_data(net, vsub,</span><br><span style="color: hsl(120, 100%, 40%);">+           gsup_msg->sm_rp_oa_len, gsup_msg->sm_rp_oa,</span><br><span style="color: hsl(120, 100%, 40%);">+             gsup_msg->sm_rp_ui_len, gsup_msg->sm_rp_ui);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DLSMS, LOGL_NOTICE, "Failed to send MT SMS, "</span><br><span style="color: hsl(120, 100%, 40%);">+                  "ignoring MT-forwardSM-Req message...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          /* TODO: notify sender about that? */</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 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%);">+msg_error:</span><br><span style="color: hsl(120, 100%, 40%);">+       /* TODO: notify sender about that? */</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLSMS, LOGL_NOTICE, "RX malformed MT-forwardSM-Req\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11920">change 11920</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/11920"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-msc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I57357982ca0e51f6722c24a4aa1d0fb3e6caef88 </div>
<div style="display:none"> Gerrit-Change-Number: 11920 </div>
<div style="display:none"> Gerrit-PatchSet: 13 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-CC: Stefan Sperling <stsp@stsp.name> </div>