/** * \brief get all channel and non-channel data * \param rig The rig handle * \param chans Array of channels where to store the data * \param cfgps Array of config parameters to retrieve * \param vals Array of values where to store the data * * Retrieves the data associated with all the memory channels, * and rigs memory parameters. * This is the preferred method to support clonable rigs. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_mem_all(), rig_set_mem_all_cb() * \todo finish coding and testing of mem_all functions */ int HAMLIB_API rig_get_mem_all (RIG *rig, channel_t chans[], const struct confparams cfgps[], value_t vals[]) { struct rig_caps *rc; int retval; struct map_all_s mem_all_arg; if (CHECK_RIG_ARG(rig) || !chans || !cfgps || !vals) return -RIG_EINVAL; rc = rig->caps; mem_all_arg.chans = chans; mem_all_arg.cfgps = cfgps; mem_all_arg.vals = vals; if (rc->get_mem_all_cb) return rc->get_mem_all_cb(rig, map_chan, map_parm, (rig_ptr_t)&mem_all_arg); /* * if not available, emulate it * * TODO: save_current_state, restore_current_state */ retval = rig_get_chan_all (rig, chans); if (retval != RIG_OK) return retval; retval = get_parm_all_cb_generic (rig, map_parm, (rig_ptr_t)cfgps, (rig_ptr_t)vals); return retval; }
int HAMLIB_API rig_set_mem(RIG *rig, vfo_t vfo, int ch) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) return -RIG_EINVAL; caps = rig->caps; if (caps->set_mem == NULL) return -RIG_ENAVAIL; if ((caps->targetable_vfo&RIG_TARGETABLE_PURE) || vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) return caps->set_mem(rig, vfo, ch); if (!caps->set_vfo) return -RIG_ENTARGET; curr_vfo = rig->state.current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) return retcode; retcode = caps->set_mem(rig, vfo, ch); caps->set_vfo(rig, curr_vfo); return retcode; }
/** * \brief get all channel and non-channel data by call-back * \param rig The rig handle * \param chan_cb The callback for channel data * \param parm_cb The callback for non-channel(aka parm) data * \param arg Cookie passed to \a chan_cb and \a parm_cb * * Retrieves the data associated with all the memory channels, * and rigs memory parameters, by callback. * This is the preferred method to support clonable rigs. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_mem_all_cb(), rig_set_mem_all() * * \todo get all parm's * \todo finish coding and testing of mem_all functions */ int HAMLIB_API rig_get_mem_all_cb (RIG *rig, chan_cb_t chan_cb, confval_cb_t parm_cb, rig_ptr_t arg) { struct rig_caps *rc; int retval; if (CHECK_RIG_ARG(rig) || !chan_cb) return -RIG_EINVAL; rc = rig->caps; if (rc->get_mem_all_cb) return rc->get_mem_all_cb(rig, chan_cb, parm_cb, arg); /* if not available, emulate it */ retval = rig_get_chan_all_cb (rig, chan_cb, arg); if (retval != RIG_OK) return retval; #if 0 retval = rig_get_parm_cb (rig, parm_cb, arg); if (retval != RIG_OK) return retval; #else return -RIG_ENIMPL; #endif return retval; }
/** * \brief set all channel and non-channel data * \param rig The rig handle * \param chans Channel data * \param cfgps ?? * \param vals ?? * * Writes the data associated with all the memory channels, * and rigs memory parameters. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_mem_all(), rig_set_mem_all_cb() * * \todo set all parm's * \todo finish coding and testing of mem_all functions */ int HAMLIB_API rig_set_mem_all (RIG *rig, const channel_t chans[], const struct confparams cfgps[], const value_t vals[]) { struct rig_caps *rc; int retval; struct map_all_s mem_all_arg; if (CHECK_RIG_ARG(rig) || !chans || !cfgps || !vals) return -RIG_EINVAL; rc = rig->caps; mem_all_arg.chans = (channel_t *) chans; mem_all_arg.cfgps = cfgps; mem_all_arg.vals = (value_t *) vals; if (rc->set_mem_all_cb) return rc->set_mem_all_cb(rig, map_chan, map_parm, (rig_ptr_t)&mem_all_arg); /* if not available, emulate it */ retval = rig_set_chan_all (rig, chans); if (retval != RIG_OK) return retval; #if 0 retval = rig_set_parm_all (rig, parms); if (retval != RIG_OK) return retval; #else return -RIG_ENIMPL; #endif return retval; }
/** * \brief get all channel data * \param rig The rig handle * \param chans The location where to store all the channel data * * Retrieves the data associated with all the memory channels. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_chan_all_cb(), rig_set_chan_all() */ int HAMLIB_API rig_get_chan_all(RIG *rig, channel_t chans[]) { struct rig_caps *rc; struct map_all_s map_arg; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chans) { return -RIG_EINVAL; } rc = rig->caps; map_arg.chans = chans; if (rc->get_chan_all_cb) { return rc->get_chan_all_cb(rig, map_chan, (rig_ptr_t)&map_arg); } /* * if not available, emulate it * * TODO: save_current_state, restore_current_state */ retval = get_chan_all_cb_generic(rig, map_chan, (rig_ptr_t)&map_arg); return retval; }
/** * \brief set all channel data * \param rig The rig handle * \param chans The location of data to set for all channels * * Write the data associated with all the memory channels. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_set_chan_all_cb(), rig_get_chan_all() */ int HAMLIB_API rig_set_chan_all(RIG *rig, const channel_t chans[]) { struct rig_caps *rc; struct map_all_s map_arg; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chans) { return -RIG_EINVAL; } rc = rig->caps; map_arg.chans = (channel_t *) chans; if (rc->set_chan_all_cb) { return rc->set_chan_all_cb(rig, map_chan, (rig_ptr_t)&map_arg); } /* if not available, emulate it */ retval = set_chan_all_cb_generic(rig, map_chan, (rig_ptr_t)&map_arg); return retval; }
/** * \brief get all channel data, by callback * \param rig The rig handle * \param chan_cb Pointer to a callback function to retrieve channel data * \param arg Arbitrary argument passed back to \a chan_cb * * Retrieves the data associated with a all the memory channels. * This is the preferred method to support clonable rigs. * * \a chan_cb is called first with no data in chan (chan equals NULL). * This means the application has to provide a struct where to store * future data for channel channel_num. If channel_num == chan->channel_num, * the application does not need to provide a new allocated structure. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_chan_all(), rig_set_chan_all_cb() */ int HAMLIB_API rig_get_chan_all_cb(RIG *rig, chan_cb_t chan_cb, rig_ptr_t arg) { struct rig_caps *rc; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chan_cb) { return -RIG_EINVAL; } rc = rig->caps; if (rc->get_chan_all_cb) { return rc->get_chan_all_cb(rig, chan_cb, arg); } /* if not available, emulate it */ retval = get_chan_all_cb_generic(rig, chan_cb, arg); return retval; }
/** * \brief lookup the memory type and capabilities * \param rig The rig handle * \param ch The memory channel number * * Lookup the memory type and capabilities associated with a channel number. * If \a ch equals RIG_MEM_CAPS_ALL, then a union of all the mem_caps sets * is returned (pointer to static memory). * * \return a pointer to a chan_t structure if the operation has been sucessful, * otherwise a NULL pointer, most probably because of incorrect channel number * or buggy backend. */ const chan_t *HAMLIB_API rig_lookup_mem_caps(RIG *rig, int ch) { chan_t *chan_list; static chan_t chan_list_all; int i, j; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return NULL; } if (ch == RIG_MEM_CAPS_ALL) { memset(&chan_list_all, 0, sizeof(chan_list_all)); chan_list = rig->state.chan_list; chan_list_all.start = chan_list[0].start; chan_list_all.type = RIG_MTYPE_NONE; /* meaningless */ for (i = 0; i < CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { unsigned char *p1, *p2; p1 = (unsigned char *)&chan_list_all.mem_caps; p2 = (unsigned char *)&chan_list[i].mem_caps; /* It's kind of hackish, we just want to do update set with: * chan_list_all.mem_caps |= chan_list[i].mem_caps */ for (j = 0; j < sizeof(channel_cap_t); j++) { p1[j] |= p2[j]; } /* til the end, most probably meaningless */ chan_list_all.end = chan_list[i].end; } return &chan_list_all; } chan_list = rig->state.chan_list; for (i = 0; i < CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (ch >= chan_list[i].start && ch <= chan_list[i].end) { return &chan_list[i]; } } return NULL; }
/** * \brief get memory channel count * \param rig The rig handle * * Get the total memory channel count, computed from the rig caps * * \return the memory count */ int HAMLIB_API rig_mem_count(RIG *rig) { const chan_t *chan_list; int i, count; if (CHECK_RIG_ARG(rig)) return -RIG_EINVAL; chan_list = rig->state.chan_list; count = 0; for (i=0; i<CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { count += chan_list[i].end - chan_list[i].start + 1; } return count; }
/** * \brief set the current memory channel number * \param rig The rig handle * \param vfo The target VFO * \param ch The memory channel number * * Sets the current memory channel number. * It is not mandatory for the radio to be in memory mode. Actually * it depends on rigs. YMMV. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_mem() */ int HAMLIB_API rig_set_mem(RIG *rig, vfo_t vfo, int ch) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_mem == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_PURE) || vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) { return caps->set_mem(rig, vfo, ch); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rig->state.current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_mem(rig, vfo, ch); caps->set_vfo(rig, curr_vfo); return retcode; }
/** * \brief set all channel and non-channel data by call-back * \param rig The rig handle * \param chan_cb The callback for channel data * \param parm_cb The callback for non-channel(aka parm) data * \param arg Cookie passed to \a chan_cb and \a parm_cb * * Writes the data associated with all the memory channels, * and rigs memory parameters, by callback. * This is the preferred method to support clonable rigs. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_mem_all_cb(), rig_set_mem_all() * \todo finish coding and testing of mem_all functions */ int HAMLIB_API rig_set_mem_all_cb(RIG *rig, chan_cb_t chan_cb, confval_cb_t parm_cb, rig_ptr_t arg) { struct rig_caps *rc; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chan_cb) { return -RIG_EINVAL; } rc = rig->caps; if (rc->set_mem_all_cb) { return rc->set_mem_all_cb(rig, chan_cb, parm_cb, arg); } /* if not available, emulate it */ retval = rig_set_chan_all_cb(rig, chan_cb, arg); if (retval != RIG_OK) { return retval; } #if 0 retval = rig_set_parm_all_cb(rig, parm_cb, arg); if (retval != RIG_OK) { return retval; } #else return -RIG_ENIMPL; #endif return retval; }
/** * \brief get all channel data, by callback * \param rig The rig handle * \param chan_cb Pointer to a callback function to retrieve channel data * \param arg Arbitrary argument passed back to \a chan_cb * * Retrieves the data associated with a all the memory channels. * This is the preferred method to support clonable rigs. * * \a chan_cb is called first with no data in chan (chan equals NULL). * This means the application has to provide a struct where to store * future data for channel channel_num. If channel_num == chan->channel_num, * the application does not need to provide a new allocated structure. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_chan_all(), rig_set_chan_all_cb() */ int HAMLIB_API rig_get_chan_all_cb (RIG *rig, chan_cb_t chan_cb, rig_ptr_t arg) { struct rig_caps *rc; int retval; if (CHECK_RIG_ARG(rig) || !chan_cb) return -RIG_EINVAL; rc = rig->caps; if (rc->get_chan_all_cb) return rc->get_chan_all_cb(rig, chan_cb, arg); /* if not available, emulate it */ retval = get_chan_all_cb_generic (rig, chan_cb, arg); return retval; }
/** * \brief set all channel data * \param rig The rig handle * \param chans The location of data to set for all channels * * Write the data associated with all the memory channels. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_set_chan_all_cb(), rig_get_chan_all() */ int HAMLIB_API rig_set_chan_all (RIG *rig, const channel_t chans[]) { struct rig_caps *rc; struct map_all_s map_arg; int retval; if (CHECK_RIG_ARG(rig) || !chans) return -RIG_EINVAL; rc = rig->caps; map_arg.chans = (channel_t *) chans; if (rc->set_chan_all_cb) return rc->set_chan_all_cb(rig, map_chan, (rig_ptr_t)&map_arg); /* if not available, emulate it */ retval = set_chan_all_cb_generic (rig, map_chan, (rig_ptr_t)&map_arg); return retval; }
/** * \brief get memory channel count * \param rig The rig handle * * Get the total memory channel count, computed from the rig caps * * \return the memory count */ int HAMLIB_API rig_mem_count(RIG *rig) { const chan_t *chan_list; int i, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } chan_list = rig->state.chan_list; count = 0; for (i = 0; i < CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { count += chan_list[i].end - chan_list[i].start + 1; } return count; }
/** * \brief get all channel data * \param rig The rig handle * \param chans The location where to store all the channel data * * Retrieves the data associated with all the memory channels. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_get_chan_all_cb(), rig_set_chan_all() */ int HAMLIB_API rig_get_chan_all (RIG *rig, channel_t chans[]) { struct rig_caps *rc; struct map_all_s map_arg; int retval; if (CHECK_RIG_ARG(rig) || !chans) return -RIG_EINVAL; rc = rig->caps; map_arg.chans = chans; if (rc->get_chan_all_cb) return rc->get_chan_all_cb(rig, map_chan, (rig_ptr_t)&map_arg); /* * if not available, emulate it * * TODO: save_current_state, restore_current_state */ retval = get_chan_all_cb_generic (rig, map_chan, (rig_ptr_t)&map_arg); return retval; }
/** * \brief get channel data * \param rig The rig handle * \param chan The location where to store the channel data * * Retrieves the data associated with a channel. This channel can either * be the state of a VFO specified by \a chan->vfo, or a memory channel * specified with \a chan->vfo = RIG_VFO_MEM and \a chan->channel_num. * See #channel_t for more information. * * Example: \code channel_t chan; int err; chan->vfo = RIG_VFO_MEM; chan->channel_num = 10; err = rig_get_channel(rig, &chan); if (err != RIG_OK) error("get_channel failed: %s", rigerror(err)); \endcode * * The rig_get_channel is supposed to have no impact on the current VFO * and memory number selected. Depending on backend and rig capabilities, * the chan struct may not be filled in completely. * * Note: chan->ext_levels is a pointer to a newly mallocated memory. * This is the responsability of the caller to manage and eventually * free it. * * \return RIG_OK if the operation has been sucessful, otherwise * a negative value if an error occured (in which case, cause is * set appropriately). * * \sa rig_set_channel() */ int HAMLIB_API rig_get_channel(RIG *rig, channel_t *chan) { struct rig_caps *rc; int curr_chan_num, get_mem_status = RIG_OK; vfo_t curr_vfo; vfo_t vfo; /* requested vfo */ int retcode; int can_emulate_by_vfo_mem, can_emulate_by_vfo_op; #ifdef PARANOID_CHANNEL_HANDLING channel_t curr_chan; #endif if (CHECK_RIG_ARG(rig) || !chan) return -RIG_EINVAL; /* * TODO: check validity of chan->channel_num */ rc = rig->caps; if (rc->get_channel) return rc->get_channel(rig, chan); /* * if not available, emulate it * Optional: get_vfo, set_vfo * TODO: check return codes */ vfo = chan->vfo; if (vfo == RIG_VFO_CURR) return generic_save_channel(rig, chan); /* any emulation requires set_mem() */ if (vfo == RIG_VFO_MEM && !rc->set_mem) return -RIG_ENAVAIL; can_emulate_by_vfo_mem = rc->set_vfo && ((rig->state.vfo_list & RIG_VFO_MEM) == RIG_VFO_MEM); can_emulate_by_vfo_op = rc->vfo_op && rig_has_vfo_op(rig, RIG_OP_TO_VFO); if (!can_emulate_by_vfo_mem && !can_emulate_by_vfo_op) return -RIG_ENTARGET; curr_vfo = rig->state.current_vfo; /* may be needed if the restore_channel has some side effects */ #ifdef PARANOID_CHANNEL_HANDLING generic_save_channel(rig, &curr_chan); #endif if (vfo == RIG_VFO_MEM) get_mem_status = rig_get_mem(rig, RIG_VFO_CURR, &curr_chan_num); if (can_emulate_by_vfo_mem && curr_vfo != vfo) { retcode = rig_set_vfo(rig, vfo); if (retcode != RIG_OK) return retcode; } if (vfo == RIG_VFO_MEM) rig_set_mem(rig, RIG_VFO_CURR, chan->channel_num); if (!can_emulate_by_vfo_mem && can_emulate_by_vfo_op) { retcode = rig_vfo_op(rig, RIG_VFO_CURR, RIG_OP_TO_VFO); if (retcode != RIG_OK) return retcode; } retcode = generic_save_channel(rig, chan); /* restore current memory number */ if (vfo == RIG_VFO_MEM && get_mem_status == RIG_OK) rig_set_mem(rig, RIG_VFO_CURR, curr_chan_num); if (can_emulate_by_vfo_mem) rig_set_vfo(rig, curr_vfo); #ifdef PARANOID_CHANNEL_HANDLING generic_restore_channel(rig, &curr_chan); #endif return retcode; }