diff --git a/channels/chan_simpleusb.c b/channels/chan_simpleusb.c index fd0c5ad..df3f17d 100644 --- a/channels/chan_simpleusb.c +++ b/channels/chan_simpleusb.c @@ -153,6 +153,9 @@ enum { CD_IGNORE, CD_HID, CD_HID_INVERT, CD_PP, CD_PP_INVERT }; enum { SD_IGNORE, SD_HID, SD_HID_INVERT, SD_PP, SD_PP_INVERT }; // no,external,externalinvert,software enum { PAGER_NONE, PAGER_A, PAGER_B }; +/*! \brief type of signal detection used for carrier (cos) or ctcss */ +static const char * const signal_type[] = {"no", "usb", "usbinvert", "pp", "ppinvert"}; + /*! * \brief Descriptor for one of our channels. * There is one used for 'default' values (from the [general] entry in @@ -237,8 +240,8 @@ struct chan_simpleusb_pvt { int32_t destate; /* deemphasis state variable */ int32_t prestate; /* preemphasis state variable */ - char rxcdtype; - char rxsdtype; + int rxcdtype; + int rxsdtype; int rxoncnt; /* Counts the number of 20 ms intervals after RX activity */ int txoffcnt; /* Counts the number of 20 ms intervals after TX unkey */ @@ -294,10 +297,12 @@ struct chan_simpleusb_pvt { unsigned int wanteeprom:1; /* indicator if we should use EEPROM */ unsigned int usedtmf:1; /* indicator is we should decode DTMF */ unsigned int invertptt:1; /* indicator if we need to invert ptt */ - unsigned int rxboostset:1; /* indicator if receive boost is needed */ + unsigned int rxboost:1; /* indicator if receive boost is needed */ unsigned int plfilter:1; /* indicator if we need a pl filter */ unsigned int deemphasis:1; /* indicator if we need deemphasis filter */ unsigned int preemphasis:1; /* indicator if we need preemphasis filter */ + unsigned int rx_cos_active:1; /* indicator if cos is active - active state after processing */ + unsigned int rx_ctcss_active:1; /* indicator if ctcss is active - active state after processing */ /* EEPROM access variables */ unsigned short eeprom[EEPROM_USER_LEN]; @@ -2204,6 +2209,7 @@ static struct ast_frame *simpleusb_read(struct ast_channel *c) } else if (!cd) { o->rxoncnt = 0; } + o->rx_cos_active = cd; /* Check for SD - CTCSS active */ sd = 1; @@ -2221,6 +2227,7 @@ static struct ast_frame *simpleusb_read(struct ast_channel *c) if (o->rxctcssoverride) { sd = 1; } + o->rx_ctcss_active = sd; /* Timer for how long TX has been unkeyed - used with txoffdelay */ if (o->txoffdelay) { if (o->txkeyed == 1) { @@ -2673,7 +2680,7 @@ static int console_unkey(int fd, int argc, const char *const *argv) static int susb_active(int fd, int argc, const char *const *argv) { if (argc == 2) { - ast_cli(fd, "Active (command) Simple USB Radio device is [%s]\n", simpleusb_active); + ast_cli(fd, "Active Simple USB Radio device is [%s].\n", simpleusb_active); } else if (argc != 3) { return RESULT_SHOWUSAGE; } else { @@ -2697,67 +2704,6 @@ static int susb_active(int fd, int argc, const char *const *argv) return RESULT_SUCCESS; } -/*! - * \brief Process asterisk cli request for receiver deviation display. - * \param fd Asterisk cli fd - * \param o Private struct - * \return Cli success, showusage, or failure. - */ -static void tune_rxdisplay(int fd, struct chan_simpleusb_pvt *o) -{ - int j, waskeyed, meas, ncols = 75, wasverbose; - char str[256]; - - for (j = 0; j < ncols; j++) { - str[j] = ' '; - } - str[j] = 0; - ast_cli(fd, " %s \r", str); - ast_cli(fd, "RX VOICE DISPLAY:\n"); - ast_cli(fd, " v -- 3KHz v -- 5KHz\n"); - - o->measure_enabled = 1; - o->discfactor = 1000; - o->discounterl = o->discounteru = 0; - wasverbose = option_verbose; - option_verbose = 0; - - waskeyed = !o->rxkeyed; - for (;;) { - o->amax = o->amin = 0; - if (ast_radio_poll_input(fd, 100)) { - break; - } - if (o->rxkeyed != waskeyed) { - for (j = 0; j < ncols; j++) { - str[j] = ' '; - } - str[j] = 0; - ast_cli(fd, " %s \r", str); - } - waskeyed = o->rxkeyed; - if (!o->rxkeyed) { - ast_cli(fd, "\r"); - continue; - } - meas = o->apeak; - for (j = 0; j < ncols; j++) { - int thresh = (meas * ncols) / 16384; - if (j < thresh) { - str[j] = '='; - } else if (j == thresh) { - str[j] = '>'; - } else { - str[j] = ' '; - } - } - str[j] = 0; - ast_cli(fd, "|%s|\r", str); - } - o->measure_enabled = 0; - option_verbose = wasverbose; -} - /*! * \brief Process Asterisk CLI request to swap usb devices * \param fd Asterisk CLI fd @@ -2830,6 +2776,99 @@ static void tune_flash(int fd, struct chan_simpleusb_pvt *o, int intflag) } } +/*! + * \brief Process asterisk cli request for receiver deviation display. + * \param fd Asterisk cli fd + * \param o Private struct + * \return Cli success, showusage, or failure. + */ +static void tune_rxdisplay(int fd, struct chan_simpleusb_pvt *o) +{ + int j, waskeyed, meas, ncols = 75, wasverbose; + char str[256]; + + for (j = 0; j < ncols; j++) { + str[j] = ' '; + } + str[j] = 0; + ast_cli(fd, " %s \r", str); + ast_cli(fd, "RX VOICE DISPLAY:\n"); + ast_cli(fd, " v -- 3KHz v -- 5KHz\n"); + + o->measure_enabled = 1; + o->discfactor = 1000; + o->discounterl = o->discounteru = 0; + wasverbose = option_verbose; + option_verbose = 0; + + waskeyed = !o->rxkeyed; + for (;;) { + o->amax = o->amin = 0; + if (ast_radio_poll_input(fd, 100)) { + break; + } + if (o->rxkeyed != waskeyed) { + for (j = 0; j < ncols; j++) { + str[j] = ' '; + } + str[j] = 0; + ast_cli(fd, " %s \r", str); + } + waskeyed = o->rxkeyed; + if (!o->rxkeyed) { + ast_cli(fd, "\r"); + continue; + } + meas = o->apeak; + for (j = 0; j < ncols; j++) { + int thresh = (meas * ncols) / 16384; + if (j < thresh) { + str[j] = '='; + } else if (j == thresh) { + str[j] = '>'; + } else { + str[j] = ' '; + } + } + str[j] = 0; + ast_cli(fd, "|%s|\r", str); + } + o->measure_enabled = 0; + option_verbose = wasverbose; +} + +/*! + * \brief Process asterisk cli request for cos, ctcss, and ptt live display. + * \param fd Asterisk cli fd + * \param o Private struct + * \return Cli success, showusage, or failure. + */ +static void tune_rxtx_status(int fd, struct chan_simpleusb_pvt *o) +{ + int wasverbose; + + ast_cli(fd, "Receiver/Transmitter Status Display:\n"); + ast_cli(fd, " COS | CTCSS | COS | PTT\n"); + ast_cli(fd, " Input | Input | Out | Out\n"); + + wasverbose = option_verbose; + option_verbose = 0; + + for (;;) { + /* If they press any key, exit live display */ + if (ast_radio_poll_input(fd, 200)) { + break; + } + ast_cli(fd, " %s | %s | %s | %s\r", + o->rxcdtype ? (o->rx_cos_active ? "Keyed" : "Clear") : "Off ", + o->rxsdtype ? (o->rx_ctcss_active ? "Keyed" : "Clear") : "Off ", + o->rxkeyed ? "Keyed" : "Clear", + (o->txkeyed || o->txtestkey) ? "Keyed" : "Clear"); + } + + option_verbose = wasverbose; +} + /*! * \brief Process Asterisk CLI request susb tune. * \param fd Asterisk CLI fd @@ -3144,6 +3183,18 @@ static void tune_write(struct chan_simpleusb_pvt *o) } \ } +#define CONFIG_UPDATE_BOOL(field) \ + if (ast_variable_update(category, #field, o->field ? "true" : "false", NULL, 0)) { \ + ast_log(LOG_WARNING, "Failed to update %s\n", #field); \ + } + +#define CONFIG_UPDATE_SIGNAL(key, field) \ + if (ast_variable_update(category, #key, signal_type[o->field], NULL, 0)) { \ + ast_log(LOG_WARNING, "Failed to update %s\n", #field); \ + } + + + category = ast_category_get(cfg, o->name, NULL); if (!category) { ast_log(LOG_ERROR, "No category '%s' exists?\n", o->name); @@ -3152,6 +3203,15 @@ static void tune_write(struct chan_simpleusb_pvt *o) CONFIG_UPDATE_INT(rxmixerset); CONFIG_UPDATE_INT(txmixaset); CONFIG_UPDATE_INT(txmixbset); + CONFIG_UPDATE_BOOL(rxboost); + CONFIG_UPDATE_BOOL(preemphasis); + CONFIG_UPDATE_BOOL(deemphasis); + CONFIG_UPDATE_BOOL(plfilter); + CONFIG_UPDATE_BOOL(invertptt); + CONFIG_UPDATE_SIGNAL(carrierfrom, rxcdtype); + CONFIG_UPDATE_SIGNAL(ctcssfrom, rxsdtype); + CONFIG_UPDATE_INT(rxondelay); + CONFIG_UPDATE_INT(txoffdelay); if (ast_config_text_file_save2(CONFIG, cfg, "chan_simpleusb", 0)) { ast_log(LOG_WARNING, "Failed to save config\n"); } @@ -3160,6 +3220,8 @@ static void tune_write(struct chan_simpleusb_pvt *o) ast_config_destroy(cfg); #undef CONFIG_UPDATE_STR #undef CONFIG_UPDATE_INT +#undef CONFIG_UPDATE_BOOL +#undef CONFIG_UPDATE_SIGNAL if (o->wanteeprom) { ast_mutex_lock(&o->eepromlock); @@ -3179,6 +3241,32 @@ static void tune_write(struct chan_simpleusb_pvt *o) /*! * \brief Process tune menu commands. + * + * The following 'menu-support' commands are used: + * + * susb tune menusupport X - where X is one of the following: + * 0 - get current settings + * 1 - get node names that are configured in simpleusb.conf + * 2 - print parameters + * 3 - get node names that are configured in simpleusb.conf, except current device + * b - receiver tune display + * c - receive level + * f - txa level + * g - txb level + * j - save current settings for the selected node + * k - change echo mode + * l - generate test tone + * m - change rxboost + * n - change pre-emphasis + * o - change de-emphasis + * p - change plfilter + * q - change ptt keying mode + * r - change carrierfrom setting + * s - change ctcss from setting + * t - change rx on delay + * u - change tx off delay + * v - view cos, ctcss and ptt status + * * \param fd Asterisk CLI fd * \param o Private struct. * \param cmd Command to process. @@ -3192,7 +3280,10 @@ static void tune_menusupport(int fd, struct chan_simpleusb_pvt *o, const char *c option_verbose = 0; switch (cmd[0]) { case '0': /* return audio processing configuration */ - ast_cli(fd, "0,0,%d\n", o->echomode); + ast_cli(fd, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + o->txmixaset, o->txmixbset, o->echomode, o->rxboost, o->preemphasis, + o->deemphasis, o->plfilter, o->invertptt, o->rxcdtype, o->rxsdtype, + o->rxondelay, o->txoffdelay); break; case '1': /* return usb device name list */ for (x = 0, oy = simpleusb_default.next; oy && oy->name; oy = oy->next, x++) { @@ -3253,13 +3344,15 @@ static void tune_menusupport(int fd, struct chan_simpleusb_pvt *o, const char *c break; case 'k': /* change echo mode */ if (cmd[1]) { - if (cmd[1] > '0') + if (cmd[1] > '0') { o->echomode = 1; - else + } else { o->echomode = 0; + } ast_cli(fd, "Echo Mode changed to %s\n", (o->echomode) ? "Enabled" : "Disabled"); - } else + } else { ast_cli(fd, "Echo Mode is currently %s\n", (o->echomode) ? "Enabled" : "Disabled"); + } break; case 'l': /* send test tone */ if (!o->hasusb) { @@ -3268,6 +3361,105 @@ static void tune_menusupport(int fd, struct chan_simpleusb_pvt *o, const char *c } tune_flash(fd, o, 1); break; + case 'm': /* change rxboost */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->rxboost = 1; + } else { + o->rxboost = 0; + } + ast_cli(fd, "RxBoost changed to %s\n", (o->rxboost) ? "Enabled" : "Disabled"); + } else { + ast_cli(fd, "RxBoost is currently %s\n", (o->rxboost) ? "Enabled" : "Disabled"); + } + break; + case 'n': /* change pre-emphasis */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->preemphasis = 1; + } else { + o->preemphasis = 0; + } + ast_cli(fd, "Pre-emphasis changed to %s\n", (o->preemphasis) ? "Enabled" : "Disabled"); + } else { + ast_cli(fd, "Pre-emphasis is currently %s\n", (o->preemphasis) ? "Enabled" : "Disabled"); + } + break; + case 'o': /* change de-emphasis */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->deemphasis = 1; + } else { + o->deemphasis = 0; + } + ast_cli(fd, "De-emphasis changed to %s\n", (o->deemphasis) ? "Enabled" : "Disabled"); + } else { + ast_cli(fd, "De-emphasis is currently %s\n", (o->deemphasis) ? "Enabled" : "Disabled"); + } + break; + case 'p': /* change pl filter */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->plfilter = 1; + } else { + o->plfilter = 0; + } + ast_cli(fd, "PL Filter changed to %s\n", (o->plfilter) ? "Enabled" : "Disabled"); + } else { + ast_cli(fd, "PL Filter is currently %s\n", (o->plfilter) ? "Enabled" : "Disabled"); + } + break; + case 'q': /* change ptt mode */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->invertptt = 1; + } else { + o->invertptt = 0; + } + ast_cli(fd, "PTT mode changed to %s\n", (o->invertptt) ? "Open" : "Ground"); + } else { + ast_cli(fd, "PTT mode is currently %s\n", (o->plfilter) ? "Open" : "Ground"); + } + break; + case 'r': /* change carrier from */ + if (cmd[1]) { + o->rxcdtype = atoi(&cmd[1]); + ast_cli(fd, "Carrier From changed to %s\n", signal_type[o->rxcdtype]); + } else { + ast_cli(fd, "Carrier From is currently %s\n", signal_type[o->rxcdtype]); + } + break; + case 's': /* change ctcss from */ + if (cmd[1]) { + o->rxsdtype = atoi(&cmd[1]); + ast_cli(fd, "CTCSS From changed to %s\n", signal_type[o->rxsdtype]); + } else { + ast_cli(fd, "CTCSS From is currently %s\n", signal_type[o->rxsdtype]); + } + break; + case 't': /* change rx on delay */ + if (cmd[1]) { + o->rxondelay = atoi(&cmd[1]); + ast_cli(fd, "RX On Delay From changed to %d\n", o->rxondelay); + } else { + ast_cli(fd, "RX On Delay is currently %d\n", o->rxondelay); + } + break; + case 'u': /* change tx off delay */ + if (cmd[1]) { + o->txoffdelay = atoi(&cmd[1]); + ast_cli(fd, "TX Off Delay From changed to %d\n", o->txoffdelay); + } else { + ast_cli(fd, "TX Off Delay is currently %d\n", o->txoffdelay); + } + break; + case 'v': /* receiver/transmitter status display */ + if (!o->hasusb) { + ast_cli(fd, USB_UNASSIGNED_FMT, o->name, o->devstr); + break; + } + tune_rxtx_status(fd, o); + break; default: ast_cli(fd, "Invalid Command\n"); break; @@ -3373,7 +3565,7 @@ static void mixer_write(struct chan_simpleusb_pvt *o) mic_setting = o->rxmixerset * o->micmax / C119B_ADJUSTMENT; /* get interval step size */ f = C119B_ADJUSTMENT / (float) o->micmax; - o->rxboostset = 1; /*rxboost is always set for this device */ + o->rxboost = 1; /*rxboost is always set for this device */ break; default: mic_setting = o->rxmixerset * o->micmax / 1000; @@ -3381,7 +3573,7 @@ static void mixer_write(struct chan_simpleusb_pvt *o) f = 1000.0 / (float) o->micmax; } ast_radio_setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL, mic_setting, 0); - ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0); + ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboost, 0); ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_SW, 1, 0); /* set the received voice adjustment factor */ o->rxvoiceadj = 1.0 + (modff(((float) o->rxmixerset) / f, &f1) * .187962); @@ -3441,7 +3633,7 @@ static struct chan_simpleusb_pvt *store_config(const struct ast_config *cfg, con CV_BOOL("invertptt", o->invertptt); CV_F("carrierfrom", store_rxcdtype(o, (char *) v->value)); CV_F("ctcssfrom", store_rxsdtype(o, (char *) v->value)); - CV_BOOL("rxboost", o->rxboostset); + CV_BOOL("rxboost", o->rxboost); CV_UINT("hdwtype", o->hdwtype); CV_UINT("eeprom", o->wanteeprom); CV_UINT("rxondelay", o->rxondelay); diff --git a/channels/chan_usbradio.c b/channels/chan_usbradio.c index 7215660..08847fd 100644 --- a/channels/chan_usbradio.c +++ b/channels/chan_usbradio.c @@ -159,6 +159,16 @@ enum { RX_KEY_CARRIER, RX_KEY_CARRIER_CODE }; enum { TX_OUT_OFF, TX_OUT_VOICE, TX_OUT_LSD, TX_OUT_COMPOSITE, TX_OUT_AUX }; enum { TOC_NONE, TOC_PHASE, TOC_NOTONE }; +/*! \brief type of signal detection used for carrier (cd) or ctcss (sd) */ +static const char * const cd_signal_type[] = {"no", "dsp", "vox", "usb", "usbinvert", "pp", "ppinvert"}; +static const char * const sd_signal_type[] = {"no", "usb", "usbinvert", "dsp", "pp", "ppinvert"}; + +/*! \brief demodulation type */ +static const char * const demodulation_type[] = {"no", "speaker", "flat"}; + +/*! \brief mixer type */ +static const char * const mixer_type[] = {"no", "voice", "tone", "composite", "auxvoice"}; + /*! * \brief Descriptor for one of our channels. * There is one used for 'default' values (from the [general] entry in @@ -254,10 +264,10 @@ struct chan_usbradio_pvt { t_pmr_chan *pmrChan; - char rxdemod; + int rxdemod; float rxgain; - char rxcdtype; - char rxsdtype; + int rxcdtype; + int rxsdtype; int rxsquelchadj; /* this copy needs to be here for initialization */ int rxsqhyst; int rxsqvoxadj; @@ -266,8 +276,8 @@ struct chan_usbradio_pvt { char txtoctype; float txctcssgain; - char txmixa; - char txmixb; + int txmixa; + int txmixb; int rxlpf; int rxhpf; int txlpf; @@ -312,7 +322,7 @@ struct chan_usbradio_pvt { // end remote operation info int rxmixerset; - int txboostset; + int txboost; float rxvoiceadj; float rxctcssadj; int txmixaset; @@ -370,12 +380,14 @@ struct chan_usbradio_pvt { unsigned int wanteeprom:1; /* indicator if we should use EEPROM */ unsigned int usedtmf:1; /* indicator is we should decode DTMF */ unsigned int invertptt:1; /* indicator if we need to invert ptt */ - unsigned int rxboostset:1; /* indicator if receive boost is needed */ + unsigned int rxboost:1; /* indicator if receive boost is needed */ unsigned int rxcpusaver:1; /* indicator if receive cpu save is enabled */ unsigned int txcpusaver:1; /* indicator if transmit cpu save is enabled */ unsigned int txprelim:1; /* indicator if tx pre lim is enabled */ unsigned int txlimonly:1; /* indicator if tx lim only is enabled */ unsigned int rxctcssoverride:1; /* indicator if receive ctcss override is enabled */ + unsigned int rx_cos_active:1; /* indicator if cos is active - active state after processing */ + unsigned int rx_ctcss_active:1; /* indicator if ctcss is active - active state after processing */ /* EEPROM access variables */ unsigned short eeprom[EEPROM_USER_LEN]; @@ -1061,7 +1073,7 @@ static void *hidthread(void *arg) tChan.area = o->area; tChan.ukey = o->ukey; tChan.name = o->name; - tChan.b.txboost = o->txboostset; + tChan.b.txboost = o->txboost; tChan.fever = o->fever; o->pmrChan = createPmrChannel(&tChan, FRAME_SIZE); @@ -2162,6 +2174,7 @@ static struct ast_frame *usbradio_read(struct ast_channel *c) o->rxcarrierdetect = cd; ast_debug(3, "Channel %s: rxcarrierdetect = %i.\n", o->name, cd); } + o->rx_cos_active = cd; if (o->pmrChan->b.ctcssRxEnable && o->pmrChan->rxCtcss->decode != o->rxctcssdecode) { ast_debug(3, "Channel %s: rxctcssdecode = %i.\n", o->name, o->pmrChan->rxCtcss->decode); @@ -2220,6 +2233,7 @@ static struct ast_frame *usbradio_read(struct ast_channel *c) if (o->rxctcssoverride) { sd = 1; } + o->rx_ctcss_active = sd; /* Timer for how long TX has been unkeyed - used with txoffdelay */ if (o->txoffdelay) { if (o->txkeyed == 1) { @@ -2659,7 +2673,7 @@ static int console_unkey(int fd, int argc, const char *const *argv) static int radio_active(int fd, int argc, const char *const *argv) { if (argc == 2) { - ast_cli(fd, "Active (command) USB Radio device is [%s]\n", usbradio_active); + ast_cli(fd, "Active USB Radio device is [%s].\n", usbradio_active); } else if (argc != 3) { return RESULT_SHOWUSAGE; } else { @@ -3326,7 +3340,7 @@ static void tune_rxinput(int fd, struct chan_usbradio_pvt *o, int setsql, int in while (tries < maxtries) { ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL, setting, 0); - ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0); + ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboost, 0); if (ast_radio_wait_or_poll(fd, 100, intflag)) { o->pmrChan->b.tuning = 0; @@ -3441,7 +3455,7 @@ static void tune_rxinput(int fd, struct chan_usbradio_pvt *o, int setsql, int in * \param o Private struct * \return CLI success, showusage, or failure. */ -static void do_rxdisplay(int fd, struct chan_usbradio_pvt *o) +static void tune_rxdisplay(int fd, struct chan_usbradio_pvt *o) { int j, waskeyed, meas, ncols = 75; char str[256]; @@ -3499,6 +3513,39 @@ static void do_rxdisplay(int fd, struct chan_usbradio_pvt *o) o->pmrChan->spsMeasure->enabled = 0; } +/*! + * \brief Process asterisk cli request for cos, ctcss, and ptt live display. + * \param fd Asterisk cli fd + * \param o Private struct + * \return Cli success, showusage, or failure. + */ +static void tune_rxtx_status(int fd, struct chan_usbradio_pvt *o) +{ + int wasverbose; + + ast_cli(fd, "Receiver/Transmitter Status Display:\n"); + ast_cli(fd, " COS | CTCSS | COS | PTT\n"); + ast_cli(fd, " Input | Input | Out | Out\n"); + + wasverbose = option_verbose; + option_verbose = 0; + + for (;;) { + /* If they press any key, exit live display */ + if (ast_radio_poll_input(fd, 200)) { + break; + } + ast_cli(fd, " %s | %s | %s | %s\r", + o->rxcdtype ? (o->rx_cos_active ? "Keyed" : "Clear") : "Off ", + o->rxsdtype ? (o->rx_ctcss_active ? "Keyed" : "Clear") : "Off ", + o->rxkeyed ? "Keyed" : "Clear", + (o->txkeyed || o->txtestkey) ? "Keyed" : "Clear"); + } + + option_verbose = wasverbose; +} + + /*! * \brief Set received voice level. * \param fd Asterisk CLI fd. @@ -3539,7 +3586,7 @@ static void _menu_rxvoice(int fd, struct chan_usbradio_pvt *o, const char *str) adjustment = o->rxmixerset * o->micmax / C119B_ADJUSTMENT; /* get interval step size */ f = C119B_ADJUSTMENT / (float) o->micmax; - o->rxboostset = 1; /*rxboost is always set for this device */ + o->rxboost = 1; /*rxboost is always set for this device */ break; default: adjustment = o->rxmixerset * o->micmax / 1000; @@ -3547,7 +3594,7 @@ static void _menu_rxvoice(int fd, struct chan_usbradio_pvt *o, const char *str) f = 1000.0 / (float) o->micmax; } ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL, adjustment, 0); - ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0); + ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboost, 0); o->rxvoiceadj = 0.5 + (modff(((float) i) / f, &f1) * .093981); } *(o->pmrChan->prxVoiceAdjust) = o->rxvoiceadj * M_Q8; @@ -3806,6 +3853,37 @@ static void _menu_txtone(int fd, struct chan_usbradio_pvt *o, const char *cstr) /*! * \brief Process tune menu commands. + * + * susb tune menusupport X - where X is one of the following: + * 0 - get flatrx, ctcssenable, echomode + * 1 - get node names that are configured in simpleusb.conf + * 2 - print parameters + * 3 - get node names that are configured in simpleusb.conf, except current device + * a - receive rx level + * b - receiver tune display + * c - receive level + * d - receive ctcss level + * e - squelch level + * f - voice level + * g - aux level + * h - transmit a test tone + * i - tune receive level + * j - save current settings for the selected node + * k - change echo mode + * l - generate test tone + * m - change rxboost + * n - change txboost + * o - change carrier from + * p - change ctcss from + * q - change rx on delay + * r - change tx off delay + * s - change tx pre limiting + * t - change tx limiting only + * u - change rx demodulation + * v - view cos, ctcss and ptt status + * w - change tx mixer a + * x - change tx mixer b + * * \param fd Asterisk CLI fd * \param o Private struct. * \param cmd Command to process. @@ -3828,7 +3906,10 @@ static void tune_menusupport(int fd, struct chan_usbradio_pvt *o, const char *cm } switch (cmd[0]) { case '0': /* return audio processing configuration */ - ast_cli(fd, "%d,%d,%d\n", flatrx, txhasctcss, o->echomode); + ast_cli(fd, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + flatrx, txhasctcss, o->echomode, o->rxboost, o->txboost, + o->rxcdtype, o->rxsdtype, o->rxondelay, o->txoffdelay, + o->txprelim, o->txlimonly, o->rxdemod, o->txmixa, o->txmixb); break; case '1': /* return usb device name list */ for (x = 0, oy = usbradio_default.next; oy && oy->name; oy = oy->next, x++) { @@ -3867,7 +3948,7 @@ static void tune_menusupport(int fd, struct chan_usbradio_pvt *o, const char *cm ast_cli(fd, USB_UNASSIGNED_FMT, o->name, o->devstr); break; } - do_rxdisplay(fd, o); + tune_rxdisplay(fd, o); break; case 'c': /* set receive voice level */ if (!o->hasusb) { @@ -3924,13 +4005,15 @@ static void tune_menusupport(int fd, struct chan_usbradio_pvt *o, const char *cm break; case 'k': /* change echo mode */ if (cmd[1]) { - if (cmd[1] > '0') + if (cmd[1] > '0') { o->echomode = 1; - else + } else { o->echomode = 0; + } ast_cli(fd, "Echo Mode changed to %s\n", (o->echomode) ? "Enabled" : "Disabled"); - } else + } else { ast_cli(fd, "Echo Mode is currently %s\n", (o->echomode) ? "Enabled" : "Disabled"); + } break; case 'l': /* transmit test tone */ if (!o->hasusb) { @@ -3939,6 +4022,117 @@ static void tune_menusupport(int fd, struct chan_usbradio_pvt *o, const char *cm } tune_flash(fd, o, 1); break; + case 'm': /* change rxboost */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->rxboost = 1; + } else { + o->rxboost = 0; + } + ast_cli(fd, "RxBoost changed to %s\n", (o->rxboost) ? "Enabled" : "Disabled"); + } else { + ast_cli(fd, "RxBoost is currently %s\n", (o->rxboost) ? "Enabled" : "Disabled"); + } + break; + case 'n': /* change txboost */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->txboost = 1; + } else { + o->txboost = 0; + } + ast_cli(fd, "TxBoost changed to %s\n", (o->txboost) ? "Enabled" : "Disabled"); + } else { + ast_cli(fd, "TxBoost is currently %s\n", (o->txboost) ? "Enabled" : "Disabled"); + } + break; + case 'o': /* change carrier from */ + if (cmd[1]) { + o->rxcdtype = atoi(&cmd[1]); + ast_cli(fd, "Carrier From changed to %s\n", cd_signal_type[o->rxcdtype]); + } else { + ast_cli(fd, "Carrier From is currently %s\n", cd_signal_type[o->rxcdtype]); + } + break; + case 'p': /* change ctcss from */ + if (cmd[1]) { + o->rxsdtype = atoi(&cmd[1]); + ast_cli(fd, "CTCSS From changed to %s\n", sd_signal_type[o->rxsdtype]); + } else { + ast_cli(fd, "CTCSS From is currently %s\n", sd_signal_type[o->rxsdtype]); + } + break; + case 'q': /* change rx on delay */ + if (cmd[1]) { + o->rxondelay = atoi(&cmd[1]); + ast_cli(fd, "RX On Delay From changed to %d\n", o->rxondelay); + } else { + ast_cli(fd, "RX On Delay is currently %d\n", o->rxondelay); + } + break; + case 'r': /* change tx off delay */ + if (cmd[1]) { + o->txoffdelay = atoi(&cmd[1]); + ast_cli(fd, "TX Off Delay From changed to %d\n", o->txoffdelay); + } else { + ast_cli(fd, "TX Off Delay is currently %d\n", o->txoffdelay); + } + break; + case 's': /* change txprelim */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->txprelim = 1; + } else { + o->txprelim = 0; + } + ast_cli(fd, "TxPrelim changed to %s\n", (o->txprelim) ? "Enabled" : "Disabled"); + } else { + ast_cli(fd, "TxPrelim is currently %s\n", (o->txprelim) ? "Enabled" : "Disabled"); + } + break; + case 't': /* change txlimonly */ + if (cmd[1]) { + if (cmd[1] > '0') { + o->txlimonly = 1; + } else { + o->txlimonly = 0; + } + ast_cli(fd, "TxLimonly changed to %s\n", (o->txlimonly) ? "Enabled" : "Disabled"); + } else { + ast_cli(fd, "TxLimonly is currently %s\n", (o->txlimonly) ? "Enabled" : "Disabled"); + } + break; + case 'u': /* change rxdemod */ + if (cmd[1]) { + o->rxdemod = atoi(&cmd[1]); + ast_cli(fd, "RX Demodulation changed to %d\n", o->rxdemod); + } else { + ast_cli(fd, "RX Demodulation is currently %d\n", o->rxdemod); + } + break; + case 'v': /* receiver/transmitter status display */ + if (!o->hasusb) { + ast_cli(fd, USB_UNASSIGNED_FMT, o->name, o->devstr); + break; + } + tune_rxtx_status(fd, o); + break; + case 'w': /* change txmixa */ + if (cmd[1]) { + o->txmixa = atoi(&cmd[1]); + ast_cli(fd, "TX Mixer A changed to %d\n", o->txmixa); + } else { + ast_cli(fd, "TX Mixer A is currently %d\n", o->txmixa); + } + break; + case 'x': /* change txmixb */ + if (cmd[1]) { + o->txmixb = atoi(&cmd[1]); + ast_cli(fd, "TX Mixer B changed to %d\n", o->txmixb); + } else { + ast_cli(fd, "TX Mixer B is currently %d\n", o->txmixb); + } + break; default: ast_cli(fd, "Invalid Command\n"); break; @@ -4152,6 +4346,11 @@ static void tune_write(struct chan_usbradio_pvt *o) } \ } +#define CONFIG_UPDATE_BOOL(field) \ + if (ast_variable_update(category, #field, o->field ? "true" : "false", NULL, 0)) { \ + ast_log(LOG_WARNING, "Failed to update %s\n", #field); \ + } + #define CONFIG_UPDATE_FLOAT(field) { \ char _buf[15]; \ snprintf(_buf, sizeof(_buf), "%f", o->field); \ @@ -4159,6 +4358,12 @@ static void tune_write(struct chan_usbradio_pvt *o) ast_log(LOG_WARNING, "Failed to update %s\n", #field); \ } \ } + +#define CONFIG_UPDATE_SIGNAL(key, field, signal_type) \ + if (ast_variable_update(category, #key, signal_type[o->field], NULL, 0)) { \ + ast_log(LOG_WARNING, "Failed to update %s\n", #field); \ + } + category = ast_category_get(cfg, o->name, NULL); if (!category) { @@ -4173,6 +4378,17 @@ static void tune_write(struct chan_usbradio_pvt *o) CONFIG_UPDATE_INT(txctcssadj); CONFIG_UPDATE_INT(rxsquelchadj); CONFIG_UPDATE_INT(fever); + CONFIG_UPDATE_BOOL(rxboost); + CONFIG_UPDATE_BOOL(txboost); + CONFIG_UPDATE_SIGNAL(carrierfrom, rxcdtype, cd_signal_type); + CONFIG_UPDATE_SIGNAL(ctcssfrom, rxsdtype, sd_signal_type); + CONFIG_UPDATE_INT(rxondelay); + CONFIG_UPDATE_INT(txoffdelay); + CONFIG_UPDATE_BOOL(txprelim); + CONFIG_UPDATE_BOOL(txlimonly); + CONFIG_UPDATE_SIGNAL(rxdemod, rxdemod, demodulation_type); + CONFIG_UPDATE_SIGNAL(txmixa, txmixa, mixer_type); + CONFIG_UPDATE_SIGNAL(txmixb, txmixb, mixer_type); if (ast_config_text_file_save2(CONFIG, cfg, "chan_usbradio", 0)) { ast_log(LOG_WARNING, "Failed to save config\n"); } @@ -4181,7 +4397,9 @@ static void tune_write(struct chan_usbradio_pvt *o) ast_config_destroy(cfg); #undef CONFIG_UPDATE_STR #undef CONFIG_UPDATE_INT +#undef CONFIG_UPDATE_BOOL #undef CONFIG_UPDATE_FLOAT +#undef CONFIG_UPDATE_SIGNAL if (o->wanteeprom) { ast_mutex_lock(&o->eepromlock); @@ -4229,13 +4447,13 @@ static void mixer_write(struct chan_usbradio_pvt *o) switch (o->devtype) { case C119B_PRODUCT_ID: mic_setting = o->rxmixerset * o->micmax / C119B_ADJUSTMENT; - o->rxboostset = 1; /*rxboost is always set for this device */ + o->rxboost = 1; /*rxboost is always set for this device */ break; default: mic_setting = o->rxmixerset * o-> micmax / 1000; } ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL, mic_setting, 0); - ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0); + ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboost, 0); ast_radio_setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_SW, 1, 0); } @@ -4380,8 +4598,8 @@ static void pmrdump(struct chan_usbradio_pvt *o) pd(o->txtoctype); pd(o->rxmixerset); - pd(o->rxboostset); - pd(o->txboostset); + pd(o->rxboost); + pd(o->txboost); pf(o->rxvoiceadj); pf(o->rxctcssadj); @@ -4608,8 +4826,8 @@ static struct chan_usbradio_pvt *store_config(const struct ast_config *cfg, cons CV_UINT("rxfreq", o->rxfreq); CV_UINT("txfreq", o->txfreq); CV_F("rxgain", store_rxgain(o, (char *) v->value)); - CV_BOOL("rxboost", o->rxboostset); - CV_BOOL("txboost", o->txboostset); + CV_BOOL("rxboost", o->rxboost); + CV_BOOL("txboost", o->txboost); CV_UINT("rxctcssrelax", o->rxctcssrelax); CV_F("txtoctype", store_txtoctype(o, (char *) v->value)); CV_UINT("hdwtype", o->hdwtype); @@ -4756,7 +4974,7 @@ static struct chan_usbradio_pvt *store_config(const struct ast_config *cfg, cons tChan.b.lsdrxpolarity = o->lsdrxpolarity; tChan.b.lsdtxpolarity = o->lsdtxpolarity; - tChan.b.txboost = o->txboostset; + tChan.b.txboost = o->txboost; tChan.tracetype = o->tracetype; tChan.tracelevel = o->tracelevel; diff --git a/utils/radio-tune-menu.c b/utils/radio-tune-menu.c index b568205..6393ab2 100644 --- a/utils/radio-tune-menu.c +++ b/utils/radio-tune-menu.c @@ -26,10 +26,11 @@ * The following 'menu-support' commands are used: * * susb tune menusupport X - where X is one of the following: - * 0 - get echomode + * 0 - get current settings * 1 - get node names that are configured in simpleusb.conf * 2 - print parameters * 3 - get node names that are configured in simpleusb.conf, except current device + * a - receive rx level * b - receiver tune display * c - receive level * d - receive ctcss level @@ -41,8 +42,20 @@ * j - save current settings for the selected node * k - change echo mode * l - generate test tone + * m - change rxboost + * n - change txboost + * o - change carrier from + * p - change ctcss from + * q - change rx on delay + * r - change tx off delay + * s - change tx pre limiting + * t - change tx limiting only + * u - change rx demodulation + * v - view cos, ctcss and ptt status + * w - change tx mixer a + * x - change tx mixer b * - * Some of these commands take optional parameters to set values. + * Most of these commands take optional parameters to set values. * */ @@ -56,6 +69,19 @@ #include #include +/*! \brief type of signal detection used for carrier (cd) or ctcss (sd) */ +static const char * const cd_signal_type[] = {"no", "dsp", "vox", "usb", "usbinvert", "pp", "ppinvert"}; +static const char * const sd_signal_type[] = {"no", "usb", "usbinvert", "dsp", "pp", "ppinvert"}; + +/*! \brief demodulation type */ +static const char * const demodulation_type[] = {"no", "speaker", "flat"}; + +/*! \brief mixer type */ +static const char * const mixer_type[] = {"no", "voice", "tone", "composite", "auxvoice"}; + +/*! \brief command prefix for Asterisk - simpleusb channel driver access */ +#define COMMAND_PREFIX "radio " + /*! * \brief Signal handler * \param sig Signal to watch. @@ -67,7 +93,6 @@ static void ourhandler(int sig) signal(sig, ourhandler); while (waitpid(-1, &i, WNOHANG) > 0); - return; } /*! @@ -397,12 +422,12 @@ static int astgetresp(char *cmd) printf("\n"); /* print selected USB device */ - if (astgetresp("radio active")) { + if (astgetresp(COMMAND_PREFIX "active")) { return; } /* get device list from Asterisk */ - if (astgetline("radio tune menu-support 1", buf, sizeof(buf) - 1)) { + if (astgetline(COMMAND_PREFIX "tune menu-support 1", buf, sizeof(buf) - 1)) { exit(255); } n = explode_string(buf, strs, 100, ',', 0); @@ -439,10 +464,9 @@ static int astgetresp(char *cmd) printf("USB device not changed\n"); return; } - snprintf(str, sizeof(str) - 1, "radio active %s", strs[i - 1]); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "active %s", strs[i - 1]); astgetresp(str); - return; } /*! @@ -456,12 +480,12 @@ static void menu_swapusb(void) printf("\n"); /* print selected USB device */ - if (astgetresp("radio active")) { + if (astgetresp(COMMAND_PREFIX "active")) { return; } /* get device list from Asterisk */ - if (astgetline("radio tune menu-support 3", buf, sizeof(buf) - 1)) { + if (astgetline(COMMAND_PREFIX "tune menu-support 3", buf, sizeof(buf) - 1)) { exit(255); } n = explode_string(buf, strs, 100, ',', 0); @@ -497,10 +521,9 @@ static void menu_swapusb(void) printf("USB device not swapped\n"); return; } - snprintf(str, sizeof(str) - 1, "radio tune swap %s", strs[i - 1]); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune swap %s", strs[i - 1]); astgetresp(str); - return; } /*! @@ -512,10 +535,10 @@ static void menu_swapusb(void) char str[100]; for (;;) { - if (astgetresp("radio tune menu-support b")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support b")) { break; } - if (astgetresp("radio tune menu-support c")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support c")) { break; } @@ -540,13 +563,12 @@ static void menu_swapusb(void) printf("Entry Error, Rx voice setting not changed\n"); continue; } - sprintf(str, "radio tune menu-support c%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support c%d", i); if (astgetresp(str)) { break; } } - return; } /*! @@ -557,7 +579,7 @@ static void menu_swapusb(void) char str[100]; int i, x; - if (astgetresp("radio tune menu-support e")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support e")) { return; } @@ -582,21 +604,21 @@ static void menu_swapusb(void) printf("Entry Error, Rx Squelch Level setting not changed\n"); return; } - sprintf(str, "radio tune menu-support e%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support e%d", i); astgetresp(str); - return; } /*! * \brief Menu option to set txvoice level. + * \param keying Boolean to indicate if we are currently keying. */ static void menu_txvoice(int keying) { char str[100]; int i, x; - if (astgetresp("radio tune menu-support f")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support f")) { return; } @@ -604,7 +626,7 @@ static void menu_swapusb(void) if (fgets(str, sizeof(str) - 1, stdin) == NULL) { printf("Tx Voice Level setting not changed\n"); if (keying) { - astgetresp("radio tune menu-support fK"); + astgetresp(COMMAND_PREFIX "tune menu-support fK"); } return; } @@ -614,7 +636,7 @@ static void menu_swapusb(void) if (!str[0]) { printf("Tx Voice Level setting not changed\n"); if (keying) { - astgetresp("radio tune menu-support fK"); + astgetresp(COMMAND_PREFIX "tune menu-support fK"); } return; } @@ -628,13 +650,12 @@ static void menu_swapusb(void) return; } if (keying) { - sprintf(str, "radio tune menu-support fK%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support fK%d", i); } else { - sprintf(str, "radio tune menu-support f%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support f%d", i); } astgetresp(str); - return; } /*! @@ -645,7 +666,7 @@ static void menu_swapusb(void) char str[100]; int i, x; - if (astgetresp("radio tune menu-support g")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support g")) { return; } @@ -670,14 +691,14 @@ static void menu_swapusb(void) printf("Entry Error, Aux Voice Level setting not changed\n"); return; } - sprintf(str, "radio tune menu-support g%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support g%d", i); astgetresp(str); - return; } /*! * \brief Menu option to set txtone level. + * \param keying Boolean to indicate if we are currently keying. */ static void menu_txtone(int keying) @@ -685,7 +706,7 @@ static void menu_swapusb(void) char str[100]; int i, x; - if (astgetresp("radio tune menu-support h")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support h")) { return; } @@ -693,7 +714,7 @@ static void menu_swapusb(void) if (fgets(str, sizeof(str) - 1, stdin) == NULL) { printf("Tx CTCSS Modulation Level setting not changed\n"); if (keying) { - astgetresp("radio tune menu-support hK"); + astgetresp(COMMAND_PREFIX "tune menu-support hK"); } return; } @@ -703,7 +724,7 @@ static void menu_swapusb(void) if (!str[0]) { printf("Tx CTCSS Modulation Level setting not changed\n"); if (keying) { - astgetresp("radio tune menu-support hK"); + astgetresp(COMMAND_PREFIX "tune menu-support hK"); } return; } @@ -717,13 +738,232 @@ static void menu_swapusb(void) return; } if (keying) { - sprintf(str, "radio tune menu-support hK%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support hK%d", i); } else { - sprintf(str, "radio tune menu-support h%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support h%d", i); } astgetresp(str); - return; +} + +/*! + * \brief Menu option view cos, ctcss and ptt status. + */ + static void menu_view_status(void) + { + + astgetresp(COMMAND_PREFIX "tune menu-support v"); + +} + +/*! + * \brief Menu option to select list value. + * \param value_name Pointer to description of item being changed. + * \param items Pointer to array of options. + * \param max_items Number of items in the items array. + * \param selection Current selected item. + */ + static int menu_select_value(const char *value_name, const char * const *items, int max_items, int selection) +{ + char str[100]; + int i; + + printf("\nPlease select from the following methods for %s:\n", value_name); + + for (i = 0; i < max_items; i++) { + snprintf(str, sizeof(str) - 1, "%d) %s %s\n", i + 1, items[i], selection == i ? "- Current" : ""); + printf(str); + } + + printf("Select new %s or C/R for current): ", value_name); + if (fgets(str, sizeof(str) - 1, stdin) == NULL) { + printf("Method not changed\n"); + return 0; + } + if (str[0] && (str[strlen(str) - 1] == '\n')) { + str[strlen(str) - 1] = 0; + } + if (!str[0] || (str[0] < '1' || atoi(str) > max_items)) { + printf("Method not changed\n"); + return 0; + } + return atoi(str); +} + +/*! + * \brief Menu option to set delay value. + * \param delay_type Pointer to the description of the delay type. + * \param menu_option Pointer to the menusupport option to update. + * \param delay The current delay setting. + */ + static int menu_get_delay(const char *delay_type, const char *menu_option, int delay) +{ + char str[100]; + int value, x; + + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support %s", menu_option); + if (astgetresp(str)) { + return delay; + } + + printf("Enter new %s setting (0-999, or C/R for '%d'): ", delay_type, delay); + if (fgets(str, sizeof(str) - 1, stdin) == NULL) { + printf("Setting not changed\n"); + return delay; + } + if (str[0] && (str[strlen(str) - 1] == '\n')) { + str[strlen(str) - 1] = 0; + } + if (!str[0]) { + printf("Setting not changed\n"); + return delay; + } + for (x = 0; str[x]; x++) { + if (!isdigit(str[x])) { + break; + } + } + if (str[x] || (sscanf(str, "%d", &value) < 1) || (value < 0) || (value > 999)) { + printf("Entry Error, setting not changed\n"); + return delay; + } + + return value; +} + +/*! + * \brief Options menu. + */ +static void options_menu(void) +{ + int flatrx = 0, txhasctcss = 0, echomode = 0; + int rxboost = 0, txboost = 0, carrierfrom = 0, ctcssfrom = 0; + int rxondelay = 0, txoffdelay = 0, txprelim = 0, txlimonly = 0; + int rxdemod = 0, txmixa = 0, txmixb = 0; + int result; + char str[256]; + + for (;;) { + + /* get device parameters from Asterisk */ + if (astgetline(COMMAND_PREFIX "tune menu-support 0", str, sizeof(str) - 1)) { + return; + } + if (sscanf(str, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + &flatrx, &txhasctcss, &echomode, &rxboost, &txboost, + &carrierfrom, &ctcssfrom, &rxondelay, &txoffdelay, + &txprelim, & txlimonly, &rxdemod, &txmixa, &txmixb) != 14) { + fprintf(stderr, "Error parsing device parameters: %s\n", str); + return; + } + + printf("\nOptions Menu\n"); + printf("1) Toggle RX Boost (currently '%s')\n", rxboost ? "enabled" : "disabled"); + printf("2) Toggle TX Boost (currently '%s')\n", txboost ? "enabled" : "disabled"); + printf("3) Change RX Demodulation (currently '%s')\n", demodulation_type[rxdemod]); + printf("4) Change RX On Delay (currently '%d')\n", rxondelay); + printf("5) Change TX Off Delay (currently '%d')\n", txoffdelay); + printf("6) Toggle TX Prelimiting (currently '%s')\n", rxboost ? "enabled" : "disabled"); + printf("7) Toggle TX Limiting Only (currently '%s')\n", txboost ? "enabled" : "disabled"); + printf("8) Change TX Mixer A (currently '%s')\n", mixer_type[txmixa]); + printf("9) Change Tx Mixer B (currently '%s')\n", mixer_type[txmixb]); + printf("0) Exit Menu\n"); + printf("\nPlease enter your selection now: "); + + if (fgets(str, sizeof(str) - 1, stdin) == NULL) { + break; + } + if (strlen(str) != 2) { /* it's 2 because of \n at end */ + printf("Invalid Entry, try again\n"); + continue; + } + + /* if to exit */ + if (str[0] == '0') { + break; + } + + switch (str[0]) { + case '1': /* toggle rxboost */ + if (rxboost) { + if (astgetresp(COMMAND_PREFIX "tune menu-support m0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support m1")) { + exit(255); + } + } + break; + case '2': /* toggle txboost */ + if (txboost) { + if (astgetresp(COMMAND_PREFIX "tune menu-support n0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support n1")) { + exit(255); + } + } + break; + case '3': /* select rx demodulation */ + result = menu_select_value("RX Demodulation", demodulation_type, 3, rxdemod); + if (result > 0) { + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support u%d", result - 1); + astgetresp(str); + } + break; + case '4': /* set rx on delay */ + result = menu_get_delay("RX On Delay", "q", rxondelay); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support q%d", result); + astgetresp(str); + break; + case '5': /* set tx off delay */ + result = menu_get_delay("TX Off Delay", "r", txoffdelay); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support r%d", result); + astgetresp(str); + break; + case '6': /* toggle txprelim */ + if (txprelim) { + if (astgetresp(COMMAND_PREFIX "tune menu-support s0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support s1")) { + exit(255); + } + } + break; + case '7': /* toggle txlimonly */ + if (txlimonly) { + if (astgetresp(COMMAND_PREFIX "tune menu-support t0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support t1")) { + exit(255); + } + } + break; + case '8': /* select tx mixer a */ + result = menu_select_value("TX Mixer A", mixer_type, 5, txmixa); + if (result > 0) { + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support w%d", result - 1); + astgetresp(str); + } + break; + case '9': /* select tx mixer b */ + result = menu_select_value("TX Mixer B", mixer_type, 5, txmixb); + if (result > 0) { + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support x%d", result - 1); + astgetresp(str); + } + break; + default: + printf("Invalid Entry, try again\n"); + break; + } + } } /*! @@ -732,27 +972,36 @@ static void menu_swapusb(void) int main(int argc, char *argv[]) { int flatrx = 0, txhasctcss = 0, keying = 0, echomode = 0; + int rxboost = 0, txboost = 0, carrierfrom = 0, ctcssfrom = 0; + int rxondelay = 0, txoffdelay = 0, txprelim = 0, txlimonly = 0; + int rxdemod = 0, txmixa = 0, txmixb = 0; char str[256]; + int result; signal(SIGCHLD, ourhandler); for (;;) { /* get device parameters from Asterisk */ - if (astgetline("radio tune menu-support 0", str, sizeof(str) - 1)) { + if (astgetline(COMMAND_PREFIX "tune menu-support 0", str, sizeof(str) - 1)) { + printf("The setup information for chan_usbradio could not be retrieved!\n\n"); + printf("Verify that Asterisk is running and chan_usbradio is loaded.\n\n"); exit(255); } - if (sscanf(str, "%d,%d,%d", &flatrx, &txhasctcss, &echomode) != 3) { - fprintf(stderr, "Error parsing device parameters\n"); + if (sscanf(str, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + &flatrx, &txhasctcss, &echomode, &rxboost, &txboost, + &carrierfrom, &ctcssfrom, &rxondelay, &txoffdelay, + &txprelim, & txlimonly, &rxdemod, &txmixa, &txmixb) != 14) { + fprintf(stderr, "Error parsing device parameters: %s\n", str); exit(255); } printf("\n"); - /* print selected USB device */ - if (astgetresp("radio active")) { + /* print selected USB device at the top of our menu*/ + if (astgetresp(COMMAND_PREFIX "active")) { break; } - printf("1) Select USB device\n"); + printf("1) Select active USB device\n"); if (flatrx) { printf("2) Auto-Detect Rx Noise Level Value (with no carrier)\n"); } else { @@ -789,11 +1038,15 @@ static void menu_swapusb(void) } else { printf("9) Does not apply to this USB device configuration\n"); } - printf("E) Toggle Echo Mode (currently %s)\n", (echomode) ? "Enabled" : "Disabled"); + printf("E) Toggle Echo Mode (currently '%s')\n", (echomode) ? "enabled" : "disabled"); printf("F) Flash (Toggle PTT and Tone output several times)\n"); + printf("G) Change Carrier From (currently '%s')\n", cd_signal_type[carrierfrom]); + printf("H) Change CTCSS From (currently '%s')\n", sd_signal_type[ctcssfrom]); printf("P) Print Current Parameter Values\n"); + printf("O) Options Menu\n"); printf("S) Swap Current USB device with another USB device\n"); - printf("T) Toggle Transmit Test Tone/Keying (currently %s)\n", (keying) ? "Enabled" : "Disabled"); + printf("T) Toggle Transmit Test Tone/Keying (currently '%s')\n", (keying) ? "enabled" : "disabled"); + printf("V) View COS, CTCSS and PTT Status\n"); printf("W) Write (Save) Current Parameter Values\n"); printf("0) Exit Menu\n"); printf("\nPlease enter your selection now: "); @@ -812,93 +1065,117 @@ static void menu_swapusb(void) } switch (str[0]) { - case '1': + case '1': /* select active usb device */ menu_selectusb(); - break; + break; /* select flatrx */ case '2': if (!flatrx) { break; } - if (astgetresp("radio tune menu-support a")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support a")) { exit(255); } break; - case '3': + case '3': /* set receive level using display */ menu_rxvoice(); break; - case '4': + case '4': /* set ctcss level */ if (!flatrx) { break; } - if (astgetresp("radio tune menu-support d")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support d")) { exit(255); } break; - case '5': + case '5': /* set squelch level */ if (!flatrx) { break; } menu_rxsquelch(); break; - case '6': + case '6': /* set tx level */ menu_txvoice(keying); break; - case '7': + case '7': /* set aux level */ menu_auxvoice(); break; - case '8': + case '8': /* set ctcss level */ if (!txhasctcss) { break; } menu_txtone(keying); break; - case '9': + case '9': /* set auto detect rx voice level */ if (!flatrx) { break; } - if (astgetresp("radio tune menu-support i")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support i")) { exit(255); } break; - case 'e': + case 'e': /* toggle echo mode */ case 'E': if (echomode) { - if (astgetresp("radio tune menu-support k0")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support k0")) { exit(255); } } else { - if (astgetresp("radio tune menu-support k1")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support k1")) { exit(255); } } break; - case 'f': + case 'f': /* flash - toggle ptt and tone */ case 'F': - if (astgetresp("radio tune menu-support l")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support l")) { exit(255); } break; - case 'p': + case 'g': /* select carrier from */ + case 'G': + result = menu_select_value("Carrier From", cd_signal_type, 7, carrierfrom); + if (result > 0) { + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support o%d", result - 1); + astgetresp(str); + } + break; + case 'h': /* select ctcss from */ + case 'H': + result = menu_select_value("CTCSS From", sd_signal_type, 6, ctcssfrom); + if (result > 0) { + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support p%d", result - 1); + astgetresp(str); + } + break; + case 'o': /* options menu */ + case 'O': + options_menu(); + break; + case 'p': /* print current values */ case 'P': - if (astgetresp("radio tune menu-support 2")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support 2")) { exit(255); } break; - case 's': + case 's': /* swap usb device with another device */ case 'S': menu_swapusb(); break; - case 'w': - case 'W': - if (astgetresp("radio tune menu-support j")) { - exit(255); - } - break; - case 't': + case 't': /* toggle test tone */ case 'T': keying = !keying; printf("Transmit Test Tone/Keying is now %s\n", (keying) ? "Enabled" : "Disabled"); break; + case 'v': /* view cos, ctcss, and ptt status - live */ + case 'V': + menu_view_status(); + break; + case 'w': /* write settings to configuration file */ + case 'W': + if (astgetresp(COMMAND_PREFIX "tune menu-support j")) { + exit(255); + } + break; default: printf("Invalid Entry, try again\n"); break; diff --git a/utils/simpleusb-tune-menu.c b/utils/simpleusb-tune-menu.c index a508fb9..8b70ab3 100644 --- a/utils/simpleusb-tune-menu.c +++ b/utils/simpleusb-tune-menu.c @@ -26,7 +26,7 @@ * The following 'menu-support' commands are used: * * susb tune menusupport X - where X is one of the following: - * 0 - get echomode + * 0 - get current settings * 1 - get node names that are configured in simpleusb.conf * 2 - print parameters * 3 - get node names that are configured in simpleusb.conf, except current device @@ -37,8 +37,18 @@ * j - save current settings for the selected node * k - change echo mode * l - generate test tone + * m - change rxboost + * n - change pre-emphasis + * o - change de-emphasis + * p - change plfilter + * q - change ptt keying mode + * r - change carrierfrom setting + * s - change ctcss from setting + * t - change rx on delay + * u - change tx off delay + * v - view cos, ctcss and ptt status * - * Some of these commands take optional parameters to set values. + * Most of these commands take optional parameters to set values. * */ @@ -52,6 +62,12 @@ #include #include +/*! \brief type of signal detection used for carrier (cos) or ctcss */ +static const char * const signal_type[] = {"no", "usb", "usbinvert", "pp", "ppinvert"}; + +/*! \brief command prefix for Asterisk - simpleusb channel driver access */ +#define COMMAND_PREFIX "susb " + /*! * \brief Signal handler * \param sig Signal to watch. @@ -63,7 +79,6 @@ static void ourhandler(int sig) signal(sig, ourhandler); while (waitpid(-1, &i, WNOHANG) > 0); - return; } /*! @@ -392,12 +407,12 @@ static int astgetresp(char *cmd) printf("\n"); /* print selected USB device */ - if (astgetresp("susb active")) { + if (astgetresp(COMMAND_PREFIX "active")) { return; } /* get device list from Asterisk */ - if (astgetline("susb tune menu-support 1", buf, sizeof(buf) - 1)) { + if (astgetline(COMMAND_PREFIX "tune menu-support 1", buf, sizeof(buf) - 1)) { exit(255); } n = explode_string(buf, strs, 100, ',', 0); @@ -434,10 +449,9 @@ static int astgetresp(char *cmd) printf("USB device not changed\n"); return; } - snprintf(str, sizeof(str) - 1, "susb active %s", strs[i - 1]); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "active %s", strs[i - 1]); astgetresp(str); - return; } /*! @@ -451,12 +465,12 @@ static int astgetresp(char *cmd) printf("\n"); /* print selected USB device */ - if (astgetresp("susb active")) { + if (astgetresp(COMMAND_PREFIX "active")) { return; } /* get device list from Asterisk */ - if (astgetline("susb tune menu-support 3", buf, sizeof(buf) - 1)) { + if (astgetline(COMMAND_PREFIX "tune menu-support 3", buf, sizeof(buf) - 1)) { exit(255); } n = explode_string(buf, strs, 100, ',', 0); @@ -492,10 +506,9 @@ static int astgetresp(char *cmd) printf("USB device not swapped\n"); return; } - snprintf(str, sizeof(str) - 1, "susb tune swap %s", strs[i - 1]); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune swap %s", strs[i - 1]); astgetresp(str); - return; } /*! @@ -507,10 +520,10 @@ static int astgetresp(char *cmd) char str[100]; for (;;) { - if (astgetresp("susb tune menu-support b")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support b")) { break; } - if (astgetresp("susb tune menu-support c")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support c")) { break; } @@ -535,25 +548,25 @@ static int astgetresp(char *cmd) printf("Entry Error, Rx voice setting not changed\n"); continue; } - sprintf(str, "susb tune menu-support c%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support c%d", i); if (astgetresp(str)) { break; } } - return; } /*! * \brief Menu option to set txa level. + * \param keying Boolean to indicate if we are currently keying. */ static void menu_txa(int keying) { char str[100]; int i, x; - if (astgetresp("susb tune menu-support f")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support f")) { return; } @@ -561,7 +574,7 @@ static int astgetresp(char *cmd) if (fgets(str, sizeof(str) - 1, stdin) == NULL) { printf("Tx A Level setting not changed\n"); if (keying) { - astgetresp("susb tune menu-support fK"); + astgetresp(COMMAND_PREFIX "tune menu-support fK"); } return; } @@ -571,7 +584,7 @@ static int astgetresp(char *cmd) if (!str[0]) { printf("Tx A Level setting not changed\n"); if (keying) { - astgetresp("susb tune menu-support fK"); + astgetresp(COMMAND_PREFIX "tune menu-support fK"); } return; } @@ -585,24 +598,24 @@ static int astgetresp(char *cmd) return; } if (keying) { - sprintf(str, "susb tune menu-support fK%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support fK%d", i); } else { - sprintf(str, "susb tune menu-support f%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support f%d", i); } astgetresp(str); - return; } /*! * \brief Menu option to set txb level. - */ + * \param keying Boolean to indicate if we are currently keying. +*/ static void menu_txb(int keying) { char str[100]; int i, x; - if (astgetresp("susb tune menu-support g")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support g")) { return; } @@ -610,7 +623,7 @@ static int astgetresp(char *cmd) if (fgets(str, sizeof(str) - 1, stdin) == NULL) { printf("Tx B Level setting not changed\n"); if (keying) { - astgetresp("susb tune menu-support gK"); + astgetresp(COMMAND_PREFIX "tune menu-support gK"); } return; } @@ -620,7 +633,7 @@ static int astgetresp(char *cmd) if (!str[0]) { printf("Tx B Level setting not changed\n"); if (keying) { - astgetresp("susb tune menu-support gK"); + astgetresp(COMMAND_PREFIX "tune menu-support gK"); } return; } @@ -634,13 +647,94 @@ static int astgetresp(char *cmd) return; } if (keying) { - sprintf(str, "susb tune menu-support gK%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support gK%d", i); } else { - sprintf(str, "susb tune menu-support g%d", i); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support g%d", i); } astgetresp(str); - return; +} + +/*! + * \brief Menu option to select signal type. + * \param signal Pointer to signal description. + * \param selection Current signal selection. + */ + static int menu_signal_type(const char *signal, int selection) +{ + char str[100]; + + printf("\nPlease select from the following methods for %s:\n", signal); + printf("1) no %s\n", selection == 0 ? "- Current" : ""); + printf("2) usb %s\n", selection == 1 ? "- Current" : ""); + printf("3) usbinvert %s\n", selection == 2 ? "- Current" : ""); + printf("4) pp %s\n", selection == 3 ? "- Current" : ""); + printf("5) ppinvert %s\n", selection == 4 ? "- Current" : ""); + + printf("Select new %s or C/R for current): ", signal); + if (fgets(str, sizeof(str) - 1, stdin) == NULL) { + printf("Method not changed\n"); + return 0; + } + if (str[0] && (str[strlen(str) - 1] == '\n')) { + str[strlen(str) - 1] = 0; + } + if (!str[0] || (str[0] < '1' || str[0] > '5') || strlen(str) > 1) { + printf("Method not changed\n"); + return 0; + } + return atoi(str); +} + +/*! + * \brief Menu option to set delay value. + * \param delay_type Pointer to the description of the delay type. + * \param menu_option Pointer to the menusupport option to update. + * \param delay The current delay setting. + */ + static int menu_get_delay(const char *delay_type, const char *menu_option, int delay) +{ + char str[100]; + int value, x; + + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support %s", menu_option); + if (astgetresp(str)) { + return delay; + } + + printf("Enter new %s setting (0-999, or C/R for '%d'): ", delay_type, delay); + if (fgets(str, sizeof(str) - 1, stdin) == NULL) { + printf("Setting not changed\n"); + return delay; + } + if (str[0] && (str[strlen(str) - 1] == '\n')) { + str[strlen(str) - 1] = 0; + } + if (!str[0]) { + printf("Setting not changed\n"); + return delay; + } + for (x = 0; str[x]; x++) { + if (!isdigit(str[x])) { + break; + } + } + if (str[x] || (sscanf(str, "%d", &value) < 1) || (value < 0) || (value > 999)) { + printf("Entry Error, setting not changed\n"); + return delay; + } + + return value; +} + +/*! + * \brief Menu option view cos, ctcss and ptt status. + */ + static void menu_view_status(void) + { + + astgetresp(COMMAND_PREFIX "tune menu-support v"); + } /*! @@ -648,7 +742,11 @@ static int astgetresp(char *cmd) */ int main(int argc, char *argv[]) { - int flatrx = 0, txhasctcss = 0, keying = 0, echomode = 0; + int txmixaset = 0, txmixbset = 0, keying = 0, echomode = 0; + int rxboost = 0, preemphasis = 0, deemphasis = 0; + int plfilter = 0, pttmode = 0, carrierfrom = 0, ctcssfrom = 0; + int rxondelay = 0, txoffdelay = 0; + int result; char str[256]; signal(SIGCHLD, ourhandler); @@ -656,37 +754,51 @@ static int astgetresp(char *cmd) for (;;) { /* get device parameters from Asterisk */ - if (astgetline("susb tune menu-support 0", str, sizeof(str) - 1)) { + if (astgetline(COMMAND_PREFIX "tune menu-support 0", str, sizeof(str) - 1)) { + printf("The setup information for chan_simpleusb could not be retrieved!\n\n"); + printf("Verify that Asterisk is running and chan_simpleusb is loaded.\n\n"); exit(255); } - if (sscanf(str, "%d,%d,%d", &flatrx, &txhasctcss, &echomode) != 3) { - fprintf(stderr, "Error parsing device parameters\n"); + if (sscanf(str, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + &txmixaset, &txmixbset, &echomode, &rxboost, &preemphasis, &deemphasis, + &plfilter, &pttmode, &carrierfrom, &ctcssfrom, &rxondelay, &txoffdelay) != 12) { + fprintf(stderr, "Error parsing device parameters: %s\n", str); exit(255); } printf("\n"); - /* print selected USB device */ - if (astgetresp("susb active")) { + /* print selected USB device at the top of our menu*/ + if (astgetresp(COMMAND_PREFIX "active")) { break; } - printf("1) Select USB device\n"); + printf("1) Select active USB device\n"); printf("2) Set Rx Voice Level (using display)\n"); if (keying) { - printf("3) Set Transmit A Level and send test tone\n"); + printf("3) Set Transmit A Level (currently '%d') and send test tone\n", txmixaset); } else { - printf("3) Set Transmit A Level\n"); + printf("3) Set Transmit A Level (currently '%d')\n", txmixaset); } if (keying) { - printf("4) Set Transmit B Level and send test tone\n"); + printf("4) Set Transmit B Level (currently '%d') and send test tone\n", txmixbset); } else { - printf("4) Set Transmit B Level\n"); + printf("4) Set Transmit B Level (currently '%d')\n", txmixbset); } - printf("E) Toggle Echo Mode (currently %s)\n", (echomode) ? "Enabled" : "Disabled"); + printf("B) Toggle RX Boost (currently '%s')\n", rxboost ? "enabled" : "disabled"); + printf("C) Toggle Pre-emphasis (currently '%s')\n", preemphasis ? "enabled" : "disabled"); + printf("D) Toggle De-emphasis (currently '%s')\n", deemphasis ? "enabled" : "disabled"); + printf("E) Toggle Echo Mode (currently '%s')\n", echomode ? "enabled" : "disabled"); printf("F) Flash (Toggle PTT and Tone output several times)\n"); + printf("G) Toggle PL Filter (currently '%s')\n", plfilter ? "enabled" : "disabled"); + printf("H) Toggle PTT mode (currently '%s')\n", pttmode ? "open" : "ground"); + printf("I) Change Carrier From (currently '%s')\n", signal_type[carrierfrom]); + printf("J) Change CTCSS From (currently '%s')\n", signal_type[ctcssfrom]); + printf("K) Change RX On Delay (currently '%d')\n", rxondelay); + printf("L) Change TX Off Delay (currently '%d')\n", txoffdelay); printf("P) Print Current Parameter Values\n"); printf("S) Swap Current USB device with another USB device\n"); - printf("T) Toggle Transmit Test Tone/Keying (currently %s)\n", (keying) ? "Enabled" : "Disabled"); + printf("T) Toggle Transmit Test Tone/Keying (currently '%s')\n", keying ? "enabled" : "disabled"); + printf("V) View COS, CTCSS and PTT Status\n"); printf("W) Write (Save) Current Parameter Values\n"); printf("0) Exit Menu\n"); printf("\nPlease enter your selection now: "); @@ -705,57 +817,149 @@ static int astgetresp(char *cmd) } switch (str[0]) { - case '1': + case '1': /* select active usb device */ menu_selectusb(); break; - case '2': + case '2': /* set receive level using display */ menu_rxvoice(); break; - case '3': + case '3': /* set transmit level a */ menu_txa(keying); break; - case '4': + case '4': /* set transmit level b */ menu_txb(keying); break; - case 'e': + case 'b': /* toggle rxboost */ + case 'B': + if (rxboost) { + if (astgetresp(COMMAND_PREFIX "tune menu-support m0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support m1")) { + exit(255); + } + } + break; + case 'c': /* toggle pre-emphasis */ + case 'C': + if (preemphasis) { + if (astgetresp(COMMAND_PREFIX "tune menu-support n0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support n1")) { + exit(255); + } + } + break; + case 'd': /* toggle de-emphasis */ + case 'D': + if (deemphasis) { + if (astgetresp(COMMAND_PREFIX "tune menu-support o0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support o1")) { + exit(255); + } + } + break; + case 'e': /* toggle echo mode */ case 'E': if (echomode) { - if (astgetresp("susb tune menu-support k0")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support k0")) { exit(255); } } else { - if (astgetresp("susb tune menu-support k1")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support k1")) { exit(255); } } break; - case 'f': + case 'f': /* flash - toggle ptt and tone */ case 'F': - if (astgetresp("susb tune menu-support l")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support l")) { exit(255); } break; - case 'p': + case 'g': /* toggle pl filter */ + case 'G': + if (plfilter) { + if (astgetresp(COMMAND_PREFIX "tune menu-support p0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support p1")) { + exit(255); + } + } + break; + case 'h': /* toggle ptt mode */ + case 'H': + if (pttmode) { + if (astgetresp(COMMAND_PREFIX "tune menu-support q0")) { + exit(255); + } + } else { + if (astgetresp(COMMAND_PREFIX "tune menu-support q1")) { + exit(255); + } + } + break; + case 'i': /* select carrier from */ + case 'I': + result = menu_signal_type("Carrier From", carrierfrom); + if (result > 0) { + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support r%d", result - 1); + astgetresp(str); + } + break; + case 'j': /* select ctcss from */ + case 'J': + result = menu_signal_type("CTCSS From", ctcssfrom); + if (result > 0) { + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support s%d", result - 1); + astgetresp(str); + } + break; + case 'k': /* set rx on delay */ + case 'K': + result = menu_get_delay("RX On Delay", "t", rxondelay); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support t%d", result); + astgetresp(str); + break; + case 'l': /* set tx off delay */ + case 'L': + result = menu_get_delay("TX Off Delay", "u", txoffdelay); + snprintf(str, sizeof(str) - 1, COMMAND_PREFIX "tune menu-support u%d", result); + astgetresp(str); + break; + case 'p': /* print current values */ case 'P': - if (astgetresp("susb tune menu-support 2")) { + if (astgetresp(COMMAND_PREFIX "tune menu-support 2")) { exit(255); } break; - case 's': + case 's': /* swap usb device with another device */ case 'S': menu_swapusb(); break; - case 'w': - case 'W': - if (astgetresp("susb tune menu-support j")) { - exit(255); - } - break; - case 't': + case 't': /* toggle test tone */ case 'T': keying = !keying; printf("Transmit Test Tone/Keying is now %s\n", (keying) ? "Enabled" : "Disabled"); break; + case 'v': /* view cos, ctcss, and ptt status - live */ + case 'V': + menu_view_status(); + break; + case 'w': /* write settings to configuration file */ + case 'W': + if (astgetresp(COMMAND_PREFIX "tune menu-support j")) { + exit(255); + } + break; default: printf("Invalid Entry, try again\n"); break;