Example #1
0
/*
 * th_get_freq
 * Assumes rig!=NULL, freq!=NULL
 */
int
th_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
	char buf[20];
	int retval, step;

	rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);

	if (vfo != RIG_VFO_CURR && vfo != rig->state.current_vfo)
		return kenwood_wrong_vfo(__func__, vfo);

	*freq = 0;

	retval = kenwood_safe_transaction(rig, "FQ", buf, sizeof(buf), 17);
	if (retval != RIG_OK)
		return retval;

	retval = num_sscanf(buf, "FQ %"SCNfreq",%x", freq, &step);
	if (retval != 2) {
		rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf);
		return -RIG_ERJCTED;
	}

	return RIG_OK;
}
Example #2
0
/* push/pull language is uses for stuff inside 710 driver rather than get/set */
int 
tmd710_pull_fo(RIG * rig,vfo_t vfo, tmd710_fo *fo_struct) {
  char cmdbuf[50];
  char buf[50];
  int vfonum = 0;
  int retval;

  rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);

  switch (vfo) {
  case (RIG_VFO_CURR):
    vfonum = rig->state.current_vfo==RIG_VFO_B;
    break;
  case (RIG_VFO_A):
    vfonum = 0;
    break;
  case (RIG_VFO_B):
    vfonum = 1;
    break;

  }
  
  
  // if (vfo != RIG_VFO_CURR && vfo != rig->state.current_vfo)
  //return kenwood_wrong_vfo(__func__, vfo);
  snprintf(cmdbuf,49,"FO %d",vfonum);
  
  retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 49);
  if (retval != RIG_OK)
    return retval;
  
  retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", 
		      &fo_struct->vfo, &fo_struct->freq, 
		      &fo_struct->step, &fo_struct->shift, 
		      &fo_struct->reverse, &fo_struct->tone, 
		      &fo_struct->ct, &fo_struct->dsc, 
		      &fo_struct->tone_freq, &fo_struct->ct_freq,
		      &fo_struct->dsc_val, &fo_struct->offset,
		      &fo_struct->mode);
  if (retval != 13) {
    rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf);
    return -RIG_ERJCTED;
  }
  return RIG_OK;
  
}
Example #3
0
static int netrigctl_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
{
  int ret, len;
  char cmd[CMD_MAX];
  char buf[BUF_MAX];

  rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);

  len = sprintf(cmd, "i\n");

  ret = netrigctl_transaction(rig, cmd, len, buf);
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, tx_freq));

  return RIG_OK;
}
Example #4
0
File: rx340.c Project: dh1tw/hamlib
/*
 * rx340_get_freq
 * Assumes rig!=NULL, freq!=NULL
 */
int rx340_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
    char buf[BUFSZ];
    int buf_len;
    int retval;
    double f;

#define REPORT_FREQ "TF"EOM
    retval = rx340_transaction(rig, REPORT_FREQ, strlen(REPORT_FREQ), buf, &buf_len);
    if (retval < 0)
        return retval;

    if (buf_len < 2 || buf[0] != 'F' || num_sscanf(buf+1, "%lf", &f) != 1)
        return -RIG_EPROTO;

	*freq = f*1e6;

	return RIG_OK;
}
Example #5
0
File: rs.c Project: DF4OR/hamlib
int rs_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
{
	char buf[RESPSZ], *slevel;
	int buf_len, retval;

    switch (level) {
        case RIG_LEVEL_STRENGTH: slevel = BOM "SENS:DATA? \"VOLT:AC\"" EOM; break;
        case RIG_LEVEL_ATT: slevel = BOM "INP:ATT:STAT?" EOM; break;
        case RIG_LEVEL_AF: slevel = BOM "SYST:AUD:VOL?" EOM; break;
        case RIG_LEVEL_SQL:
        case RIG_LEVEL_AGC:
        case RIG_LEVEL_RF:
             return -RIG_ENIMPL;
        default:
             return -RIG_EINVAL;
    }

    retval = rs_transaction(rig, slevel, strlen(slevel), buf, &buf_len);
    if (retval < 0)
        return retval;

    switch (level) {
        case RIG_LEVEL_STRENGTH:
            /* assumes FORMAat:DATA ASCii
             * result in dBuV, keep only integer part
             */
            sscanf(buf, "%d", &val->i);
            val->i -= 34;
            break;
        case RIG_LEVEL_ATT:
            val->i = (!memcmp(buf, "ON", 2) || !memcmp(buf, "1", 1)) ? rig->state.attenuator[0] : 0;
            break;
        case RIG_LEVEL_AF:
            if (num_sscanf(buf, "%f", &val->f) != 1)
                return -RIG_EPROTO;
            break;
        default:
             return -RIG_EINVAL;
    }

	return retval;
}
Example #6
0
File: rx340.c Project: dh1tw/hamlib
/*
 * rx340_get_mode
 * Assumes rig!=NULL, mode!=NULL
 */
int rx340_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
{
    char buf[BUFSZ];
    int buf_len;
    int retval;
    double f;

#define REPORT_MODEFILTER "TDI"EOM
    retval = rx340_transaction(rig, REPORT_MODEFILTER,
            strlen(REPORT_MODEFILTER), buf, &buf_len);
    if (retval < 0)
        return retval;

    if (buf_len < 4 || buf[0] != 'D' || buf[2] != 'I')
        return -RIG_EPROTO;

	switch (buf[1]) {
        case RX340_USB: *mode = RIG_MODE_USB; break;
        case RX340_LSB: *mode = RIG_MODE_LSB; break;
        case RX340_CW1:
        case RX340_CW:  *mode = RIG_MODE_CW; break;
        case RX340_FM:  *mode = RIG_MODE_FM; break;
        case RX340_AM:  *mode = RIG_MODE_AM; break;
        case RX340_SAM: *mode = RIG_MODE_AMS; break;
        case RX340_ISB: *mode = RIG_MODE_DSB; break;
		default:
			rig_debug(RIG_DEBUG_ERR,
							"%s: unknown mode '%c'\n",
							__func__, buf[1]);
			return -RIG_EPROTO;
	}

    if (num_sscanf(buf+3, "%lf", &f) != 1)
        return -RIG_EPROTO;

	*width = f*1e3;

	return RIG_OK;
}
Example #7
0
int
gp2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
{
    char buf[RESPSZ], *slevel;
    int buf_len, retval, ival;

    rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo));

    switch (level)
    {
    case RIG_LEVEL_AF:
        slevel = BOM "SL?" EOM;
        break;

    case RIG_LEVEL_SQL:
        slevel = BOM "SQ?" EOM;
        break;

    case RIG_LEVEL_STRENGTH:
    case RIG_LEVEL_ATT:
    case RIG_LEVEL_AGC:
    case RIG_LEVEL_RF:
        return -RIG_ENIMPL;

    default:
        return -RIG_EINVAL;
    }

    retval = gp2000_transaction(rig, slevel, strlen(slevel), buf, &buf_len);

    if (retval < 0)
    {
        return retval;
    }

    switch (level)
    {
    case RIG_LEVEL_AF:
        if (num_sscanf(buf, "%*cSL%d", &ival) != 1)
        {
            return -RIG_EPROTO;
        }

        val->f = ival;

        break;

    case RIG_LEVEL_SQL:
        if (num_sscanf(buf, "%*cSQ%1d", &ival) != 1)
        {
            return -RIG_EPROTO;
        }

        val->f = ival;

        break;

    default:
        return -RIG_EINVAL;
    }

    return retval;
}
Example #8
0
/*
 * mimics rpcrig_open() from rpcrig/rpcrig_backend.c
 */
static int netrigctl_open(RIG *rig)
{
  int ret, len, i;
  struct rig_state *rs = &rig->state;
  int prot_ver;
  char cmd[CMD_MAX];
  char buf[BUF_MAX];

  rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);


  len = sprintf(cmd, "\\dump_state\n");

  ret = netrigctl_transaction(rig, cmd, len, buf);
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  prot_ver = atoi(buf);
#define RIGCTLD_PROT_VER 0
  if (prot_ver < RIGCTLD_PROT_VER)
	  return -RIG_EPROTO;

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->itu_region = atoi(buf);

  for (i=0; i<FRQRANGESIZ; i++) {
	ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
	if (ret <= 0)
		return (ret < 0) ? ret : -RIG_EPROTO;

	ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%x%d%d%x%x",
		&rs->rx_range_list[i].start,
		&rs->rx_range_list[i].end,
		&rs->rx_range_list[i].modes,
		&rs->rx_range_list[i].low_power,
		&rs->rx_range_list[i].high_power,
		&rs->rx_range_list[i].vfo,
		&rs->rx_range_list[i].ant
		);
	if (ret != 7)
		return -RIG_EPROTO;
	if (RIG_IS_FRNG_END(rs->rx_range_list[i]))
		break;
  }
  for (i=0; i<FRQRANGESIZ; i++) {
	ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
	if (ret <= 0)
		return (ret < 0) ? ret : -RIG_EPROTO;

	ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%x%d%d%x%x",
		&rs->tx_range_list[i].start,
		&rs->tx_range_list[i].end,
		&rs->tx_range_list[i].modes,
		&rs->tx_range_list[i].low_power,
		&rs->tx_range_list[i].high_power,
		&rs->tx_range_list[i].vfo,
		&rs->tx_range_list[i].ant
		);
	if (ret != 7)
		return -RIG_EPROTO;
	if (RIG_IS_FRNG_END(rs->tx_range_list[i]))
		break;
  }
  for (i=0; i<TSLSTSIZ; i++) {
	ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  	if (ret <= 0)
		return (ret < 0) ? ret : -RIG_EPROTO;

	ret = sscanf(buf, "%x%ld",
                                &rs->tuning_steps[i].modes,
                                &rs->tuning_steps[i].ts);
	if (ret != 2)
		return -RIG_EPROTO;
	if (RIG_IS_TS_END(rs->tuning_steps[i]))
		break;
  }

  for (i=0; i<FLTLSTSIZ; i++) {
	ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  	if (ret <= 0)
		return (ret < 0) ? ret : -RIG_EPROTO;

	ret = sscanf(buf, "%x%ld",
                                &rs->filters[i].modes,
                                &rs->filters[i].width);
	if (ret != 2)
		return -RIG_EPROTO;
	if (RIG_IS_FLT_END(rs->filters[i]))
		break;
  }

#if 0
  /* TODO */
chan_t chan_list[CHANLSTSIZ]; /*!< Channel list, zero ended */
#endif

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->max_rit = atol(buf);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->max_xit = atol(buf);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->max_ifshift = atol(buf);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->announces = atoi(buf);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  ret = sscanf (buf, "%d%d%d%d%d%d%d",
		  &rs->preamp[0], &rs->preamp[1],
		  &rs->preamp[2], &rs->preamp[3],
		  &rs->preamp[4], &rs->preamp[5],
		  &rs->preamp[6]);
  if (ret < 0 || ret >= MAXDBLSTSIZ)
	  ret = 0;
  rs->preamp[ret] = RIG_DBLST_END;

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  ret = sscanf (buf, "%d%d%d%d%d%d%d",
		  &rs->attenuator[0], &rs->attenuator[1],
		  &rs->attenuator[2], &rs->attenuator[3],
		  &rs->attenuator[4], &rs->attenuator[5],
		  &rs->attenuator[6]);
  if (ret < 0 || ret >= MAXDBLSTSIZ)
	  ret = 0;
  rs->attenuator[ret] = RIG_DBLST_END;

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->has_get_func = strtol(buf, NULL, 0);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->has_set_func = strtol(buf, NULL, 0);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->has_get_level = strtol(buf, NULL, 0);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->has_set_level = strtol(buf, NULL, 0);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->has_get_parm = strtol(buf, NULL, 0);

  ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", sizeof("\n"));
  if (ret <= 0)
	return (ret < 0) ? ret : -RIG_EPROTO;

  rs->has_set_parm = strtol(buf, NULL, 0);

#if 0
gran_t level_gran[RIG_SETTING_MAX];   /*!< level granularity */
gran_t parm_gran[RIG_SETTING_MAX];    /*!< parm granularity */
#endif

  for (i=0; i<FRQRANGESIZ && !RIG_IS_FRNG_END(rs->rx_range_list[i]); i++) {
	rs->vfo_list |= rs->rx_range_list[i].vfo;
  }
  for (i=0; i<FRQRANGESIZ && !RIG_IS_FRNG_END(rs->tx_range_list[i]); i++) {
	rs->vfo_list |= rs->tx_range_list[i].vfo;
  }

  return RIG_OK;
}
Example #9
0
/*
 * th_decode_event is called by sa_sigio, when some asynchronous
 * data has been received from the rig.
 */
int
th_decode_event (RIG *rig)
{
	char asyncbuf[128];
	int retval;
	size_t async_len=128;

	rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);

	retval = kenwood_transaction(rig, NULL, 0, asyncbuf, &async_len);
	if (retval != RIG_OK)
		return retval;

	rig_debug(RIG_DEBUG_TRACE, "%s: Decoding message\n", __func__);

	if (async_len> 3 && asyncbuf[0] == 'B' && asyncbuf[1] == 'U' && asyncbuf[2] == 'F') {

		vfo_t vfo;
		freq_t freq, offset;
		int mode;
		int step, shift, rev, tone, ctcss, tonefq, ctcssfq;

		retval = num_sscanf(asyncbuf, "BUF %d,%"SCNfreq",%X,%d,%d,%d,%d,,%d,,%d,%"SCNfreq",%d",
					  &vfo, &freq, &step, &shift, &rev, &tone,
					  &ctcss, &tonefq, &ctcssfq, &offset, &mode);

		if (retval != 11) {
			rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BUF message '%s'\n", __func__, asyncbuf);
			return -RIG_ERJCTED;
		}

		/* Calibration and conversions */
		vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B;
		mode = (mode == 0) ? RIG_MODE_FM : RIG_MODE_AM;

		rig_debug(RIG_DEBUG_TRACE, "%s: Buffer (vfo %d, freq %"PRIfreq" Hz, mode %d)\n", __func__, vfo, freq, mode);

		/* Callback execution */
		if (rig->callbacks.vfo_event) {
			rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg);
		}

		if (rig->callbacks.freq_event) {
			rig->callbacks.freq_event(rig, vfo, freq, rig->callbacks.freq_arg);
		}

		if (rig->callbacks.mode_event) {
			rig->callbacks.mode_event(rig, vfo, mode, RIG_PASSBAND_NORMAL,
							rig->callbacks.mode_arg);
		}

	} else if (async_len> 2 && asyncbuf[0] == 'S' && asyncbuf[1] == 'M') {

		vfo_t vfo;
		int lev;
		retval = sscanf(asyncbuf, "SM %d,%d", &vfo, &lev);
		if (retval != 2) {
			rig_debug(RIG_DEBUG_ERR, "%s: Unexpected SM message '%s'\n", __func__, asyncbuf);
			return -RIG_ERJCTED;
		}

		/* Calibration and conversions */
		vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B;

		rig_debug(RIG_DEBUG_TRACE, "%s: Signal strength event - signal = %.3f\n", __func__, (float)(lev / 5.0));

		/* Callback execution */
#if STILLHAVETOADDCALLBACK
		if (rig->callbacks.strength_event)
			rig->callbacks.strength_event(rig, vfo,(float)(lev / 5.0),
							rig->callbacks.strength_arg);
#endif

	} else if (async_len > 2 && asyncbuf[0] == 'B' && asyncbuf[1] == 'Y') {

		vfo_t vfo;
		int busy;

		retval = sscanf(asyncbuf, "BY %d,%d", &vfo, &busy);
		if (retval != 2) {
			rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BY message '%s'\n", __func__, asyncbuf);
			return -RIG_ERJCTED;
		}
		vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B;
		rig_debug(RIG_DEBUG_TRACE, "%s: Busy event - status = '%s'\n",
				__func__, (busy == 0) ? "OFF" : "ON" );
		return -RIG_ENIMPL;
		/* This event does not have a callback. */

	} else if (async_len > 2 && asyncbuf[0] == 'B' && asyncbuf[1] == 'C') {

		vfo_t vfo;
		retval = sscanf(asyncbuf, "BC %d", &vfo);
		if (retval != 1) {
			rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BC message '%s'\n", __func__, asyncbuf);
			return -RIG_ERJCTED;
		}
		vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B;

		rig_debug(RIG_DEBUG_TRACE, "%s: VFO event - vfo = %d\n", __func__, vfo);
		if (rig->callbacks.vfo_event)
			rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg);

	} else {

		rig_debug(RIG_DEBUG_ERR, "%s: Unsupported transceive cmd '%s'\n", __func__, asyncbuf);
		return -RIG_ENIMPL;
	}

	return RIG_OK;
}
Example #10
0
/* --------------------------------------------------------------------- */
int th_get_channel(RIG *rig, channel_t *chan)
{
	char membuf[64],ackbuf[ACKBUF_LEN];
	int retval;
	size_t ack_len;
	freq_t freq,offset;
	char req[16],scf[128];
	int step, shift, rev, tone, ctcss, tonefq, ctcssfq, dcs, dcscode, mode, lockout;
	const char *mr_extra;
	int channel_num;
	vfo_t vfo;
	const struct kenwood_priv_caps *priv=(const struct kenwood_priv_caps *)rig->caps->priv;
	const chan_t *chan_caps;

	if (chan->vfo == RIG_VFO_MEM) {

		chan_caps = rig_lookup_mem_caps(rig, chan->channel_num);
		if (!chan_caps)
			return -RIG_ECONF;
	} else {
        /* TODO: stuff channel_num (out of current freq) and chan_caps */
		return -RIG_ENIMPL;
    }

	channel_num = chan->channel_num;
	vfo = chan->vfo;
	memset(chan, 0, sizeof(channel_t));
	chan->channel_num = channel_num;
	chan->vfo = vfo;

	if (rig->caps->rig_model == RIG_MODEL_THF7E ||
				rig->caps->rig_model == RIG_MODEL_THF6A)
		mr_extra = "";
	else
		mr_extra = "0, ";

	channel_num -= chan_caps->start;

	switch (chan_caps->type) {
	case RIG_MTYPE_MEM:
		if (chan_caps[1].type == RIG_MTYPE_PRIO) {
			/* Info */
			sprintf(req, "MR %s0,I-%01d",mr_extra,channel_num);
		} else
			sprintf(req, "MR %s0,%03d",mr_extra,channel_num);
		break;

	case RIG_MTYPE_EDGE:
		if (chan_caps[1].type == RIG_MTYPE_EDGE) {
			sprintf(req, "MR %s0,L%01d",mr_extra,channel_num);
			sprintf(chan->channel_desc, "L%01d",channel_num);
		} else {
   			sprintf(req, "MR %s0,U%01d",mr_extra,channel_num);
			sprintf(chan->channel_desc, "U%01d",channel_num);
		}
		break;

	case RIG_MTYPE_PRIO:
		if (chan_caps->start == chan_caps->end) {
   			sprintf(req, "MR %s0,PR",mr_extra);
			sprintf(chan->channel_desc, "Pr");
		} else {
   			sprintf(req, "MR %s0,PR%01d",mr_extra,channel_num+1);
			sprintf(chan->channel_desc, "Pr%01d",channel_num+1);
		}
		break;

	case RIG_MTYPE_CALL:
		sprintf(req, "CR 0,%01d",channel_num);
		if (chan->channel_num==chan_caps->start) sprintf(chan->channel_desc, "Call V");
		else if (chan->channel_num==chan_caps->end) sprintf(chan->channel_desc, "Call U");
		else sprintf(chan->channel_desc, "Call");
		break;

	case RIG_MTYPE_BAND:
		sprintf(req, "VR %01X",channel_num);
		sprintf(chan->channel_desc, "BAND %01X",channel_num);
		break;

	default:
		return -RIG_EINVAL;
	}

	sprintf(membuf, "%s",req);
	ack_len=ACKBUF_LEN;

	retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
	if (retval != RIG_OK)
		return retval;

	/*
	 * TODO: dcs/mode/lockout are not there on TH-G71
	 */
	mode = RIG_MODE_NONE;
	rev = lockout = dcs = dcscode = 0;

	strcpy(scf,req);
	if (chan_caps->mem_caps.dcs_sql)
	{
	/* Step can be hexa
	 * Lockout is optional on some channels
	 */
		strcat(scf, ",%"SCNfreq",%x,%d,%d,%d,%d,%d,%d,%d,%d,%"SCNfreq",%d,%d");

		retval = num_sscanf(ackbuf, scf,
				&freq, &step, &shift, &rev, &tone,
				&ctcss, &dcs, &tonefq, &ctcssfq, &dcscode,
				&offset, &mode, &lockout);
		if (retval < 12) {
			rig_debug(RIG_DEBUG_WARN, "%s: sscanf failed %d\n", __func__, retval);
			return -RIG_EPROTO;
		}
	} else {
		strcat(scf, ",%"SCNfreq",%x,%d,%d,%d,%d,,%d,,%d,%"SCNfreq);
		retval = num_sscanf(ackbuf, scf,
				&freq, &step, &shift, &rev, &tone,
				&ctcss, &tonefq, &ctcssfq, &offset);
		if (retval != 9) {
			rig_debug(RIG_DEBUG_WARN, "%s: sscanf failed %d\n", __func__, retval);
		}
	}

	chan->funcs = rev ? RIG_FUNC_REV : 0;
	chan->flags = lockout ? RIG_CHFLAG_SKIP : 0;
	chan->freq=freq;
	chan->vfo=RIG_VFO_MEM;
	chan->tuning_step=rig->state.tuning_steps[step].ts;

	if (priv->mode_table) {
		chan->mode = kenwood2rmode(mode, priv->mode_table);
		if (chan->mode == RIG_MODE_NONE) {
			rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Mode value '%d'\n",
			__func__, mode);
			return -RIG_EPROTO;
		}
	} else {
		/* No mode info (TH-G71, TMV7,..),
		 * guess it from current freq
		 */
		chan->mode = (freq < MHz(136)) ? RIG_MODE_AM : RIG_MODE_FM;
	}

	chan->width=rig_passband_normal(rig, chan->mode);

	switch (shift) {
	case 0 :
		chan->rptr_shift=RIG_RPT_SHIFT_NONE;
		break;
	case 1 :
		chan->rptr_shift=RIG_RPT_SHIFT_PLUS;
		break;
	case 2 :
		chan->rptr_shift=RIG_RPT_SHIFT_MINUS;
		offset = -offset;
		break;
	default:
		rig_debug(RIG_DEBUG_ERR, "%s: not supported shift %d\n",
				__func__, shift);
		chan->rptr_shift=RIG_RPT_SHIFT_NONE;
	}

	chan->rptr_offs=offset;

	/* FIXME: ctcss_list for t[fm]*.c */
	//chan->ctcss_tone=rig->caps->ctcss_list[tonefq==1?0:tonefq-2];
	// chan->ctcss_sql=rig->caps->ctcss_list[ctcssfq==1?0:ctcssfq-2];
	if (tone)
		chan->ctcss_tone=rig->caps->ctcss_list[tonefq];
	else
		chan->ctcss_tone=0;

	if (ctcss)
		chan->ctcss_sql=rig->caps->ctcss_list[ctcssfq];
	else
		chan->ctcss_sql=0;

	if (dcs)
		chan->dcs_sql=chan->dcs_code=rig->caps->dcs_list[dcscode];
	else
		chan->dcs_sql=chan->dcs_code=0;

	chan->tx_freq=RIG_FREQ_NONE;
	if (shift==RIG_RPT_SHIFT_NONE &&
			((chan_caps->type==RIG_MTYPE_MEM && chan_caps->start == 0) ||
				chan_caps->type==RIG_MTYPE_CALL)) {
		/* split ? */
		req[3+strlen(mr_extra)]='1';
		sprintf(membuf, "%s",req);
		ack_len=ACKBUF_LEN;
		retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
		if (retval == RIG_OK) {
			strcpy(scf,req);
			strcat(scf, ",%"SCNfreq",%x");
			retval = num_sscanf(ackbuf, scf, &freq, &step);
			chan->tx_freq=freq;
			chan->split=RIG_SPLIT_ON;
		}
	}

	/* If not set already by special channels.. */
	if (chan->channel_desc[0] == '\0') {
		if (chan_caps[1].type == RIG_MTYPE_PRIO)
			sprintf(membuf, "MNA %sI-%01d",mr_extra,channel_num);
		else
			sprintf(membuf, "MNA %s%03d",mr_extra,channel_num);
		ack_len=ACKBUF_LEN;

		/* Get memory name */
		retval = kenwood_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len);
		if (retval != RIG_OK)
			return retval;

		if (ack_len > rig->caps->chan_desc_sz)
			ack_len = rig->caps->chan_desc_sz;

		strncpy(chan->channel_desc,ackbuf+strlen(membuf)+1,ack_len);
		chan->channel_desc[ack_len] = '\0';
	}

	return RIG_OK;
}