diff --git a/DroidStar.pro b/DroidStar.pro index 6e456ed..a490ac1 100644 --- a/DroidStar.pro +++ b/DroidStar.pro @@ -202,6 +202,7 @@ android:HEADERS += androidserialport.h macx:HEADERS += micpermission.h !ios:HEADERS += serialambe.h serialmodem.h android:ANDROID_VERSION_CODE = 79 +android:QT_ANDROID_MIN_SDK_VERSION = 31 contains(ANDROID_TARGET_ARCH,armeabi-v7a) { ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android diff --git a/HostsTab.qml b/HostsTab.qml index 03e21c5..bc6fafb 100644 --- a/HostsTab.qml +++ b/HostsTab.qml @@ -41,9 +41,10 @@ Item { wrapMode: Text.WordWrap color: "white" text: qsTr("Custom hostfile format:\n" + - " \n" + + " \n" + "Example: REF REF123 192.168.1.1 20001\n" + - "Example: DMR MyNet 192.168.1.1 62030 passw0rd") + "Example: DMR MyNet 192.168.1.1 62030 passw0rd\n" + + "Example: IAX 12345 192.168.1.1 4569 iaxclient iaxpass") } TextArea { id: hostsTxtEdit diff --git a/MainTab.qml b/MainTab.qml index 150a160..c89f46a 100644 --- a/MainTab.qml +++ b/MainTab.qml @@ -50,6 +50,10 @@ Item { } } + Keys.onPressed: { + console.log("Key pressed: " + event.key); + } + property alias element3: _element3 property alias label1: _label1 property alias label2: _label2 @@ -228,11 +232,6 @@ Item { droidstar.set_pkgid(settingsTab.pkgidEdit.text); droidstar.set_dmr_options(settingsTab.dmroptsEdit.text); droidstar.set_dmr_pc(mainTab.privateBox.checked); - droidstar.set_iaxuser(settingsTab.iaxuserEdit.text); - droidstar.set_iaxpass(settingsTab.iaxpassEdit.text); - droidstar.set_iaxnode(settingsTab.iaxnodeEdit.text); - droidstar.set_iaxhost(settingsTab.iaxhostEdit.text); - droidstar.set_iaxport(settingsTab.iaxportEdit.text); droidstar.set_txtimeout(settingsTab.txtimerEdit.text); //droidstar.set_toggletx(toggleTX.checked); droidstar.set_xrf2ref(settingsTab.xrf2ref.checked); @@ -327,7 +326,7 @@ Item { Text { id: _dtmflabel x: 5 - y: (parent.height / rows + 1) * 1; + y: (parent.height / rows + 1) * 4; width: parent.width / 5 height: parent.height / rows; text: qsTr("DTMF") @@ -339,7 +338,7 @@ Item { TextField { id: _editIAXDTMF x: (parent.width / 4) - y: (parent.height / rows + 1) * 1; + y: (parent.height / rows + 1) * 4; width: (parent.width * 3 / 8) - 4; height: parent.height / rows; font.pixelSize: parent.height / 35 @@ -349,7 +348,7 @@ Item { Button { id: _dtmfsendbutton x: (parent.width * 5 / 8) - y: (parent.height / rows + 1) * 1; + y: (parent.height / rows + 1) * 4; width: (parent.width * 3 / 8) - 5; height: parent.height / rows; text: qsTr("Send") diff --git a/README.md b/README.md index 530ecd4..22fb66d 100644 --- a/README.md +++ b/README.md @@ -50,15 +50,7 @@ MYCALL/URCALL/RPTR1/RPTR2 are for Dstar modes REF/DCS/XRF. These fields need to # IAX Client for AllStar DroidStar can connect to an AllStar node as an IAX(2) client. See the AllStar wiki and other AllStar, Asterisk, and IAX2 protocal related websites for the technical details of IAX2 for AllStar. This is a basic client and currently only uLaw audio codec is supported. This is the default codec on most AllStar nodes. -Username: Defined in your nodes iax.conf file, usually iaxclient - -Password: Defined as 'secret' in your iax.conf - -Node[@Context]: ID and context of your AllStar node. The context is optional and if not specified, defaults to iax-client. - -Host: hostname or IP address of node. - -Port: UDP port of node, usually 4569. +All IAX nodes are now defined on the Hosts tab. The example shows the format. Once there are one or more IAX nodes defined on the Hosts tab, they will be available to select when IAX mode is selected from the Main tab. This change allows multiple IAX nodes to be defined. Add DTMF commands like \*3node, \*1node, \*70, etc in the IAX DTMF box and hit send to send the DTMF string. Details on various commands can be found at the AllStar wiki and others. diff --git a/SettingsTab.qml b/SettingsTab.qml index 2041f30..9e29cf8 100644 --- a/SettingsTab.qml +++ b/SettingsTab.qml @@ -33,11 +33,6 @@ Item { property alias swidEdit: swidedit property alias pkgidEdit: pkgidedit property alias dmroptsEdit: dmroptsedit - property alias iaxuserEdit: iaxuseredit - property alias iaxpassEdit: iaxpassedit - property alias iaxnodeEdit: iaxnodeedit - property alias iaxhostEdit: iaxhostedit - property alias iaxportEdit: iaxportedit property alias m173200: m17_3200 property alias m171600: m17_1600 property alias mycallEdit: mycalledit @@ -404,99 +399,7 @@ Item { height: 25 selectByMouse: true } - Text { - id: iaxuserlabel - x: 10 - y: 510 - width: 80 - height: 25 - text: qsTr("IAX User") - color: "white" - verticalAlignment: Text.AlignVCenter - } - TextField { - id: iaxuseredit - x: 100 - y: iaxuserlabel.y - width: 125 - height: 25 - selectByMouse: true - } - Text { - id: iaxpasslabel - x: 10 - y: 540 - width: 80 - height: 25 - text: qsTr("IAX secret") - color: "white" - verticalAlignment: Text.AlignVCenter - } - TextField { - id: iaxpassedit - x: 100 - y: iaxpasslabel.y - width: 125 - height: 25 - selectByMouse: true - echoMode: TextInput.Password - } - Text { - id: iaxnodelabel - x: 10 - y: 570 - width: 80 - height: 25 - text: qsTr("IAX Node") - color: "white" - verticalAlignment: Text.AlignVCenter - } - TextField { - id: iaxnodeedit - x: 100 - y: iaxnodelabel.y - width: 125 - height: 25 - selectByMouse: true - inputMethodHints: "ImhPreferNumbers" - } - Text { - id: iaxhostlabel - x: 10 - y: 600 - width: 80 - height: 25 - text: qsTr("IAX Host") - color: "white" - verticalAlignment: Text.AlignVCenter - } - TextField { - id: iaxhostedit - x: 100 - y: iaxhostlabel.y - width: 125 - height: 25 - selectByMouse: true - } - Text { - id: iaxportlabel - x: 10 - y: 630 - width: 80 - height: 25 - text: qsTr("IAX Port") - color: "white" - verticalAlignment: Text.AlignVCenter - } - TextField { - id: iaxportedit - x: 100 - y: iaxportlabel.y - width: 125 - height: 25 - selectByMouse: true - inputMethodHints: "ImhPreferNumbers" - } + Text { id: mycallLabel x: 10 diff --git a/droidstar.cpp b/droidstar.cpp index 369f43f..d7a6ec7 100644 --- a/droidstar.cpp +++ b/droidstar.cpp @@ -95,8 +95,8 @@ void DroidStar::keepScreenOn() void DroidStar::reset_connect_status() { if(connect_status == Mode::CONNECTED_RW){ - connect_status = Mode::CONNECTING; - process_connect(); + connect_status = Mode::CONNECTING; + process_connect(); } } #endif @@ -190,7 +190,6 @@ void DroidStar::file_downloaded(QString filename) void DroidStar::dtmf_send_clicked(QString dtmf) { QByteArray tx(dtmf.simplified().toUtf8(), dtmf.simplified().size()); - //tx.prepend('*'); emit send_dtmf(tx); } @@ -265,33 +264,34 @@ void DroidStar::process_connect() else if(m_protocol == "M17"){ m_refname = m_saved_m17host; } + else if(m_protocol == "IAX"){ + m_refname = m_saved_iaxhost; + } emit connect_status_changed(1); connect_status = Mode::CONNECTING; QStringList sl; - if(m_protocol != "IAX"){ - m_host = m_hostmap[m_refname]; - sl = m_host.split(','); + m_host = m_hostmap[m_refname]; + sl = m_host.split(','); - if( (m_protocol == "M17") && !m_mdirect && (m_ipv6) && (sl.size() > 2) && (sl.at(2) != "none") ){ - m_host = sl.at(2).simplified(); - m_port = sl.at(1).toInt(); - } - else if(sl.size() > 1){ - m_host = sl.at(0).simplified(); - m_port = sl.at(1).toInt(); - } - else if( (m_protocol == "M17") && m_mdirect ){ - qDebug() << "Going MMDVM_DIRECT"; - } - else{ - m_errortxt = "Invalid host selection"; - connect_status = Mode::DISCONNECTED; - emit connect_status_changed(5); - return; - } - } + if( (m_protocol == "M17") && !m_mdirect && (m_ipv6) && (sl.size() > 2) && (sl.at(2) != "none") ){ + m_host = sl.at(2).simplified(); + m_port = sl.at(1).toInt(); + } + else if(sl.size() > 1){ + m_host = sl.at(0).simplified(); + m_port = sl.at(1).toInt(); + } + else if( (m_protocol == "M17") && m_mdirect ){ + qDebug() << "Going MMDVM_DIRECT"; + } + else{ + m_errortxt = "Invalid host selection"; + connect_status = Mode::DISCONNECTED; + emit connect_status_changed(5); + return; + } QString vocoder = ""; if( (m_vocoder != "Software vocoder") && (m_vocoder.contains(':')) ){ @@ -324,14 +324,13 @@ void DroidStar::process_connect() m_mode->moveToThread(m_modethread); if(m_protocol == "IAX"){ - m_mode->set_iax_params(m_iaxuser, m_iaxpassword, m_iaxnode, m_iaxhost, m_iaxport); - m_mode->init(m_callsign, m_dmrid, nxdnid, m_module, m_refname, m_iaxhost, m_iaxport, m_ipv6, vocoder, modem, m_capture, m_playback, m_mdirect); + QString iaxuser = sl.at(2).simplified(); + QString iaxpass = sl.at(3).simplified(); + m_mode->set_iax_params(iaxuser, iaxpass, m_refname, m_host, m_port); connect(this, SIGNAL(send_dtmf(QByteArray)), m_mode, SLOT(send_dtmf(QByteArray))); } - else{ - m_mode->init(m_callsign, m_dmrid, nxdnid, m_module, m_refname, m_host, m_port, m_ipv6, vocoder, modem, m_capture, m_playback, m_mdirect); - } + m_mode->init(m_callsign, m_dmrid, nxdnid, m_module, m_refname, m_host, m_port, m_ipv6, vocoder, modem, m_capture, m_playback, m_mdirect); m_mode->set_modem_flags(rxInvert, txInvert, pttInvert, useCOSAsLockout, duplex); m_mode->set_modem_params(m_modemBaud.toUInt(), rxfreq, txfreq, m_modemTxDelay.toInt(), m_modemRxLevel.toFloat(), m_modemRFLevel.toFloat(), ysfTXHang, m_modemCWIdTxLevel.toFloat(), m_modemDstarTxLevel.toFloat(), m_modemDMRTxLevel.toFloat(), m_modemYSFTxLevel.toFloat(), m_modemP25TxLevel.toFloat(), m_modemNXDNTxLevel.toFloat(), pocsagTXLevel, m17TXLevel); @@ -513,6 +512,7 @@ void DroidStar::process_mode_change(const QString &m) m_label6 = ""; } if(m == "IAX"){ + process_iax_hosts(); m_label1 = ""; m_label2 = ""; m_label3 = ""; @@ -538,6 +538,7 @@ void DroidStar::save_settings() m_settings->setValue("P25HOST", m_saved_p25host); m_settings->setValue("NXDNHOST", m_saved_nxdnhost); m_settings->setValue("M17HOST", m_saved_m17host); + m_settings->setValue("IAXHOST", m_saved_iaxhost); m_settings->setValue("MODULE", QString(m_module)); m_settings->setValue("CALLSIGN", m_callsign); m_settings->setValue("DMRID", m_dmrid); @@ -562,11 +563,6 @@ void DroidStar::save_settings() m_settings->setValue("TXTOGGLE", m_toggletx ? "true" : "false"); m_settings->setValue("XRF2REF", m_xrf2ref ? "true" : "false"); m_settings->setValue("USRTXT", m_dstarusertxt); - m_settings->setValue("IAXUSER", m_iaxuser); - m_settings->setValue("IAXPASS", m_iaxpassword); - m_settings->setValue("IAXNODE", m_iaxnode); - m_settings->setValue("IAXHOST", m_iaxhost); - m_settings->setValue("IAXPORT", m_iaxport); m_settings->setValue("ModemRxFreq", m_modemRxFreq); m_settings->setValue("ModemTxFreq", m_modemTxFreq); @@ -604,6 +600,7 @@ void DroidStar::process_settings() m_saved_p25host = m_settings->value("P25HOST").toString().simplified(); m_saved_nxdnhost = m_settings->value("NXDNHOST").toString().simplified(); m_saved_m17host = m_settings->value("M17HOST").toString().simplified(); + m_saved_iaxhost = m_settings->value("IAXHOST").toString().simplified(); m_module = m_settings->value("MODULE").toString().toStdString()[0]; m_callsign = m_settings->value("CALLSIGN").toString().simplified(); m_dmrid = m_settings->value("DMRID").toString().simplified().toUInt(); @@ -628,11 +625,6 @@ void DroidStar::process_settings() m_toggletx = (m_settings->value("TXTOGGLE", "true").toString().simplified() == "true") ? true : false; m_dstarusertxt = m_settings->value("USRTXT").toString().simplified(); m_xrf2ref = (m_settings->value("XRF2REF").toString().simplified() == "true") ? true : false; - m_iaxuser = m_settings->value("IAXUSER").toString().simplified(); - m_iaxpassword = m_settings->value("IAXPASS").toString().simplified(); - m_iaxnode = m_settings->value("IAXNODE").toString().simplified(); - m_saved_iaxhost = m_iaxhost = m_settings->value("IAXHOST").toString().simplified(); - m_iaxport = m_settings->value("IAXPORT", "4569").toString().simplified().toUInt(); m_localhosts = m_settings->value("LOCALHOSTS").toString(); m_modemRxFreq = m_settings->value("ModemRxFreq", "438800000").toString().simplified(); @@ -986,6 +978,25 @@ void DroidStar::process_m17_hosts() } } +void DroidStar::process_iax_hosts() +{ + m_hostmap.clear(); + m_hostsmodel.clear(); + m_customhosts = m_localhosts.split('\n'); + for (const auto& i : std::as_const(m_customhosts)){ + QStringList line = i.simplified().split(' '); + if(line.at(0) == "IAX"){ + m_hostmap[line.at(1).simplified()] = line.at(2).simplified() + "," + line.at(3).simplified() + "," + line.at(4).simplified() + "," + line.at(5).simplified(); + } + } + + QMap::const_iterator i = m_hostmap.constBegin(); + while (i != m_hostmap.constEnd()) { + m_hostsmodel.append(i.key()); + ++i; + } +} + void DroidStar::process_dmr_ids() { QFileInfo check_file(config_path + "/DMRIDs.dat"); diff --git a/droidstar.h b/droidstar.h index 7288a67..fa582b1 100644 --- a/droidstar.h +++ b/droidstar.h @@ -92,15 +92,10 @@ public slots: void set_pkgid(const QString &pkgid){ m_pkgid = pkgid; save_settings(); } void set_dmr_options(const QString &dmropts) { m_dmropts = dmropts; save_settings(); } void set_dmr_pc(int pc) { m_pc = pc; emit dmrpc_state_changed(m_pc); } - //void set_host(const QString &host) { m_host = host; save_settings(); } void set_module(const QString &module) { m_module = module.toStdString()[0]; save_settings(); emit module_changed(m_module);} void set_protocol(const QString &protocol) { m_protocol = protocol; save_settings(); } void set_input_volume(qreal v); void set_modelchange(bool t){ m_modelchange = t; } - void set_iaxuser(const QString &user){ m_iaxuser = user; save_settings(); } - void set_iaxpass(const QString &pass){ m_iaxpassword = pass; save_settings(); } - void set_iaxnode(const QString &node){ m_iaxnode = node; save_settings(); } - void set_iaxhost(const QString &host){ m_iaxhost = host; save_settings(); } void set_mycall(const QString &mycall) { m_mycall = mycall; save_settings(); emit mycall_changed(mycall); } void set_urcall(const QString &urcall) { m_urcall = urcall; save_settings(); emit urcall_changed(urcall); } void set_rptr1(const QString &rptr1) { m_rptr1 = rptr1; save_settings(); emit rptr1_changed(rptr1); qDebug() << "rpt1 == " << m_rptr1; } @@ -200,10 +195,6 @@ public slots: QString get_nxdn_host() { return m_saved_nxdnhost; } QString get_m17_host() { return m_saved_m17host; } QString get_iax_host() { return m_saved_iaxhost; } - QString get_iax_user() { return m_iaxuser; } - QString get_iax_pass() { return m_iaxpassword; } - QString get_iax_node() { return m_iaxnode; } - QString get_iax_port() { return QString::number(m_iaxport); } QString get_mycall() { return m_mycall; } QString get_urcall() { return m_urcall; } QString get_rptr1() { return m_rptr1; } @@ -328,10 +319,6 @@ private: QThread *m_modethread; Mode *m_mode; QByteArray user_data; - QString m_iaxuser; - QString m_iaxpassword; - QString m_iaxnode; - QString m_iaxhost; QString m_localhosts; int m_iaxport; bool m_settings_processed; @@ -391,6 +378,7 @@ private slots: void process_p25_hosts(); void process_nxdn_hosts(); void process_m17_hosts(); + void process_iax_hosts(); void process_dmr_ids(); void process_nxdn_ids(); void update_data(Mode::MODEINFO); diff --git a/main.qml b/main.qml index f67398a..f07fb51 100644 --- a/main.qml +++ b/main.qml @@ -342,10 +342,11 @@ ApplicationWindow { } if(droidstar.get_mode() === "IAX"){ //mainTab.comboMode.width = mainTab.width / 2; - mainTab.comboHost.visible = false; - mainTab.dtmflabel.visible = true; - mainTab.editIAXDTMF.visible = true; - mainTab.dtmfsendbutton.visible = true; + mainTab.comboHost.visible = true; + mainTab.dtmflabel.visible = true; + mainTab.editIAXDTMF.visible = true; + mainTab.dtmfsendbutton.visible = true; + mainTab.comboHost.currentIndex = mainTab.comboHost.find(droidstar.get_iax_host()); mainTab.comboModule.visible = false; mainTab.comboSlot.visible = false; mainTab.comboCC.visible = false; @@ -401,6 +402,9 @@ ApplicationWindow { if(droidstar.get_mode() === "M17"){ mainTab.comboHost.currentIndex = mainTab.comboHost.find(droidstar.get_m17_host()); } + if(droidstar.get_mode() === "IAX"){ + mainTab.comboHost.currentIndex = mainTab.comboHost.find(droidstar.get_iax_host()); + } mainTab.comboModule.currentIndex = mainTab.comboModule.find(droidstar.get_module()); settingsTab.callsignEdit.text = droidstar.get_callsign(); settingsTab.dmridEdit.text = droidstar.get_dmrid(); @@ -416,11 +420,6 @@ ApplicationWindow { settingsTab.pkgidEdit.text = droidstar.get_pkgid(); settingsTab.dmroptsEdit.text = droidstar.get_dmr_options(); mainTab.dmrtgidEdit.text = droidstar.get_dmrtgid(); - settingsTab.iaxuserEdit.text = droidstar.get_iax_user(); - settingsTab.iaxpassEdit.text = droidstar.get_iax_pass(); - settingsTab.iaxnodeEdit.text = droidstar.get_iax_node(); - settingsTab.iaxhostEdit.text = droidstar.get_iax_host(); - settingsTab.iaxportEdit.text = droidstar.get_iax_port(); settingsTab.mycallEdit.text = droidstar.get_mycall(); settingsTab.urcallEdit.text = droidstar.get_urcall(); settingsTab.rptr1Edit.text = droidstar.get_rptr1();