<p>neels <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmocom-bb/+/17415">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  neels: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">virt_phy: implement GSMTAP_CHANNEL_VOICE<br><br>GSMTAP_CHANNEL_VOICE is the mechanism by which GSMTAP can [finally!]<br>be used to transport circuit-switched voice codec payload, and not<br>just signalling.<br><br>Original patch by Neels Hofmeyr, heavily extended by Harald Welte.<br><br>Change-Id: Id72cf23b7c6587efae4cdaa7b50ab4d85b8c8d22<br>---<br>M src/host/virt_phy/configure.ac<br>M src/host/virt_phy/src/gsmtapl1_if.c<br>M src/host/virt_phy/src/virt_prim_traffic.c<br>3 files changed, 63 insertions(+), 14 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/host/virt_phy/configure.ac b/src/host/virt_phy/configure.ac</span><br><span>index a2c2bf6..fbff2c1 100644</span><br><span>--- a/src/host/virt_phy/configure.ac</span><br><span>+++ b/src/host/virt_phy/configure.ac</span><br><span>@@ -12,6 +12,8 @@</span><br><span> AC_PROG_INSTALL</span><br><span> </span><br><span> dnl checks for libraries</span><br><span style="color: hsl(120, 100%, 40%);">+dnl TODO: insert libosmocore version with GSMTAP_CHANNEL_VOICE: PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.4.0)</span><br><span style="color: hsl(120, 100%, 40%);">+dnl       (at time of writing not released yet)</span><br><span> PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)</span><br><span> PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm)</span><br><span> </span><br><span>diff --git a/src/host/virt_phy/src/gsmtapl1_if.c b/src/host/virt_phy/src/gsmtapl1_if.c</span><br><span>index 30f88ff..3fa69c4 100644</span><br><span>--- a/src/host/virt_phy/src/gsmtapl1_if.c</span><br><span>+++ b/src/host/virt_phy/src/gsmtapl1_if.c</span><br><span>@@ -26,6 +26,7 @@</span><br><span> #include <osmocom/gsm/rsl.h></span><br><span> #include <osmocom/gsm/gsm_utils.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/core/msgb.h></span><br><span> #include <stddef.h></span><br><span> #include <stdlib.h></span><br><span>@@ -48,6 +49,29 @@</span><br><span>     return lname;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Return gsmtap_um_voice_type or -1 on error */</span><br><span style="color: hsl(120, 100%, 40%);">+static int get_um_voice_type(enum gsm48_chan_mode tch_mode, uint8_t rsl_chantype)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (tch_mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+   case GSM48_CMODE_SPEECH_V1:</span><br><span style="color: hsl(120, 100%, 40%);">+           switch (rsl_chantype) {</span><br><span style="color: hsl(120, 100%, 40%);">+               case RSL_CHAN_Bm_ACCHs:</span><br><span style="color: hsl(120, 100%, 40%);">+                       return GSMTAP_UM_VOICE_FR;</span><br><span style="color: hsl(120, 100%, 40%);">+            case RSL_CHAN_Lm_ACCHs:</span><br><span style="color: hsl(120, 100%, 40%);">+                       return GSMTAP_UM_VOICE_HR;</span><br><span style="color: hsl(120, 100%, 40%);">+            default:</span><br><span style="color: hsl(120, 100%, 40%);">+                      return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM48_CMODE_SPEECH_EFR:</span><br><span style="color: hsl(120, 100%, 40%);">+          return GSMTAP_UM_VOICE_EFR;</span><br><span style="color: hsl(120, 100%, 40%);">+   case GSM48_CMODE_SPEECH_AMR:</span><br><span style="color: hsl(120, 100%, 40%);">+          return GSMTAP_UM_VOICE_AMR;</span><br><span style="color: hsl(120, 100%, 40%);">+   default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return -1;</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> /**</span><br><span>  * Replace l11 header of given msgb by a gsmtap header and send it over the virt um.</span><br><span>  */</span><br><span>@@ -74,12 +98,25 @@</span><br><span>           rsl_chantype = RSL_CHAN_OSMO_PDCH;</span><br><span>           timeslot = tn;</span><br><span>               subslot = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-            gsmtap_chan = chantype_rsl2gsmtap(rsl_chantype, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+           gsmtap_chan = chantype_rsl2gsmtap2(rsl_chantype, 0, false);</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case L1CTL_TRAFFIC_REQ:</span><br><span style="color: hsl(120, 100%, 40%);">+               ul = (struct l1ctl_info_ul *)l1h->data;</span><br><span style="color: hsl(120, 100%, 40%);">+            rsl_dec_chan_nr(ul->chan_nr, &rsl_chantype, &subslot, &timeslot);</span><br><span style="color: hsl(120, 100%, 40%);">+              gsmtap_chan = chantype_rsl2gsmtap2(rsl_chantype, 0, true);</span><br><span style="color: hsl(120, 100%, 40%);">+            /* the first byte indicates the type of voice codec (gsmtap_um_voice_type);</span><br><span style="color: hsl(120, 100%, 40%);">+            * let's first strip any data in front of the l2 header, then push this extra</span><br><span style="color: hsl(120, 100%, 40%);">+              * byte to the front and finally adjust the l2h pointer */</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_pull_to_l2(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+         msgb_push_u8(msg, get_um_voice_type(ms->state.tch_mode, rsl_chantype));</span><br><span style="color: hsl(120, 100%, 40%);">+            msg->l2h = msg->data;</span><br><span style="color: hsl(120, 100%, 40%);">+           data = msgb_l2(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+          data_len = msgb_l2len(msg);</span><br><span>          break;</span><br><span>       default:</span><br><span>             ul = (struct l1ctl_info_ul *)l1h->data;</span><br><span>           rsl_dec_chan_nr(ul->chan_nr, &rsl_chantype, &subslot, &timeslot);</span><br><span style="color: hsl(0, 100%, 40%);">-                gsmtap_chan = chantype_rsl2gsmtap(rsl_chantype, ul->link_id);</span><br><span style="color: hsl(120, 100%, 40%);">+              gsmtap_chan = chantype_rsl2gsmtap2(rsl_chantype, ul->link_id, false);</span><br><span>             break;</span><br><span>       }</span><br><span> </span><br><span>@@ -219,13 +256,7 @@</span><br><span>         switch (gsmtap_chantype & ~GSMTAP_CHANNEL_ACCH & 0xff) {</span><br><span>     case GSMTAP_CHANNEL_TCH_H:</span><br><span>   case GSMTAP_CHANNEL_TCH_F:</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-         /* TODO: handle voice */</span><br><span style="color: hsl(0, 100%, 40%);">-                if (!facch && !tch_acch) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      l1ctl_tx_traffic_ind(msg, arfcn, link_id, chan_nr, fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       snr, signal_dbm, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(120, 100%, 40%);">+               /* This is TCH signalling, for voice frames see GSMTAP_CHANNEL_VOICE */</span><br><span>      case GSMTAP_CHANNEL_SDCCH4:</span><br><span>  case GSMTAP_CHANNEL_SDCCH8:</span><br><span>          /* only forward messages on dedicated channels to l2, if</span><br><span>@@ -235,6 +266,16 @@</span><br><span>                      l1ctl_tx_data_ind(ms, msg, arfcn, link_id, chan_nr, fn, snr_db, signal_dbm, 0, 0);</span><br><span>           }</span><br><span>            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSMTAP_CHANNEL_VOICE_F:</span><br><span style="color: hsl(120, 100%, 40%);">+  case GSMTAP_CHANNEL_VOICE_H:</span><br><span style="color: hsl(120, 100%, 40%);">+          /* only forward messages on dedicated channels to l2, if</span><br><span style="color: hsl(120, 100%, 40%);">+               * the timeslot and subslot is fitting */</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ms->state.dedicated.tn == timeslot</span><br><span style="color: hsl(120, 100%, 40%);">+                 && ms->state.dedicated.subslot == subslot) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   l1ctl_tx_traffic_ind(ms, msg, arfcn, link_id, chan_nr, fn,</span><br><span style="color: hsl(120, 100%, 40%);">+                                         snr_db, signal_dbm, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span>       case GSMTAP_CHANNEL_CBCH51:</span><br><span>          /* only pass CBCH data if the user application actually indicated that a CBCH</span><br><span>                 * is present */</span><br><span>diff --git a/src/host/virt_phy/src/virt_prim_traffic.c b/src/host/virt_phy/src/virt_prim_traffic.c</span><br><span>index 5f6b273..3d2b2b1 100644</span><br><span>--- a/src/host/virt_phy/src/virt_prim_traffic.c</span><br><span>+++ b/src/host/virt_phy/src/virt_prim_traffic.c</span><br><span>@@ -84,7 +84,8 @@</span><br><span>        struct msgb *l1ctl_msg = NULL;</span><br><span>       struct l1ctl_traffic_ind * l1ti;</span><br><span>     struct l1ctl_info_dl * l1dl;</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t *frame, frame_len;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *frame;</span><br><span style="color: hsl(120, 100%, 40%);">+       int frame_len;</span><br><span>       uint8_t rsl_chan_type, subchan, timeslot;</span><br><span>    l1ctl_msg = l1ctl_msgb_alloc(L1CTL_TRAFFIC_IND);</span><br><span>     l1dl = (struct l1ctl_info_dl *) msgb_put(l1ctl_msg, sizeof(*l1dl));</span><br><span>@@ -101,11 +102,16 @@</span><br><span>  l1dl->num_biterr = 0; /* no biterrors */</span><br><span>  l1dl->fire_crc = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      /* TODO: traffic decoding and decryption */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     frame_len = msgb_length(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* The first byte indicates the type of voice frame (enum gsmtap_um_voice_type),</span><br><span style="color: hsl(120, 100%, 40%);">+       * which we simply ignore here and pass on the frame without that byte.</span><br><span style="color: hsl(120, 100%, 40%);">+        * TODO: Check for consistency with ms->state.tch_mode ? */</span><br><span style="color: hsl(120, 100%, 40%);">+        frame_len = msgb_length(msg) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (frame_len < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               msgb_free(l1ctl_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+         return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span>    frame = (uint8_t *) msgb_put(l1ctl_msg, frame_len);</span><br><span style="color: hsl(0, 100%, 40%);">-     memcpy(frame, msgb_data(msg), frame_len);</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(frame, msgb_data(msg)+1, frame_len);</span><br><span> </span><br><span>      DEBUGPMS(DL1P, ms, "Tx L1CTL_TRAFFIC_IND (chan_nr=0x%02x, link_id=0x%02x)\n", chan_nr, link_id);</span><br><span>   l1ctl_sap_tx_to_l23_inst(ms, l1ctl_msg);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmocom-bb/+/17415">change 17415</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/c/osmocom-bb/+/17415"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmocom-bb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Id72cf23b7c6587efae4cdaa7b50ab4d85b8c8d22 </div>
<div style="display:none"> Gerrit-Change-Number: 17415 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>