diff --git a/DVAPDongle.cpp b/DVAPDongle.cpp index 27163af..e9af580 100644 --- a/DVAPDongle.cpp +++ b/DVAPDongle.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 by Thomas Early, N7TAE + * Copyright 2017-2018,2021 by Thomas Early, N7TAE * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,85 +36,83 @@ CDVAPDongle::~CDVAPDongle() { } -bool CDVAPDongle::Initialize(const char *serialno, const int frequency, const int offset, int const power, const int squelch) +bool CDVAPDongle::open_device(const char *device) { - bool ok = false; - char device[128]; - - do + if (0 == access(device, R_OK | W_OK)) { - for (int i = 0; i < 32; i++) + if (open_serial(device)) { - sprintf(device, "/dev/ttyUSB%d", i); - - if (access(device, R_OK | W_OK) != 0) - continue; - - ok = OpenSerial(device); - if (!ok) - continue; - - if (flock(serfd, LOCK_EX | LOCK_NB) != 0) + if (0 == flock(serfd, LOCK_EX | LOCK_NB)) { - close(serfd); - serfd = -1; - ok = false; - printf("Device %s is already locked/used\n", device); - continue; + printf("Device %s is now locked for exclusive use\n", device); + return true; } - printf("Device %s now locked for exclusive use\n", device); - - ok = get_ser(device, serialno); - if (!ok) + else { close(serfd); serfd = -1; - continue; + fprintf(stderr, "Device %s is alread locked/used\n", device); } - break; } - if (!ok) - break; + } + return false; +} - ok = get_name(); - if (!ok) - break; +bool CDVAPDongle::Initialize(const char *devpath, const char *serialno, const int frequency, const int offset, int const power, const int squelch) +{ + bool ok = false; - ok = get_fw(); - if (!ok) - break; + if (devpath) + { + // device path is specified in cfg file, try to open it + ok = open_device(devpath); + if (! ok) + { + fprintf(stderr, "Device %s could not be opened\n", devpath); + } + } + else + { + // serial number is specified in cfg file, try to find it and open it + char device[16]; + for (int i = 0; i < 32; i++) + { + sprintf(device, "/dev/ttyUSB%d", i); + + if (open_device(device)) + { + if (get_ser(device, serialno)) + { + ok = true; + } + else + { + close(serfd); + serfd = -1; + } + } + if (ok) + break; + } + } + ok = ok && get_name(); - ok = set_modu(); - if (!ok) - break; + ok = ok && get_fw(); - ok = set_mode(); - if (!ok) - break; + ok = ok && set_modu(); - ok = set_sql(squelch); - if (!ok) - break; + ok = ok && set_mode(); - ok = set_pwr(power); - if (!ok) - break; + ok = ok && set_sql(squelch); - ok = set_off(offset); - if (!ok) - break; + ok = ok && set_pwr(power); - ok = set_freq(frequency); - if (!ok) - break; + ok = ok && set_off(offset); - ok = start_dvap(); - if (!ok) - break; + ok = ok && set_freq(frequency); - } - while (false); + ok = ok && start_dvap(); if (!ok) { @@ -124,9 +122,8 @@ bool CDVAPDongle::Initialize(const char *serialno, const int frequency, const in close(serfd); serfd = -1; } - return false; } - return true; + return ok; } REPLY_TYPE CDVAPDongle::GetReply(SDVAP_REGISTER &dr) @@ -786,7 +783,7 @@ int CDVAPDongle::read_from_dvp(void *buffer, unsigned int len) return len; } -bool CDVAPDongle::OpenSerial(char *device) +bool CDVAPDongle::open_serial(const char *device) { static termios t; diff --git a/DVAPDongle.h b/DVAPDongle.h index 5431f60..fc3c8a2 100644 --- a/DVAPDongle.h +++ b/DVAPDongle.h @@ -1,6 +1,6 @@ #pragma once /* - * Copyright 2017,2020 by Thomas Early, N7TAE + * Copyright 2017,2020,2021 by Thomas Early, N7TAE * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -97,7 +97,7 @@ class CDVAPDongle public: CDVAPDongle(); ~CDVAPDongle(); - bool Initialize(const char *serialno, const int frequency, const int offset, const int power, const int squelch); + bool Initialize(const char *devpath, const char *serialno, const int frequency, const int offset, const int power, const int squelch); REPLY_TYPE GetReply(SDVAP_REGISTER &dr); void Stop(); int KeepAlive(); @@ -112,7 +112,8 @@ private: SDVAP_REGISTER dvapreg; // functions - bool OpenSerial(char *device); + bool open_serial(const char *device); + bool open_device(const char *device); int read_from_dvp(void* buf, unsigned int len); int write_to_dvp(const void* buf, const unsigned int len); bool syncit(); diff --git a/QnetDVAP.cpp b/QnetDVAP.cpp index 8ae4e51..39c2505 100644 --- a/QnetDVAP.cpp +++ b/QnetDVAP.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 2010,2011 by Scott Lawson KI4LKF * - * Copyright (C) 2015,2020 by Thomas A. Early N7TAE + * Copyright (C) 2015,2020,2021 by Thomas A. Early N7TAE * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,10 +18,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/*** - KI4LKF, N7TAE -***/ - #include #include #include @@ -176,7 +172,13 @@ bool CQnetDVAP::ReadConfig(const char *cfgFile) RPTR.resize(CALL_SIZE, ' '); OWNER.resize(CALL_SIZE, ' '); - cfg.GetValue(dvap_path+"_serial_number", type, MODULE_SERIAL_NUMBER, 8, 10); + cfg.GetValue(dvap_path+"_serial_number", type, MODULE_SERIAL_NUMBER, 0, 10); + cfg.GetValue(dvap_path+"_device", type, MODULE_DEVICE, 0, 16); + if (0==MODULE_DEVICE.size() && 0==MODULE_SERIAL_NUMBER.size()) + { + fprintf(stderr, "Either a device path or a serial number must be specifed for a DVAP\n"); + return true; + } double f; cfg.GetValue(dvap_path+"_frequency", type, f, 100.0, 1400.0); MODULE_FREQUENCY = (int)(1.0e6*f); @@ -905,7 +907,7 @@ bool CQnetDVAP::Init(const char *file, const int amod) RPTR_and_MOD[7] = RPTR_MOD; /* open dvp */ - if (!dongle.Initialize(MODULE_SERIAL_NUMBER.c_str(), MODULE_FREQUENCY, MODULE_OFFSET, MODULE_POWER, MODULE_SQUELCH)) + if (!dongle.Initialize(MODULE_DEVICE.c_str(), MODULE_SERIAL_NUMBER.c_str(), MODULE_FREQUENCY, MODULE_OFFSET, MODULE_POWER, MODULE_SQUELCH)) return true; if (ToGate.Open(togate.c_str(), this)) diff --git a/QnetDVAP.h b/QnetDVAP.h index 445ff32..00cfcf8 100644 --- a/QnetDVAP.h +++ b/QnetDVAP.h @@ -55,7 +55,8 @@ private: std::string RPTR; std::string OWNER; char RPTR_MOD; - std::string MODULE_SERIAL_NUMBER; /* APxxxxxx */ + std::string MODULE_SERIAL_NUMBER; /* AP123456 */ + std::string MODULE_DEVICE; /* /dev/ttyUSBx */ int MODULE_FREQUENCY; /* between 144000000 and 148000000 */ int MODULE_POWER; /* between -12 and 10 */ int MODULE_SQUELCH; /* between -128 and -45 */ diff --git a/defaults b/defaults index de704ff..eeb5d22 100644 --- a/defaults +++ b/defaults @@ -144,11 +144,12 @@ itap_ap_mode=false # Set to true if you are operating in Access Point Mo # # DVAP - Special parameters when: module.x='dvap' # -module_x_frequency=0 # in MHz, you must specify an operational frequency for the DVAP -module_x_offset=0 # it's a frequency tweak, in Hz -dvap_power=10 # TX power level: -12 to 10, 10 is maximum power -dvap_squelch=-100 # RX Squelch: -128 to -45, -100 to -80 usually works best -dvap_serial_number='APXXXXXX' # The serial number of your DVAP is visible through the bottom of the case +module_x_frequency=0 # in MHz, you must specify an operational frequency for the DVAP +module_x_offset=0 # it's a frequency tweak, in Hz +dvap_power=10 # TX power level: -12 to 10, 10 is maximum power +dvap_squelch=-100 # RX Squelch: -128 to -45, -100 to -80 usually works best +dvap_device='' # Config by device or by serial number. +dvap_serial_number='' # The serial number of your DVAP is visible through the bottom of the case ########################################################################################################################## # diff --git a/qnconfig b/qnconfig index 0973a17..44e3cb3 100755 --- a/qnconfig +++ b/qnconfig @@ -433,6 +433,8 @@ ModuleMenu () { echo -n "of : Offset in Hz = "; EvaluateVar {${mod},dvap}_offset echo -n "po : Power (in dBm from -12 to 10) = "; EvaluateVar {${mod},dvap}_power echo -n "sq : Squelch (in dBm from -128 to -45) = "; EvaluateVar {${mod},dvap}_squelch + echo " You MUST specify either a serial number or a device path!" + echo -n "dv : Device path (/dev/ttyUSBx) = "; EvaluateVar {${mod},dvap}_device echo -n "sn : Serial # (visible through the case) = "; EvaluateVar {${mod},dvap}_serial_number elif [[ "${!mod}" == 'dvrptr' ]]; then echo -n "tx : Transmit frequency, in MHz = "; EvaluateVar {${mod},dvrptr}_tx_frequency @@ -485,7 +487,9 @@ ModuleMenu () { elif [[ "$key" == ar* ]]; then SetBooleanValue ${mod}_auto_link "$value" elif [[ "$key" == cs* ]]; then eval ${mod}_callsign="${value^^}" elif [[ "$key" == du* ]]; then SetBooleanValue ${mod}_duplex "$value" - elif [[ "$key" == dv* ]]; then eval ${mod}_device="$value" + elif [[ "$key" == dv* ]]; then + eval ${mod}_device="$value" + unset ${mod}_serial_number elif [[ "$key" == fr* ]]; then eval ${mod}_frequency="$value" elif [[ "$key" == gp* ]]; then eval ${mod}_gateway_port="$value" elif [[ "$key" == hf* ]]; then SetBooleanValue ${mod}_is_hf "$value" @@ -505,7 +509,9 @@ ModuleMenu () { elif [[ "$key" == ro* ]]; then eval ${mod}_rx_offset="$value" elif [[ "$key" == rq* ]]; then eval ${mod}_rqst_count="$value" elif [[ "$key" == rx* ]]; then eval ${mod}_rx_frequency="$value" - elif [[ "$key" == sn* ]]; then eval ${mod}_serial_number="${value^^}" + elif [[ "$key" == sn* ]]; then + eval ${mod}_serial_number="${value^^}" + unset {$mod}_device elif [[ "$key" == sq* ]]; then eval ${mod}_squelch="$value" elif [[ "$key" == td* ]]; then eval ${mod}_tx_delay="$value" elif [[ "$key" == tl* ]]; then eval ${mod}_tx_level="$value" @@ -723,7 +729,7 @@ while [[ "$ans" != q* ]] do clear echo - echo " QnConfig Main Menu V#210219" + echo " QnConfig Main Menu V#210409" echo echo -n "a : Module A - "; if [ -z $module_a ]; then echo ""; else echo "${module_a^^}"; fi echo -n "b : Module B - "; if [ -z $module_b ]; then echo ""; else echo "${module_b^^}"; fi