static int optoscan_send_freq(RIG *rig, pltstate_t *state) { unsigned char buff[OPTO_BUFF_SIZE]; char md, pd; freq_t freq; rmode_t mode; freq = state->next_freq; mode = state->next_mode; memset(buff, 0, OPTO_BUFF_SIZE); to_bcd(buff, freq, 5 * 2); /* to_bcd requires nibble len */ rig2icom_mode(rig, mode, 0, (unsigned char *) &md, (signed char *) &pd); buff[5] = md; /* read echo'd chars only...there will be no ACK from this command * * Note: * It may have waited fro pltstate->usleep_time before reading the echo'd * chars, but the read will be blocking anyway. --SF * */ return icom_transaction(rig, C_CTL_MISC, S_OPTO_NXT, buff, 6, NULL, NULL); return RIG_OK; }
/* * optoscan_get_info * Assumes rig!=NULL, rig->state.priv!=NULL */ const char *optoscan_get_info(RIG *rig) { unsigned char ackbuf[16]; int ack_len, retval; static char info[64]; /* select LOCAL control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDID, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) return NULL; if (ack_len != 7) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_info: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return NULL; } sprintf(info, "OptoScan%c%c%c, software version %d.%d, " "interface version %d.%d\n", ackbuf[2], ackbuf[3], ackbuf[4], ackbuf[5] >> 4, ackbuf[5] & 0xf, ackbuf[6] >> 4, ackbuf[6] & 0xf); return info; }
/* * optoscan_close * Assumes rig!=NULL, rig->state.priv!=NULL */ int optoscan_close(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char ackbuf[16]; int ack_len, retval; rs = &rig->state; priv = (struct icom_priv_data *)rs->priv; /* select LOCAL control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_LOCAL, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) return retval; if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_close: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } free(priv->pltstate); return RIG_OK; }
/* * Assumes rig!=NULL, rig->state.priv!=NULL */ static int ic756pro2_set_ext_parm(RIG *rig, token_t token, value_t val) { unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len, ep_len, val_len; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ int icom_val = 0; int retval; ep_len = 0; /* 0 implies BCD data */ val_len = 1; switch(token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; icom_val = val.f; break; case TOK_MEMNAME: ep_sc = S_MEM_NAME; icom_val = val.i ? 1 : 0; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; /* TODO: check range this actually doesn't decode the input type 'string' */ icom_val = val.i; break; case TOK_MYCALL: /* max 10 ASCII char */ ep_len = strlen(val.cs); if (ep_len > 10) return -RIG_EINVAL; ep_sc = S_MEM_MYCALL; memcpy(epbuf, val.cs, ep_len); break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 = 250, 300, 350, 500, 1000 */ if (val.i < 0 || val.i > 4) return -RIG_EINVAL; ep_sc = S_MEM_RTTY_FL_PB; icom_val = val.i; break; default: return -RIG_EINVAL; } if (ep_len == 0) { to_bcd_be(epbuf, (long long)icom_val, val_len*2); ep_len += val_len; } retval = icom_transaction (rig, ep_cmd, ep_sc, epbuf, ep_len, ackbuf, &ack_len); if (retval != RIG_OK) return retval; if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __FUNCTION__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; }
/* * Assumes rig!=NULL, rig->state.priv!=NULL */ int optoscan_set_ext_parm(RIG *rig, token_t token, value_t val) { unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len; int retval, subcode; memset(epbuf, 0, MAXFRAMELEN); memset(ackbuf, 0, MAXFRAMELEN); switch (token) { case TOK_TAPECNTL: if (val.i == 0) { subcode = S_OPTO_TAPE_OFF; } else { subcode = S_OPTO_TAPE_ON; } break; case TOK_5KHZWIN: if (val.i == 0) { subcode = S_OPTO_5KSCOFF; } else { subcode = S_OPTO_5KSCON; } break; case TOK_SPEAKER: if (val.i == 0) { subcode = S_OPTO_SPKROFF; } else { subcode = S_OPTO_SPKRON; } break; default: return -RIG_EINVAL; } retval = icom_transaction(rig, C_CTL_MISC, subcode, epbuf, 0, ackbuf, &ack_len); if (retval != RIG_OK) return retval; if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __FUNCTION__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; }
/* * optoscan_set_level * Assumes rig!=NULL, rig->state.priv!=NULL */ int optoscan_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { unsigned char lvlbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int retval; memset(lvlbuf, 0, MAXFRAMELEN); /* * So far, levels of float type are in [0.0..1.0] range */ if (RIG_LEVEL_IS_FLOAT(level)) icom_val = val.f * 255; else icom_val = val.i; switch (level) { case RIG_LEVEL_AF: lvl_cn = C_CTL_MISC; if (icom_val == 0) { lvl_sc = S_OPTO_SPKROFF; } else { lvl_sc = S_OPTO_SPKRON; } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %d", level); return -RIG_EINVAL; } retval = icom_transaction(rig, lvl_cn, lvl_sc, lvlbuf, 0, ackbuf, &ack_len); if (retval != RIG_OK) return retval; if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_set_level: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; }
int optoscan_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { unsigned char dtmfbuf[MAXFRAMELEN], digit; int len, retval, digitpos; unsigned char xlate[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', '*', '#' }; digitpos = 0; do { retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDDTMF, NULL, 0, dtmfbuf, &len); if (retval != RIG_OK) return retval; if (len != 3) { rig_debug(RIG_DEBUG_ERR, "optoscan_recv_dtmf: ack NG (%#.2x), len=%d\n", dtmfbuf[0], len); return -RIG_ERJCTED; } digit = dtmfbuf[2]; if (digit < 0x16) { digits[digitpos] = xlate[digit]; digitpos++; } } while ((digit != 0x99) && (digitpos < *length)); *length = digitpos; digits[digitpos] = 0; if (*length > 0) { rig_debug(RIG_DEBUG_ERR, "optoscan_recv_dtmf: %d digits - %s\n", *length, digits); } else { rig_debug(RIG_DEBUG_ERR, "optoscan_recv_dtmf: no digits to read.\n"); } return RIG_OK; }
/* * optoscan_open * Assumes rig!=NULL, rig->state.priv!=NULL */ int optoscan_open(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; pltstate_t *pltstate; unsigned char ackbuf[16]; int ack_len, retval; rs = &rig->state; priv = (struct icom_priv_data *)rs->priv; pltstate = malloc(sizeof(pltstate_t)); if (!pltstate) { return -RIG_ENOMEM; } memset(pltstate, 0, sizeof(pltstate_t)); priv->pltstate = pltstate; /* select REMOTE control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_REMOTE, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { free(pltstate); return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_open: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); free(pltstate); return -RIG_ERJCTED; } return RIG_OK; }
/* * optoscan_get_dcs_code * Assumes rig!=NULL, rig->state.priv!=NULL */ int optoscan_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDDCS, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) return retval; if (tone_len != 4) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_dcs_code: ack NG (%#.2x), " "len=%d\n", tonebuf[0], tone_len); return -RIG_ERJCTED; } tone_len -= 2; *code = from_bcd_be(tonebuf + 2, tone_len * 2); rig_debug(RIG_DEBUG_ERR, "optoscan_get_dcs_code: *code=%d\n", *code); return RIG_OK; }
/* * Assumes rig!=NULL, status_block !=NULL */ static int optoscan_get_status_block(RIG *rig, struct optostat *status_block) { int retval, ack_len, expected_len; unsigned char ackbuf[MAXFRAMELEN]; memset(status_block, 0, sizeof(struct optostat)); retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDSTAT, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) return retval; switch (rig->caps->rig_model) { case RIG_MODEL_OS456: expected_len = 4; break; case RIG_MODEL_OS535: expected_len = 5; break; default: rig_debug(RIG_DEBUG_ERR, "optoscan_get_status_block: unknown rig model"); return -RIG_ERJCTED; break; } if (ack_len != expected_len) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_status_block: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } if (ackbuf[2] & 1) status_block->remote_control = 1; if (ackbuf[2] & 2) status_block->DTMF_pending = 1; if (ackbuf[2] & 4) status_block->DTMF_overrun = 1; if (ackbuf[2] & 16) status_block->squelch_open = 1; if (ackbuf[2] & 32) status_block->CTCSS_active = 1; if (ackbuf[2] & 64) status_block->DCS_active = 1; if (ackbuf[3] & 1) status_block->tape_enabled = 1; if (ackbuf[3] & 2) status_block->speaker_enabled = 1; if (ackbuf[3] & 4) status_block->fivekhz_enabled = 1; if (ackbuf[3] & 16) status_block->audio_present = 1; rig_debug(RIG_DEBUG_VERBOSE, "remote_control = %d\n", status_block->remote_control); rig_debug(RIG_DEBUG_VERBOSE, "DTMF_pending = %d\n", status_block->DTMF_pending); rig_debug(RIG_DEBUG_VERBOSE, "DTMF_overrun = %d\n", status_block->DTMF_overrun); rig_debug(RIG_DEBUG_VERBOSE, "squelch_open = %d\n", status_block->squelch_open); rig_debug(RIG_DEBUG_VERBOSE, "CTCSS_active = %d\n", status_block->CTCSS_active); rig_debug(RIG_DEBUG_VERBOSE, "DCS_active = %d\n", status_block->DCS_active); rig_debug(RIG_DEBUG_VERBOSE, "tape_enabled = %d\n", status_block->tape_enabled); rig_debug(RIG_DEBUG_VERBOSE, "speaker_enabled = %d\n", status_block->speaker_enabled); rig_debug(RIG_DEBUG_VERBOSE, "fivekhz_enabled = %d\n", status_block->fivekhz_enabled); rig_debug(RIG_DEBUG_VERBOSE, "audio_present = %d\n", status_block->audio_present); return RIG_OK; }
/* * optoscan_get_level * Assumes rig!=NULL, rig->state.priv!=NULL, val!=NULL */ int optoscan_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct optostat status_block; unsigned char lvlbuf[MAXFRAMELEN]; int lvl_len = 0; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int cmdhead; int retval; if (level != RIG_LEVEL_AF) { switch (level) { case RIG_LEVEL_RAWSTR: lvl_cn = C_RD_SQSM; lvl_sc = S_SML; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %d", level); return -RIG_EINVAL; } retval = icom_transaction(rig, lvl_cn, lvl_sc, NULL, 0, lvlbuf, &lvl_len); if (retval != RIG_OK) return retval; /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (lvl_sc == -1) ? 1 : 2; lvl_len -= cmdhead; if (lvlbuf[0] != ACK && lvlbuf[0] != lvl_cn) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_level: ack NG (%#.2x), " "len=%d\n", lvlbuf[0], lvl_len); return -RIG_ERJCTED; } /* * The result is a 3 digit BCD, but in *big endian* order: 0000..0255 * (from_bcd is little endian) */ icom_val = from_bcd_be(lvlbuf + cmdhead, lvl_len * 2); } else { /* level == RIG_LEVEL_AF */ retval = optoscan_get_status_block(rig, &status_block); if (retval != RIG_OK) return retval; icom_val = 0; if (status_block.speaker_enabled == 1) icom_val = 255; } switch (level) { case RIG_LEVEL_RAWSTR: val->i = icom_val; break; default: if (RIG_LEVEL_IS_FLOAT(level)) val->f = (float)icom_val / 255; else val->i = icom_val; } rig_debug(RIG_DEBUG_TRACE, "optoscan_get_level: %d %d %d %f\n", lvl_len, icom_val, val->i, val->f); return RIG_OK; }
/* * Assumes rig!=NULL, rig->state.priv!=NULL * and val points to a buffer big enough to hold the conf value. */ static int ic756pro2_get_ext_parm(RIG *rig, token_t token, value_t *val) { const struct confparams *cfp; unsigned char resbuf[MAXFRAMELEN]; int res_len, icom_val=0; int cmdhead; int retval; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ switch(token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; break; case TOK_MEMNAME: ep_sc = S_MEM_NAME; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; break; case TOK_MYCALL: /* max 10 ASCII char */ ep_sc = S_MEM_MYCALL; break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 */ ep_sc = S_MEM_RTTY_FL_PB; break; default: rig_debug(RIG_DEBUG_ERR,"Unsupported get_ext_parm %d", token); return -RIG_EINVAL; } retval = icom_transaction (rig, ep_cmd, ep_sc, NULL, 0, resbuf, &res_len); if (retval != RIG_OK) return retval; /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (ep_sc == -1) ? 1:S_MEM_SC_LEN + 1; res_len -= cmdhead; /* should echo cmd, subcmd and then data, if you get an ack something is wrong */ if (resbuf[0] != ep_cmd) { if (resbuf[0] == ACK) { rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " "len=%d\n", __FUNCTION__,resbuf[0],res_len); return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_ERR,"%s: ack NG (%#.2x), " "len=%d\n", __FUNCTION__,resbuf[0],res_len); return -RIG_ERJCTED; } } cfp = rig_ext_lookup_tok(rig, token); switch(cfp->type) { case RIG_CONF_STRING: memcpy(val->s, resbuf, res_len); break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: val->i = from_bcd_be(resbuf+cmdhead, res_len*2); break; case RIG_CONF_NUMERIC: val->f = from_bcd_be(resbuf+cmdhead, res_len*2); break; default: rig_debug(RIG_DEBUG_ERR,"%s: protocol error (%#.2x), " "len=%d\n", __FUNCTION__,resbuf[0],res_len); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE,"%s: %d %d %d %f\n", __FUNCTION__, res_len, icom_val, val->i, val->f); return RIG_OK; }