<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/17377">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
pespin: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">osmo-bts-virtual: 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>Depends: libosmocore.git I952044a17334f35712e087dc41781805000aebc1<br>Change-Id: I1cd9a251ce0b87181a0822d7940bbfc9f1428543<br>---<br>M src/osmo-bts-virtual/l1_if.c<br>M src/osmo-bts-virtual/scheduler_virtbts.c<br>2 files changed, 79 insertions(+), 12 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo-bts-virtual/l1_if.c b/src/osmo-bts-virtual/l1_if.c</span><br><span>index ab2cb76..b6a3507 100644</span><br><span>--- a/src/osmo-bts-virtual/l1_if.c</span><br><span>+++ b/src/osmo-bts-virtual/l1_if.c</span><br><span>@@ -128,12 +128,7 @@</span><br><span> break;</span><br><span> case GSMTAP_CHANNEL_TCH_F:</span><br><span> case GSMTAP_CHANNEL_TCH_H:</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">- /* TODO: handle voice messages */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!facch && ! tch_acch) {</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_INDICATION, msg);</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> case GSMTAP_CHANNEL_PACCH:</span><br><span>@@ -151,6 +146,19 @@</span><br><span> l1sap.u.data.pdch_presence_info = PRES_INFO_BOTH;</span><br><span> l1if_process_meas_res(pinst->trx, timeslot, fn, chan_nr, 0, 0, 0, 0);</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%);">+ /* the first byte indicates the type of voice codec (gsmtap_um_voice_type) */</span><br><span style="color: hsl(120, 100%, 40%);">+ msg->l2h = msgb_pull(msg, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_INDICATION, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sap.u.tch.chan_nr = chan_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sap.u.tch.fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sap.u.tch.rssi = 0; /* Radio Signal Strength Indicator. Best -> 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sap.u.tch.ber10k = 0; /* Bit Error Rate in 0.01%. Best -> 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sap.u.tch.ta_offs_256bits = 0; /* Burst time of arrival in quarter bits. Probably used for Timing Advance calc. Best -> 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sap.u.tch.lqual_cb = 10 * signal_dbm; /* Link quality in centiBel = 10 * dB. */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1if_process_meas_res(pinst->trx, timeslot, fn, chan_nr, 0, 0, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> case GSMTAP_CHANNEL_AGCH:</span><br><span> case GSMTAP_CHANNEL_PCH:</span><br><span> case GSMTAP_CHANNEL_BCCH:</span><br><span>diff --git a/src/osmo-bts-virtual/scheduler_virtbts.c b/src/osmo-bts-virtual/scheduler_virtbts.c</span><br><span>index 90288d1..72a6874 100644</span><br><span>--- a/src/osmo-bts-virtual/scheduler_virtbts.c</span><br><span>+++ b/src/osmo-bts-virtual/scheduler_virtbts.c</span><br><span>@@ -52,8 +52,8 @@</span><br><span> * This will at first wrap the msg with a GSMTAP header and then write it to the declared multicast socket.</span><br><span> * TODO: we might want to remove unused argument uint8_t tn</span><br><span> */</span><br><span style="color: hsl(0, 100%, 40%);">-static void tx_to_virt_um(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">- enum trx_chan_type chan, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+static void _tx_to_virt_um(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum trx_chan_type chan, struct msgb *msg, bool is_voice_frame)</span><br><span> {</span><br><span> const struct trx_chan_desc *chdesc = &trx_chan_desc[chan];</span><br><span> struct msgb *outmsg; /* msg to send with gsmtap header prepended */</span><br><span>@@ -76,7 +76,7 @@</span><br><span> l1sap_fn2ccch_block(fn) >= num_agch(l1t->trx, "PH-DATA-REQ"))</span><br><span> gsmtap_chantype = GSMTAP_CHANNEL_PCH;</span><br><span> else</span><br><span style="color: hsl(0, 100%, 40%);">- gsmtap_chantype = chantype_rsl2gsmtap(rsl_chantype, chdesc->link_id); /* the logical channel type */</span><br><span style="color: hsl(120, 100%, 40%);">+ gsmtap_chantype = chantype_rsl2gsmtap2(rsl_chantype, chdesc->link_id, is_voice_frame); /* the logical channel type */</span><br><span> </span><br><span> #if MODULO_HYPERFRAME</span><br><span> /* Restart fn after every superframe (26 * 51 frames) to simulate hyperframe overflow each 6 seconds. */</span><br><span>@@ -105,6 +105,65 @@</span><br><span> msgb_free(msg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void tx_to_virt_um(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum trx_chan_type chan, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ _tx_to_virt_um(l1t, tn, fn, chan, msg, false);</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%);">+static struct gsm_lchan *lchan_from_l1t(struct l1sched_trx *l1t, uint8_t tn, enum trx_chan_type chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_bts_trx_ts *ts;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t subslot = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(l1t && l1t->trx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (chan == TRXC_TCHH_1)</span><br><span style="color: hsl(120, 100%, 40%);">+ subslot = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ts = &l1t->trx->ts[tn];</span><br><span style="color: hsl(120, 100%, 40%);">+ return &ts->lchan[subslot];</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%);">+/* Determine the gsmtap_um_voice_type of a gsm_lchan */</span><br><span style="color: hsl(120, 100%, 40%);">+static int get_um_voice_type(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (lchan->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%);">+ if (lchan->type == GSM_LCHAN_TCH_H)</span><br><span style="color: hsl(120, 100%, 40%);">+ return GSMTAP_UM_VOICE_HR;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ return GSMTAP_UM_VOICE_FR;</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 style="color: hsl(120, 100%, 40%);">+static void tx_to_virt_um_voice_frame(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum trx_chan_type chan, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *lchan = lchan_from_l1t(l1t, tn, chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ int um_voice_type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ um_voice_type = get_um_voice_type(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (um_voice_type < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPLCHAN(lchan, DL1P, LOGL_ERROR, "Cannot determine Um voice type from lchan\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ um_voice_type = 0xff;</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%);">+ /* the first byte indicates the type of voice codec (gsmtap_um_voice_type) */</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, um_voice_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ msg->l2h = msg->data;</span><br><span style="color: hsl(120, 100%, 40%);">+ _tx_to_virt_um(l1t, tn, fn, chan, msg, true);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*</span><br><span> * TX on downlink</span><br><span> */</span><br><span>@@ -414,8 +473,8 @@</span><br><span> if (msg_facch) {</span><br><span> tx_to_virt_um(l1t, tn, fn, chan, msg_facch);</span><br><span> msgb_free(msg_tch);</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- tx_to_virt_um(l1t, tn, fn, chan, msg_tch);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (msg_tch)</span><br><span style="color: hsl(120, 100%, 40%);">+ tx_to_virt_um_voice_frame(l1t, tn, fn, chan, msg_tch);</span><br><span> </span><br><span> send_burst:</span><br><span> </span><br><span>@@ -456,7 +515,7 @@</span><br><span> tx_to_virt_um(l1t, tn, fn, chan, msg_facch);</span><br><span> msgb_free(msg_tch);</span><br><span> } else if (msg_tch)</span><br><span style="color: hsl(0, 100%, 40%);">- tx_to_virt_um(l1t, tn, fn, chan, msg_tch);</span><br><span style="color: hsl(120, 100%, 40%);">+ tx_to_virt_um_voice_frame(l1t, tn, fn, chan, msg_tch);</span><br><span> </span><br><span> send_burst:</span><br><span> return NULL;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/17377">change 17377</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/osmo-bts/+/17377"/><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-Change-Id: I1cd9a251ce0b87181a0822d7940bbfc9f1428543 </div>
<div style="display:none"> Gerrit-Change-Number: 17377 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </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: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>