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.
pull/1/head
Andreas Eversberg 3 years ago
parent a98b05beb0
commit 7189984bbb
  1. 25
      src/cnetz/cnetz.c
  2. 4
      src/cnetz/cnetz.h
  3. 67
      src/cnetz/dsp.c
  4. 2
      src/cnetz/dsp.h

@ -377,21 +377,23 @@ int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char *
goto error;
/* go into idle state */
cnetz_set_dsp_mode(cnetz, DSP_MODE_OGK);
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_OGK, 0);
if (chan_type == CHAN_TYPE_OGK || chan_type == CHAN_TYPE_OGK_SPK)
cnetz_set_dsp_mode(cnetz, DSP_MODE_OGK);
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 */
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));
cnetz->dsp_mode = 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);
cnetz->sched_dsp_mode = mode;
cnetz->sched_switch_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_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…
Cancel
Save