<p>tnt has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13242">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">libmsc: Allow different channel types to be requested as silent calls<br><br>Change-Id: I82645708dd27864cf33ea9cc993ead0983415602<br>Signed-off-by: Sylvain Munaut <tnt@246tNt.com><br>---<br>M include/osmocom/msc/silent_call.h<br>M src/libmsc/msc_vty.c<br>M src/libmsc/silent_call.c<br>3 files changed, 153 insertions(+), 22 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/42/13242/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/msc/silent_call.h b/include/osmocom/msc/silent_call.h</span><br><span>index 70324e5..dbd7dcc 100644</span><br><span>--- a/include/osmocom/msc/silent_call.h</span><br><span>+++ b/include/osmocom/msc/silent_call.h</span><br><span>@@ -2,9 +2,12 @@</span><br><span> #define _SILENT_CALL_H</span><br><span> </span><br><span> struct ran_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm0808_channel_type;</span><br><span> </span><br><span> extern int gsm_silent_call_start(struct vlr_subscr *vsub,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 void *data, int type);</span><br><span style="color: hsl(120, 100%, 40%);">+          struct gsm0808_channel_type *ct,</span><br><span style="color: hsl(120, 100%, 40%);">+              const char *traffic_dst_ip, uint16_t traffic_dst_port,</span><br><span style="color: hsl(120, 100%, 40%);">+                void *data);</span><br><span> extern int gsm_silent_call_stop(struct vlr_subscr *vsub);</span><br><span> </span><br><span> #if 0</span><br><span>diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c</span><br><span>index 2adb2a4..4ec2e5b 100644</span><br><span>--- a/src/libmsc/msc_vty.c</span><br><span>+++ b/src/libmsc/msc_vty.c</span><br><span>@@ -1042,21 +1042,35 @@</span><br><span>        return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"</span><br><span style="color: hsl(120, 100%, 40%);">+#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"</span><br><span> #define CHAN_TYPE_HELP                   \</span><br><span>            "Any channel\n"               \</span><br><span>            "TCH/F channel\n"     \</span><br><span style="color: hsl(120, 100%, 40%);">+             "TCH/H channel\n"     \</span><br><span>            "Any TCH channel\n"   \</span><br><span>            "SDCCH channel\n"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"</span><br><span style="color: hsl(120, 100%, 40%);">+#define CHAN_MODE_HELP                          \</span><br><span style="color: hsl(120, 100%, 40%);">+             "Signalling only\n"           \</span><br><span style="color: hsl(120, 100%, 40%);">+             "Speech with HR codec\n"      \</span><br><span style="color: hsl(120, 100%, 40%);">+             "Speech with FR codec\n"      \</span><br><span style="color: hsl(120, 100%, 40%);">+             "Speech with EFR codec\n"     \</span><br><span style="color: hsl(120, 100%, 40%);">+             "Speech with AMR codec\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> DEFUN(subscriber_silent_call_start,</span><br><span>       subscriber_silent_call_start_cmd,</span><br><span style="color: hsl(0, 100%, 40%);">-      "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",</span><br><span style="color: hsl(120, 100%, 40%);">+      "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65536>]",</span><br><span>       SUBSCR_HELP "Silent call operation\n" "Start silent call\n"</span><br><span style="color: hsl(0, 100%, 40%);">- CHAN_TYPE_HELP)</span><br><span style="color: hsl(120, 100%, 40%);">+       CHAN_TYPE_HELP CHAN_MODE_HELP</span><br><span style="color: hsl(120, 100%, 40%);">+ "Target IP for RTP traffic (default 127.0.0.1)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+   "Target port for RTP traffic (default: 4000)\n")</span><br><span> {</span><br><span>      struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);</span><br><span style="color: hsl(0, 100%, 40%);">-   int rc, type;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm0808_channel_type ct;</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *ip = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint16_t port = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc, speech;</span><br><span> </span><br><span>  if (!vsub) {</span><br><span>                 vty_out(vty, "%% No subscriber found for %s %s%s",</span><br><span>@@ -1064,16 +1078,52 @@</span><br><span>               return CMD_WARNING;</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (!strcmp(argv[2], "tch/f"))</span><br><span style="color: hsl(0, 100%, 40%);">-                type = RSL_CHANNEED_TCH_F;</span><br><span style="color: hsl(0, 100%, 40%);">-      else if (!strcmp(argv[2], "tch/any"))</span><br><span style="color: hsl(0, 100%, 40%);">-         type = RSL_CHANNEED_TCH_ForH;</span><br><span style="color: hsl(0, 100%, 40%);">-   else if (!strcmp(argv[2], "sdcch"))</span><br><span style="color: hsl(0, 100%, 40%);">-           type = RSL_CHANNEED_SDCCH;</span><br><span style="color: hsl(0, 100%, 40%);">-      else</span><br><span style="color: hsl(0, 100%, 40%);">-            type = RSL_CHANNEED_ANY;        /* Defaults to ANY */</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&ct, 0x00, sizeof(ct));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  rc = gsm_silent_call_start(vsub, vty, type);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!strcmp(argv[3], "signalling")) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ct.ch_indctr = GSM0808_CHAN_SIGN;</span><br><span style="color: hsl(120, 100%, 40%);">+             ct.perm_spch[0] = 0; /* Spare but required */</span><br><span style="color: hsl(120, 100%, 40%);">+         ct.perm_spch_len = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcmp(argv[3], "speech-hr")) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ct.ch_indctr = GSM0808_CHAN_SPEECH;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch[0] = GSM0808_PERM_HR1;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch_len = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcmp(argv[3], "speech-fr")) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ct.ch_indctr = GSM0808_CHAN_SPEECH;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch[0] = GSM0808_PERM_FR1;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch_len = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcmp(argv[3], "speech-efr")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ct.ch_indctr = GSM0808_CHAN_SPEECH;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch[0] = GSM0808_PERM_FR2;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch_len = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcmp(argv[3], "speech-amr")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ct.ch_indctr = GSM0808_CHAN_SPEECH;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch[0] = GSM0808_PERM_FR3;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch[1] = GSM0808_PERM_HR3;</span><br><span style="color: hsl(120, 100%, 40%);">+           ct.perm_spch_len = 2;</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%);">+   speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!strcmp(argv[2], "tch/f"))</span><br><span style="color: hsl(120, 100%, 40%);">+              ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;</span><br><span style="color: hsl(120, 100%, 40%);">+     else if (!strcmp(argv[2], "tch/h"))</span><br><span style="color: hsl(120, 100%, 40%);">+         ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;</span><br><span style="color: hsl(120, 100%, 40%);">+     else if (!strcmp(argv[2], "tch/any"))</span><br><span style="color: hsl(120, 100%, 40%);">+               ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (!strcmp(argv[2], "sdcch")) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (speech) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                   return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             ct.ch_rate_type = GSM0808_SIGN_SDCCH;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else</span><br><span style="color: hsl(120, 100%, 40%);">+                ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ip   = argc >= 5 ? argv[4] : "127.0.0.1";</span><br><span style="color: hsl(120, 100%, 40%);">+        port = argc >= 6 ? atoi(argv[5]) : 4000;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);</span><br><span>    switch (rc) {</span><br><span>        case -ENODEV:</span><br><span>                vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);</span><br><span>diff --git a/src/libmsc/silent_call.c b/src/libmsc/silent_call.c</span><br><span>index 2a9fa9c..cadd17d 100644</span><br><span>--- a/src/libmsc/silent_call.c</span><br><span>+++ b/src/libmsc/silent_call.c</span><br><span>@@ -24,6 +24,7 @@</span><br><span> #include <unistd.h></span><br><span> #include <errno.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/msc/signal.h></span><br><span> #include <osmocom/msc/debug.h></span><br><span>@@ -31,13 +32,37 @@</span><br><span> #include <osmocom/msc/gsm_subscriber.h></span><br><span> #include <osmocom/msc/vlr.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/sigtran/sccp_helpers.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct silent_call_data {</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm0808_channel_type ct;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     char traffic_ip[INET_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+     uint16_t traffic_port;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      void *data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_timer_list timer;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ran_conn *conn;</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%);">+static void timer_cb(void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct silent_call_data *scd = (struct silent_call_data *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+       ran_conn_communicating(scd->conn);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(scd);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* paging of the requested subscriber has completed */</span><br><span> static int paging_cb_silent(unsigned int hooknum, unsigned int event,</span><br><span>                        struct msgb *msg, void *_conn, void *_data)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  struct silent_call_data *scd = (struct silent_call_data *)_data;</span><br><span>     struct ran_conn *conn = _conn;</span><br><span>       struct scall_signal_data sigdata;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct msgb *msg_ass;</span><br><span>        int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   int i;</span><br><span> </span><br><span>   if (hooknum != GSM_HOOK_RR_PAGING)</span><br><span>           return -EINVAL;</span><br><span>@@ -45,7 +70,7 @@</span><br><span>  DEBUGP(DLSMS, "paging_cb_silent: ");</span><br><span> </span><br><span>   sigdata.conn = conn;</span><br><span style="color: hsl(0, 100%, 40%);">-    sigdata.data = _data;</span><br><span style="color: hsl(120, 100%, 40%);">+ sigdata.data = scd->data;</span><br><span> </span><br><span>     switch (event) {</span><br><span>     case GSM_PAGING_SUCCEEDED:</span><br><span>@@ -56,20 +81,58 @@</span><br><span>                     conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn);</span><br><span> #endif</span><br><span>            conn->silent_call = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Increment lchan reference count and mark as active*/</span><br><span>              ran_conn_get(conn, RAN_CONN_USE_SILENT_CALL);</span><br><span style="color: hsl(0, 100%, 40%);">-           /* increment lchan reference count */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Schedule a timer to mark it as active */</span><br><span style="color: hsl(120, 100%, 40%);">+           scd->conn = conn;</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_timer_setup(&scd->timer, timer_cb, scd);</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_timer_schedule(&scd->timer, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Manually craft an assignement message with requested mode */</span><br><span style="color: hsl(120, 100%, 40%);">+               if (scd->ct.ch_indctr == GSM0808_CHAN_SPEECH) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    struct gsm0808_speech_codec_list scl;</span><br><span style="color: hsl(120, 100%, 40%);">+                 union {</span><br><span style="color: hsl(120, 100%, 40%);">+                               struct sockaddr_storage st;</span><br><span style="color: hsl(120, 100%, 40%);">+                           struct sockaddr_in in;</span><br><span style="color: hsl(120, 100%, 40%);">+                        } rtp_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 memset(&rtp_addr, 0, sizeof(rtp_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                   rtp_addr.in.sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+                     rtp_addr.in.sin_port = osmo_htons(scd->traffic_port);</span><br><span style="color: hsl(120, 100%, 40%);">+                      rtp_addr.in.sin_addr.s_addr = inet_addr(scd->traffic_ip);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                        for (i=0; i<scd->ct.perm_spch_len; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                         gsm0808_speech_codec_from_chan_type(&scl.codec[i], scd->ct.perm_spch[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+                      scl.len = scd->ct.perm_spch_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 msg_ass = gsm0808_create_ass(&scd->ct, NULL, &rtp_addr.st, &scl, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+                } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      msg_ass = gsm0808_create_ass(&scd->ct, NULL, NULL, NULL, NULL);</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%);">+           /* Send assignement message, hoping it will work */</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg_ass);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Signal completion */</span><br><span>              osmo_signal_dispatch(SS_SCALL, S_SCALL_SUCCESS, &sigdata);</span><br><span>               break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     case GSM_PAGING_EXPIRED:</span><br><span>     case GSM_PAGING_BUSY:</span><br><span>                DEBUGP(DLSMS, "expired\n");</span><br><span>                osmo_signal_dispatch(SS_SCALL, S_SCALL_EXPIRED, &sigdata);</span><br><span>               break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     default:</span><br><span>             rc = -EINVAL;</span><br><span>                break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+               talloc_free(scd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  return rc;</span><br><span> }</span><br><span> </span><br><span>@@ -120,18 +183,33 @@</span><br><span> </span><br><span> </span><br><span> /* initiate a silent call with a given subscriber */</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_silent_call_start(struct vlr_subscr *vsub, void *data, int type)</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_silent_call_start(struct vlr_subscr *vsub,</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm0808_channel_type *ct,</span><br><span style="color: hsl(120, 100%, 40%);">+      const char *traffic_dst_ip, uint16_t traffic_dst_port,</span><br><span style="color: hsl(120, 100%, 40%);">+        void *data)</span><br><span> {</span><br><span>     struct subscr_request *req;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct silent_call_data *scd;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       /* FIXME the VTY command allows selecting a silent call channel type.</span><br><span style="color: hsl(0, 100%, 40%);">-    * This doesn't apply to the situation after MSCSPLIT with an</span><br><span style="color: hsl(0, 100%, 40%);">-        * A-interface. */</span><br><span style="color: hsl(0, 100%, 40%);">-      req = subscr_request_conn(vsub, paging_cb_silent, data,</span><br><span style="color: hsl(120, 100%, 40%);">+       scd = talloc_zero(vsub, struct silent_call_data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   memcpy(&scd->ct, ct, sizeof(struct gsm0808_channel_type));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (traffic_dst_ip) {</span><br><span style="color: hsl(120, 100%, 40%);">+         strncpy(scd->traffic_ip, traffic_dst_ip, sizeof(scd->traffic_ip));</span><br><span style="color: hsl(120, 100%, 40%);">+              scd->traffic_port = traffic_dst_port;</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%);">+   scd->data = data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        req = subscr_request_conn(vsub, paging_cb_silent, scd,</span><br><span>                                 "establish silent call",</span><br><span>                                   SGSAP_SERV_IND_CS_CALL);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!req)</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!req) {</span><br><span style="color: hsl(120, 100%, 40%);">+           talloc_free(scd);</span><br><span>            return -ENODEV;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  return 0;</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13242">change 13242</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/13242"/><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: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I82645708dd27864cf33ea9cc993ead0983415602 </div>
<div style="display:none"> Gerrit-Change-Number: 13242 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: tnt <tnt@246tNt.com> </div>