forked from cellular-infrastructure/osmocom-analog
C-Netz: At correct timeslot switch channel mode
Without this, the first BQ(K) message came to early, so that BSA 51 released when receiving ZFZ(K) one frame too early.
This commit is contained in:
parent
a98b05beb0
commit
7189984bbb
|
@ -377,21 +377,23 @@ int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *
|
|||
goto error;
|
||||
|
||||
/* go into idle state */
|
||||
if (chan_type == CHAN_TYPE_OGK || chan_type == CHAN_TYPE_OGK_SPK)
|
||||
cnetz_set_dsp_mode(cnetz, DSP_MODE_OGK);
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_OGK, 0);
|
||||
else
|
||||
cnetz_set_dsp_mode(cnetz, DSP_MODE_OFF);
|
||||
cnetz_go_idle(cnetz);
|
||||
|
||||
#ifdef DEBUG_SPK
|
||||
transaction_t *trans = create_transaction(cnetz, TRANS_DS, 2, 2, 22002, -1, -1);
|
||||
trans->mo_call = 1;
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 2);
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, (cnetz->sched_ts + 2) & 31);
|
||||
#else
|
||||
/* create transaction for speech channel loopback */
|
||||
if (loopback && chan_type == CHAN_TYPE_SPK) {
|
||||
transaction_t *trans = create_transaction(cnetz, TRANS_VHQ_K, 2, 2, 22002, -1, -1);
|
||||
trans->mo_call = 1;
|
||||
cnetz_set_dsp_mode(cnetz, DSP_MODE_SPK_K);
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 0);
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, (cnetz->sched_ts + 1) & 31);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -509,10 +511,11 @@ void cnetz_go_idle(cnetz_t *cnetz)
|
|||
|
||||
/* set scheduler to OgK or turn off SpK */
|
||||
if (cnetz->dsp_mode == DSP_MODE_SPK_K || cnetz->dsp_mode == DSP_MODE_SPK_V) {
|
||||
/* go idle after next frame/slot */
|
||||
cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, 1);
|
||||
/* switch next frame after distributed signaling boundary (mutliple of 8 slots) */
|
||||
cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 8) & 24);
|
||||
} else {
|
||||
cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, 0);
|
||||
/* switch next frame */
|
||||
cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 1) & 31);
|
||||
cnetz_set_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF);
|
||||
}
|
||||
|
||||
|
@ -533,7 +536,7 @@ static void cnetz_release(transaction_t *trans, uint8_t cause)
|
|||
trans_new_state(trans, (trans->cnetz->dsp_mode == DSP_MODE_OGK) ? TRANS_VA : TRANS_AF);
|
||||
trans->repeat = 0;
|
||||
trans->release_cause = cause;
|
||||
trans->cnetz->sched_switch_mode = 0;
|
||||
trans->cnetz->sched_dsp_mode_ts = -1;
|
||||
timer_stop(&trans->timer);
|
||||
}
|
||||
|
||||
|
@ -1068,7 +1071,7 @@ vak:
|
|||
/* change state to busy */
|
||||
cnetz_new_state(spk, CNETZ_BUSY);
|
||||
/* schedule switching two slots ahead */
|
||||
cnetz_set_sched_dsp_mode(spk, DSP_MODE_SPK_K, 2);
|
||||
cnetz_set_sched_dsp_mode(spk, DSP_MODE_SPK_K, (cnetz->sched_ts + 2) & 31);
|
||||
/* relink */
|
||||
unlink_transaction(trans);
|
||||
link_transaction(trans, spk);
|
||||
|
@ -1384,7 +1387,7 @@ no_auth:
|
|||
/* next sub frame */
|
||||
trans_new_state(trans, TRANS_VHQ_V);
|
||||
trans->repeat = 0;
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1);
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, (cnetz->sched_ts + 1) & 31);
|
||||
#ifndef DEBUG_SPK
|
||||
timer_start(&trans->timer, 0.075 + 0.6 * F_VHQ); /* one slot + F_VHQ frames */
|
||||
#endif
|
||||
|
@ -1401,7 +1404,7 @@ no_auth:
|
|||
/* next sub frame */
|
||||
trans_new_state(trans, TRANS_VHQ_V);
|
||||
trans->repeat = 0;
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1);
|
||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, (cnetz->sched_ts + 1) & 31);
|
||||
timer_start(&trans->timer, 0.075 + 0.6 * F_VHQ); /* one slot + F_VHQ frames */
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -94,8 +94,8 @@ struct cnetz {
|
|||
int sched_ts; /* current time slot */
|
||||
int sched_last_ts; /* last timeslot we transmitted, to sync time of the receiver */
|
||||
int sched_r_m; /* Rufblock (0) / Meldeblock (1) */
|
||||
int sched_switch_mode; /* counts slots until mode is switched */
|
||||
enum dsp_mode sched_dsp_mode; /* what mode shall be switched to */
|
||||
int sched_dsp_mode_ts; /* time slot when to switch mode (-1 = don't switch) */
|
||||
|
||||
/* dsp states */
|
||||
enum dsp_mode dsp_mode; /* current mode: audio, "Telegramm", .... */
|
||||
|
|
|
@ -54,6 +54,27 @@ scrambler_t scrambler_test_scrambler1;
|
|||
scrambler_t scrambler_test_scrambler2;
|
||||
#endif
|
||||
|
||||
const char *cnetz_dsp_mode_name(enum dsp_mode mode)
|
||||
{
|
||||
static char invalid[16];
|
||||
|
||||
switch (mode) {
|
||||
case DSP_SCHED_NONE:
|
||||
return "SCHED_NONE";
|
||||
case DSP_MODE_OFF:
|
||||
return "OFF";
|
||||
case DSP_MODE_OGK:
|
||||
return "OGK";
|
||||
case DSP_MODE_SPK_K:
|
||||
return "SPK_K";
|
||||
case DSP_MODE_SPK_V:
|
||||
return "SPK_V";
|
||||
}
|
||||
|
||||
sprintf(invalid, "invalid(%d)", mode);
|
||||
return invalid;
|
||||
}
|
||||
|
||||
static sample_t ramp_up[256], ramp_down[256];
|
||||
|
||||
void dsp_init(void)
|
||||
|
@ -166,6 +187,8 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
|
|||
scrambler_setup(&scrambler_test_scrambler2, cnetz->sender.samplerate);
|
||||
#endif
|
||||
|
||||
cnetz->sched_dsp_mode_ts = -1;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
@ -636,10 +659,11 @@ again:
|
|||
}
|
||||
|
||||
/* switch to speech channel */
|
||||
if (cnetz->sched_switch_mode && cnetz->sched_r_m == 0) {
|
||||
if (--cnetz->sched_switch_mode == 0) {
|
||||
if (cnetz->sched_dsp_mode_ts >= 0 && cnetz->sched_r_m == 0) {
|
||||
if (cnetz->sched_dsp_mode_ts == cnetz->sched_ts) {
|
||||
/* OgK / SpK(K) / SpK(V) */
|
||||
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Switching channel (mode)\n");
|
||||
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Now switchting channel mode to %s at timeslot %d\n", cnetz_dsp_mode_name(cnetz->sched_dsp_mode), cnetz->sched_dsp_mode_ts);
|
||||
cnetz->sched_dsp_mode_ts = -1;
|
||||
cnetz_set_dsp_mode(cnetz, cnetz->sched_dsp_mode);
|
||||
}
|
||||
}
|
||||
|
@ -843,39 +867,22 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
|
|||
cnetz->sender.rxbuf_pos = pos;
|
||||
}
|
||||
|
||||
const char *cnetz_dsp_mode_name(enum dsp_mode mode)
|
||||
{
|
||||
static char invalid[16];
|
||||
|
||||
switch (mode) {
|
||||
case DSP_SCHED_NONE:
|
||||
return "SCHED_NONE";
|
||||
case DSP_MODE_OFF:
|
||||
return "OFF";
|
||||
case DSP_MODE_OGK:
|
||||
return "OGK";
|
||||
case DSP_MODE_SPK_K:
|
||||
return "SPK_K";
|
||||
case DSP_MODE_SPK_V:
|
||||
return "SPK_V";
|
||||
}
|
||||
|
||||
sprintf(invalid, "invalid(%d)", mode);
|
||||
return invalid;
|
||||
}
|
||||
|
||||
void cnetz_set_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode)
|
||||
{
|
||||
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "DSP mode %s -> %s\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode));
|
||||
if (mode != cnetz->dsp_mode) {
|
||||
PDEBUG_CHAN(DDSP, DEBUG_INFO, "DSP mode %s -> %s\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode));
|
||||
cnetz->dsp_mode = mode;
|
||||
}
|
||||
/* we must get rid of partly received frame */
|
||||
fsk_demod_reset(&cnetz->fsk_demod);
|
||||
}
|
||||
|
||||
void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int frames_ahead)
|
||||
void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int timeslot)
|
||||
{
|
||||
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, " Schedule DSP mode %s -> %s in %d frames\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode), frames_ahead);
|
||||
if (mode != cnetz->dsp_mode) {
|
||||
PDEBUG_CHAN(DDSP, DEBUG_INFO, "Schedule DSP mode %s -> %s at timeslot %d\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode), timeslot);
|
||||
cnetz->sched_dsp_mode = mode;
|
||||
cnetz->sched_switch_mode = frames_ahead;
|
||||
cnetz->sched_dsp_mode_ts = timeslot;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,5 +5,5 @@ void dsp_cleanup_sender(cnetz_t *cnetz);
|
|||
void calc_clock_speed(cnetz_t *cnetz, double samples, int tx, int result);
|
||||
void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count);
|
||||
void cnetz_set_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode);
|
||||
void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int frames_ahead);
|
||||
void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int timeslot);
|
||||
|
||||
|
|
Loading…
Reference in New Issue