mobile: fix GAPK I/O producing too many UL frames
GAPK I/O is currently generating too many UL voice frames, causing Tx queue overflow in the L1 PHY. Change the logic to make DL voice frames drive the Uplink processing chain, like we do for CSD. Change-Id: I3a7fa223cb592acd5b850819e0682c9c8f81e9d1
This commit is contained in:
parent
20107916e5
commit
f12b17dffb
|
@ -42,6 +42,6 @@ gapk_io_state_alloc_mode_rate(struct osmocom_ms *ms,
|
|||
void gapk_io_state_free(struct gapk_io_state *state);
|
||||
|
||||
void gapk_io_enqueue_dl(struct gapk_io_state *state, struct msgb *msg);
|
||||
int gapk_io_serve_ms(struct osmocom_ms *ms, struct gapk_io_state *state);
|
||||
void gapk_io_dequeue_ul(struct osmocom_ms *ms, struct gapk_io_state *state);
|
||||
|
||||
#endif /* WITH_GAPK_IO */
|
||||
|
|
|
@ -24,6 +24,5 @@ struct tch_state {
|
|||
};
|
||||
|
||||
int tch_init(struct osmocom_ms *ms);
|
||||
int tch_serve_ms(struct osmocom_ms *ms);
|
||||
int tch_send_msg(struct osmocom_ms *ms, struct msgb *msg);
|
||||
int tch_send_mncc_frame(struct osmocom_ms *ms, const struct gsm_data_frame *frame);
|
||||
|
|
|
@ -81,7 +81,6 @@ int mobile_work(struct osmocom_ms *ms)
|
|||
w |= gsm322_cs_dequeue(ms);
|
||||
w |= gsm_sim_job_dequeue(ms);
|
||||
w |= mncc_dequeue(ms);
|
||||
w |= tch_serve_ms(ms);
|
||||
if (w)
|
||||
work = 1;
|
||||
} while (w);
|
||||
|
|
|
@ -503,6 +503,7 @@ gapk_io_state_alloc_mode_rate(struct osmocom_ms *ms,
|
|||
return gapk_io_state_alloc(ms, codec);
|
||||
}
|
||||
|
||||
/* Enqueue a Downlink TCH frame */
|
||||
void gapk_io_enqueue_dl(struct gapk_io_state *state, struct msgb *msg)
|
||||
{
|
||||
if (state->tch_dl_fb_len >= GAPK_ULDL_QUEUE_LIMIT) {
|
||||
|
@ -513,49 +514,23 @@ void gapk_io_enqueue_dl(struct gapk_io_state *state, struct msgb *msg)
|
|||
|
||||
msgb_enqueue_count(&state->tch_dl_fb, msg,
|
||||
&state->tch_dl_fb_len);
|
||||
|
||||
/* Decode and play a received DL TCH frame */
|
||||
osmo_gapk_pq_execute(state->pq_sink);
|
||||
}
|
||||
|
||||
/* Serves both UL/DL TCH frame I/O buffers */
|
||||
int gapk_io_serve_ms(struct osmocom_ms *ms, struct gapk_io_state *state)
|
||||
/* Dequeue an Uplink TCH frame */
|
||||
void gapk_io_dequeue_ul(struct osmocom_ms *ms, struct gapk_io_state *state)
|
||||
{
|
||||
int work = 0;
|
||||
struct msgb *msg;
|
||||
|
||||
/**
|
||||
* Make sure we have at least two DL frames
|
||||
* to prevent discontinuous playback.
|
||||
*/
|
||||
if (state->tch_dl_fb_len < 2)
|
||||
return 0;
|
||||
/* Record and encode an UL TCH frame */
|
||||
osmo_gapk_pq_execute(state->pq_source);
|
||||
|
||||
/**
|
||||
* TODO: if there is an active call, but no TCH frames
|
||||
* in DL buffer, put silence frames using the upcoming
|
||||
* ECU (Error Concealment Unit) of libosmocodec.
|
||||
*/
|
||||
while (!llist_empty(&state->tch_dl_fb)) {
|
||||
/* Decode and play a received DL TCH frame */
|
||||
osmo_gapk_pq_execute(state->pq_sink);
|
||||
|
||||
/* Record and encode an UL TCH frame back */
|
||||
osmo_gapk_pq_execute(state->pq_source);
|
||||
|
||||
work |= 1;
|
||||
}
|
||||
|
||||
while (!llist_empty(&state->tch_ul_fb)) {
|
||||
struct msgb *tch_msg;
|
||||
|
||||
/* Obtain one TCH frame from the UL buffer */
|
||||
tch_msg = msgb_dequeue_count(&state->tch_ul_fb,
|
||||
&state->tch_ul_fb_len);
|
||||
|
||||
/* Push a voice frame to the lower layers */
|
||||
tch_send_msg(ms, tch_msg);
|
||||
|
||||
work |= 1;
|
||||
}
|
||||
|
||||
return work;
|
||||
/* Obtain one TCH frame from the UL buffer */
|
||||
msg = msgb_dequeue_count(&state->tch_ul_fb, &state->tch_ul_fb_len);
|
||||
if (msg != NULL)
|
||||
tch_send_msg(ms, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,7 +45,6 @@ void tch_data_state_free(struct tch_data_state *state);
|
|||
|
||||
int tch_voice_recv(struct osmocom_ms *ms, struct msgb *msg);
|
||||
int tch_data_recv(struct osmocom_ms *ms, struct msgb *msg);
|
||||
int tch_voice_serve_ms(struct osmocom_ms *ms);
|
||||
|
||||
/* Receive a Downlink traffic (voice/data) frame from the lower layers */
|
||||
static int tch_recv_cb(struct osmocom_ms *ms, struct msgb *msg)
|
||||
|
@ -116,20 +115,6 @@ int tch_send_mncc_frame(struct osmocom_ms *ms, const struct gsm_data_frame *fram
|
|||
return tch_send_msg(ms, nmsg);
|
||||
}
|
||||
|
||||
int tch_serve_ms(struct osmocom_ms *ms)
|
||||
{
|
||||
struct tch_state *state = ms->tch_state;
|
||||
int rc = 0;
|
||||
|
||||
if (state == NULL)
|
||||
return 0;
|
||||
if (state->is_voice)
|
||||
rc = tch_voice_serve_ms(ms);
|
||||
/* TODO: else tch_data_serve_ms() */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void tch_trans_cstate_active_cb(struct gsm_trans *trans, bool rx_only)
|
||||
{
|
||||
struct osmocom_ms *ms = trans->ms;
|
||||
|
|
|
@ -90,11 +90,12 @@ int tch_voice_recv(struct osmocom_ms *ms, struct msgb *msg)
|
|||
return tch_forward_mncc(ms, msg);
|
||||
case TCH_VOICE_IOH_GAPK:
|
||||
#ifdef WITH_GAPK_IO
|
||||
/* Enqueue a frame to the DL TCH buffer */
|
||||
if (state->gapk_io != NULL)
|
||||
if (state->gapk_io != NULL) {
|
||||
gapk_io_enqueue_dl(state->gapk_io, msg);
|
||||
else
|
||||
gapk_io_dequeue_ul(ms, state->gapk_io);
|
||||
} else {
|
||||
msgb_free(msg);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case TCH_VOICE_IOH_L1PHY:
|
||||
|
@ -107,18 +108,6 @@ int tch_voice_recv(struct osmocom_ms *ms, struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tch_voice_serve_ms(struct osmocom_ms *ms)
|
||||
{
|
||||
#ifdef WITH_GAPK_IO
|
||||
struct tch_voice_state *state = &ms->tch_state->voice;
|
||||
|
||||
if (state->handler == TCH_VOICE_IOH_GAPK)
|
||||
return gapk_io_serve_ms(ms, state->gapk_io);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tch_voice_state_init(struct gsm_trans *trans, struct tch_voice_state *state)
|
||||
{
|
||||
struct osmocom_ms *ms = trans->ms;
|
||||
|
|
Loading…
Reference in New Issue