diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index 1168bca6..0843e819 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -58,7 +58,7 @@ static void cbRxFontBrowser(Fl_Widget*, void*) { ReceiveText->setFont(font); ReceiveText->setFontSize(size); ReceiveText->setFontColor(progdefaults.RxFontcolor, FTextBase::RECV); - + fsq_rx_text->setFont(font); fsq_rx_text->setFontSize(size); fsq_rx_text->setFontColor(progdefaults.RxFontcolor, FTextBase::RECV); @@ -113,12 +113,12 @@ static void cbMacroEditFontBrowser(Fl_Widget*, void*) { progdefaults.MacroEditFontnbr = font; progdefaults.MacroEditFontsize = size; - + update_macroedit_font(); MacroText->textfont(font); MacroText->textsize(size); - + font_browser->hide(); progdefaults.changed = true; @@ -141,7 +141,7 @@ static void cbMacroBtnFontBrowser(Fl_Widget*, void*) { progdefaults.MacroBtnFontcolor = font_browser->fontColor(); font_browser->hide(); - + btnGroup1->labelcolor(progdefaults.MacroBtnFontcolor); btnGroup1->labelfont(progdefaults.MacroBtnFontnbr); btnGroup1->labelsize(progdefaults.MacroBtnFontsize); @@ -1586,7 +1586,7 @@ static void cb_btnSmeter_bg_color(Fl_Button*, void*) { progdefaults.Smeter_bg_color.R = r; progdefaults.Smeter_bg_color.G = g; progdefaults.Smeter_bg_color.B = b; - + set_smeter_colors(); progdefaults.changed = true; @@ -1606,7 +1606,7 @@ static void cb_btnSmeter_scale_color(Fl_Button*, void*) { progdefaults.Smeter_scale_color.R = r; progdefaults.Smeter_scale_color.G = g; progdefaults.Smeter_scale_color.B = b; - + set_smeter_colors(); progdefaults.changed = true; @@ -1626,7 +1626,7 @@ static void cb_btnSmeter_meter_color(Fl_Button*, void*) { progdefaults.Smeter_meter_color.R = r; progdefaults.Smeter_meter_color.G = g; progdefaults.Smeter_meter_color.B = b; - + set_smeter_colors(); progdefaults.changed = true; @@ -1646,7 +1646,7 @@ static void cb_btnPWR_bg_color(Fl_Button*, void*) { progdefaults.PWRmeter_bg_color.R = r; progdefaults.PWRmeter_bg_color.G = g; progdefaults.PWRmeter_bg_color.B = b; - + set_smeter_colors(); progdefaults.changed = true; @@ -1666,7 +1666,7 @@ static void cb_btnPWR_scale_color(Fl_Button*, void*) { progdefaults.PWRmeter_scale_color.R = r; progdefaults.PWRmeter_scale_color.G = g; progdefaults.PWRmeter_scale_color.B = b; - + set_smeter_colors(); progdefaults.changed = true; @@ -1686,7 +1686,7 @@ static void cb_btnPWR_meter_Color(Fl_Button*, void*) { progdefaults.PWRmeter_meter_color.R = r; progdefaults.PWRmeter_meter_color.G = g; progdefaults.PWRmeter_meter_color.B = b; - + set_smeter_colors(); progdefaults.changed = true; @@ -3404,6 +3404,12 @@ static void cb_cnt_pilot_power(Fl_Counter2* o, void*) { progdefaults.changed = true; } +Fl_Check_Button *btnPSK8Preamble=(Fl_Check_Button *)0; + +static void cb_btnPSK8Preamble(Fl_Check_Button* o, void*) { + progStatus.psk8DCDShortFlag = o->value(); +} + Fl_Group *tabRTTY=(Fl_Group *)0; Fl_Tabs *tabsRTTY=(Fl_Tabs *)0; @@ -5627,6 +5633,7 @@ if(o->value()) disable_config_p2p_io_widgets(); else enable_config_p2p_io_widgets(); +kiss_io_set_button_state(0); } Fl_Check_Button *btnEnable_arq=(Fl_Check_Button *)0; @@ -5745,6 +5752,51 @@ static void cb_btn_restart_kiss(Fl_Button*, void*) { //restart_kiss_server(); } +Fl_Button *btn_connect_kiss_io=(Fl_Button *)0; + +static void cb_btn_connect_kiss_io(Fl_Button*, void*) { + connect_to_kiss_io(); +} + +Fl_Check_Button *btnKissTCPIO=(Fl_Check_Button *)0; + +static void cb_btnKissTCPIO(Fl_Check_Button* o, void*) { + if(o->value()) { + progdefaults.kiss_tcp_io = true; + progStatus.kiss_tcp_io = true; +} else { + progStatus.kiss_tcp_io = false; + progdefaults.kiss_tcp_io = false; +} +kiss_io_set_button_state(0); +} + +Fl_Check_Button *btnKissUDPIO=(Fl_Check_Button *)0; + +static void cb_btnKissUDPIO(Fl_Check_Button* o, void*) { + if(o->value()) { + progdefaults.kiss_tcp_io = false; + progStatus.kiss_tcp_io = false; +} else { + progStatus.kiss_tcp_io = true; + progdefaults.kiss_tcp_io = true; +} + +kiss_io_set_button_state(0); +} + +Fl_Check_Button *btnKissTCPListen=(Fl_Check_Button *)0; + +static void cb_btnKissTCPListen(Fl_Check_Button* o, void*) { + if(o->value()) { + progdefaults.kiss_tcp_listen = true; + progStatus.kiss_tcp_listen = true; +} else { + progStatus.kiss_tcp_listen = false; + progdefaults.kiss_tcp_listen = false; +}; +} + Fl_Input2 *txtArq_ip_address=(Fl_Input2 *)0; static void cb_txtArq_ip_address(Fl_Input2* o, void*) { @@ -5899,6 +5951,7 @@ Fl_Double_Window* ConfigureDialog() { tabOperator->tooltip(_("Operator information")); tabOperator->callback((Fl_Callback*)cb_tabOperator); tabOperator->when(FL_WHEN_CHANGED); + tabOperator->hide(); { Fl_Group* o = new Fl_Group(55, 35, 490, 170, _("Station")); o->box(FL_ENGRAVED_FRAME); o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); @@ -7694,6 +7747,7 @@ i on a\ntouch screen device such as a tablet.")); tabsModems->selection_color(FL_LIGHT1); tabsModems->align(Fl_Align(FL_ALIGN_TOP_RIGHT)); { tabCW = new Fl_Group(0, 50, 600, 330, _("CW")); + tabCW->hide(); { tabsCW = new Fl_Tabs(0, 50, 600, 330); tabsCW->selection_color(FL_LIGHT1); { Fl_Group* o = new Fl_Group(0, 75, 600, 305, _("General")); @@ -8983,7 +9037,6 @@ i on a\ntouch screen device such as a tablet.")); tabContestia->end(); } // Fl_Group* tabContestia { tabPSK = new Fl_Group(0, 50, 600, 330, _("PSK")); - tabPSK->hide(); { tabsPSK = new Fl_Tabs(0, 50, 600, 330); tabsPSK->selection_color(FL_LIGHT1); { grpPSK = new Fl_Group(0, 75, 600, 305, _("General")); @@ -9090,13 +9143,13 @@ i on a\ntouch screen device such as a tablet.")); { Fl_Group* o = new Fl_Group(55, 327, 490, 47, _("8 psk")); o->box(FL_ENGRAVED_FRAME); o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); - { Fl_Check_Button* o = btnPSKpilot = new Fl_Check_Button(141, 342, 113, 20, _("Pilot tone")); + { Fl_Check_Button* o = btnPSKpilot = new Fl_Check_Button(100, 340, 113, 20, _("Pilot tone")); btnPSKpilot->tooltip(_("Enable encode/decode vestigial pilot tone")); btnPSKpilot->down_box(FL_DOWN_BOX); btnPSKpilot->callback((Fl_Callback*)cb_btnPSKpilot); o->value(progdefaults.pskpilot); } // Fl_Check_Button* btnPSKpilot - { Fl_Counter2* o = cnt_pilot_power = new Fl_Counter2(305, 342, 75, 20, _("pilot power (dB)")); + { Fl_Counter2* o = cnt_pilot_power = new Fl_Counter2(205, 340, 75, 20, _("pilot power (dB)")); cnt_pilot_power->tooltip(_("Pilot tone power relative to signal")); cnt_pilot_power->type(1); cnt_pilot_power->box(FL_UP_BOX); @@ -9116,6 +9169,12 @@ i on a\ntouch screen device such as a tablet.")); o->value(progdefaults.pilot_power); o->labelsize(FL_NORMAL_SIZE); } // Fl_Counter2* cnt_pilot_power + { Fl_Check_Button* o = btnPSK8Preamble = new Fl_Check_Button(410, 340, 113, 20, _("Short Preamble")); + btnPSK8Preamble->tooltip(_("Enable encode/decode vestigial pilot tone")); + btnPSK8Preamble->down_box(FL_DOWN_BOX); + btnPSK8Preamble->callback((Fl_Callback*)cb_btnPSK8Preamble); + o->value(progStatus.psk8DCDShortFlag); + } // Fl_Check_Button* btnPSK8Preamble o->end(); } // Fl_Group* o grpPSK->end(); @@ -11907,7 +11966,6 @@ and restarted if needed.")); { tabIO = new Fl_Group(0, 25, 600, 355, _("IO")); tabIO->tooltip(_("Program to Program Communications")); tabIO->callback((Fl_Callback*)cb_tabIO); - tabIO->hide(); { Fl_Group* o = new Fl_Group(6, 34, 588, 102); o->box(FL_ENGRAVED_BOX); o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); @@ -11948,9 +12006,9 @@ and restarted if needed.")); progStatus.ip_lock ? o->deactivate() : o->activate(); } // Fl_Check_Button* btnEnable_csma { new Fl_Box(8, 37, 582, 72, _("Enable ARQ for programs that support TCP and FLDIGI ARQ protocol.\nEnable KIS\ -S for programs that supports UDP and TNC-2 KISS protocol.\nOnly one interface \ -(ARQ/KISS) can be active at any given time.\nKISS/ARQ/XML Addr/Port changes re\ -quire program restart.")); +S for programs that supports TCP/UDP and TNC-2 KISS protocol.\nOnly one interf\ +ace (ARQ/KISS) can be active at any given time.\nKISS/ARQ/XML Addr/Port change\ +s require program restart.")); } // Fl_Box* o o->end(); } // Fl_Group* o @@ -12020,7 +12078,7 @@ quire program restart.")); o->step(1,10); progStatus.ip_lock ? o->deactivate() : o->activate(); } // Fl_Counter* cntBusyChannelSeconds - { Fl_Check_Button* o = btnEnableBusyChannel = new Fl_Check_Button(425, 147, 65, 15, _("Busy")); + { Fl_Check_Button* o = btnEnableBusyChannel = new Fl_Check_Button(331, 145, 65, 15, _("Busy")); btnEnableBusyChannel->tooltip(_("Enable Busy Channel")); btnEnableBusyChannel->down_box(FL_DOWN_BOX); btnEnableBusyChannel->callback((Fl_Callback*)cb_btnEnableBusyChannel); @@ -12044,7 +12102,7 @@ quire program restart.")); o->value(progdefaults.kiss_out_port.c_str()); progStatus.ip_lock ? o->deactivate() : o->activate(); } // Fl_Input2* txtKiss_ip_out_port_no - { Fl_Check_Button* o = btnEnable_dual_port = new Fl_Check_Button(425, 168, 90, 16, _("Dual Port")); + { Fl_Check_Button* o = btnEnable_dual_port = new Fl_Check_Button(485, 169, 90, 16, _("Dual Port")); btnEnable_dual_port->tooltip(_("Enable when both programs are using the same IP address")); btnEnable_dual_port->down_box(FL_DOWN_BOX); btnEnable_dual_port->callback((Fl_Callback*)cb_btnEnable_dual_port); @@ -12056,6 +12114,32 @@ quire program restart.")); btn_restart_kiss->hide(); progStatus.ip_lock ? o->deactivate() : o->activate(); } // Fl_Button* btn_restart_kiss + { Fl_Button* o = btn_connect_kiss_io = new Fl_Button(504, 193, 82, 25, _("Connect")); + btn_connect_kiss_io->tooltip(_("Return KISS TCP IO connection to a Listening state")); + btn_connect_kiss_io->callback((Fl_Callback*)cb_btn_connect_kiss_io); + (progStatus.ip_lock || !progStatus.kiss_tcp_io) ? o->deactivate() : o->activate(); + } // Fl_Button* btn_connect_kiss_io + { Fl_Check_Button* o = btnKissTCPIO = new Fl_Check_Button(425, 145, 60, 15, _("TCP")); + btnKissTCPIO->tooltip(_("Check to enable TCP/IP IO Connection")); + btnKissTCPIO->down_box(FL_DOWN_BOX); + btnKissTCPIO->callback((Fl_Callback*)cb_btnKissTCPIO); + if(progStatus.kiss_tcp_io) o->value(true); else o->value(false); + progStatus.ip_lock ? o->deactivate() : o->activate(); + } // Fl_Check_Button* btnKissTCPIO + { Fl_Check_Button* o = btnKissUDPIO = new Fl_Check_Button(425, 170, 60, 15, _("UDP")); + btnKissUDPIO->tooltip(_("Check to enable UDP/IP IO")); + btnKissUDPIO->down_box(FL_DOWN_BOX); + btnKissUDPIO->callback((Fl_Callback*)cb_btnKissUDPIO); + if(progStatus.kiss_tcp_io) o->value(true); else o->value(false); + progStatus.ip_lock ? o->deactivate() : o->activate(); + } // Fl_Check_Button* btnKissUDPIO + { Fl_Check_Button* o = btnKissTCPListen = new Fl_Check_Button(485, 145, 95, 15, _("Listen / Bind")); + btnKissTCPListen->tooltip(_("Monitor for TCP connection")); + btnKissTCPListen->down_box(FL_DOWN_BOX); + btnKissTCPListen->callback((Fl_Callback*)cb_btnKissTCPListen); + if(progStatus.kiss_tcp_listen) o->value(true); else o->value(false); + progStatus.ip_lock ? o->deactivate() : o->activate(); + } // Fl_Check_Button* btnKissTCPListen o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(6, 225, 588, 35, _("ARQ")); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index 78376d7b..01b1c5ef 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -1,122 +1,122 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0303 -i18n_type 1 -i18n_include "gettext.h" -i18n_function _ -header_name {.h} +version 1.0303 +i18n_type 1 +i18n_include "gettext.h" +i18n_function _ +header_name {.h} code_name {.cxx} decl {\#include } {private local -} +} decl {\#include } {private local -} +} decl {\#include } {private local -} +} decl {\#include } {private local -} +} decl {\#include } {private local -} +} decl {\#include } {private local -} +} decl {\#include "main.h"} {private local -} +} decl {\#include "fl_digi.h"} {private local -} +} decl {\#include "data_io.h"} {private local -} +} decl {\#include "Viewer.h"} {private global -} +} decl {\#include "font_browser.h"} {public global -} +} decl {\#include "soundconf.h"} {private local -} +} decl {\#include "globals.h"} {public local -} +} decl {\#include "modem.h"} {public local -} +} decl {\#include "configuration.h"} {public local -} +} decl {\#include "combo.h"} {public local -} +} decl {\#include "waterfall.h"} {private local -} +} decl {\#include "rigxml.h"} {private local -} +} decl {\#include "lookupcall.h"} {private local -} +} decl {\#include "icons.h"} {private local -} +} decl {\#include "Viewer.h"} {private local -} +} decl {\#include "pskrep.h"} {private global -} +} decl {\#include "flinput2.h"} {public local -} +} decl {\#include "flslider2.h"} {public local -} +} decl {\#include "flmisc.h"} {public local -} +} decl {\#include "logsupport.h"} {private local -} +} decl {\#include "notify.h"} {private local -} +} decl {\#include "debug.h"} {private local -} +} decl {\#include "status.h"} {private local -} +} decl {\#include "rx_extract.h"} {private local -} +} decl {\#include "kmlserver.h"} {private local -} +} decl {\#include "macroedit.h"} {private local -} +} decl {\#include "fileselect.h"} {private local -} +} decl {extern void WefaxDestDirSet(Fl_File_Chooser *w, void *userdata);} {private local -} +} decl {\#if USE_HAMLIB \#include "hamlib.h" \#endif} {private local -} +} decl {Fl_Double_Window *dlgConfig;} {public local -} +} decl {Mode_Browser* mode_browser;} {public local -} +} Function {choose_color(Fl_Color & c)} {private return_type void } { @@ -124,7 +124,7 @@ Function {choose_color(Fl_Color & c)} {private return_type void Fl::get_color(c, r, g, b); if (fl_color_chooser("Font color", r, g, b)) c = fl_rgb_color(r, g, b);} {} -} +} Function {cbRxFontBrowser(Fl_Widget*, void*)} {open private return_type void } { @@ -144,7 +144,7 @@ Function {cbRxFontBrowser(Fl_Widget*, void*)} {open private return_type void ReceiveText->setFont(font); ReceiveText->setFontSize(size); ReceiveText->setFontColor(progdefaults.RxFontcolor, FTextBase::RECV); - + fsq_rx_text->setFont(font); fsq_rx_text->setFontSize(size); fsq_rx_text->setFontColor(progdefaults.RxFontcolor, FTextBase::RECV); @@ -156,7 +156,7 @@ Function {cbRxFontBrowser(Fl_Widget*, void*)} {open private return_type void font_browser->hide(); progdefaults.changed = true;} {} -} +} Function {cbTxFontBrowser(Fl_Widget*, void*)} {open private return_type void } { @@ -188,7 +188,7 @@ Function {cbTxFontBrowser(Fl_Widget*, void*)} {open private return_type void font_browser->hide(); progdefaults.changed = true;} {} -} +} Function {cbMacroEditFontBrowser(Fl_Widget*, void*)} {private return_type void } { @@ -201,16 +201,16 @@ Function {cbMacroEditFontBrowser(Fl_Widget*, void*)} {private return_type void progdefaults.MacroEditFontnbr = font; progdefaults.MacroEditFontsize = size; - + update_macroedit_font(); MacroText->textfont(font); MacroText->textsize(size); - + font_browser->hide(); progdefaults.changed = true;} {} -} +} Function {cbWaterfallFontBrowser(Fl_Widget*, void*)} {return_type void } { @@ -222,7 +222,7 @@ Function {cbWaterfallFontBrowser(Fl_Widget*, void*)} {return_type void progdefaults.changed = true; font_browser->hide();} {} -} +} Function {cbMacroBtnFontBrowser(Fl_Widget*, void*)} {private return_type void } { @@ -231,7 +231,7 @@ Function {cbMacroBtnFontBrowser(Fl_Widget*, void*)} {private return_type void progdefaults.MacroBtnFontcolor = font_browser->fontColor(); font_browser->hide(); - + btnGroup1->labelcolor(progdefaults.MacroBtnFontcolor); btnGroup1->labelfont(progdefaults.MacroBtnFontnbr); btnGroup1->labelsize(progdefaults.MacroBtnFontsize); @@ -249,7 +249,7 @@ Function {cbMacroBtnFontBrowser(Fl_Widget*, void*)} {private return_type void progdefaults.changed = true; colorize_macros();} {} -} +} Function {cbViewerFontBrowser(Fl_Widget*, void*)} {return_type void } { @@ -259,7 +259,7 @@ Function {cbViewerFontBrowser(Fl_Widget*, void*)} {return_type void progdefaults.changed = true; font_browser->hide();} {} -} +} Function {cbFreqControlFontBrowser(Fl_Widget*, void*)} {return_type void } { @@ -277,7 +277,7 @@ Function {cbFreqControlFontBrowser(Fl_Widget*, void*)} {return_type void qsoFreqDisp3->redraw(); font_browser->hide();} {} -} +} Function {cbLOGGINGFontBrowser(Fl_Widget*, void*)} {private return_type void } { @@ -299,7 +299,7 @@ Function {cbLOGGINGFontBrowser(Fl_Widget*, void*)} {private return_type void font_browser->hide(); progdefaults.changed = true;} {} -} +} Function {cbLOGBOOKFontBrowser(Fl_Widget*, void*)} {private return_type void } { @@ -321,7 +321,7 @@ Function {cbLOGBOOKFontBrowser(Fl_Widget*, void*)} {private return_type void font_browser->hide(); progdefaults.changed = true;} {} -} +} Function {set_qrzxml_buttons(Fl_Button* b)} {return_type void } { @@ -331,7 +331,7 @@ Function {set_qrzxml_buttons(Fl_Button* b)} {return_type void for (size_t i = 0; i < sizeof(qrzbxml)/sizeof(*qrzbxml); i++) qrzbxml[i]->value(b == qrzbxml[i]);} {} -} +} Function {set_qrzweb_buttons(Fl_Button* b)} {return_type void } { @@ -341,7 +341,7 @@ Function {set_qrzweb_buttons(Fl_Button* b)} {return_type void for (size_t i = 0; i < sizeof(qrzbweb)/sizeof(*qrzbweb); i++) qrzbweb[i]->value(b == qrzbweb[i]);} {} -} +} Function {ConfigureDialog()} {open } { @@ -366,8 +366,8 @@ static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {} } { Fl_Group tabOperator { label Operator - callback {progdefaults.changed = true;} open selected - tooltip {Operator information} xywh {0 25 600 355} when 1 + callback {progdefaults.changed = true;} open + tooltip {Operator information} xywh {0 25 600 355} when 1 hide } { Fl_Group {} { label Station open @@ -1912,7 +1912,7 @@ font_browser->show();} progdefaults.Smeter_bg_color.R = r; progdefaults.Smeter_bg_color.G = g; progdefaults.Smeter_bg_color.B = b; - + set_smeter_colors(); progdefaults.changed = true;} @@ -1931,7 +1931,7 @@ font_browser->show();} progdefaults.Smeter_scale_color.R = r; progdefaults.Smeter_scale_color.G = g; progdefaults.Smeter_scale_color.B = b; - + set_smeter_colors(); progdefaults.changed = true;} @@ -1950,7 +1950,7 @@ font_browser->show();} progdefaults.Smeter_meter_color.R = r; progdefaults.Smeter_meter_color.G = g; progdefaults.Smeter_meter_color.B = b; - + set_smeter_colors(); progdefaults.changed = true;} @@ -1974,7 +1974,7 @@ font_browser->show();} progdefaults.PWRmeter_bg_color.R = r; progdefaults.PWRmeter_bg_color.G = g; progdefaults.PWRmeter_bg_color.B = b; - + set_smeter_colors(); progdefaults.changed = true;} @@ -1993,7 +1993,7 @@ font_browser->show();} progdefaults.PWRmeter_scale_color.R = r; progdefaults.PWRmeter_scale_color.G = g; progdefaults.PWRmeter_scale_color.B = b; - + set_smeter_colors(); progdefaults.changed = true;} @@ -2012,7 +2012,7 @@ font_browser->show();} progdefaults.PWRmeter_meter_color.R = r; progdefaults.PWRmeter_meter_color.G = g; progdefaults.PWRmeter_meter_color.B = b; - + set_smeter_colors(); progdefaults.changed = true;} @@ -2957,7 +2957,7 @@ behaves inside the waterfall} xywh {65 207 150 22} box DOWN_BOX color 7 align 8 } { Fl_Group tabCW { label CW open - xywh {0 50 600 330} + xywh {0 50 600 330} hide } { Fl_Tabs tabsCW {open xywh {0 50 600 330} selection_color 50 @@ -4160,7 +4160,7 @@ progdefaults.changed = true;} } Fl_Group tabPSK { label PSK open - xywh {0 50 600 330} hide + xywh {0 50 600 330} } { Fl_Tabs tabsPSK {open xywh {0 50 600 330} selection_color 50 @@ -4241,18 +4241,24 @@ progdefaults.changed = true;} label {Pilot tone} callback {progdefaults.pskpilot = o->value(); progdefaults.changed = true;} - tooltip {Enable encode/decode vestigial pilot tone} xywh {141 342 113 20} down_box DOWN_BOX + tooltip {Enable encode/decode vestigial pilot tone} xywh {100 340 113 20} down_box DOWN_BOX code0 {o->value(progdefaults.pskpilot);} } Fl_Counter cnt_pilot_power { label {pilot power (dB)} callback {progdefaults.pilot_power = o->value(); progdefaults.changed = true;} - tooltip {Pilot tone power relative to signal} xywh {305 342 75 20} type Simple align 8 minimum -60 maximum -20 step 1 value -30 + tooltip {Pilot tone power relative to signal} xywh {205 340 75 20} type Simple align 8 minimum -60 maximum -20 step 1 value -30 code0 {o->value(progdefaults.pilot_power);} code1 {o->labelsize(FL_NORMAL_SIZE);} class Fl_Counter2 } + Fl_Check_Button btnPSK8Preamble { + label {Short Preamble} + callback {progStatus.psk8DCDShortFlag = o->value();} + tooltip {Enable encode/decode vestigial pilot tone} xywh {410 340 113 20} down_box DOWN_BOX + code0 {o->value(progStatus.psk8DCDShortFlag);} + } } } } @@ -6987,8 +6993,8 @@ progdefaults.changed = true;} } Fl_Group tabIO { label IO - callback {btnDisable_p2p_io_widgets->value(1);} open - tooltip {Program to Program Communications} xywh {0 25 600 355} hide + callback {btnDisable_p2p_io_widgets->value(1);} open selected + tooltip {Program to Program Communications} xywh {0 25 600 355} code0 {btnDisable_p2p_io_widgets->value(1);} } { Fl_Group {} {open @@ -6996,11 +7002,12 @@ progdefaults.changed = true;} } { Fl_Check_Button btnDisable_p2p_io_widgets { label Lock user_data_type long - callback {progStatus.ip_lock = o->value(); + callback { progStatus.ip_lock = o->value(); if(o->value()) disable_config_p2p_io_widgets(); else - enable_config_p2p_io_widgets();} + enable_config_p2p_io_widgets(); +kiss_io_set_button_state(0);} tooltip {Allow/Disallow Changes} xywh {12 112 85 20} down_box DOWN_BOX code0 {o->value(progStatus.ip_lock);} } @@ -7056,7 +7063,7 @@ progdefaults.changed = true;} } Fl_Box {} { label {Enable ARQ for programs that support TCP and FLDIGI ARQ protocol. -Enable KISS for programs that supports UDP and TNC-2 KISS protocol. +Enable KISS for programs that supports TCP/UDP and TNC-2 KISS protocol. Only one interface (ARQ/KISS) can be active at any given time. KISS/ARQ/XML Addr/Port changes require program restart.} xywh {8 37 582 72} @@ -7123,7 +7130,7 @@ progdefaults.changed = true;} else progdefaults.enableBusyChannel = false; progdefaults.changed = true;} - tooltip {Enable Busy Channel} xywh {425 147 65 15} down_box DOWN_BOX + tooltip {Enable Busy Channel} xywh {331 145 65 15} down_box DOWN_BOX code0 {if(progdefaults.enableBusyChannel) o->value(true);} code1 {else o->value(false);} code2 {progStatus.ip_lock ? o->deactivate() : o->activate();} @@ -7146,7 +7153,7 @@ else progdefaults.kiss_dual_port_enabled = false; progdefaults.changed = true;} - tooltip {Enable when both programs are using the same IP address} xywh {425 168 90 16} down_box DOWN_BOX + tooltip {Enable when both programs are using the same IP address} xywh {485 169 90 16} down_box DOWN_BOX code0 {if(progdefaults.kiss_dual_port_enabled) o->value(true); else o->value(false);} code1 {progStatus.ip_lock ? o->deactivate() : o->activate();} } @@ -7156,6 +7163,54 @@ progdefaults.changed = true;} xywh {505 193 82 25} hide code0 {progStatus.ip_lock ? o->deactivate() : o->activate();} } + Fl_Button btn_connect_kiss_io { + label Connect + callback {connect_to_kiss_io();} + tooltip {Return KISS TCP IO connection to a Listening state} xywh {504 193 82 25} + code0 {(progStatus.ip_lock || !progStatus.kiss_tcp_io) ? o->deactivate() : o->activate();} + } + Fl_Check_Button btnKissTCPIO { + label TCP + callback {if(o->value()) { + progdefaults.kiss_tcp_io = true; + progStatus.kiss_tcp_io = true; +} else { + progStatus.kiss_tcp_io = false; + progdefaults.kiss_tcp_io = false; +} +kiss_io_set_button_state(0);} + tooltip {Check to enable TCP/IP IO Connection} xywh {425 145 60 15} down_box DOWN_BOX + code0 {if(progStatus.kiss_tcp_io) o->value(true); else o->value(false);} + code1 {progStatus.ip_lock ? o->deactivate() : o->activate();} + } + Fl_Check_Button btnKissUDPIO { + label UDP + callback {if(o->value()) { + progdefaults.kiss_tcp_io = false; + progStatus.kiss_tcp_io = false; +} else { + progStatus.kiss_tcp_io = true; + progdefaults.kiss_tcp_io = true; +} + +kiss_io_set_button_state(0);} + tooltip {Check to enable UDP/IP IO} xywh {425 170 60 15} down_box DOWN_BOX + code0 {if(progStatus.kiss_tcp_io) o->value(true); else o->value(false);} + code1 {progStatus.ip_lock ? o->deactivate() : o->activate();} + } + Fl_Check_Button btnKissTCPListen { + label {Listen / Bind} + callback {if(o->value()) { + progdefaults.kiss_tcp_listen = true; + progStatus.kiss_tcp_listen = true; +} else { + progStatus.kiss_tcp_listen = false; + progdefaults.kiss_tcp_listen = false; +}} + tooltip {Monitor for TCP connection} xywh {485 145 95 15} down_box DOWN_BOX + code0 {if(progStatus.kiss_tcp_listen) o->value(true); else o->value(false);} + code1 {progStatus.ip_lock ? o->deactivate() : o->activate();} + } } Fl_Group {} { label ARQ open @@ -7340,18 +7395,18 @@ progdefaults.changed = false;} xywh {20 388 130 22} } } -} +} Function {openConfig()} {return_type void } { code {if (!dlgConfig) createConfig(); progdefaults.loadDefaults();} {} -} +} Function {closeDialog()} {return_type void } { code {if (dlgConfig) dlgConfig->hide();} {} -} +} Function {createConfig()} {return_type void } { @@ -7359,10 +7414,10 @@ Function {createConfig()} {return_type void dlgConfig = ConfigureDialog(); dlgConfig->xclass(PACKAGE_NAME); }} {} -} +} decl {class Fl_File_Chooser ;} {public global -} +} Function {WefaxDestDirSet(Fl_File_Chooser *w, void *userdata)} {return_type void } { @@ -7372,7 +7427,7 @@ if( ( w->value() != NULL ) && ( ! w->shown() ) ) { btnWefaxSaveDir->redraw(); cb_btnWefaxSaveDir( btnWefaxSaveDir, NULL ); }} {} -} +} Function {KmlDestDirSet(Fl_File_Chooser *w, void *userdata)} {open return_type void } { @@ -7382,9 +7437,9 @@ if( ( w->value() != NULL ) && ( ! w->shown() ) ) { btnKmlSaveDir->redraw(); cb_btnKmlSaveDir( btnKmlSaveDir, NULL ); }} {} -} +} -Function {make_window()} {} {} +Function {make_window()} {} {} Function {make_window()} {open -} {} +} {} diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 66248a1f..8632104c 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -1418,6 +1418,8 @@ void update_scope() active_modem->refresh_scope(); } +extern bool valid_kiss_modem(std::string modem_name); + void init_modem(trx_mode mode, int freq) { ENSURE_THREAD(FLMAIN_TID); @@ -1441,10 +1443,26 @@ void init_modem(trx_mode mode, int freq) stopMacroTimer(); if (data_io_enabled == KISS_IO) { - if(!bcast_rsid_kiss_frame(freq, mode, (int) active_modem->get_txfreq(), active_modem->get_mode(), + trx_mode current_mode = active_modem->get_mode(); + if(!bcast_rsid_kiss_frame(freq, mode, (int) active_modem->get_txfreq(), current_mode, progdefaults.rsid_notify_only ? RSID_KISS_NOTIFY : RSID_KISS_ACTIVE)) { + LOG_INFO("Invaild Modem for KISS I/O (%s)", mode_info[mode].sname); - return; + + if(!fl_choice2(_("Switch to ARQ I/O"), _("Yes"), _("No"), NULL)) { + btnEnable_kiss->value(false); + btnEnable_kiss->do_callback(); + + btnEnable_arq->value(true); + btnEnable_arq->do_callback(); + } else { + std::string modem_name; + modem_name.assign(mode_info[current_mode].sname); + bool valid = valid_kiss_modem(modem_name); + if(!valid) + current_mode = MODE_PSK250; + mode = current_mode; + } } } @@ -5808,7 +5826,7 @@ void create_fl_digi_main_primary() { smeter->w(), smeter->h()); pwr_level = new Fl_Value_Slider2( - pwrlevel_grp->x(), pwrlevel_grp->y(), + pwrlevel_grp->x(), pwrlevel_grp->y(), pwrlevel_grp->w() - 50, pwrlevel_grp->h()); pwr_level->type(FL_HOR_NICE_SLIDER); pwr_level->range(0, 100.0); @@ -6027,7 +6045,7 @@ void create_fl_digi_main_primary() { opUsage = new Fl_Input2( opOutUsage->x() + opOutUsage->w() + pad, opOutUsage->y(), - opUsageFrame->w() - opOutUsage->w() - 50 - 3 * pad, + opUsageFrame->w() - opOutUsage->w() - 50 - 3 * pad, Hentry); opUsageEnter = new Fl_Button( @@ -6165,7 +6183,7 @@ void create_fl_digi_main_primary() { outSerNo1->type(FL_NORMAL_OUTPUT); inpSerNo1 = new Fl_Input2( - rightof(outSerNo1) + pad, y3, + rightof(outSerNo1) + pad, y3, 40, Hentry, "# R"); inpSerNo1->align(FL_ALIGN_LEFT); @@ -9219,6 +9237,52 @@ void set_ip_to_default(int which_io) } } +void kiss_io_set_button_state(void *ptr) +{ + + if(progStatus.kiss_tcp_io) { + btn_connect_kiss_io->activate(); + + btn_connect_kiss_io->redraw(); + btnKissTCPIO->activate(); + btnKissTCPIO->value(true); + btnKissTCPListen->activate(); + + btnKissUDPIO->value(false); + btnKissUDPIO->activate(); + btnEnable_dual_port->deactivate(); + + } else { + btn_connect_kiss_io->activate(); + + btnKissTCPIO->value(false); + btnKissTCPIO->activate(); + btnKissTCPListen->activate(); + + btnKissUDPIO->value(true); + btnKissUDPIO->activate(); + btnEnable_dual_port->activate(); + } + + char *label = (char *)0; + if(ptr) + label = (char *)ptr; + + if(label) { + btn_connect_kiss_io->label(label); + btn_connect_kiss_io->redraw(); + } + + if(progStatus.ip_lock) { + btn_connect_kiss_io->deactivate(); + btnKissTCPIO->deactivate(); + btnKissUDPIO->deactivate(); + btnKissTCPListen->deactivate(); + btnEnable_dual_port->deactivate(); + } + +} + void set_CSV(int start) { if (! (active_modem->get_mode() == MODE_ANALYSIS || diff --git a/src/include/confdialog.h b/src/include/confdialog.h index 34e217eb..1f16dcc4 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -392,6 +392,7 @@ extern Fl_ListBox *listbox_psk_status_timeout; extern Fl_Check_Button *btnEnablePSKbrowsing; extern Fl_Check_Button *btnPSKpilot; extern Fl_Counter2 *cnt_pilot_power; +extern Fl_Check_Button *btnPSK8Preamble; extern Fl_Group *tabRTTY; extern Fl_Tabs *tabsRTTY; extern Fl_ListBox *selShift; @@ -721,6 +722,10 @@ extern Fl_Check_Button *btnEnableBusyChannel; extern Fl_Input2 *txtKiss_ip_out_port_no; extern Fl_Check_Button *btnEnable_dual_port; extern Fl_Button *btn_restart_kiss; +extern Fl_Button *btn_connect_kiss_io; +extern Fl_Check_Button *btnKissTCPIO; +extern Fl_Check_Button *btnKissUDPIO; +extern Fl_Check_Button *btnKissTCPListen; extern Fl_Input2 *txtArq_ip_address; extern Fl_Input2 *txtArq_ip_port_no; extern Fl_Button *btnDefault_arq_ip; diff --git a/src/include/configuration.h b/src/include/configuration.h index a0d011ca..321171db 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -1682,6 +1682,12 @@ ELEM_(bool, csma_enabled, "CSMA_ENABLED", \ "Use CSMA on heavy traffic channels (AX25)", \ true) \ + ELEM_(bool, kiss_tcp_io, "KISS_TCP_IO", \ + "Connect kiss io via TCP/IP vise UDP/IP", \ + false) \ + ELEM_(bool, kiss_tcp_listen, "KISS_TCP_LISTEN", \ + "Listen for TCP connection (Server mode)", \ + false) \ ELEM_(std::string, flrig_ip_address, "FLRIG_IP_ADDRESS", \ "IP Address of flrig server", \ DEFAULT_FLRIG_IP_ADDRESS) \ @@ -1891,9 +1897,12 @@ ELEM_(bool, us_units, "US_UNITS", \ "Use US units of distance for QRB", \ false) \ - ELEM_(int, MacroEditFontsize, "MACROEDITFONTSIZE", \ + ELEM_(int, MacroEditFontsize, "MACROEDITFONTSIZE", \ "RX text font size", \ - 16) + 16) \ + ELEM_(bool, psk8DCDShortFlag, "PSK8DCDSHORTFLAG", \ + "Flag: Change DCD pre-ample length", \ + false) // declare the struct diff --git a/src/include/data_io.h b/src/include/data_io.h index 6911fb7a..b1146e4f 100644 --- a/src/include/data_io.h +++ b/src/include/data_io.h @@ -27,6 +27,13 @@ #ifndef fldigi_data_io_h #define fldigi_data_io_h +#include "gettext.h" + +#define IO_CONNECT_STR _("Connect") +#define IO_DISCONNECT_STR _("Disc") +#define IO_START_STR _("Start") +#define IO_STOP_STR _("Stop") + #define DEFAULT_ARQ_IP_ADDRESS "127.0.0.1" #define DEFAULT_ARQ_IP_PORT "7322" @@ -49,20 +56,25 @@ enum {DISABLED_IO, ARQ_IO, KISS_IO, XMLRPC_IO, FLRIG_IO, FLLOG_IO}; #define RSID_KISS_ACTIVE 0x02 #define RSID_KISS_USER 0x03 +#define DATA_IO_NA 0x00 +#define DATA_IO_TCP 0x01 +#define DATA_IO_UDP 0x02 + // This variable indepent of progdefaults.data_io_enabled // and progStatus.data_io_enabled // Only on start de we assign this variable with progStatus.data_io_enabled. // This is one way assignment as we dont want to save all of the available states // this variable will have. extern int data_io_enabled; // Located in kiss_io.cxx +extern int data_io_type; // Located in kiss_io.cxx extern void disable_config_p2p_io_widgets(void); extern void enable_config_p2p_io_widgets(void); extern void set_ip_to_default(int which_io); // KISS implementation -extern void kiss_init(void); -extern void kiss_close(void); +extern void kiss_init(bool connect_flag); +extern void kiss_close(bool override_flag); extern void kiss_reset(void); extern void WriteKISS(const char data); extern void WriteKISS(const char *data); @@ -78,6 +90,8 @@ extern bool kiss_bcast_trx_toggle; extern bool bcast_rsid_kiss_frame(int new_wf_pos, int new_mode, int old_wf_pos, int old_mode, int notify); extern void bcast_trxc_kiss_frame(void); extern void update_kpsql_fractional_gain(int value); +extern void kiss_io_set_button_state(void *); +extern void connect_to_kiss_io(void); // ARQ implementation extern void arq_init(void); diff --git a/src/include/kiss_io.h b/src/include/kiss_io.h index 369308ed..2d47ef9d 100644 --- a/src/include/kiss_io.h +++ b/src/include/kiss_io.h @@ -83,7 +83,7 @@ bool bcast_rsid_kiss_frame(int new_wf_pos, int new_mode, int old_wf_pos, int old inline std::string uppercase_string(std::string str); static double detect_signal(int freq, int bw, double *low, double *high); static bool kiss_queue_frame(KISS_QUEUE_FRAME * frame, std::string cmd); -static bool valid_kiss_modem(std::string _modem); +bool valid_kiss_modem(std::string _modem); static KISS_QUEUE_FRAME *encap_kiss_frame(char *buffer, size_t size, int frame_type, int kiss_port_no); static KISS_QUEUE_FRAME *encap_kiss_frame(std::string data, int kiss_frame_type, int port); static KISS_QUEUE_FRAME *encap_kiss_frame(std::string package, int frame_type, int kiss_port_no); diff --git a/src/include/socket.h b/src/include/socket.h index ac1153ec..3ffc41b2 100644 --- a/src/include/socket.h +++ b/src/include/socket.h @@ -138,10 +138,12 @@ public: void listen(int backlog = SOMAXCONN); Socket accept(void); Socket accept1(void); + Socket * accept2(void); // Client void connect(const Address& addr); void connect(void); + bool connect1(void); // Data Transimission size_t send(const void* buf, size_t len); diff --git a/src/include/status.h b/src/include/status.h index f6308bd3..09f38729 100644 --- a/src/include/status.h +++ b/src/include/status.h @@ -164,9 +164,11 @@ struct status { int busyChannelSeconds; int kpsql_attenuation; bool csma_enabled; + bool kiss_tcp_io; + bool kiss_tcp_listen; bool ip_lock; double squelch_value; - + bool psk8DCDShortFlag; std::string browser_search; bool meters; diff --git a/src/include/timeops.h b/src/include/timeops.h index da7fb0e3..9611cac1 100644 --- a/src/include/timeops.h +++ b/src/include/timeops.h @@ -26,11 +26,10 @@ #include #ifdef __MINGW32__ # include -//#endif #else # if !HAVE_CLOCK_GETTIME -enum clockid_t { CLOCK_REALTIME, CLOCK_MONOTONIC }; -int clock_gettime(clockid_t clock_id, struct timespec* tp); + enum clockid_t { CLOCK_REALTIME, CLOCK_MONOTONIC }; + int clock_gettime(clockid_t clock_id, struct timespec* tp); # endif #endif diff --git a/src/main.cxx b/src/main.cxx index 2b8c2801..0000c323 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -348,7 +348,7 @@ void delayed_startup(void *) data_io_enabled = DISABLED_IO; arq_init(); - kiss_init(); + //kiss_init(); if (progdefaults.connect_to_maclogger) maclogger_init(); data_io_enabled = progStatus.data_io_enabled; @@ -771,7 +771,7 @@ void exit_process() { if (progdefaults.kml_enabled) KmlServer::Exit(); arq_close(); - kiss_close(); + kiss_close(false); maclogger_close(); XML_RPC_Server::stop(); diff --git a/src/misc/kiss_io.cxx b/src/misc/kiss_io.cxx index 5a02f852..774b80b4 100644 --- a/src/misc/kiss_io.cxx +++ b/src/misc/kiss_io.cxx @@ -95,10 +95,11 @@ static pthread_mutex_t external_mutex = PTHREAD_MUTEX_INITIALIZER; bool kiss_enabled = false; bool kiss_exit = false; bool kiss_rx_exit = false; +bool allow_kiss_socket_io = false; static bool smack_crc_enabled = false; static int crc_mode = CRC16_CCITT; -static std::string default_kiss_modem = "PSK63RC5"; +static std::string default_kiss_modem = "BPSK250"; static std::string kiss_modem = ""; static unsigned int transmit_buffer_flush_timeout = 0; @@ -147,6 +148,7 @@ static double kpsql_threshold = 0.0; extern int IMAGE_WIDTH; Socket *kiss_socket = 0; int data_io_enabled = DISABLED_IO; +int data_io_type = DATA_IO_UDP; //static bool host_responded = false; // Used to scale the sensitivity of KPSQL @@ -165,6 +167,7 @@ extern void abort_tx(); static std::vector availabe_kiss_modems; extern void ax25_decode(unsigned char *buffer, size_t count, bool pad, bool tx_flag); +static void kiss_main_thread_close(void *ptr); static int kiss_raw_enabled = KISS_RAW_DISABLED; @@ -422,28 +425,25 @@ static void set_slider2(Fl_Slider2 * sider, int value) sider->do_callback(); } - /********************************************************************************** * **********************************************************************************/ -/* -static void set_valuator(Fl_Valuator* valuator, double value) -{ - valuator->value(value); - valuator->do_callback(); -} -*/ -/********************************************************************************** - * - **********************************************************************************/ -static bool valid_kiss_modem(string _modem) +bool valid_kiss_modem(string _modem) { if(_modem.empty()) return false; int index = 0; int count = availabe_kiss_modems.size(); + if(count < 1) { + for(index = 0; index < NUM_MODES; index++) + if(mode_info[index].iface_io & KISS_IO) + availabe_kiss_modems.push_back(mode_info[index].sname); + count = availabe_kiss_modems.size(); + } + std::string cmp_str = ""; + index = 0; while(index < count) { cmp_str = uppercase_string(availabe_kiss_modems[index]); @@ -3360,25 +3360,49 @@ static void *ReadFromHostSocket(void *args) static char buffer[2048]; string str_buffer; size_t count = 0; - + Socket *tmp_socket = (Socket *)0; memset(buffer, 0, sizeof(buffer)); str_buffer.reserve(sizeof(buffer)); LOG_INFO("%s", "Kiss RX loop started. "); + kiss_rx_exit = false; + allow_kiss_socket_io = false; + + if(progStatus.kiss_tcp_io && progStatus.kiss_tcp_listen) { + tmp_socket = kiss_socket->accept2(); + if(!tmp_socket) { + kiss_rx_exit = true; + } else { + kiss_socket->shut_down(); + kiss_socket->close(); + kiss_socket = tmp_socket; + } + } + + allow_kiss_socket_io = true; + while(!kiss_rx_exit) { memset(buffer, 0, sizeof(buffer)); try { + if(allow_kiss_socket_io) { + if(progStatus.kiss_tcp_io) + count = kiss_socket->recv((void *) buffer, sizeof(buffer) - 1); + else count = kiss_socket->recvFrom((void *) buffer, sizeof(buffer) - 1); + } } catch (...) { - if (errno) LOG_INFO("recvFrom Socket Error %d", errno); + if (errno) LOG_INFO("recv/recvFrom Socket Error %d", errno); count = 0; } - if(count && (data_io_enabled == KISS_IO)) { + if((count == 0) && (errno != 0)) { + kiss_rx_exit = true; + } + if(count && (data_io_enabled == KISS_IO)) { #ifdef EXTENED_DEBUG_INFO LOG_HEX(buffer, count); #endif @@ -3388,7 +3412,11 @@ static void *ReadFromHostSocket(void *args) } kiss_exit = true; + allow_kiss_socket_io = false; + if(kiss_socket) + kiss_socket->shut_down(); + Fl::awake(kiss_main_thread_close, (void *) 0); LOG_INFO("%s", "Kiss RX loop exit. "); return (void *)0; @@ -3415,7 +3443,12 @@ static void ReadFromHostSocket() } try { + if(allow_kiss_socket_io) { + if(progStatus.kiss_tcp_io) + count = kiss_socket->recv((void *) buffer, sizeof(buffer) - 1); + else count = kiss_socket->recvFrom((void *) buffer, sizeof(buffer) - 1); + } } catch (...) { LOG_INFO("Kiss RX Loop Shutdown"); count = 0; @@ -3589,10 +3622,16 @@ void WriteToHostSocket(void) if(to_host.empty()) return; if(kiss_socket && data_io_enabled == KISS_IO) { + if(allow_kiss_socket_io) { + if(progStatus.kiss_tcp_io) + kiss_socket->send(to_host.c_str(), to_host.size()); + else kiss_socket->sendTo(to_host.c_str(), to_host.size()); + } #ifdef EXTENED_DEBUG_INFO LOG_HEX(to_host.c_str(), to_host.size()); #endif + } to_host.clear(); } @@ -3721,6 +3760,55 @@ void WriteToHostBCastFramesBuffered(void) kiss_bc_frame.clear(); } +/********************************************************************************** + * + **********************************************************************************/ +bool tcp_init(bool connect_flag) +{ + if(progdefaults.kiss_address.empty() || progdefaults.kiss_io_port.empty()) { + LOG_DEBUG("%s", "KISS IP Address or Port null"); + return false; + } + + kiss_ip_address.assign(progdefaults.kiss_address); + kiss_ip_io_port.assign(progdefaults.kiss_io_port); + kiss_ip_out_port.assign(progdefaults.kiss_out_port); + + try { + kiss_socket = new Socket(Address(kiss_ip_address.c_str(), kiss_ip_io_port.c_str(), "tcp")); + kiss_socket->set_autoclose(true); + kiss_socket->set_nonblocking(false); + + if(progdefaults.kiss_tcp_listen) + kiss_socket->bind(); + } + catch (const SocketException& e) { + LOG_ERROR("Could not resolve %s: %s", kiss_ip_address.c_str(), e.what()); + if(kiss_socket) { + kiss_socket->shut_down(); + kiss_socket->close(); + delete kiss_socket; + kiss_socket = 0; + kiss_enabled = 0; + } + return false; + } + + if(connect_flag) { + if(kiss_socket->connect1() == false) { + LOG_INFO("Connection Failed: Host program present?"); + kiss_socket->shut_down(); + kiss_socket->close(); + delete kiss_socket; + kiss_socket = 0; + kiss_enabled = 0; + return false; + } + } + + return true; +} + /********************************************************************************** * **********************************************************************************/ @@ -3741,15 +3829,25 @@ bool udp_init(void) kiss_socket->set_dual_port_number(kiss_ip_out_port); kiss_socket->set_autoclose(true); kiss_socket->set_nonblocking(false); + + if(progdefaults.kiss_tcp_listen) // Listen flag indcates server mode. kiss_socket->bindUDP(); - } - catch (const SocketException& e) { + + } catch (const SocketException& e) { LOG_ERROR("Could not resolve %s: %s", kiss_ip_address.c_str(), e.what()); + if(kiss_socket) { + kiss_socket->shut_down(); + kiss_socket->close(); + delete kiss_socket; + kiss_socket = 0; + kiss_enabled = 0; + } return false; } return true; } + /********************************************************************************** * **********************************************************************************/ @@ -3816,44 +3914,45 @@ void kiss_reset(void) /********************************************************************************** * **********************************************************************************/ -void kiss_init(void) +void kiss_init(bool connect_flag) { kiss_enabled = false; kiss_exit = false; - int index = 0; - - for(index = 0; index < NUM_MODES; index++) - if(mode_info[index].iface_io & KISS_IO) - availabe_kiss_modems.push_back(mode_info[index].sname); - // progStatus.data_io_enabled (widget state), data_io_enabled (program state) + if(progStatus.data_io_enabled == KISS_IO) { if(!(active_modem->iface_io() & KISS_IO)) { set_default_kiss_modem(); } } - if(init_hist_flag) { memset(histogram, 0, sizeof(histogram)); init_hist_flag = false; } - if(!udp_init()) return; - - LOG_INFO("%s", "UDP Init - OK"); - srand(time(0)); // For CSMA persistance - update_kpsql_fractional_gain(progdefaults.kpsql_attenuation); + data_io_type = DATA_IO_NA; + + if(progStatus.kiss_tcp_io) { + if(progStatus.kiss_tcp_listen) connect_flag = false; + Fl::awake(kiss_io_set_button_state, (void *) IO_CONNECT_STR); + if(!tcp_init(connect_flag)) return; + LOG_INFO("%s", "TCP Init - OK"); + } else { + Fl::awake(kiss_io_set_button_state, (void *) IO_START_STR); + if(!udp_init()) return; + LOG_INFO("%s", "UDP Init - OK"); + } + if (pthread_create(&kiss_thread, NULL, kiss_loop, NULL) < 0) { LOG_ERROR("KISS kiss_thread: pthread_create failed"); return; } - #ifdef KISS_RX_THREAD if (pthread_create(&kiss_rx_socket_thread, NULL, ReadFromHostSocket, NULL) < 0) { LOG_ERROR("KISS kiss_rx_socket_thread: pthread_create failed"); @@ -3863,24 +3962,49 @@ void kiss_init(void) } #endif + if(progStatus.kiss_tcp_io) { + Fl::awake(kiss_io_set_button_state, (void *) IO_DISCONNECT_STR); + data_io_type = DATA_IO_TCP; + } else { + Fl::awake(kiss_io_set_button_state, (void *) IO_STOP_STR); + data_io_type = DATA_IO_UDP; + } + + if(progdefaults.data_io_enabled == KISS_IO) + data_io_enabled = KISS_IO; + kiss_enabled = true; + allow_kiss_socket_io = true; } /********************************************************************************** * **********************************************************************************/ -void kiss_close(void) +void kiss_main_thread_close(void *ptr) { - if (!kiss_enabled) return; + kiss_close(true); +} + +/********************************************************************************** + * + **********************************************************************************/ +void kiss_close(bool override_flag) +{ +// if (!kiss_enabled && !override_flag) return; kiss_text_available = false; + allow_kiss_socket_io = false; - if(data_io_enabled == KISS_IO) + if(data_io_enabled == KISS_IO) { data_io_enabled = DISABLED_IO; + data_io_type = DATA_IO_NA; + } if(kiss_socket) { kiss_socket->shut_down(); kiss_socket->close(); + } else { + return; } #ifdef KISS_RX_THREAD @@ -3905,8 +4029,26 @@ void kiss_close(void) LOG_INFO("%s", "Kiss loop terminated. "); - + kiss_socket = 0; kiss_enabled = false; + + if(progdefaults.kiss_tcp_io) + Fl::awake(kiss_io_set_button_state, (void *) IO_CONNECT_STR); + else + Fl::awake(kiss_io_set_button_state, (void *) IO_START_STR); + +} + +/********************************************************************************** + * + **********************************************************************************/ +void connect_to_kiss_io(void) +{ + if(kiss_socket) { + kiss_close(true); + } else { + kiss_init(progdefaults.kiss_tcp_listen ? false : true); + } } /********************************************************************************** diff --git a/src/misc/socket.cxx b/src/misc/socket.cxx index b9be9bac..dbc024ef 100644 --- a/src/misc/socket.cxx +++ b/src/misc/socket.cxx @@ -665,9 +665,11 @@ void Socket::bind(void) #else ; #endif - if (::bind(sockfd, ainfo->ai_addr, ainfo->ai_addrlen) == -1) + if (::bind(sockfd, ainfo->ai_addr, ainfo->ai_addrlen) == -1) { + if(errno != EADDRINUSE) // EADDRINUSE == 48 throw SocketException(errno, "bind"); } +} /// /// Binds the socket to the address associated with the object @@ -801,6 +803,30 @@ Socket Socket::accept1(void) return s; } +/// +/// Accepts a connection +/// +/// The socket must already have been bound to an address via a call to the bind +/// method. +/// +/// @return A Socket instance pointer for the accepted connection +/// +Socket * Socket::accept2(void) +{ + listen(); + + // wait for fd to become readable + if (nonblocking && ((timeout.tv_sec > 0) || (timeout.tv_usec > 0))) + if (!wait(0)) + throw SocketException(ETIMEDOUT, "select"); + + int r; + if ((r = ::accept(sockfd, NULL, 0)) == -1) + return (Socket *)0; + set_close_on_exec(true, r); + + return new Socket(r); +} /// /// Connects the socket to the address that is associated with the object @@ -813,6 +839,20 @@ void Socket::connect(void) if (::connect(sockfd, ainfo->ai_addr, ainfo->ai_addrlen) == -1) throw SocketException(errno, "connect"); } +/// +/// Connects the socket to the address that is associated with the object +/// Return connect state (T/F) +/// +bool Socket::connect1(void) +{ +#ifndef NDEBUG + LOG_DEBUG("Connecting to %s", address.get_str(ainfo).c_str()); +#endif + if (::connect(sockfd, ainfo->ai_addr, ainfo->ai_addrlen) == -1) { + return false; + } + return true; +} /// /// Set socket to allow for broadcasting. @@ -875,8 +915,14 @@ size_t Socket::send(const void* buf, size_t len) shutdown(sockfd, SHUT_WR); throw SocketException(errno, "send"); } else if (r == -1) { - if (errno != EAGAIN) + switch(errno) { + case EAGAIN: + case ENOTCONN: + case EBADF: + break; + default: throw SocketException(errno, "send"); + } r = 0; } } diff --git a/src/misc/status.cxx b/src/misc/status.cxx index 8641679e..93509619 100644 --- a/src/misc/status.cxx +++ b/src/misc/status.cxx @@ -199,8 +199,11 @@ status progStatus = { progdefaults.busyChannelSeconds, progdefaults.kpsql_attenuation, progdefaults.csma_enabled, + progdefaults.kiss_tcp_io, + progdefaults.kiss_tcp_listen, true, 0.0, + progdefaults.psk8DCDShortFlag, "CQ", // string browser_search; @@ -321,6 +324,9 @@ void status::saveLastState() busyChannelSeconds = progdefaults.busyChannelSeconds; kpsql_attenuation = progdefaults.kpsql_attenuation; csma_enabled = progdefaults.csma_enabled; + kiss_tcp_io = progdefaults.kiss_tcp_io; + kiss_tcp_listen = progdefaults.kiss_tcp_listen; + squelch_value = 0; Fl_Preferences spref(HomeDir.c_str(), "w1hkj.com", PACKAGE_TARNAME); @@ -335,6 +341,8 @@ void status::saveLastState() spref.set("pwr_squelch_level", sldrPwrSquelchValue); spref.set("afc_enabled", afconoff); + spref.set("psk8DCDShortFlag", psk8DCDShortFlag); + spref.set("log_enabled", LOGenabled); spref.set("wf_carrier", carrier); @@ -479,6 +487,9 @@ if (!bWF_only) { spref.set("busyChannelSeconds", busyChannelSeconds); spref.set("kpsql_attenuation", kpsql_attenuation); spref.set("csma_enabled", csma_enabled); + spref.set("kiss_tcp_io", kiss_tcp_io); + spref.set("kiss_tcp_listen", kiss_tcp_listen); + spref.set("browser_search", browser_search.c_str()); spref.set("meters", meters); @@ -707,6 +718,10 @@ void status::loadLastState() spref.get("busyChannelSeconds", i, busyChannelSeconds); busyChannelSeconds = i; spref.get("kpsql_attenuation", i, kpsql_attenuation); kpsql_attenuation = i; spref.get("csma_enabled", i, csma_enabled); csma_enabled = i; + spref.get("kiss_tcp_io", i, kiss_tcp_io); kiss_tcp_io = i; + spref.get("kiss_tcp_listen", i, kiss_tcp_listen); kiss_tcp_listen = i; + + spref.get("psk8DCDShortFlag", i, psk8DCDShortFlag); psk8DCDShortFlag = i; memset(strbuff, 0, sizeof(strbuff)); spref.get("browser_search", strbuff, browser_search.c_str(), sizeof(strbuff) - 1); @@ -865,6 +880,8 @@ void status::initLastState() cntKPSQLAttenuation->value(kpsql_attenuation); progdefaults.kpsql_attenuation = kpsql_attenuation; + kiss_io_set_button_state(0); + if (bWF_only) fl_digi_main->resize(mainX, mainY, mainW, Hmenu + Hwfall + Hstatus); else { diff --git a/src/psk/psk.cxx b/src/psk/psk.cxx index 3e629a6a..fa9e4943 100644 --- a/src/psk/psk.cxx +++ b/src/psk/psk.cxx @@ -773,7 +773,7 @@ psk::psk(trx_mode pskmode) : modem() dec->setchunksize(4); dec2 = new viterbi(K13, K16_POLY1, K16_POLY2); dec2->setchunksize(4); - + } else if (_xpsk || _8psk || _16psk) { enc = new encoder(K13, K13_POLY1, K13_POLY2); dec = new viterbi(K13, K13_POLY1, K13_POLY2); @@ -1143,9 +1143,9 @@ void psk::vestigial_afc() { std::setprecision(2); std::setw(5); for (i = 0; i < 11; i++) if (abs(sfft_bins[i]) > 2.0*avg) break; if (i < 11) { -// std::cout << "bin: " << i +// std::cout << "bin: " << i // << ", freq offset: " << (i - 5)*samplerate/16384.0 -// << ", amp: " << abs(sfft_bins[i]) +// << ", amp: " << abs(sfft_bins[i]) // << ", avg: " << avg << "\n"; if (i != 5) { frequency -= 1.0*(i-5)*samplerate/sfft_size; @@ -1351,7 +1351,7 @@ void psk::rx_symbol(cmplx symbol, int car) if (!_disablefec) break; set_dcdON = 0; break; - + case 0x10410410: // xpsk DCD on (with FEC enabled) if (_pskr) break; if (_qpsk) break; @@ -1361,7 +1361,7 @@ void psk::rx_symbol(cmplx symbol, int car) if (_disablefec) break; set_dcdON = 1; break; - + case 0x00000000: // bpsk DCD off. x,8,16psk DCD on (with FEC disabled). if (_pskr) break; if (_xpsk || _8psk || _16psk) { @@ -1419,7 +1419,7 @@ void psk::rx_symbol(cmplx symbol, int car) phasequality = (phasequality + lastphasequality) / 2; // Differential modem: average probabilities between current and previous symbols lastphasequality = phasequality; int soft_qualityerror = static_cast(128 - (128 * phasequality)) ; - + if (soft_qualityerror > 255-25) // Prevent soft-bit wrap-around (crossing of value 128) softpuncture = true; else if (soft_qualityerror < 128/3) // First 1/3 of phase delta is considered a perfect signal @@ -1427,8 +1427,8 @@ void psk::rx_symbol(cmplx symbol, int car) else if (soft_qualityerror > 128 - (128/8) ) // Last 1/8 of phase delta triggers a puncture softpuncture = true; else - soft_qualityerror /= 2; // Scale the FEC error to prevent premature cutoff - + soft_qualityerror /= 2; // Scale the FEC error to prevent premature cutoff + if (softpuncture) { for(int i=0; i to clear bit accumulators on both Tx and Rx ends. } + int symbol; if (_16psk) symbol = 8; else if (_8psk) symbol = 4; else symbol = 2; - for (int i = 0; i < dcdbits; i++) + + int _dcdbits = dcdbits - 1; + if(progStatus.psk8DCDShortFlag) + _dcdbits = 32/(symbits - 1); + + for (int i = 0; i <= _dcdbits; i++) // DCD window is only 32-bits wide tx_symbol(symbol); // 0 degrees // Standard BPSK postamble // DCD off sequence (unmodulated carrier) @@ -2132,6 +2138,12 @@ int psk::tx_process() { int c; + // DCD window is only 32 bits, send a maximum of 3-times. + if(progStatus.psk8DCDShortFlag) { + if ( (_8psk || _xpsk || _16psk) && preamble > 96) + preamble = 96; + } + if (preamble > 0) { if (_pskr || ((_xpsk || _8psk || _16psk) && !_disablefec) ) { if (startpreamble == true) {