acerion / cwdaemon

Morse code daemon for unix systems
GNU General Public License v2.0
14 stars 5 forks source link

cwdaemon stops working after esc 0 (reset) is issued #6

Closed jmeloranta closed 2 years ago

jmeloranta commented 2 years ago

I am trying to use cwdaemon with tlf (contest program). Before running tlf, everything works fine. But once I start tlf, cwdaemon stops working (it receives commands etc. via its udp socket but no DTR keying takes place). The first thing tlf does when it starts is to send esc 0 to reset cwdaemon and somehow after this DTR keying stops working. I can see from the code that this reset causes call to cwdaemon_reset_libcw_output(). Playing around there a bit makes tlf work cwdaemon: allowing routines cwdaemon_close_libcw_output() and cwdaemon_open_libcw_output() to be called only once. These are called the first time when cwdaemon starts up and second time when esc 0 is sent. So, essentially esc 0 won't make these two function calls. I don't know the code well enough to fix it properly.

If it matters, this is on Raspberry pi 4 (arm64) running Debian.

jmeloranta commented 2 years ago

So here is what I did to make it work (but again probably for wrong reason). I included the changes in bold (except the two last changes have just ** - somehow github does not want to make them bold).

void cwdaemon_reset_libcw_output(void) { static char been_here = 0; / This function is called when cwdaemon receives '0' escape code. README describes this code as "Reset to default values". Therefore we use default_ below.

       However, the function is called after "current_" values
       have been reset to "default_" values. So maybe we could use
       "current_" values and somehow encapsulate the calls to
       cw_set_*() functions? The calls are also made elsewhere.
    */

if(!been_here) { / Delete old generator (if it exists). / cwdaemon_close_libcw_output();

    cwdaemon_debug(CWDAEMON_VERBOSITY_I, __func__, __LINE__, "setting sound system \"%s\"", cw_get_audio_system_label(default_audio_system));

    if (cwdaemon_open_libcw_output(default_audio_system)) {
            has_audio_output = true;
    } else {
            has_audio_output = false;
            return;
    }
**}**

    /* Remember that tone queue is bound to a generator.  When
       cwdaemon switches on request to other sound system, it will
       have to re-register the callback. */
    cw_register_tone_queue_low_callback(cwdaemon_tone_queue_low_callback, NULL, tq_low_watermark);

    cw_set_frequency(default_morse_tone);
    cw_set_send_speed(default_morse_speed);
    cw_set_volume(default_morse_volume);
    cw_set_gap(0);
    cw_set_weighting(default_weighting * 0.6 + CWDAEMON_MORSE_WEIGHTING_MAX);

    **been_here = 1;**
    return;

}

acerion commented 2 years ago

I don't have access to RPi, but I will try to re-create the problem on my PC. Can you please send me the version numbers of cwdaemon and libcw that you are using?

jmeloranta commented 2 years ago

libcw-dev/testing,now 3.6.0-5 arm64 [installed] cwdaemon/testing,now 0.10.2-3 arm64 [installed] and also up to date cwdaemon from git behaves the same way.

In case cwdaemon_open_libcw_output() is trying to access audio, I am running pulseaudio on the pi. I also tried playing with DEVICE setting in /etc/default/cwdaemon but that did not help. I think I pretty much tried all the settings mentioned there.

acerion commented 2 years ago

I have reproduced it on my PC and I think that I have found a solution.

In src/cwdaemon.c please move call to cw_register_keying_callback() from main() to cwdaemon_reset_almost_all() (put it at the end of the function, after cwdaemon_reset_libcw_output()).

cw_register_keying_callback() registers a cwdaemon's callback, and reset of libcw probably un-registers the callback. The registration should be (re)done during start of cwdaemon and on each reset of libcw. Putting the registration in cwdaemon_reset_almost_all() should cover both cases.

Please let me know if this fixes the problem.

jmeloranta commented 2 years ago

Yes, this seems to fix the problem. Thanks!

acerion commented 2 years ago

Thank you for verification and feedback! I will leave the ticket open for now, as a reminder that I have to commit this fix and write a test that catches this kind of problem in future.

Also thank you for reporting the issue in the first place :)

acerion commented 2 years ago

Today I have released cwdaemon 0.11.0 that fixes this issue. I'm closing this ticket.