/*
 *  Hamlib Interface - rig state cache routines
 *  Copyright (c) 2000-2012 by Stephane Fillod
 *  Copyright (c) 2000-2003 by Frank Singleton
 *
 *
 *   This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "cache.h"
#include "hamlib/rig_state.h"
#include "misc.h"

#define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !STATE(r)->comm_state)

/**
 * \file cache.c
 * \addtogroup rig
 * @{
 */

int rig_set_cache_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
    struct rig_cache *cachep = CACHE(rig);
    struct rig_state *rs = STATE(rig);

    ENTERFUNC;

    rig_cache_show(rig, __func__, __LINE__);

    if (vfo == RIG_VFO_CURR)
    {
        // if CURR then update this before we figure out the real VFO
        vfo = rs->current_vfo;
    }
    else if (vfo == RIG_VFO_TX)
    {
        vfo = rs->tx_vfo;
        rig_debug(RIG_DEBUG_VERBOSE, "%s: TX VFO = %s\n", __func__, rig_strvfo(vfo));
    }
    else if (vfo == RIG_VFO_RX)
    {
        vfo = rs->rx_vfo;
        rig_debug(RIG_DEBUG_VERBOSE, "%s: RX VFO = %s\n", __func__, rig_strvfo(vfo));
    }

    // pick a sane default
    if (vfo == RIG_VFO_NONE || vfo == RIG_VFO_CURR) { vfo = RIG_VFO_A; }

    if (vfo == RIG_VFO_SUB && cachep->satmode) { vfo = RIG_VFO_SUB_A; };

    if (vfo == RIG_VFO_OTHER) { vfo = vfo_fixup(rig, vfo, cachep->split); }

    if (vfo == rs->current_vfo)
    {
        cachep->modeCurr = mode;

        if (width > 0)
        {
            cachep->widthCurr = width;
        }

        elapsed_ms(&cachep->time_modeCurr, HAMLIB_ELAPSED_SET);
    }

    switch (vfo)
    {
    case RIG_VFO_ALL: // we'll use NONE to reset all VFO caches
        elapsed_ms(&cachep->time_modeMainA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeMainB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeMainC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeSubA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeSubB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeSubC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthMainA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthMainB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthMainC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthSubA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthSubB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthSubC, HAMLIB_ELAPSED_INVALIDATE);
        break;

    case RIG_VFO_A:
    case RIG_VFO_VFO:
    case RIG_VFO_MAIN:
    case RIG_VFO_MAIN_A:
        cachep->modeMainA = mode;

        if (width > 0) { cachep->widthMainA = width; }

        elapsed_ms(&cachep->time_modeMainA, HAMLIB_ELAPSED_SET);
        elapsed_ms(&cachep->time_widthMainA, HAMLIB_ELAPSED_SET);
        break;

    case RIG_VFO_B:
    case RIG_VFO_SUB:
    case RIG_VFO_MAIN_B:
        cachep->modeMainB = mode;

        if (width > 0) { cachep->widthMainB = width; }

        elapsed_ms(&cachep->time_modeMainB, HAMLIB_ELAPSED_SET);
        elapsed_ms(&cachep->time_widthMainB, HAMLIB_ELAPSED_SET);
        break;

    case RIG_VFO_C:
    case RIG_VFO_MAIN_C:
        cachep->modeMainC = mode;

        if (width > 0) { cachep->widthMainC = width; }

        elapsed_ms(&cachep->time_modeMainC, HAMLIB_ELAPSED_SET);
        elapsed_ms(&cachep->time_widthMainC, HAMLIB_ELAPSED_SET);
        break;

    case RIG_VFO_SUB_A:
        cachep->modeSubA = mode;
        elapsed_ms(&cachep->time_modeSubA, HAMLIB_ELAPSED_SET);
        break;

    case RIG_VFO_SUB_B:
        cachep->modeSubB = mode;
        elapsed_ms(&cachep->time_modeSubB, HAMLIB_ELAPSED_SET);
        break;

    case RIG_VFO_SUB_C:
        cachep->modeSubC = mode;
        elapsed_ms(&cachep->time_modeSubC, HAMLIB_ELAPSED_SET);
        break;

    case RIG_VFO_MEM:
        cachep->modeMem = mode;
        elapsed_ms(&cachep->time_modeMem, HAMLIB_ELAPSED_SET);
        break;

    default:
        rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo=%s\n", __func__, __LINE__,
                  rig_strvfo(vfo));
        RETURNFUNC(-RIG_EINTERNAL);
    }

    rig_cache_show(rig, __func__, __LINE__);
    RETURNFUNC(RIG_OK);
}

int rig_set_cache_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
    int flag = HAMLIB_ELAPSED_SET;
    struct rig_cache *cachep = CACHE(rig);
    struct rig_state *rs = STATE(rig);

    if (rig_need_debug(RIG_DEBUG_CACHE))
    {
        rig_cache_show(rig, __func__, __LINE__);
    }

    rig_debug(RIG_DEBUG_CACHE, "%s(%d):  vfo=%s, current_vfo=%s\n", __func__,
              __LINE__,
              rig_strvfo(vfo), rig_strvfo(rs->current_vfo));

    if (vfo == RIG_VFO_CURR)
    {
        // if CURR then update this before we figure out the real VFO
        vfo = rs->current_vfo;
    }

    // if freq == 0 then we are asking to invalidate the cache
    if (freq == 0) { flag = HAMLIB_ELAPSED_INVALIDATE; }

    // pick a sane default
    if (vfo == RIG_VFO_NONE || vfo == RIG_VFO_CURR) { vfo = RIG_VFO_A; }

    if (vfo == RIG_VFO_SUB && cachep->satmode) { vfo = RIG_VFO_SUB_A; };

    if (rig_need_debug(RIG_DEBUG_CACHE))
    {
        rig_debug(RIG_DEBUG_CACHE, "%s(%d): set vfo=%s to freq=%.0f\n", __func__,
                  __LINE__,
                  rig_strvfo(vfo), freq);
    }

    if (vfo == rs->current_vfo)
    {
        cachep->freqCurr = freq;
        elapsed_ms(&cachep->time_freqCurr, flag);
    }

    switch (vfo)
    {
    case RIG_VFO_ALL: // we'll use NONE to reset all VFO caches
        elapsed_ms(&cachep->time_freqMainA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_freqMainB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_freqMainC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_freqSubA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_freqSubB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_freqSubC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_freqMem, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_vfo, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeMainA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeMainB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeMainC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeSubA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeSubB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_modeSubC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthMainA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthMainB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthMainC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthSubA, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthSubB, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_widthSubC, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_INVALIDATE);
        elapsed_ms(&cachep->time_split, HAMLIB_ELAPSED_INVALIDATE);
        break;

    case RIG_VFO_A:
    case RIG_VFO_VFO:
    case RIG_VFO_MAIN:
    case RIG_VFO_MAIN_A:
        cachep->freqMainA = freq;
        elapsed_ms(&cachep->time_freqMainA, flag);
        break;

    case RIG_VFO_B:
    case RIG_VFO_MAIN_B:
    case RIG_VFO_SUB:
        cachep->freqMainB = freq;
        elapsed_ms(&cachep->time_freqMainB, flag);
        break;

    case RIG_VFO_C:
    case RIG_VFO_MAIN_C:
        cachep->freqMainC = freq;
        elapsed_ms(&cachep->time_freqMainC, flag);
        break;

    case RIG_VFO_SUB_A:
        cachep->freqSubA = freq;
        elapsed_ms(&cachep->time_freqSubA, flag);
        break;

    case RIG_VFO_SUB_B:
        cachep->freqSubB = freq;
        elapsed_ms(&cachep->time_freqSubB, flag);
        break;

    case RIG_VFO_SUB_C:
        cachep->freqSubC = freq;
        elapsed_ms(&cachep->time_freqSubC, flag);
        break;

    case RIG_VFO_MEM:
        cachep->freqMem = freq;
        elapsed_ms(&cachep->time_freqMem, flag);
        break;

    case RIG_VFO_OTHER:
        rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): ignoring VFO_OTHER\n", __func__,
                  __LINE__);
        break;

    default:
        rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo?, vfo=%s\n", __func__, __LINE__,
                  rig_strvfo(vfo));
        return (-RIG_EINVAL);
    }

    if (rig_need_debug(RIG_DEBUG_CACHE))
    {
        rig_cache_show(rig, __func__, __LINE__);
        return (RIG_OK);
    }

    return (RIG_OK);
}

/**
 * \brief get cached values for a VFO
 * \param rig           The rig handle
 * \param vfo           The VFO to get information from
 * \param freq          The frequency is stored here
 * \param cache_ms_freq The age of the last frequency update in ms
 * \param mode          The mode is stored here
 * \param cache_ms_mode The age of the last mode update in ms
 * \param width         The width is stored here
 * \param cache_ms_width The age of the last width update in ms
 *
 * Use this to query the cache and then determine to actually fetch data from
 * the rig.
 *
 * \note All pointers must be given. No pointer can be left at NULL
 *
 * \return RIG_OK if the operation has been successful, otherwise
 * a negative value if an error occurred (in which case, cause is
 * set appropriately).
 *
 */
int rig_get_cache(RIG *rig, vfo_t vfo, freq_t *freq, int *cache_ms_freq,
                  rmode_t *mode, int *cache_ms_mode, pbwidth_t *width, int *cache_ms_width)
{
    struct rig_cache *cachep;
    struct rig_state *rs;

    if (CHECK_RIG_ARG(rig) || !freq || !cache_ms_freq ||
            !mode || !cache_ms_mode || !width || !cache_ms_width)
    {
        return -RIG_EINVAL;
    }

    cachep = CACHE(rig);
    rs = STATE(rig);

    if (rig_need_debug(RIG_DEBUG_CACHE))
    {
        ENTERFUNC2;
    }

    rig_debug(RIG_DEBUG_CACHE, "%s(%d):  vfo=%s, current_vfo=%s\n", __func__,
              __LINE__,
              rig_strvfo(vfo), rig_strvfo(rs->current_vfo));

    if (vfo == RIG_VFO_CURR)
    {
        vfo = rs->current_vfo;
    }
    else if (vfo == RIG_VFO_TX)
    {
        vfo = rs->tx_vfo;
        rig_debug(RIG_DEBUG_VERBOSE, "%s: TX VFO = %s\n", __func__, rig_strvfo(vfo));
    }
    else if (vfo == RIG_VFO_RX)
    {
        vfo = rs->rx_vfo;
        rig_debug(RIG_DEBUG_VERBOSE, "%s: RX VFO = %s\n", __func__, rig_strvfo(vfo));
    }
    else if (vfo == RIG_VFO_OTHER)
    {
        switch (rs->current_vfo)
        {
        case RIG_VFO_CURR:
            break;  // no change

        case RIG_VFO_OTHER:
            vfo = RIG_VFO_OTHER;
            break;

        case RIG_VFO_A:
            vfo = RIG_VFO_B;
            break;

        case RIG_VFO_MAIN_A:
            vfo = RIG_VFO_MAIN_B;
            break;

        case RIG_VFO_MAIN:
            vfo = RIG_VFO_SUB;
            break;

        case RIG_VFO_B:
            vfo = RIG_VFO_A;
            break;

        case RIG_VFO_MAIN_B:
            vfo = RIG_VFO_MAIN_A;
            break;

        case RIG_VFO_SUB_A:
            vfo = RIG_VFO_SUB_B;
            break;

        case RIG_VFO_SUB_B:
            vfo = RIG_VFO_SUB_A;
            break;

        case RIG_VFO_NONE:
            rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): ignoring VFO_NONE\n", __func__,
                      __LINE__);
            break;

        default:
            rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo=%s, curr_vfo=%s\n", __func__,
                      __LINE__,
                      rig_strvfo(vfo), rig_strvfo(rs->current_vfo));
        }
    }

    // pick a sane default
    if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; }

    // If we're in satmode we map SUB to SUB_A
    if (vfo == RIG_VFO_SUB && cachep->satmode) { vfo = RIG_VFO_SUB_A; };

    switch (vfo)
    {
    case RIG_VFO_CURR:
        *freq = cachep->freqCurr;
        *mode = cachep->modeCurr;
        *width = cachep->widthCurr;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqCurr,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeCurr,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthCurr,
                                     HAMLIB_ELAPSED_GET);
        break;

    case RIG_VFO_OTHER:
        *freq = cachep->freqOther;
        *mode = cachep->modeOther;
        *width = cachep->widthOther;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqOther,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeOther,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthOther,
                                     HAMLIB_ELAPSED_GET);
        break;

    case RIG_VFO_A:
    case RIG_VFO_VFO:
    case RIG_VFO_MAIN:
    case RIG_VFO_MAIN_A:
        *freq = cachep->freqMainA;
        *mode = cachep->modeMainA;
        *width = cachep->widthMainA;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqMainA,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeMainA,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthMainA,
                                     HAMLIB_ELAPSED_GET);
        break;

    case RIG_VFO_B:
    case RIG_VFO_SUB:
    case RIG_VFO_MAIN_B:
        *freq = cachep->freqMainB;
        *mode = cachep->modeMainB;
        *width = cachep->widthMainB;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqMainB,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeMainB,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthMainB,
                                     HAMLIB_ELAPSED_GET);
        break;

    case RIG_VFO_SUB_A:
        *freq = cachep->freqSubA;
        *mode = cachep->modeSubA;
        *width = cachep->widthSubA;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqSubA,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeSubA,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthSubA,
                                     HAMLIB_ELAPSED_GET);
        break;

    case RIG_VFO_SUB_B:
        *freq = cachep->freqSubB;
        *mode = cachep->modeSubB;
        *width = cachep->widthSubB;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqSubB,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeSubB,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthSubB,
                                     HAMLIB_ELAPSED_GET);
        break;

    case RIG_VFO_C:
        //case RIG_VFO_MAINC: // not used by any rig yet
        *freq = cachep->freqMainC;
        *mode = cachep->modeMainC;
        *width = cachep->widthMainC;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqMainC,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeMainC,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthMainC,
                                     HAMLIB_ELAPSED_GET);
        break;

    case RIG_VFO_SUB_C:
        *freq = cachep->freqSubC;
        *mode = cachep->modeSubC;
        *width = cachep->widthSubC;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqSubC,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeSubC,
                                    HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthSubC,
                                     HAMLIB_ELAPSED_GET);
        break;

    case RIG_VFO_MEM:
        *freq = cachep->freqMem;
        *mode = cachep->modeMem;
        *width = cachep->widthMem;
        *cache_ms_freq = elapsed_ms(&cachep->time_freqMem, HAMLIB_ELAPSED_GET);
        *cache_ms_mode = elapsed_ms(&cachep->time_modeMem, HAMLIB_ELAPSED_GET);
        *cache_ms_width = elapsed_ms(&cachep->time_widthMem,
                                     HAMLIB_ELAPSED_GET);
        break;

    default:
        rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo?, vfo=%s\n", __func__, __LINE__,
                  rig_strvfo(vfo));
        RETURNFUNC2(-RIG_EINVAL);
    }

    rig_debug(RIG_DEBUG_CACHE, "%s(%d): vfo=%s, freq=%.0f, mode=%s, width=%d\n",
              __func__, __LINE__, rig_strvfo(vfo),
              (double)*freq, rig_strrmode(*mode), (int)*width);

    if (rig_need_debug(RIG_DEBUG_CACHE))
    {
        RETURNFUNC2(RIG_OK);
    }

    return RIG_OK;
}

/**
 * \brief get cached values for a VFO
 * \param rig           The rig handle
 * \param vfo           The VFO to get information from
 * \param freq          The frequency is stored here
 * \param cache_ms_freq The age of the last frequency update in ms -- NULL if you don't want it

 * Use this to query the frequency cache and then determine to actually fetch data from
 * the rig.
 *
 * \return RIG_OK if the operation has been successful, otherwise
 * a negative value if an error occurred (in which case, cause is
 * set appropriately).
 *
 */
int rig_get_cache_freq(RIG *rig, vfo_t vfo, freq_t *freq, int *cache_ms_freq_p)
{
    rmode_t mode;
    int cache_ms_freq;
    int cache_ms_mode;
    pbwidth_t width;
    int cache_ms_width;
    int retval;
    retval = rig_get_cache(rig, vfo, freq, &cache_ms_freq, &mode, &cache_ms_mode,
                           &width, &cache_ms_width);

    if (retval == RIG_OK)
    {
        if (cache_ms_freq_p) { *cache_ms_freq_p = cache_ms_freq; }
    }

    return retval;
}

/* Get cache timeout period
 * Returns value in msec, -1 if error
 */
int HAMLIB_API rig_get_cache_timeout_ms(RIG *rig, hamlib_cache_t selection)
{
    rig_debug(RIG_DEBUG_TRACE, "%s: called selection=%d\n", __func__, selection);
    if (!rig) {return -1;}
    return CACHE(rig)->timeout_ms;
}

int HAMLIB_API rig_set_cache_timeout_ms(RIG *rig, hamlib_cache_t selection,
                                        int ms)
{
    rig_debug(RIG_DEBUG_TRACE, "%s: called selection=%d, ms=%d\n", __func__,
              selection, ms);
    if (!rig) {return -RIG_EINVAL;}
    CACHE(rig)->timeout_ms = ms;
    return RIG_OK;
}

void rig_cache_show(RIG *rig, const char *func, int line)
{
    struct rig_cache *cachep = CACHE(rig);

    rig_debug(RIG_DEBUG_CACHE,
              "%s(%d): freqMainA=%.0f, modeMainA=%s, widthMainA=%d\n", func, line,
              cachep->freqMainA, rig_strrmode(cachep->modeMainA),
              (int)cachep->widthMainA);
    rig_debug(RIG_DEBUG_CACHE,
              "%s(%d): freqMainB=%.0f, modeMainB=%s, widthMainB=%d\n", func, line,
              cachep->freqMainB, rig_strrmode(cachep->modeMainB),
              (int)cachep->widthMainB);

    if (STATE(rig)->vfo_list & RIG_VFO_SUB_A)
    {
        rig_debug(RIG_DEBUG_CACHE,
                  "%s(%d): freqSubA=%.0f, modeSubA=%s, widthSubA=%d\n", func, line,
                  cachep->freqSubA, rig_strrmode(cachep->modeSubA),
                  (int)cachep->widthSubA);
        rig_debug(RIG_DEBUG_CACHE,
                  "%s(%d): freqSubB=%.0f, modeSubB=%s, widthSubB=%d\n", func, line,
                  cachep->freqSubB, rig_strrmode(cachep->modeSubB),
                  (int)cachep->widthSubB);
    }
}

/*! @} */
