jolly has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/34479?usp=email )
Change subject: ASCI: Add a flag to turn transmitter off or on ...................................................................... ASCI: Add a flag to turn transmitter off or on This flag can be used to turn transmitter off for "group receive mode" or for handover procedure. The flag is stored in the channel description of the mobile application. It is sent to layer 1 when switching to dedicated channel or when changing TCH mode. At the layer 1 the transmitter is turned off while the receiver is still active. This is done by: * scheduling a TX dummy task for TCH bursts * scheduling no TX task for SACCH bursts * not enabling the transmit window Related: OS#5364 Change-Id: I20133523adc3b204cd2181bfe664fe66020a10e3 --- M include/l1ctl_proto.h M src/host/layer23/include/osmocom/bb/common/l1ctl.h M src/host/layer23/include/osmocom/bb/common/osmocom_data.h M src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h M src/host/layer23/src/common/l1ctl.c M src/host/layer23/src/misc/app_cbch_sniff.c M src/host/layer23/src/mobile/gsm414.c M src/host/layer23/src/mobile/gsm48_rr.c M src/host/layer23/src/modem/grr.c M src/target/firmware/include/layer1/async.h M src/target/firmware/include/layer1/sync.h M src/target/firmware/layer1/async.c M src/target/firmware/layer1/l23_api.c M src/target/firmware/layer1/prim_tch.c 14 files changed, 92 insertions(+), 42 deletions(-) Approvals: laforge: Looks good to me, but someone else must approve fixeria: Looks good to me, approved pespin: Looks good to me, but someone else must approve Jenkins Builder: Verified diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h index 8bf44cf..2bdb560 100644 --- a/include/l1ctl_proto.h +++ b/include/l1ctl_proto.h @@ -146,6 +146,7 @@ uint8_t start_codec; uint8_t codecs_bitmask; } amr; + uint8_t tch_flags; } __attribute__((packed)); /* data on the CCCH was found. This is following the header */ @@ -219,8 +220,11 @@ uint8_t start_codec; uint8_t codecs_bitmask; } amr; + uint8_t tch_flags; } __attribute__((packed)); +#define L1CTL_TCH_FLAG_RXONLY (1<<0) /* TX disabled */ + /* the l1_info_ul header is in front */ struct l1ctl_rach_req { uint8_t ra; @@ -265,6 +269,7 @@ }; uint8_t tch_mode; uint8_t audio_mode; + uint8_t tch_flags; } __attribute__((packed)); struct l1ctl_dm_freq_req { diff --git a/src/host/layer23/include/osmocom/bb/common/l1ctl.h b/src/host/layer23/include/osmocom/bb/common/l1ctl.h index 40b3159..d49e16d 100644 --- a/src/host/layer23/include/osmocom/bb/common/l1ctl.h +++ b/src/host/layer23/include/osmocom/bb/common/l1ctl.h @@ -26,11 +26,10 @@ uint8_t ra, uint16_t offset, uint8_t combined); /* Transmit L1CTL_DM_EST_REQ */ -int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, - uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, uint8_t audio_mode); -int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, - uint16_t *ma, uint8_t ma_len, uint8_t chan_nr, uint8_t tsc, - uint8_t tch_mode, uint8_t audio_mode); +int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr, uint8_t tsc, + uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags); +int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, uint16_t *ma, uint8_t ma_len, + uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags); /* Transmit L1CTL_DM_FREQ_REQ */ int l1ctl_tx_dm_freq_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, @@ -50,8 +49,8 @@ int l1ctl_tx_ccch_mode_req(struct osmocom_ms *ms, uint8_t ccch_mode); /* Transmit TCH_MODE_REQ */ -int l1ctl_tx_tch_mode_req(struct osmocom_ms *ms, uint8_t tch_mode, - uint8_t audio_mode, uint8_t tch_loop_mode); +int l1ctl_tx_tch_mode_req(struct osmocom_ms *ms, uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags, + uint8_t tch_loop_mode); /* Transmit ECHO_REQ */ int l1ctl_tx_echo_req(struct osmocom_ms *ms, unsigned int len); diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h index 3e5c13a..60e12df 100644 --- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h +++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h @@ -83,6 +83,7 @@ struct osmocom_ms *ms; uint8_t tch_mode; uint8_t audio_mode; + uint8_t tch_flags; }; struct osmobb_neigh_pm_ind { diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h index ae9b867..299b6e5 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h +++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h @@ -101,6 +101,7 @@ uint8_t start; /* start time available */ struct gsm_time start_tm; /* start time */ uint8_t mode; /* mode of channel */ + uint8_t tch_flags; /* E.g. L1CTL_TCH_FLAG_RXONLY */ uint8_t cipher; /* ciphering of channel */ }; diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c index e3a4015..e950c85 100644 --- a/src/host/layer23/src/common/l1ctl.c +++ b/src/host/layer23/src/common/l1ctl.c @@ -443,8 +443,8 @@ } /* Transmit L1CTL_TCH_MODE_REQ */ -int l1ctl_tx_tch_mode_req(struct osmocom_ms *ms, uint8_t tch_mode, - uint8_t audio_mode, uint8_t tch_loop_mode) +int l1ctl_tx_tch_mode_req(struct osmocom_ms *ms, uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags, + uint8_t tch_loop_mode) { struct msgb *msg; struct l1ctl_tch_mode_req *req; @@ -458,6 +458,7 @@ req = (struct l1ctl_tch_mode_req *) msgb_put(msg, sizeof(*req)); req->tch_mode = tch_mode; req->audio_mode = audio_mode; + req->tch_flags = tch_flags; req->tch_loop_mode = tch_loop_mode; /* TODO: Set AMR codec in req if req->tch_mode==GSM48_CMODE_SPEECH_AMR */ @@ -536,9 +537,8 @@ } /* Transmit L1CTL_DM_EST_REQ */ -int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, - uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, - uint8_t audio_mode) +int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, + uint8_t audio_mode, uint8_t tch_flags) { struct msgb *msg; struct l1ctl_info_ul *ul; @@ -561,14 +561,13 @@ req->h0.band_arfcn = htons(band_arfcn); req->tch_mode = tch_mode; req->audio_mode = audio_mode; + req->tch_flags = tch_flags; return osmo_send_l1(ms, msg); } -int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, - uint16_t *ma, uint8_t ma_len, - uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, - uint8_t audio_mode) +int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, uint16_t *ma, uint8_t ma_len, + uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags) { struct msgb *msg; struct l1ctl_info_ul *ul; @@ -596,6 +595,7 @@ req->h1.ma[i] = htons(ma[i]); req->tch_mode = tch_mode; req->audio_mode = audio_mode; + req->tch_flags = tch_flags; return osmo_send_l1(ms, msg); } @@ -831,6 +831,7 @@ mc.tch_mode = conf->tch_mode; mc.audio_mode = conf->audio_mode; + mc.tch_flags = conf->tch_flags; mc.ms = ms; osmo_signal_dispatch(SS_L1CTL, S_L1CTL_TCH_MODE_CONF, &mc); diff --git a/src/host/layer23/src/misc/app_cbch_sniff.c b/src/host/layer23/src/misc/app_cbch_sniff.c index dbf6d00..f83815e 100644 --- a/src/host/layer23/src/misc/app_cbch_sniff.c +++ b/src/host/layer23/src/misc/app_cbch_sniff.c @@ -68,12 +68,12 @@ return l1ctl_tx_dm_est_req_h1(ms, s->maio, s->hsn, s->hopping, s->hopp_len, chan_nr, s->tsc, - GSM48_CMODE_SIGN, 0); + GSM48_CMODE_SIGN, 0, 0); } else { LOGP(DRR, LOGL_INFO, "chan_nr = 0x%02x TSC = %d ARFCN = %d\n", s->chan_nr, s->tsc, s->arfcn); return l1ctl_tx_dm_est_req_h0(ms, s->arfcn, - chan_nr, s->tsc, GSM48_CMODE_SIGN, 0); + chan_nr, s->tsc, GSM48_CMODE_SIGN, 0, 0); } } diff --git a/src/host/layer23/src/mobile/gsm414.c b/src/host/layer23/src/mobile/gsm414.c index ced15ed..90fc2df 100644 --- a/src/host/layer23/src/mobile/gsm414.c +++ b/src/host/layer23/src/mobile/gsm414.c @@ -137,7 +137,7 @@ /* Instruct the L1 to enable received TCH loopback mode * FIXME: delay applying this mode, so we can send the ACK first */ - l1ctl_tx_tch_mode_req(ms, rr->cd_now.mode, rr->audio_mode, rr->tch_loop_mode); + l1ctl_tx_tch_mode_req(ms, rr->cd_now.mode, rr->audio_mode, rr->cd_now.tch_flags, rr->tch_loop_mode); /* Craft and send the ACKnowledgement */ nmsg = alloc_gsm414_msg(GSM414_MT_CLOSE_TCH_LOOP_ACK); @@ -178,7 +178,7 @@ rsl_chan_nr_str(rr->cd_now.chan_nr), loop_mode_name(rr->tch_loop_mode)); /* Instruct the L1 to disable the TCH loopback mode */ - l1ctl_tx_tch_mode_req(ms, rr->cd_now.mode, rr->audio_mode, L1CTL_TCH_LOOP_OPEN); + l1ctl_tx_tch_mode_req(ms, rr->cd_now.mode, rr->audio_mode, rr->cd_now.tch_flags, L1CTL_TCH_LOOP_OPEN); /* Only the loop mode C needs to be ACKnowledged */ bool needs_ack = rr->tch_loop_mode == L1CTL_TCH_LOOP_C; diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c index 910ded7..ec23092 100644 --- a/src/host/layer23/src/mobile/gsm48_rr.c +++ b/src/host/layer23/src/mobile/gsm48_rr.c @@ -90,8 +90,7 @@ static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg); static int gsm48_rr_dl_est(struct osmocom_ms *ms); static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms); -static int gsm48_rr_set_mode(struct osmocom_ms *ms, uint8_t chan_nr, - uint8_t mode); +static int gsm48_rr_set_mode(struct osmocom_ms *ms, uint8_t chan_nr, uint8_t mode, uint8_t tch_flags); static int gsm48_rr_rel_cnf(struct osmocom_ms *ms, struct msgb *msg); int gsm414_rcv_test(struct osmocom_ms *ms, const struct msgb *msg); @@ -3040,16 +3039,13 @@ return -EINVAL; } - LOGP(DRR, LOGL_INFO, " Channel type %d, subch %d, ts %d, mode %d, " - "audio-mode %d, cipher %d\n", ch_type, ch_subch, ch_ts, - cd->mode, rr->audio_mode, rr->cipher_type + 1); + LOGP(DRR, LOGL_INFO, " Channel type %d, subch %d, ts %d, mode %d, audio-mode %d, flags 0x%02x, cipher %d\n", + ch_type, ch_subch, ch_ts, cd->mode, rr->audio_mode, cd->tch_flags, rr->cipher_type + 1); if (cd->h) - l1ctl_tx_dm_est_req_h1(ms, cd->maio, cd->hsn, - ma, ma_len, cd->chan_nr, cd->tsc, cd->mode, - rr->audio_mode); + l1ctl_tx_dm_est_req_h1(ms, cd->maio, cd->hsn, ma, ma_len, cd->chan_nr, cd->tsc, cd->mode, + rr->audio_mode, cd->tch_flags); else - l1ctl_tx_dm_est_req_h0(ms, cd->arfcn, cd->chan_nr, cd->tsc, - cd->mode, rr->audio_mode); + l1ctl_tx_dm_est_req_h0(ms, cd->arfcn, cd->chan_nr, cd->tsc, cd->mode, rr->audio_mode, cd->tch_flags); rr->dm_est = 1; /* old SI 5/6 are not valid on a new dedicated channel */ @@ -3079,7 +3075,7 @@ l1ctl_tx_crypto_req(ms, rr->cd_now.chan_nr, rr->cipher_type + 1, subscr->key, 8); - gsm48_rr_set_mode(ms, cd->chan_nr, cd->mode); + gsm48_rr_set_mode(ms, cd->chan_nr, cd->mode, cd->tch_flags); return 0; } @@ -3473,8 +3469,7 @@ */ /* set channel mode in case of TCH */ -static int gsm48_rr_set_mode(struct osmocom_ms *ms, uint8_t chan_nr, - uint8_t mode) +static int gsm48_rr_set_mode(struct osmocom_ms *ms, uint8_t chan_nr, uint8_t mode, uint8_t tch_flags) { struct gsm48_rrlayer *rr = &ms->rrlayer; uint8_t ch_type, ch_subch, ch_ts; @@ -3501,9 +3496,9 @@ #endif /* Apply indicated channel mode */ - LOGP(DRR, LOGL_INFO, "setting TCH mode to %s, audio mode to %d\n", - get_value_string(gsm48_chan_mode_names, mode), rr->audio_mode); - l1ctl_tx_tch_mode_req(ms, mode, rr->audio_mode, rr->tch_loop_mode); + LOGP(DRR, LOGL_INFO, "setting TCH mode to %s, audio mode to %d, tch flags to %d\n", + get_value_string(gsm48_chan_mode_names, mode), rr->audio_mode, tch_flags); + l1ctl_tx_tch_mode_req(ms, mode, rr->audio_mode, tch_flags, rr->tch_loop_mode); return 0; } @@ -3687,7 +3682,7 @@ goto ack; /* Attempt to apply this mode */ - rc = gsm48_rr_set_mode(ms, cd->chan_nr, cm->mode); + rc = gsm48_rr_set_mode(ms, cd->chan_nr, cm->mode, cd->tch_flags); if (rc) goto ack; @@ -5832,5 +5827,5 @@ && ch_type != RSL_CHAN_Lm_ACCHs) return 0; - return l1ctl_tx_tch_mode_req(ms, rr->cd_now.mode, mode, rr->tch_loop_mode); + return l1ctl_tx_tch_mode_req(ms, rr->cd_now.mode, mode, rr->cd_now.tch_flags, rr->tch_loop_mode); } diff --git a/src/host/layer23/src/modem/grr.c b/src/host/layer23/src/modem/grr.c index 4e29909..b1912ea 100644 --- a/src/host/layer23/src/modem/grr.c +++ b/src/host/layer23/src/modem/grr.c @@ -485,7 +485,7 @@ lp->pdch_est_req.tsc, lp->pdch_est_req.arfcn); l1ctl_tx_dm_est_req_h0(ms, lp->pdch_est_req.arfcn, RSL_CHAN_OSMO_PDCH | lp->pdch_est_req.ts_nr, - lp->pdch_est_req.tsc, GSM48_CMODE_SIGN, 0); + lp->pdch_est_req.tsc, GSM48_CMODE_SIGN, 0, 0); } else { /* Hopping */ uint8_t ma_len = 0; @@ -515,7 +515,7 @@ lp->pdch_est_req.fhp.hsn, &ma[0], ma_len, RSL_CHAN_OSMO_PDCH | lp->pdch_est_req.ts_nr, - lp->pdch_est_req.tsc, GSM48_CMODE_SIGN, 0); + lp->pdch_est_req.tsc, GSM48_CMODE_SIGN, 0, 0); } osmo_fsm_inst_state_chg(fi, GRR_ST_PACKET_TRANSFER, 0, 0); diff --git a/src/target/firmware/include/layer1/async.h b/src/target/firmware/include/layer1/async.h index 221ffcf..b383d47 100644 --- a/src/target/firmware/include/layer1/async.h +++ b/src/target/firmware/include/layer1/async.h @@ -47,6 +47,9 @@ /* Set Audio routing mode */ uint8_t l1a_audio_mode_set(uint8_t mode); +/* Set TCH flags */ +uint8_t l1a_tch_flags_set(uint8_t flags); + /* Execute pending L1A completions */ void l1a_compl_execute(void); diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h index dd93242..ff56354 100644 --- a/src/target/firmware/include/layer1/sync.h +++ b/src/target/firmware/include/layer1/sync.h @@ -82,6 +82,7 @@ uint8_t tch_mode; uint8_t tch_sync; uint8_t audio_mode; + uint8_t tch_flags; /* 3GPP TS 44.014, section 5.1 (Calypso DSP specific numbers) */ enum l1ctl_tch_loop_mode tch_loop_mode; diff --git a/src/target/firmware/layer1/async.c b/src/target/firmware/layer1/async.c index 1f3d6f1..fe8a906 100644 --- a/src/target/firmware/layer1/async.c +++ b/src/target/firmware/layer1/async.c @@ -125,6 +125,13 @@ return mode; } +/* Set TCH flags */ +uint8_t l1a_tch_flags_set(uint8_t flags) +{ + l1s.tch_flags = flags; + return flags; +} + /* Initialize asynchronous part of Layer1 */ void l1a_init(void) { diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c index 599272f..68bb2c0 100644 --- a/src/target/firmware/layer1/l23_api.c +++ b/src/target/firmware/layer1/l23_api.c @@ -289,6 +289,7 @@ /* Mode */ l1a_tch_mode_set(est_req->tch_mode); l1a_audio_mode_set(est_req->audio_mode); + l1a_tch_flags_set(est_req->tch_flags); /* Sync */ l1s.tch_sync = 1; /* can be set without locking */ @@ -522,7 +523,7 @@ } /* Transmit a L1CTL_TCH_MODE_CONF */ -static void l1ctl_tx_tch_mode_conf(uint8_t tch_mode, uint8_t audio_mode) +static void l1ctl_tx_tch_mode_conf(uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags) { struct msgb *msg = l1ctl_msgb_alloc(L1CTL_TCH_MODE_CONF); struct l1ctl_tch_mode_conf *mode_conf; @@ -530,6 +531,7 @@ msgb_put(msg, sizeof(*mode_conf)); mode_conf->tch_mode = tch_mode; mode_conf->audio_mode = audio_mode; + mode_conf->tch_flags = l1s.tch_flags; mode_conf->tch_loop_mode = l1s.tch_loop_mode; l1_queue_for_l2(msg); @@ -543,11 +545,14 @@ (struct l1ctl_tch_mode_req *) l1h->data; uint8_t tch_mode = tch_mode_req->tch_mode; uint8_t audio_mode = tch_mode_req->audio_mode; + uint8_t tch_flags = tch_mode_req->tch_flags; printd("L1CTL_TCH_MODE_REQ (tch_mode=0x%02x audio_mode=0x%02x)\n", tch_mode, audio_mode); + tch_mode = l1a_tch_mode_set(tch_mode); audio_mode = l1a_audio_mode_set(audio_mode); + tch_flags = l1a_tch_flags_set(tch_flags); audio_set_enabled(tch_mode, audio_mode); @@ -555,7 +560,7 @@ l1s.tch_loop_mode = tch_mode_req->tch_loop_mode; /* TODO: Handle AMR codecs from tch_mode_req if tch_mode_req->tch_mode==GSM48_CMODE_SPEECH_AMR */ - l1ctl_tx_tch_mode_conf(tch_mode, audio_mode); + l1ctl_tx_tch_mode_conf(tch_mode, audio_mode, tch_flags); } /* receive a L1CTL_NEIGH_PM_REQ from L23 */ diff --git a/src/target/firmware/layer1/prim_tch.c b/src/target/firmware/layer1/prim_tch.c index 56c32fb..e3cffd1 100644 --- a/src/target/firmware/layer1/prim_tch.c +++ b/src/target/firmware/layer1/prim_tch.c @@ -478,6 +478,12 @@ ); l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0); + /* If transmission is off, use dummy task for DSP and do not open TX window. */ + if ((l1s.tch_flags & L1CTL_TCH_FLAG_RXONLY)) { + dsp_load_tx_task(TCHD_DSP_TASK, 0, tsc); /* burst_id unused for TCH */ + return 0; + } + dsp_load_tx_task( dsp_task_iq_swap(TCHT_DSP_TASK, arfcn, 1), 0, tsc /* burst_id unused for TCH */ @@ -743,6 +749,10 @@ ); l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0); + /* If transmission is off, schedule no task for DSP and do not open TX window. */ + if ((l1s.tch_flags & L1CTL_TCH_FLAG_RXONLY)) + return 0; + dsp_load_tx_task( dsp_task_iq_swap(TCHA_DSP_TASK, arfcn, 1), 0, tsc /* burst_id unused for TCHA */ -- To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/34479?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Change-Id: I20133523adc3b204cd2181bfe664fe66020a10e3 Gerrit-Change-Number: 34479 Gerrit-PatchSet: 8 Gerrit-Owner: jolly <andr...@eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanits...@sysmocom.de> Gerrit-Reviewer: jolly <andr...@eversberg.eu> Gerrit-Reviewer: laforge <lafo...@osmocom.org> Gerrit-Reviewer: pespin <pes...@sysmocom.de> Gerrit-MessageType: merged