Initial commit.

This commit is contained in:
Jonathan Naylor 2018-05-09 19:23:17 +01:00
commit 12d55cef37
430 changed files with 72067 additions and 0 deletions

View file

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{68CFAB6D-AED3-4B8A-BCB3-EE4136CA00A3}</ProjectGuid>
<RootNamespace>TimerControl</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>14.0.24720.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(WXWIN)\include;$(WXWIN)\lib\vc_dll\mswud;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(WXWIN)\include;$(WXWIN)\lib\vc_x64_dll\mswud;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../Common;../GUICommon;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../Common;../GUICommon;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;__WXDEBUG__;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../Common;../GUICommon;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(WXWIN)\include\msvc;$(WXWIN)\include;../Common;../GUICommon;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;WINVER=0x0400;__WXMSW__;WXUSINGDLL;wxUSE_GUI=1;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_dll;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="TimerControlApp.cpp" />
<ClCompile Include="TimerControlConfig.cpp" />
<ClCompile Include="TimerControlFrame.cpp" />
<ClCompile Include="TimerControlItemFile.cpp" />
<ClCompile Include="TimerControlPreferences.cpp" />
<ClCompile Include="TimerControlRemoteControlHandler.cpp" />
<ClCompile Include="TimerControlRemoteSet.cpp" />
<ClCompile Include="TimerControlRepeaterPanel.cpp" />
<ClCompile Include="TimerControlThread.cpp" />
<ClCompile Include="TimerControlThreadHelper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="TimerControlApp.h" />
<ClInclude Include="TimerControlConfig.h" />
<ClInclude Include="TimerControlDefs.h" />
<ClInclude Include="TimerControlFrame.h" />
<ClInclude Include="TimerControlItem.h" />
<ClInclude Include="TimerControlItemFile.h" />
<ClInclude Include="TimerControlPreferences.h" />
<ClInclude Include="TimerControlRemoteControlHandler.h" />
<ClInclude Include="TimerControlRemoteSet.h" />
<ClInclude Include="TimerControlRepeaterPanel.h" />
<ClInclude Include="TimerControlThread.h" />
<ClInclude Include="TimerControlThreadHelper.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.vcxproj">
<Project>{e793cb8e-2ac9-431a-bbfc-3f52537bb3cf}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\GUICommon\GUICommon.vcxproj">
<Project>{02d03515-0bbe-4553-8c40-566a597478f8}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="TimerControlApp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlConfig.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlFrame.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlItemFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlPreferences.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlRemoteControlHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlRemoteSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlRepeaterPanel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlThread.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TimerControlThreadHelper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="TimerControlApp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlDefs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlFrame.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlItem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlItemFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlPreferences.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlRemoteControlHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlRemoteSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlRepeaterPanel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlThread.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TimerControlThreadHelper.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View file

@ -0,0 +1,262 @@
/*
* Copyright (C) 2011-2015 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlThread.h"
#include "TimerControlDefs.h"
#include "TimerControlApp.h"
#include "Version.h"
#include "Logger.h"
#include <wx/config.h>
#include <wx/cmdline.h>
#include <wx/filename.h>
IMPLEMENT_APP(CTimerControlApp)
const wxChar* NAME_PARAM = wxT("Name");
const wxChar* NOLOGGING_SWITCH = wxT("nolog");
const wxChar* LOGDIR_OPTION = wxT("logdir");
const wxChar* CONFDIR_OPTION = wxT("confdir");
static const wxString LOG_BASE_NAME = wxT("timercontrol");
CTimerControlApp::CTimerControlApp() :
wxApp(),
m_name(),
m_fileName(),
m_nolog(false),
m_logDir(),
m_confDir(),
m_frame(NULL),
m_config(NULL),
m_thread(NULL)
{
}
CTimerControlApp::~CTimerControlApp()
{
}
bool CTimerControlApp::OnInit()
{
SetVendorName(VENDOR_NAME);
if (!wxApp::OnInit())
return false;
if (!m_nolog) {
wxString logBaseName = LOG_BASE_NAME;
if (!m_name.IsEmpty()) {
logBaseName.Append(wxT("_"));
logBaseName.Append(m_name);
}
#if defined(__WINDOWS__)
if (m_logDir.IsEmpty())
m_logDir = wxFileName::GetHomeDir();
#else
if (m_logDir.IsEmpty())
m_logDir = LOG_DIR;
#endif
wxLog* log = new CLogger(m_logDir, logBaseName);
wxLog::SetActiveTarget(log);
} else {
new wxLogNull;
}
#if defined(__WINDOWS__)
m_config = new CTimerControlConfig(new wxConfig(APPLICATION_NAME), m_name);
#else
if (m_confDir.IsEmpty())
m_confDir = wxT(CONF_DIR);
m_config = new CTimerControlConfig(m_confDir, m_name);
#endif
wxString frameName = APPLICATION_NAME + wxT(" - ");
if (!m_name.IsEmpty()) {
frameName.Append(m_name);
frameName.Append(wxT(" - "));
}
frameName.Append(VERSION);
if (!m_name.IsEmpty()) {
wxString fileBase = SCHEDULE_BASE_NAME;
fileBase.Append(wxT("_"));
fileBase.Append(m_name);
fileBase.Replace(wxT(" "), wxT("_"));
wxString dir = m_confDir;
if (dir.IsEmpty())
dir = wxFileName::GetHomeDir();
wxFileName fileName(dir, fileBase, wxT("dat"));
m_fileName = fileName.GetFullPath();
} else {
wxString dir = m_confDir;
if (dir.IsEmpty())
dir = wxFileName::GetHomeDir();
wxFileName fileName(dir, SCHEDULE_BASE_NAME, wxT("dat"));
m_fileName = fileName.GetFullPath();
}
wxPoint position = wxDefaultPosition;
int x, y;
getPosition(x, y);
if (x >= 0 && y >= 0)
position = wxPoint(x, y);
bool delay;
getDelay(delay);
m_frame = new CTimerControlFrame(frameName, position, delay);
m_frame->Show();
SetTopWindow(m_frame);
wxLogInfo(wxT("Starting ") + APPLICATION_NAME + wxT(" - ") + VERSION);
// Log the version of wxWidgets and the Operating System
wxLogInfo(wxT("Using wxWidgets %d.%d.%d on %s"), wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER, ::wxGetOsDescription().c_str());
createThread();
return wxApp::OnInit();
}
int CTimerControlApp::OnExit()
{
wxLogInfo(APPLICATION_NAME + wxT(" is exiting"));
m_thread->kill();
delete m_config;
return 0;
}
void CTimerControlApp::OnInitCmdLine(wxCmdLineParser& parser)
{
parser.AddSwitch(NOLOGGING_SWITCH, wxEmptyString, wxEmptyString, wxCMD_LINE_PARAM_OPTIONAL);
parser.AddOption(LOGDIR_OPTION, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
parser.AddOption(CONFDIR_OPTION, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
parser.AddParam(NAME_PARAM, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
wxApp::OnInitCmdLine(parser);
}
bool CTimerControlApp::OnCmdLineParsed(wxCmdLineParser& parser)
{
if (!wxApp::OnCmdLineParsed(parser))
return false;
m_nolog = parser.Found(NOLOGGING_SWITCH);
wxString logDir;
bool found = parser.Found(LOGDIR_OPTION, &logDir);
if (found)
m_logDir = logDir;
wxString confDir;
found = parser.Found(CONFDIR_OPTION, &confDir);
if (found)
m_confDir = confDir;
if (parser.GetParamCount() > 0U)
m_name = parser.GetParam(0U);
return true;
}
#if defined(__WXDEBUG__)
void CTimerControlApp::OnAssertFailure(const wxChar* file, int line, const wxChar* func, const wxChar* cond, const wxChar* msg)
{
wxLogFatalError(wxT("Assertion failed on line %d in file %s and function %s: %s %s"), line, file, func, cond, msg);
}
#endif
void CTimerControlApp::getGateway(wxString& address, unsigned int& port, wxString& password) const
{
m_config->getGateway(address, port, password);
}
void CTimerControlApp::setGateway(const wxString& address, unsigned int port, const wxString& password)
{
m_config->setGateway(address, port, password);
}
void CTimerControlApp::getDelay(bool& delay) const
{
m_config->getDelay(delay);
}
void CTimerControlApp::setDelay(bool delay)
{
m_config->setDelay(delay);
}
void CTimerControlApp::getPosition(int& x, int& y) const
{
m_config->getPosition(x, y);
}
void CTimerControlApp::setPosition(int x, int y)
{
m_config->setPosition(x, y);
}
void CTimerControlApp::writeConfig()
{
m_config->write();
}
void CTimerControlApp::writeItems()
{
m_frame->writeItems();
m_thread->reload();
}
void CTimerControlApp::createThread()
{
CTimerControlThread* thread = new CTimerControlThread;
wxString address, password;
unsigned int port;
getGateway(address, port, password);
thread->setGateway(address, port, password);
wxLogInfo(wxT("Gateway set to %s:%u"), address.c_str(), port);
bool delay;
getDelay(delay);
thread->setDelay(delay);
wxLogInfo(wxT("Delay set to %d"), int(delay));
wxLogInfo(wxT("Schedule file is %s"), m_fileName.c_str());
m_frame->setFileName(m_fileName);
thread->setFileName(m_fileName);
thread->reload();
// Convert the worker class into a thread
m_thread = new CTimerControlThreadHelper(thread);
m_thread->start();
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (C) 2011,2012,2013 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlApp_H
#define TimerControlApp_H
#include "TimerControlThreadHelper.h"
#include "TimerControlConfig.h"
#include "TimerControlFrame.h"
#include "TimerControlItem.h"
#include <wx/wx.h>
class CTimerControlApp : public wxApp {
public:
CTimerControlApp();
virtual ~CTimerControlApp();
virtual bool OnInit();
virtual int OnExit();
virtual void OnInitCmdLine(wxCmdLineParser& parser);
virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
// This is overridden because dialog boxes from threads are bad news
#if defined(__WXDEBUG__)
virtual void OnAssertFailure(const wxChar* file, int line, const wxChar* func, const wxChar* cond, const wxChar* msg);
#endif
virtual void getGateway(wxString& address, unsigned int& port, wxString& password) const;
virtual void setGateway(const wxString& address, unsigned int port, const wxString& password);
virtual void getDelay(bool& enabled) const;
virtual void setDelay(bool enabled);
virtual void getPosition(int& x, int& y) const;
virtual void setPosition(int x, int y);
virtual void writeConfig();
virtual void writeItems();
private:
wxString m_name;
wxString m_fileName;
bool m_nolog;
wxString m_logDir;
wxString m_confDir;
CTimerControlFrame* m_frame;
CTimerControlConfig* m_config;
CTimerControlThreadHelper* m_thread;
void createThread();
};
DECLARE_APP(CTimerControlApp)
#endif

View file

@ -0,0 +1,206 @@
/*
* Copyright (C) 2011-2015 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlConfig.h"
#include "TimerControlDefs.h"
#include "TimerControlAppD.h"
#include "Version.h"
#include "Logger.h"
#include <wx/cmdline.h>
#include <wx/wfstream.h>
#include <wx/fileconf.h>
#include <wx/filename.h>
const wxChar* NAME_PARAM = wxT("Name");
const wxChar* NOLOGGING_SWITCH = wxT("nolog");
const wxChar* LOGDIR_OPTION = wxT("logdir");
const wxChar* CONFDIR_OPTION = wxT("confdir");
const wxChar* DAEMON_SWITCH = wxT("daemon");
static const wxString LOG_BASE_NAME = wxT("timercontrold");
int main(int argc, char** argv)
{
bool res = ::wxInitialize();
if (!res) {
::fprintf(stderr, "timercontrold: failed to initialise the wxWidgets library, exiting\n");
return -1;
}
wxCmdLineParser parser(argc, argv);
parser.AddSwitch(NOLOGGING_SWITCH, wxEmptyString, wxEmptyString, wxCMD_LINE_PARAM_OPTIONAL);
parser.AddSwitch(DAEMON_SWITCH, wxEmptyString, wxEmptyString, wxCMD_LINE_PARAM_OPTIONAL);
parser.AddOption(LOGDIR_OPTION, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
parser.AddOption(CONFDIR_OPTION, wxEmptyString, wxEmptyString, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
parser.AddParam(NAME_PARAM, wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
int cmd = parser.Parse();
if (cmd != 0) {
::wxUninitialize();
return 0;
}
bool nolog = parser.Found(NOLOGGING_SWITCH);
bool daemon = parser.Found(DAEMON_SWITCH);
wxString logDir;
bool found = parser.Found(LOGDIR_OPTION, &logDir);
if (!found)
logDir.Clear();
wxString confDir;
found = parser.Found(CONFDIR_OPTION, &confDir);
if (!found)
confDir = wxT(CONF_DIR);
wxString name;
if (parser.GetParamCount() > 0U)
name = parser.GetParam(0U);
if (daemon) {
pid_t pid = ::fork();
if (pid < 0) {
::fprintf(stderr, "timercontrold: error in fork(), exiting\n");
::wxUninitialize();
return 1;
}
// If this is the parent, exit
if (pid > 0)
return 0;
// We are the child from here onwards
::setsid();
::chdir("/");
::umask(0);
}
CTimerControlAppD controller(nolog, logDir, confDir, name);
if (!controller.init()) {
::wxUninitialize();
return 1;
}
controller.run();
::wxUninitialize();
return 0;
}
CTimerControlAppD::CTimerControlAppD(bool nolog, const wxString& logDir, const wxString& confDir, const wxString& name) :
m_name(name),
m_nolog(nolog),
m_logDir(logDir),
m_confDir(confDir),
m_fileName(),
m_thread(NULL)
{
}
CTimerControlAppD::~CTimerControlAppD()
{
}
bool CTimerControlAppD::init()
{
if (!m_name.IsEmpty()) {
wxString fileBase = SCHEDULE_BASE_NAME;
fileBase.Append(wxT("_"));
fileBase.Append(m_name);
fileBase.Replace(wxT(" "), wxT("_"));
wxString dir = m_confDir;
if (dir.IsEmpty())
dir = wxFileName::GetHomeDir();
wxFileName fileName(dir, fileBase, wxT("dat"));
m_fileName = fileName.GetFullPath();
} else {
wxString dir = m_confDir;
if (dir.IsEmpty())
dir = wxFileName::GetHomeDir();
wxFileName fileName(dir, SCHEDULE_BASE_NAME, wxT("dat"));
m_fileName = fileName.GetFullPath();
}
if (!m_nolog) {
wxString logBaseName = LOG_BASE_NAME;
if (!m_name.IsEmpty()) {
logBaseName.Append(wxT("_"));
logBaseName.Append(m_name);
}
#if defined(__WINDOWS__)
if (m_logDir.IsEmpty())
m_logDir = wxFileName::GetHomeDir();
#else
if (m_logDir.IsEmpty())
m_logDir = LOG_DIR;
#endif
wxLog* log = new CLogger(m_logDir, logBaseName);
wxLog::SetActiveTarget(log);
} else {
new wxLogNull;
}
wxLogInfo(wxT("Starting ") + APPLICATION_NAME + wxT(" daemon - ") + VERSION);
// Log the version of wxWidgets and the Operating System
wxLogInfo(wxT("Using wxWidgets %d.%d.%d on %s"), wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER, ::wxGetOsDescription().c_str());
return createThread();
}
void CTimerControlAppD::run()
{
m_thread->run();
wxLogInfo(APPLICATION_NAME + wxT(" is exiting"));
}
bool CTimerControlAppD::createThread()
{
CTimerControlConfig config(m_confDir, m_name);
m_thread = new CTimerControlThread;
wxString address, password;
unsigned int port;
config.getGateway(address, port, password);
m_thread->setGateway(address, port, password);
wxLogInfo(wxT("Gateway set to %s:%u"), address.c_str(), port);
bool delay;
config.getDelay(delay);
m_thread->setDelay(delay);
wxLogInfo(wxT("Delay set to %d"), int(delay));
wxLogInfo(wxT("Schedule file is %s"), m_fileName.c_str());
m_thread->setFileName(m_fileName);
m_thread->reload();
return true;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2011 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlAppD_H
#define TimerControlAppD_H
#include "TimerControlThread.h"
#include <wx/wx.h>
class CTimerControlAppD {
public:
CTimerControlAppD(bool nolog, const wxString& logDir, const wxString& confDir, const wxString& name);
~CTimerControlAppD();
bool init();
void run();
private:
wxString m_name;
bool m_nolog;
wxString m_logDir;
wxString m_confDir;
wxString m_fileName;
CTimerControlThread* m_thread;
bool createThread();
};
#endif

View file

@ -0,0 +1,251 @@
/*
* Copyright (C) 2011,2012,2013 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlConfig.h"
#include "TimerControlDefs.h"
const wxString KEY_ADDRESS = wxT("address");
const wxString KEY_PORT = wxT("port");
const wxString KEY_PASSWORD = wxT("password");
const wxString KEY_DELAY = wxT("delay");
const wxString KEY_WINDOW_X = wxT("windowX");
const wxString KEY_WINDOW_Y = wxT("windowY");
const wxString DEFAULT_ADDRESS = wxEmptyString;
const long DEFAULT_PORT = 0L;
const wxString DEFAULT_PASSWORD = wxEmptyString;
const bool DEFAULT_DELAY = false;
const long DEFAULT_WINDOW_X = -1L;
const long DEFAULT_WINDOW_Y = -1L;
#if defined(__WINDOWS__)
CTimerControlConfig::CTimerControlConfig(wxConfigBase* config, const wxString& name) :
m_config(config),
m_name(wxT("/")),
m_address(DEFAULT_ADDRESS),
m_port(DEFAULT_PORT),
m_password(DEFAULT_PASSWORD),
m_delay(DEFAULT_DELAY),
m_x(DEFAULT_WINDOW_X),
m_y(DEFAULT_WINDOW_Y)
{
wxASSERT(config != NULL);
if (!name.IsEmpty())
m_name = wxT("/") + name;
m_config->Read(m_name + KEY_ADDRESS, &m_address, DEFAULT_ADDRESS);
long temp;
m_config->Read(m_name + KEY_PORT, &temp, DEFAULT_PORT);
m_port = (unsigned int)temp;
m_config->Read(m_name + KEY_PASSWORD, &m_password, DEFAULT_PASSWORD);
m_config->Read(m_name + KEY_DELAY, &m_delay, DEFAULT_DELAY);
m_config->Read(m_name + KEY_WINDOW_X, &temp, DEFAULT_WINDOW_X);
m_x = (unsigned int)temp;
m_config->Read(m_name + KEY_WINDOW_Y, &temp, DEFAULT_WINDOW_Y);
m_y = (unsigned int)temp;
}
CTimerControlConfig::~CTimerControlConfig()
{
delete m_config;
}
#else
CTimerControlConfig::CTimerControlConfig(const wxString& dir, const wxString& name) :
m_fileName(),
m_address(DEFAULT_ADDRESS),
m_port(DEFAULT_PORT),
m_password(DEFAULT_PASSWORD),
m_delay(DEFAULT_DELAY),
m_x(DEFAULT_WINDOW_X),
m_y(DEFAULT_WINDOW_Y)
{
wxASSERT(!dir.IsEmpty());
wxString fileName = CONFIG_FILE_NAME;
if (!name.IsEmpty())
fileName = CONFIG_FILE_NAME + wxT("_") + name;
m_fileName.Assign(dir, fileName);
wxTextFile file(m_fileName.GetFullPath());
bool exists = file.Exists();
if (!exists)
return;
bool ret = file.Open();
if (!ret) {
wxLogError(wxT("Cannot open the config file - %s"), m_fileName.GetFullPath().c_str());
return;
}
long temp;
wxString str = file.GetFirstLine();
while (!file.Eof()) {
if (str.GetChar(0U) == wxT('#')) {
str = file.GetNextLine();
continue;
}
int n = str.Find(wxT('='));
if (n == wxNOT_FOUND) {
str = file.GetNextLine();
continue;
}
wxString key = str.Left(n);
wxString val = str.Mid(n + 1U);
if (key.IsSameAs(KEY_ADDRESS)) {
m_address = val;
} else if (key.IsSameAs(KEY_PORT)) {
val.ToLong(&temp);
m_port = (unsigned int)temp;
} else if (key.IsSameAs(KEY_PASSWORD)) {
m_password = val;
} else if (key.IsSameAs(KEY_DELAY)) {
val.ToLong(&temp);
m_delay = temp == 1L;
} else if (key.IsSameAs(KEY_WINDOW_X)) {
val.ToLong(&temp);
m_x = int(temp);
} else if (key.IsSameAs(KEY_WINDOW_Y)) {
val.ToLong(&temp);
m_y = int(temp);
}
str = file.GetNextLine();
}
file.Close();
}
CTimerControlConfig::~CTimerControlConfig()
{
}
#endif
void CTimerControlConfig::getGateway(wxString& address, unsigned int& port, wxString& password) const
{
address = m_address;
port = m_port;
password = m_password;
}
void CTimerControlConfig::setGateway(const wxString& address, unsigned int port, const wxString& password)
{
m_address = address;
m_port = port;
m_password = password;
}
void CTimerControlConfig::getDelay(bool& delay) const
{
delay = m_delay;
}
void CTimerControlConfig::setDelay(bool delay)
{
m_delay = delay;
}
void CTimerControlConfig::getPosition(int& x, int& y) const
{
x = m_x;
y = m_y;
}
void CTimerControlConfig::setPosition(int x, int y)
{
m_x = x;
m_y = y;
}
#if defined(__WINDOWS__)
bool CTimerControlConfig::write()
{
m_config->Write(m_name + KEY_ADDRESS, m_address);
m_config->Write(m_name + KEY_PORT, long(m_port));
m_config->Write(m_name + KEY_PASSWORD, m_password);
m_config->Write(m_name + KEY_DELAY, m_delay);
m_config->Write(m_name + KEY_WINDOW_X, long(m_x));
m_config->Write(m_name + KEY_WINDOW_Y, long(m_y));
m_config->Flush();
return true;
}
#else
bool CTimerControlConfig::write()
{
wxTextFile file(m_fileName.GetFullPath());
bool exists = file.Exists();
if (exists) {
bool ret = file.Open();
if (!ret) {
wxLogError(wxT("Cannot open the config file - %s"), m_fileName.GetFullPath().c_str());
return false;
}
// Remove the existing file entries
file.Clear();
} else {
bool ret = file.Create();
if (!ret) {
wxLogError(wxT("Cannot create the config file - %s"), m_fileName.GetFullPath().c_str());
return false;
}
}
wxString buffer;
buffer.Printf(wxT("%s=%s"), KEY_ADDRESS.c_str(), m_address.c_str()); file.AddLine(buffer);
buffer.Printf(wxT("%s=%u"), KEY_PORT.c_str(), m_port); file.AddLine(buffer);
buffer.Printf(wxT("%s=%s"), KEY_PASSWORD.c_str(), m_password.c_str()); file.AddLine(buffer);
buffer.Printf(wxT("%s=%d"), KEY_DELAY.c_str(), m_delay ? 1 : 0); file.AddLine(buffer);
buffer.Printf(wxT("%s=%d"), KEY_WINDOW_X.c_str(), m_x); file.AddLine(buffer);
buffer.Printf(wxT("%s=%d"), KEY_WINDOW_Y.c_str(), m_y); file.AddLine(buffer);
bool ret = file.Write();
if (!ret) {
file.Close();
wxLogError(wxT("Cannot write the config file - %s"), m_fileName.GetFullPath().c_str());
return false;
}
file.Close();
return true;
}
#endif

View file

@ -0,0 +1,62 @@
/*
* Copyright (C) 2011,2012,2013 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlConfig_H
#define TimerControlConfig_H
#include <wx/wx.h>
#include <wx/config.h>
#include <wx/filename.h>
class CTimerControlConfig {
public:
#if defined(__WINDOWS__)
CTimerControlConfig(wxConfigBase* config, const wxString& name);
#else
CTimerControlConfig(const wxString& dir, const wxString& name);
#endif
~CTimerControlConfig();
void getGateway(wxString& address, unsigned int& port, wxString& password) const;
void setGateway(const wxString& address, unsigned int port, const wxString& password);
void getDelay(bool& enabled) const;
void setDelay(bool enabled);
void getPosition(int& x, int& y) const;
void setPosition(int x, int y);
bool write();
private:
#if defined(__WINDOWS__)
wxConfigBase* m_config;
wxString m_name;
#else
wxFileName m_fileName;
#endif
wxString m_address;
unsigned int m_port;
wxString m_password;
bool m_delay;
int m_x;
int m_y;
};
#endif

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2011 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlDefs_H
#define TimerControlDefs_H
#include <wx/wx.h>
const wxString APPLICATION_NAME = wxT("Timer Control");
#if !defined(__WINDOWS__)
const wxString CONFIG_FILE_NAME = wxT("timercontrol");
#endif
const wxString SCHEDULE_BASE_NAME = wxT("Schedule");
#endif

View file

@ -0,0 +1,343 @@
/*
* Copyright (C) 2011-2015 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlPreferences.h"
#include "TimerControlItemFile.h"
#include "TimerControlFrame.h"
#include "TimerControlItem.h"
#include "TimerControlDefs.h"
#include "TimerControlApp.h"
#include "Version.h"
#include "SHA256.h"
const unsigned int BORDER_SIZE = 5U;
#if defined(__WINDOWS__)
const unsigned int MAIN_HEIGHT = 350U;
const unsigned int MAIN_WIDTH = 500U;
#else
const unsigned int MAIN_HEIGHT = 400U;
const unsigned int MAIN_WIDTH = 590U;
#endif
#include <wx/aboutdlg.h>
enum {
Menu_Edit_Preferences = 7000,
Timer_Timer1,
Timer_Timer2
};
BEGIN_EVENT_TABLE(CTimerControlFrame, wxFrame)
EVT_MENU(wxID_EXIT, CTimerControlFrame::onQuit)
EVT_MENU(Menu_Edit_Preferences, CTimerControlFrame::onPreferences)
EVT_MENU(wxID_ABOUT, CTimerControlFrame::onAbout)
EVT_TIMER(Timer_Timer1, CTimerControlFrame::onTimer1)
EVT_TIMER(Timer_Timer2, CTimerControlFrame::onTimer2)
EVT_CLOSE(CTimerControlFrame::onClose)
END_EVENT_TABLE()
CTimerControlFrame::CTimerControlFrame(const wxString& title, const wxPoint& position, bool delay) :
wxFrame(NULL, -1, title, position),
m_state(TCFS_NORMAL),
m_timer1(this, Timer_Timer1),
m_timer2(this, Timer_Timer2),
m_noteBook(NULL),
m_handler(NULL),
m_password(),
m_fileName(),
m_repeaters()
{
SetMenuBar(createMenuBar());
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
wxPanel* panel = new wxPanel(this, -1);
wxBoxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);
m_noteBook = new wxNotebook(panel, -1, wxDefaultPosition, wxSize(MAIN_WIDTH, MAIN_HEIGHT));
panelSizer->Add(m_noteBook, 0, wxALL | wxGROW, BORDER_SIZE);
panel->SetSizer(panelSizer);
panelSizer->SetSizeHints(panel);
mainSizer->Add(panel);
SetSizer(mainSizer);
mainSizer->SetSizeHints(this);
m_timer1.Start(delay ? 20000 : 100, wxTIMER_ONE_SHOT);
}
CTimerControlFrame::~CTimerControlFrame()
{
}
wxMenuBar* CTimerControlFrame::createMenuBar()
{
wxMenu* fileMenu = new wxMenu();
fileMenu->Append(wxID_EXIT, _("Exit"));
wxMenu* editMenu = new wxMenu();
editMenu->Append(Menu_Edit_Preferences, _("Preferences..."));
wxMenu* helpMenu = new wxMenu();
helpMenu->Append(wxID_ABOUT, _("About Timer Control"));
wxMenuBar* menuBar = new wxMenuBar();
menuBar->Append(fileMenu, _("File"));
menuBar->Append(editMenu, _("Edit"));
menuBar->Append(helpMenu, _("Help"));
return menuBar;
}
void CTimerControlFrame::onQuit(wxCommandEvent&)
{
Close(false);
}
void CTimerControlFrame::onClose(wxCloseEvent&)
{
int x, y;
GetPosition(&x, &y);
if (x >= 0 && y >= 0) {
::wxGetApp().setPosition(x, y);
::wxGetApp().writeConfig();
}
m_timer1.Stop();
m_timer2.Stop();
if (m_handler != NULL) {
m_handler->logout();
m_handler->close();
}
Destroy();
}
void CTimerControlFrame::onPreferences(wxCommandEvent&)
{
wxString address, password;
unsigned int port;
::wxGetApp().getGateway(address, port, password);
bool delay;
::wxGetApp().getDelay(delay);
CTimerControlPreferences dialog1(this, -1, address, port, password, delay);
if (dialog1.ShowModal() != wxID_OK)
return;
address = dialog1.getAddress();
port = dialog1.getPort();
password = dialog1.getPassword();
delay = dialog1.getDelay();
::wxGetApp().setGateway(address, port, password);
::wxGetApp().setDelay(delay);
::wxGetApp().writeConfig();
wxMessageDialog dialog2(this, _("The changes made will not take effect\nuntil the application is restarted"), _("Timer Control Information"), wxICON_INFORMATION);
dialog2.ShowModal();
}
void CTimerControlFrame::onAbout(wxCommandEvent&)
{
wxAboutDialogInfo info;
info.AddDeveloper(wxT("Jonathan Naylor, G4KLX"));
info.SetCopyright(wxT("(C) 2011-2015 using GPL v2 or later"));
info.SetName(APPLICATION_NAME);
info.SetVersion(VERSION);
info.SetDescription(_("This program allows for the controlling of\nthe ircDDB Gateway."));
::wxAboutBox(info);
}
void CTimerControlFrame::onTimer1(wxTimerEvent&)
{
startup();
}
void CTimerControlFrame::onTimer2(wxTimerEvent&)
{
TC_TYPE type = m_handler->readType();
switch (type) {
case TCT_NONE:
m_handler->retry();
break;
case TCT_ACK:
if (m_state == TCFS_HASH) {
m_handler->setLoggedIn(true);
m_handler->getCallsigns();
m_state = TCFS_NORMAL;
}
break;
case TCT_NAK: {
if (m_state == TCFS_HASH || m_state == TCFS_LOGIN)
m_handler->setLoggedIn(false);
m_handler->logout();
wxString text = m_handler->readNAK();
m_state = TCFS_NORMAL;
::wxMessageBox(text);
}
break;
case TCT_RANDOM: {
unsigned int rnd = m_handler->readRandom();
sendHash(rnd);
m_state = TCFS_HASH;
}
break;
case TCT_CALLSIGNS: {
m_noteBook->DeleteAllPages();
wxArrayString data = m_handler->readCallsigns();
for (unsigned int i = 0U; i < data.GetCount(); i++)
addRepeater(data.Item(i));
m_handler->logout();
loadItems();
}
break;
}
}
void CTimerControlFrame::startup()
{
wxString address;
unsigned int port;
::wxGetApp().getGateway(address, port, m_password);
if (address.IsEmpty() || port == 0U || m_password.IsEmpty())
return;
m_handler = new CTimerControlRemoteControlHandler(address, port);
bool ret = m_handler->open();
if (!ret) {
delete m_handler;
m_handler = NULL;
return;
}
ret = m_handler->login();
if (!ret) {
m_handler->close();
delete m_handler;
m_handler = NULL;
return;
}
m_state = TCFS_LOGIN;
m_timer2.Start(100, wxTIMER_CONTINUOUS);
}
void CTimerControlFrame::addRepeater(const wxString& callsign)
{
CTimerControlRepeaterPanel* repeater = new CTimerControlRepeaterPanel(m_noteBook, -1, callsign);
m_noteBook->AddPage(repeater, callsign, false);
m_repeaters[callsign] = repeater;
}
void CTimerControlFrame::setFileName(const wxString& fileName)
{
m_fileName = fileName;
}
void CTimerControlFrame::loadItems()
{
CTimerControlItemFile file(m_fileName);
unsigned int count;
CTimerControlItem** items = file.readItems(count);
if (count == 0U)
return;
for (CRepeater_t::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it)
(*it).second->load(items, count);
delete[] items;
}
void CTimerControlFrame::writeItems()
{
// Count the total number of items from all the panels
unsigned int count = 0U;
for (CRepeater_t::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it)
count += (*it).second->getCount();
if (count == 0U)
return;
CTimerControlItem** items = new CTimerControlItem*[count];
unsigned int n = 0U;
for (CRepeater_t::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
unsigned int count1 = (*it).second->getCount();
CTimerControlItem** items1 = (*it).second->getItems();
for (unsigned int i = 0U; i < count1; i++, n++)
items[n] = items1[i];
delete[] items1;
}
CTimerControlItemFile file(m_fileName);
file.writeItems(items, count);
delete[] items;
}
void CTimerControlFrame::sendHash(unsigned int rnd)
{
unsigned int len = m_password.Len() + sizeof(unsigned int);
unsigned char* in = new unsigned char[len];
unsigned char* out = new unsigned char[32U];
::memcpy(in, &rnd, sizeof(unsigned int));
for (unsigned int i = 0U; i < m_password.Len(); i++)
in[i + sizeof(unsigned int)] = m_password.GetChar(i);
CSHA256 sha256;
sha256.buffer(in, len, out);
m_handler->sendHash(out, 32U);
delete[] in;
delete[] out;
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2011,2012 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlFrame_H
#define TimerControlFrame_H
#include "TimerControlRemoteControlHandler.h"
#include "TimerControlRepeaterPanel.h"
#include "Defs.h"
#include <wx/wx.h>
#include <wx/notebook.h>
WX_DECLARE_STRING_HASH_MAP(CTimerControlRepeaterPanel*, CRepeater_t);
enum TCF_STATE {
TCFS_NORMAL,
TCFS_LOGIN,
TCFS_HASH
};
class CTimerControlFrame : public wxFrame {
public:
CTimerControlFrame(const wxString& title, const wxPoint& position, bool delay);
virtual ~CTimerControlFrame();
virtual void onQuit(wxCommandEvent& event);
virtual void onPreferences(wxCommandEvent& event);
virtual void onAbout(wxCommandEvent& event);
virtual void onClose(wxCloseEvent& event);
virtual void onTimer1(wxTimerEvent& event);
virtual void onTimer2(wxTimerEvent& event);
virtual void setFileName(const wxString& fileName);
virtual void writeItems();
private:
TCF_STATE m_state;
wxTimer m_timer1;
wxTimer m_timer2;
wxNotebook* m_noteBook;
CTimerControlRemoteControlHandler* m_handler;
wxString m_password;
wxString m_fileName;
CRepeater_t m_repeaters;
DECLARE_EVENT_TABLE()
wxMenuBar* createMenuBar();
void startup();
void addRepeater(const wxString& callsign);
void sendHash(unsigned int rnd);
void loadItems();
};
#endif

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2011 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlItem_H
#define TimerControlItem_H
#include "Defs.h"
#include <wx/wx.h>
struct CTimerControlItem {
wxString m_repeater;
unsigned int m_day;
unsigned int m_hour;
unsigned int m_minute;
wxString m_reflector;
RECONNECT m_reconnect;
};
#endif

View file

@ -0,0 +1,137 @@
/*
* Copyright (C) 2011,2013 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlItemFile.h"
#include <wx/ffile.h>
#include <wx/file.h>
const unsigned int RECORD_LENGTH = 32U;
CTimerControlItemFile::CTimerControlItemFile(const wxString& fileName) :
m_fileName(fileName),
m_mutex()
{
}
CTimerControlItemFile::~CTimerControlItemFile()
{
}
bool CTimerControlItemFile::writeItems(CTimerControlItem** items, unsigned int count)
{
wxMutexLocker locker(m_mutex);
wxFFile file;
bool ret = file.Open(m_fileName, wxT("wb"));
if (!ret) {
wxLogError(wxT("Cannot open %s for writing"), m_fileName.c_str());
return false;
}
file.Write("TC1", 3U);
for (unsigned int i = 0U; i < count; i++) {
unsigned char buffer[RECORD_LENGTH];
::memset(buffer, ' ', RECORD_LENGTH);
wxString repeater = items[i]->m_repeater;
for (unsigned int j = 0U; j < repeater.Len(); j++)
buffer[j + 0U] = repeater.GetChar(j);
wxUint32 day = wxUint32(items[i]->m_day);
::memcpy(buffer + 8U, &day, sizeof(wxUint32));
wxUint32 hour = wxUint32(items[i]->m_hour);
::memcpy(buffer + 12U, &hour, sizeof(wxUint32));
wxUint32 minute = wxUint32(items[i]->m_minute);
::memcpy(buffer + 16U, &minute, sizeof(wxUint32));
wxString reflector = items[i]->m_reflector;
for (unsigned int j = 0U; j < reflector.Len(); j++)
buffer[j + 20U] = reflector.GetChar(j);
wxUint32 reconnect = wxUint32(items[i]->m_reconnect);
::memcpy(buffer + 28U, &reconnect, sizeof(wxUint32));
file.Write(buffer, RECORD_LENGTH);
}
file.Close();
return true;
}
CTimerControlItem** CTimerControlItemFile::readItems(unsigned int& count)
{
wxMutexLocker locker(m_mutex);
count = 0U;
bool exists = wxFile::Exists(m_fileName);
if (!exists)
return NULL;
wxFFile file;
bool ret = file.Open(m_fileName, wxT("rb"));
if (!ret)
return NULL;
unsigned int length = file.Length();
if (length < 3U) {
file.Close();
return NULL;
}
count = (length - 3U) / RECORD_LENGTH;
unsigned char buffer[RECORD_LENGTH];
file.Read(buffer, 3U);
if (::memcmp(buffer, "TC1", 3U) != 0) {
file.Close();
return NULL;
}
CTimerControlItem** items = new CTimerControlItem*[count];
for (unsigned int i = 0U; i < count; i++) {
file.Read(buffer, RECORD_LENGTH);
wxString repeater = wxString((char*)(buffer + 0U), wxConvLocal, 8U);
wxUint32* day = (wxUint32*)(buffer + 8U);
wxUint32* hour = (wxUint32*)(buffer + 12U);
wxUint32* minute = (wxUint32*)(buffer + 16U);
wxString reflector = wxString((char*)(buffer + 20U), wxConvLocal, 8U);
wxUint32* reconnect = (wxUint32*)(buffer + 28U);
CTimerControlItem* item = new CTimerControlItem;
item->m_repeater = repeater;
item->m_day = *day;
item->m_hour = *hour;
item->m_minute = *minute;
item->m_reflector = reflector.Trim();
item->m_reconnect = RECONNECT(*reconnect);
items[i] = item;
}
file.Close();
return items;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2011,2013 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlItemFile_H
#define TimerControlItemFile_H
#include "TimerControlItem.h"
#include <wx/wx.h>
class CTimerControlItemFile {
public:
CTimerControlItemFile(const wxString& fileName);
~CTimerControlItemFile();
bool writeItems(CTimerControlItem** items, unsigned int count);
CTimerControlItem** readItems(unsigned int& count);
private:
wxString m_fileName;
wxMutex m_mutex;
};
#endif

View file

@ -0,0 +1,75 @@
/*
* Copyright (C) 2011,2012 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlPreferences.h"
#include "TimerControlDefs.h"
const unsigned int BORDER_SIZE = 5U;
CTimerControlPreferences::CTimerControlPreferences(wxWindow* parent, int id, const wxString& address, unsigned int port, const wxString& password, bool delay) :
wxDialog(parent, id, wxString(_("Timer Control Preferences"))),
m_remote(NULL)
{
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
wxNotebook* noteBook = new wxNotebook(this, -1);
m_remote = new CTimerControlRemoteSet(noteBook, -1, APPLICATION_NAME, address, port, password, delay);
noteBook->AddPage(m_remote, _("Gateway"), true);
mainSizer->Add(noteBook, 1, wxALL | wxGROW, BORDER_SIZE);
mainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE);
SetAutoLayout(true);
Layout();
mainSizer->Fit(this);
mainSizer->SetSizeHints(this);
SetSizer(mainSizer);
}
CTimerControlPreferences::~CTimerControlPreferences()
{
}
bool CTimerControlPreferences::Validate()
{
return m_remote->Validate();
}
wxString CTimerControlPreferences::getAddress() const
{
return m_remote->getAddress();
}
unsigned int CTimerControlPreferences::getPort() const
{
return m_remote->getPort();
}
wxString CTimerControlPreferences::getPassword() const
{
return m_remote->getPassword();
}
bool CTimerControlPreferences::getDelay() const
{
return m_remote->getDelay();
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2011,2012 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlPreferences_H
#define TimerControlPreferences_H
#include <wx/wx.h>
#include <wx/notebook.h>
#include "TimerControlRemoteSet.h"
class CTimerControlPreferences : public wxDialog {
public:
CTimerControlPreferences(wxWindow* parent, int id, const wxString& address, unsigned int port, const wxString& password, bool delay);
virtual ~CTimerControlPreferences();
virtual bool Validate();
virtual wxString getAddress() const;
virtual unsigned int getPort() const;
virtual wxString getPassword() const;
virtual bool getDelay() const;
private:
CTimerControlRemoteSet* m_remote;
};
#endif

View file

@ -0,0 +1,295 @@
/*
* Copyright (C) 2011,2013 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlRemoteControlHandler.h"
#include "DStarDefines.h"
const unsigned int BUFFER_LENGTH = 2000U;
const unsigned int MAX_RETRIES = 3U;
CTimerControlRemoteControlHandler::CTimerControlRemoteControlHandler(const wxString& address, unsigned int port) :
m_socket(wxEmptyString, 0U),
m_address(),
m_port(port),
m_loggedIn(false),
m_retryCount(0U),
m_type(TCT_NONE),
m_inBuffer(NULL),
m_inLength(0U),
m_outBuffer(NULL),
m_outLength(0U)
{
wxASSERT(!address.IsEmpty());
wxASSERT(port > 0U);
m_address = CUDPReaderWriter::lookup(address);
m_inBuffer = new unsigned char[BUFFER_LENGTH];
m_outBuffer = new unsigned char[BUFFER_LENGTH];
}
CTimerControlRemoteControlHandler::~CTimerControlRemoteControlHandler()
{
delete[] m_inBuffer;
delete[] m_outBuffer;
}
bool CTimerControlRemoteControlHandler::open()
{
return m_socket.open();
}
TC_TYPE CTimerControlRemoteControlHandler::readType()
{
m_type = TCT_NONE;
in_addr address;
unsigned int port;
int length = m_socket.read(m_inBuffer, BUFFER_LENGTH, address, port);
if (length <= 0)
return m_type;
m_inLength = length;
if (::memcmp(m_inBuffer, "ACK", 3U) == 0) {
m_retryCount = 0U;
m_type = TCT_ACK;
return m_type;
} else if (::memcmp(m_inBuffer, "NAK", 3U) == 0) {
m_retryCount = 0U;
m_type = TCT_NAK;
return m_type;
} else if (::memcmp(m_inBuffer, "RND", 3U) == 0) {
m_retryCount = 0U;
m_type = TCT_RANDOM;
return m_type;
} else if (::memcmp(m_inBuffer, "CAL", 3U) == 0) {
m_retryCount = 0U;
m_type = TCT_CALLSIGNS;
return m_type;
}
return m_type;
}
wxString CTimerControlRemoteControlHandler::readNAK()
{
if (m_type != TCT_NAK)
return wxEmptyString;
wxString text((char*)(m_inBuffer + 3U), wxConvLocal);
return text;
}
unsigned int CTimerControlRemoteControlHandler::readRandom()
{
if (m_type != TCT_RANDOM)
return 0U;
wxUint32 random;
::memcpy(&random, m_inBuffer + 3U, sizeof(wxUint32));
return wxUINT32_SWAP_ON_BE(random);
}
wxArrayString CTimerControlRemoteControlHandler::readCallsigns()
{
wxArrayString data;
if (m_type != TCT_CALLSIGNS)
return data;
unsigned char* p = m_inBuffer + 3U;
unsigned int pos = 3U;
while (pos < m_inLength) {
unsigned char type = *p;
pos += 1U;
p += 1U;
wxString callsign((char*)p, wxConvLocal, LONG_CALLSIGN_LENGTH);
pos += LONG_CALLSIGN_LENGTH;
p += LONG_CALLSIGN_LENGTH;
if (type == 'R')
data.Add(callsign);
}
return data;
}
bool CTimerControlRemoteControlHandler::login()
{
if (m_loggedIn)
return false;
if (m_address.s_addr == INADDR_NONE)
return false;
::memcpy(m_outBuffer, "LIN", 3U);
m_outLength = 3U;
bool ret = m_socket.write(m_outBuffer, m_outLength, m_address, m_port);
if (!ret) {
m_retryCount = 0U;
return false;
} else {
m_retryCount = 1U;
return true;
}
}
void CTimerControlRemoteControlHandler::setLoggedIn(bool set)
{
m_loggedIn = set;
}
bool CTimerControlRemoteControlHandler::getCallsigns()
{
if (!m_loggedIn || m_retryCount > 0U)
return false;
::memcpy(m_outBuffer, "GCS", 3U);
m_outLength = 3U;
bool ret = m_socket.write(m_outBuffer, m_outLength, m_address, m_port);
if (!ret) {
m_retryCount = 0U;
return false;
} else {
m_retryCount = 1U;
return true;
}
}
bool CTimerControlRemoteControlHandler::sendHash(const unsigned char* hash, unsigned int length)
{
wxASSERT(hash != NULL);
wxASSERT(length > 0U);
if (m_loggedIn || m_retryCount > 0U)
return false;
unsigned char* p = m_outBuffer;
m_outLength = 0U;
::memcpy(p, "SHA", 3U);
m_outLength += 3U;
p += 3U;
::memcpy(p, hash, length);
m_outLength += length;
p += length;
bool ret = m_socket.write(m_outBuffer, m_outLength, m_address, m_port);
if (!ret) {
m_retryCount = 0U;
return false;
} else {
m_retryCount = 1U;
return true;
}
}
bool CTimerControlRemoteControlHandler::link(const wxString& callsign, RECONNECT reconnect, const wxString& reflector)
{
wxASSERT(!callsign.IsEmpty());
if (!m_loggedIn || m_retryCount > 0U)
return false;
unsigned char* p = m_outBuffer;
m_outLength = 0U;
::memcpy(p, "LNK", 3U);
m_outLength += 3U;
p += 3U;
::memset(p, ' ', LONG_CALLSIGN_LENGTH);
for (unsigned int i = 0U; i < callsign.Len(); i++)
p[i] = callsign.GetChar(i);
m_outLength += LONG_CALLSIGN_LENGTH;
p += LONG_CALLSIGN_LENGTH;
wxInt32 temp1 = wxInt32(reconnect);
wxInt32 temp2 = wxINT32_SWAP_ON_BE(temp1);
::memcpy(p, &temp2, sizeof(wxInt32));
m_outLength += sizeof(wxInt32);
p += sizeof(wxInt32);
::memset(p, ' ', LONG_CALLSIGN_LENGTH);
for (unsigned int i = 0U; i < reflector.Len(); i++)
p[i] = reflector.GetChar(i);
m_outLength += LONG_CALLSIGN_LENGTH;
p += LONG_CALLSIGN_LENGTH;
bool ret = m_socket.write(m_outBuffer, m_outLength, m_address, m_port);
if (!ret) {
m_retryCount = 0U;
return false;
} else {
m_retryCount = 1U;
return true;
}
}
bool CTimerControlRemoteControlHandler::logout()
{
if (!m_loggedIn || m_retryCount > 0U)
return false;
::memcpy(m_outBuffer, "LOG", 3U);
m_outLength = 3U;
for (unsigned int i = 0U; i < 5U; i++) {
bool ret = m_socket.write(m_outBuffer, m_outLength, m_address, m_port);
if (!ret) {
m_retryCount = 0U;
return false;
}
}
m_retryCount = 1U;
return true;
}
bool CTimerControlRemoteControlHandler::retry()
{
if (m_retryCount > 0U) {
m_retryCount++;
if (m_retryCount >= MAX_RETRIES) {
m_retryCount = 0U;
return false;
}
m_socket.write(m_outBuffer, m_outLength, m_address, m_port);
}
return true;
}
void CTimerControlRemoteControlHandler::close()
{
m_socket.close();
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (C) 2011 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlRemoteControlHandler_H
#define TimerControlRemoteControlHandler_H
#include "UDPReaderWriter.h"
#include "Defs.h"
#include <wx/wx.h>
enum TC_TYPE {
TCT_NONE,
TCT_ACK,
TCT_NAK,
TCT_RANDOM,
TCT_CALLSIGNS
};
class CTimerControlRemoteControlHandler {
public:
CTimerControlRemoteControlHandler(const wxString& address, unsigned int port);
~CTimerControlRemoteControlHandler();
bool open();
TC_TYPE readType();
wxString readNAK();
unsigned int readRandom();
wxArrayString readCallsigns();
bool login();
bool sendHash(const unsigned char* hash, unsigned int length);
void setLoggedIn(bool set);
bool getCallsigns();
bool link(const wxString& callsign, RECONNECT reconnect, const wxString& reflector);
bool logout();
bool retry();
void close();
private:
CUDPReaderWriter m_socket;
in_addr m_address;
unsigned int m_port;
bool m_loggedIn;
unsigned int m_retryCount;
TC_TYPE m_type;
unsigned char* m_inBuffer;
unsigned int m_inLength;
unsigned char* m_outBuffer;
unsigned int m_outLength;
};
#endif

View file

@ -0,0 +1,136 @@
/*
* Copyright (C) 2011,2012 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlRemoteSet.h"
#include "DStarDefines.h"
const unsigned int PASSWORD_WIDTH = 120U;
const unsigned int PORT_WIDTH = 80U;
const unsigned int PORT_LENGTH = 5U;
const unsigned int BORDER_SIZE = 5U;
CTimerControlRemoteSet::CTimerControlRemoteSet(wxWindow* parent, int id, const wxString& title, const wxString& address, unsigned int port, const wxString& password, bool delay) :
wxPanel(parent, id),
m_title(title),
m_address(NULL),
m_port(NULL),
m_password(NULL),
m_delay(NULL)
{
wxFlexGridSizer* sizer = new wxFlexGridSizer(2);
wxStaticText* addressLabel = new wxStaticText(this, -1, _("Address"));
sizer->Add(addressLabel, 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE);
m_address = new wxTextCtrl(this, -1, address, wxDefaultPosition, wxSize(PASSWORD_WIDTH, -1));
sizer->Add(m_address, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
wxStaticText* portLabel = new wxStaticText(this, -1, _("Port"));
sizer->Add(portLabel, 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE);
wxString buffer;
buffer.Printf(wxT("%u"), port);
m_port = new CPortTextCtrl(this, -1, buffer, wxDefaultPosition, wxSize(PORT_WIDTH, -1));
m_port->SetMaxLength(PORT_LENGTH);
sizer->Add(m_port, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
wxStaticText* passwordLabel = new wxStaticText(this, -1, _("Password"));
sizer->Add(passwordLabel, 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE);
m_password = new wxTextCtrl(this, -1, password, wxDefaultPosition, wxSize(PASSWORD_WIDTH, -1), wxTE_PASSWORD);
sizer->Add(m_password, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
wxStaticText* delayLabel = new wxStaticText(this, -1, _("Delay"));
sizer->Add(delayLabel, 0, wxALL | wxALIGN_RIGHT, BORDER_SIZE);
m_delay = new wxChoice(this, -1, wxDefaultPosition, wxSize(PASSWORD_WIDTH, -1));
m_delay->Append(_("Disabled"));
m_delay->Append(_("Enabled"));
sizer->Add(m_delay, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
m_delay->SetSelection(delay ? 1 : 0);
SetAutoLayout(true);
SetSizer(sizer);
}
CTimerControlRemoteSet::~CTimerControlRemoteSet()
{
}
bool CTimerControlRemoteSet::Validate()
{
wxString address = getAddress();
if (address.IsEmpty()) {
wxMessageDialog dialog(this, _("The Address is empty"), m_title + _(" Error"), wxICON_ERROR);
dialog.ShowModal();
return false;
}
unsigned int port = getPort();
if (port == 0U || port > 65535U) {
wxMessageDialog dialog(this, _("The Port is not valid"), m_title + _(" Error"), wxICON_ERROR);
dialog.ShowModal();
return false;
}
wxString password = getPassword();
if (password.IsEmpty()) {
wxMessageDialog dialog(this, _("The Password is empty"), m_title + _(" Error"), wxICON_ERROR);
dialog.ShowModal();
return false;
}
int n = m_delay->GetCurrentSelection();
if (n == wxNOT_FOUND)
return false;
return true;
}
wxString CTimerControlRemoteSet::getAddress() const
{
return m_address->GetValue();
}
unsigned int CTimerControlRemoteSet::getPort() const
{
unsigned long n;
m_port->GetValue().ToULong(&n);
return n;
}
wxString CTimerControlRemoteSet::getPassword() const
{
return m_password->GetValue();
}
bool CTimerControlRemoteSet::getDelay() const
{
int n = m_delay->GetCurrentSelection();
if (n == wxNOT_FOUND)
return false;
return n == 1;
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2011,2012 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlRemoteSet_H
#define TimerControlRemoteSet_H
#include "PortTextCtrl.h"
#include <wx/wx.h>
class CTimerControlRemoteSet : public wxPanel {
public:
CTimerControlRemoteSet(wxWindow* parent, int id, const wxString& title, const wxString& address, unsigned int port, const wxString& password, bool delay);
virtual ~CTimerControlRemoteSet();
virtual bool Validate();
virtual wxString getAddress() const;
virtual unsigned int getPort() const;
virtual wxString getPassword() const;
virtual bool getDelay() const;
private:
wxString m_title;
wxTextCtrl* m_address;
CPortTextCtrl* m_port;
wxTextCtrl* m_password;
wxChoice* m_delay;
};
#endif

View file

@ -0,0 +1,592 @@
/*
* Copyright (C) 2011,2012,2013 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlRepeaterPanel.h"
#include "TimerControlApp.h"
#include "DStarDefines.h"
#include "HostFile.h"
#include <cstdlib>
#include <wx/filename.h>
enum {
List_Select = 7100,
Button_Add,
Button_Modify,
Button_Delete
};
BEGIN_EVENT_TABLE(CTimerControlRepeaterPanel, wxPanel)
EVT_LIST_ITEM_SELECTED(List_Select, CTimerControlRepeaterPanel::onSelect)
EVT_BUTTON(Button_Add, CTimerControlRepeaterPanel::onAdd)
EVT_BUTTON(Button_Modify, CTimerControlRepeaterPanel::onModify)
EVT_BUTTON(Button_Delete, CTimerControlRepeaterPanel::onDelete)
END_EVENT_TABLE()
#if defined(__WINDOWS__)
const unsigned int LIST_HEIGHT = 350U;
const unsigned int LIST_WIDTH = 350U;
const unsigned int DAY_WIDTH = 75U;
const unsigned int TIME_WIDTH = 60U;
const unsigned int CALLSIGN_WIDTH = 100U;
const unsigned int TYPE_WIDTH = 85U;
const unsigned int BUTTON_WIDTH = 75U;
const unsigned int HOUR_WIDTH = 40U;
const unsigned int MINUTE_WIDTH = 40U;
const unsigned int REFLECTOR_WIDTH = 80U;
const unsigned int CHANNEL_WIDTH = 40U;
const unsigned int RECONNECT_WIDTH = 75U;
#else
const unsigned int LIST_HEIGHT = 350U;
const unsigned int LIST_WIDTH = 350U;
const unsigned int DAY_WIDTH = 100U;
const unsigned int TIME_WIDTH = 100U;
const unsigned int CALLSIGN_WIDTH = 100U;
const unsigned int TYPE_WIDTH = 65U;
const unsigned int BUTTON_WIDTH = 75U;
const unsigned int HOUR_WIDTH = 50U;
const unsigned int MINUTE_WIDTH = 50U;
const unsigned int REFLECTOR_WIDTH = 90U;
const unsigned int CHANNEL_WIDTH = 50U;
const unsigned int RECONNECT_WIDTH = 100U;
#endif
const unsigned int BORDER_SIZE = 5U;
int itemCompare(const void* a, const void* b)
{
const CTimerControlItem** first = (const CTimerControlItem**)a;
const CTimerControlItem** second = (const CTimerControlItem**)b;
if ((*first)->m_day != (*second)->m_day)
return int((*second)->m_day) - int((*first)->m_day);
if ((*first)->m_hour != (*second)->m_hour)
return int((*second)->m_hour) - int((*first)->m_hour);
return int((*second)->m_minute) - int((*first)->m_minute);
}
CTimerControlRepeaterPanel::CTimerControlRepeaterPanel(wxWindow* parent, int id, const wxString& callsign) :
wxPanel(parent, id),
m_callsign(callsign),
m_list(NULL),
m_day(NULL),
m_hour(NULL),
m_minute(NULL),
m_reflector(NULL),
m_channel(NULL),
m_reconnect(NULL),
m_item(NULL),
m_n(0)
{
wxBoxSizer* sizer1 = new wxBoxSizer(wxHORIZONTAL);
m_list = new wxListCtrl(this, List_Select, wxDefaultPosition, wxSize(LIST_WIDTH, LIST_HEIGHT), wxLC_REPORT | wxLC_SINGLE_SEL);
m_list->InsertColumn(0L, _("Day"));
m_list->SetColumnWidth(0L, DAY_WIDTH);
m_list->InsertColumn(1L, _("Time"));
m_list->SetColumnWidth(1L, TIME_WIDTH);
m_list->InsertColumn(2L, _("Type"));
m_list->SetColumnWidth(2L, TYPE_WIDTH);
m_list->InsertColumn(3L, _("Reflector"));
m_list->SetColumnWidth(3L, REFLECTOR_WIDTH);
sizer1->Add(m_list, 0, wxTOP | wxBOTTOM | wxLEFT | wxEXPAND, BORDER_SIZE);
wxBoxSizer* sizer2 = new wxBoxSizer(wxVERTICAL);
m_day = new wxChoice(this, -1, wxDefaultPosition, wxSize(DAY_WIDTH, -1));
m_day->Append(_("Sunday"));
m_day->Append(_("Monday"));
m_day->Append(_("Tuesday"));
m_day->Append(_("Wednesday"));
m_day->Append(_("Thursday"));
m_day->Append(_("Friday"));
m_day->Append(_("Saturday"));
m_day->Append(_("Every day"));
m_day->Append(_("Mon-Fri"));
m_day->Append(_("Sat-Sun"));
sizer2->Add(m_day, 0, wxALL, BORDER_SIZE);
m_day->SetSelection(0);
wxBoxSizer* sizer2a = new wxBoxSizer(wxHORIZONTAL);
m_hour = new wxChoice(this, -1, wxDefaultPosition, wxSize(HOUR_WIDTH, -1));
m_hour->Append(wxT("00"));
m_hour->Append(wxT("01"));
m_hour->Append(wxT("02"));
m_hour->Append(wxT("03"));
m_hour->Append(wxT("04"));
m_hour->Append(wxT("05"));
m_hour->Append(wxT("06"));
m_hour->Append(wxT("07"));
m_hour->Append(wxT("08"));
m_hour->Append(wxT("09"));
m_hour->Append(wxT("10"));
m_hour->Append(wxT("11"));
m_hour->Append(wxT("12"));
m_hour->Append(wxT("13"));
m_hour->Append(wxT("14"));
m_hour->Append(wxT("15"));
m_hour->Append(wxT("16"));
m_hour->Append(wxT("17"));
m_hour->Append(wxT("18"));
m_hour->Append(wxT("19"));
m_hour->Append(wxT("20"));
m_hour->Append(wxT("21"));
m_hour->Append(wxT("22"));
m_hour->Append(wxT("23"));
sizer2a->Add(m_hour, 0, wxALL, BORDER_SIZE);
m_hour->SetSelection(0);
wxStaticText* dummy1Label = new wxStaticText(this, -1, wxT(":"));
sizer2a->Add(dummy1Label, 0, wxALL, BORDER_SIZE);
m_minute = new wxChoice(this, -1, wxDefaultPosition, wxSize(MINUTE_WIDTH, -1));
m_minute->Append(wxT("00"));
m_minute->Append(wxT("05"));
m_minute->Append(wxT("10"));
m_minute->Append(wxT("15"));
m_minute->Append(wxT("20"));
m_minute->Append(wxT("25"));
m_minute->Append(wxT("30"));
m_minute->Append(wxT("35"));
m_minute->Append(wxT("40"));
m_minute->Append(wxT("45"));
m_minute->Append(wxT("50"));
m_minute->Append(wxT("55"));
sizer2a->Add(m_minute, 0, wxALL, BORDER_SIZE);
m_minute->SetSelection(0);
sizer2->Add(sizer2a);
wxStaticText* dummy2Label = new wxStaticText(this, -1, wxEmptyString);
sizer2->Add(dummy2Label, 0, wxALL, BORDER_SIZE);
wxBoxSizer* sizer3 = new wxBoxSizer(wxHORIZONTAL);
m_reflector = new wxChoice(this, -1, wxDefaultPosition, wxSize(REFLECTOR_WIDTH, -1));
m_reflector->Append(_("None"));
wxFileName fileName1(wxFileName::GetHomeDir(), DPLUS_HOSTS_FILE_NAME);
if (fileName1.IsFileReadable()) {
CHostFile file(fileName1.GetFullPath(), false);
for (unsigned int i = 0U; i < file.getCount(); i++)
m_reflector->Append(file.getName(i).Trim());
}
#if defined(__WINDOWS__)
wxFileName fileName4(::wxGetCwd(), DPLUS_HOSTS_FILE_NAME);
#else
wxFileName fileName4(wxT(DATA_DIR), DPLUS_HOSTS_FILE_NAME);
#endif
if (fileName4.IsFileReadable()) {
CHostFile file(fileName4.GetFullPath(), false);
for (unsigned int i = 0U; i < file.getCount(); i++) {
wxString name = file.getName(i).Trim();
if (m_reflector->FindString(name) == wxNOT_FOUND)
m_reflector->Append(name);
}
}
wxFileName fileName2(wxFileName::GetHomeDir(), DEXTRA_HOSTS_FILE_NAME);
if (fileName2.IsFileReadable()) {
CHostFile file(fileName2.GetFullPath(), false);
for (unsigned int i = 0U; i < file.getCount(); i++)
m_reflector->Append(file.getName(i).Trim());
}
#if defined(__WINDOWS__)
wxFileName fileName5(::wxGetCwd(), DEXTRA_HOSTS_FILE_NAME);
#else
wxFileName fileName5(wxT(DATA_DIR), DEXTRA_HOSTS_FILE_NAME);
#endif
if (fileName5.IsFileReadable()) {
CHostFile file(fileName5.GetFullPath(), false);
for (unsigned int i = 0U; i < file.getCount(); i++) {
wxString name = file.getName(i).Trim();
if (m_reflector->FindString(name) == wxNOT_FOUND)
m_reflector->Append(name);
}
}
wxFileName fileName3(wxFileName::GetHomeDir(), DCS_HOSTS_FILE_NAME);
if (fileName3.IsFileReadable()) {
CHostFile file(fileName3.GetFullPath(), false);
for (unsigned int i = 0U; i < file.getCount(); i++)
m_reflector->Append(file.getName(i).Trim());
}
#if defined(__WINDOWS__)
wxFileName fileName6(::wxGetCwd(), DCS_HOSTS_FILE_NAME);
#else
wxFileName fileName6(wxT(DATA_DIR), DCS_HOSTS_FILE_NAME);
#endif
if (fileName6.IsFileReadable()) {
CHostFile file(fileName6.GetFullPath(), false);
for (unsigned int i = 0U; i < file.getCount(); i++) {
wxString name = file.getName(i).Trim();
if (m_reflector->FindString(name) == wxNOT_FOUND)
m_reflector->Append(name);
}
}
sizer3->Add(m_reflector, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
m_reflector->SetSelection(0);
m_channel = new wxChoice(this, -1, wxDefaultPosition, wxSize(CHANNEL_WIDTH, -1));
m_channel->Append(wxT("A"));
m_channel->Append(wxT("B"));
m_channel->Append(wxT("C"));
m_channel->Append(wxT("D"));
m_channel->Append(wxT("E"));
m_channel->Append(wxT("F"));
m_channel->Append(wxT("G"));
m_channel->Append(wxT("H"));
m_channel->Append(wxT("I"));
m_channel->Append(wxT("J"));
m_channel->Append(wxT("K"));
m_channel->Append(wxT("L"));
m_channel->Append(wxT("M"));
m_channel->Append(wxT("N"));
m_channel->Append(wxT("O"));
m_channel->Append(wxT("P"));
m_channel->Append(wxT("Q"));
m_channel->Append(wxT("R"));
m_channel->Append(wxT("S"));
m_channel->Append(wxT("T"));
m_channel->Append(wxT("U"));
m_channel->Append(wxT("V"));
m_channel->Append(wxT("W"));
m_channel->Append(wxT("X"));
m_channel->Append(wxT("Y"));
m_channel->Append(wxT("Z"));
sizer3->Add(m_channel, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
m_channel->SetSelection(0);
sizer2->Add(sizer3);
m_reconnect = new wxChoice(this, -1, wxDefaultPosition, wxSize(RECONNECT_WIDTH, -1));
m_reconnect->Append(_("Never"));
m_reconnect->Append(_("Fixed"));
m_reconnect->Append(_("5 minutes"));
m_reconnect->Append(_("10 minutes"));
m_reconnect->Append(_("15 minutes"));
m_reconnect->Append(_("20 minutes"));
m_reconnect->Append(_("25 minutes"));
m_reconnect->Append(_("30 minutes"));
m_reconnect->Append(_("60 minutes"));
m_reconnect->Append(_("90 minutes"));
m_reconnect->Append(_("120 minutes"));
m_reconnect->Append(_("180 minutes"));
sizer2->Add(m_reconnect, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
m_reconnect->SetSelection(0);
wxStaticText* dummy3Label = new wxStaticText(this, -1, wxEmptyString);
sizer2->Add(dummy3Label, 0, wxALL, BORDER_SIZE);
wxButton* addButton = new wxButton(this, Button_Add, _("Add"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
sizer2->Add(addButton, 0, wxALL, BORDER_SIZE);
wxButton* modButton = new wxButton(this, Button_Modify, _("Modify"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
sizer2->Add(modButton, 0, wxALL, BORDER_SIZE);
wxButton* delButton = new wxButton(this, Button_Delete, _("Delete"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
sizer2->Add(delButton, 0, wxALL, BORDER_SIZE);
sizer1->Add(sizer2);
SetAutoLayout(true);
SetSizer(sizer1);
}
CTimerControlRepeaterPanel::~CTimerControlRepeaterPanel()
{
}
void CTimerControlRepeaterPanel::load(CTimerControlItem** items, unsigned int count)
{
for (unsigned int i = 0U; i < count; i++) {
if (items[i]->m_repeater.IsSameAs(m_callsign))
insertItem(items[i]);
}
reload();
}
unsigned int CTimerControlRepeaterPanel::getCount() const
{
return (unsigned int)m_list->GetItemCount();
}
CTimerControlItem** CTimerControlRepeaterPanel::getItems() const
{
unsigned int count = getCount();
CTimerControlItem** items = new CTimerControlItem*[count];
for (unsigned int i = 0U; i < count; i++)
items[i] = (CTimerControlItem*)m_list->GetItemData(i);
return items;
}
void CTimerControlRepeaterPanel::insertItem(CTimerControlItem* item)
{
switch (item->m_day) {
case 0U: m_list->InsertItem(0L, _("Sunday")); break;
case 1U: m_list->InsertItem(0L, _("Monday")); break;
case 2U: m_list->InsertItem(0L, _("Tuesday")); break;
case 3U: m_list->InsertItem(0L, _("Wednesday")); break;
case 4U: m_list->InsertItem(0L, _("Thursday")); break;
case 5U: m_list->InsertItem(0L, _("Friday")); break;
case 6U: m_list->InsertItem(0L, _("Saturday")); break;
case 7U: m_list->InsertItem(0L, _("Every day")); break;
case 8U: m_list->InsertItem(0L, _("Mon-Fri")); break;
case 9U: m_list->InsertItem(0L, _("Sat-Sun")); break;
default: m_list->InsertItem(0L, wxT("??????")); break;
}
wxString text;
text.Printf(wxT("%02u:%02u"), item->m_hour, item->m_minute);
m_list->SetItem(0L, 1, text);
switch (item->m_reconnect) {
case RECONNECT_NEVER: m_list->SetItem(0L, 2, _("Never")); break;
case RECONNECT_FIXED: m_list->SetItem(0L, 2, _("Fixed")); break;
case RECONNECT_5MINS: m_list->SetItem(0L, 2, _("5 minutes")); break;
case RECONNECT_10MINS: m_list->SetItem(0L, 2, _("10 minutes")); break;
case RECONNECT_15MINS: m_list->SetItem(0L, 2, _("15 minutes")); break;
case RECONNECT_20MINS: m_list->SetItem(0L, 2, _("20 minutes")); break;
case RECONNECT_25MINS: m_list->SetItem(0L, 2, _("25 minutes")); break;
case RECONNECT_30MINS: m_list->SetItem(0L, 2, _("30 minutes")); break;
case RECONNECT_60MINS: m_list->SetItem(0L, 2, _("60 minutes")); break;
case RECONNECT_90MINS: m_list->SetItem(0L, 2, _("90 minutes")); break;
case RECONNECT_120MINS: m_list->SetItem(0L, 2, _("120 minutes")); break;
case RECONNECT_180MINS: m_list->SetItem(0L, 2, _("180 minutes")); break;
default: m_list->SetItem(0L, 2, wxT("????????")); break;
}
if (item->m_reflector.IsEmpty())
m_list->SetItem(0L, 3, _("None"));
else
m_list->SetItem(0L, 3, item->m_reflector);
m_list->SetItemPtrData(0L, wxUIntPtr(item));
}
void CTimerControlRepeaterPanel::onSelect(wxListEvent& event)
{
m_n = event.GetIndex();
m_item = (CTimerControlItem*)m_list->GetItemData(m_n);
if (m_item == NULL)
return;
m_day->SetSelection(int(m_item->m_day));
m_hour->SetSelection(int(m_item->m_hour));
m_minute->SetSelection(int(m_item->m_minute / 5U));
if (m_item->m_reflector.IsEmpty()) {
m_reflector->SetSelection(0);
m_channel->SetSelection(0);
} else {
m_reflector->SetStringSelection(m_item->m_reflector.Left(7U).Trim());
m_channel->SetStringSelection(m_item->m_reflector.Mid(7U).Trim());
}
m_reconnect->SetSelection(int(m_item->m_reconnect));
}
void CTimerControlRepeaterPanel::onAdd(wxCommandEvent&)
{
int day = m_day->GetSelection();
int hour = m_hour->GetSelection();
int minute = m_minute->GetSelection();
int reflector = m_reflector->GetSelection();
int channel = m_channel->GetSelection();
int reconnect = m_reconnect->GetSelection();
if (day == wxNOT_FOUND || hour == wxNOT_FOUND || minute == wxNOT_FOUND || reflector == wxNOT_FOUND || channel == wxNOT_FOUND || reconnect == wxNOT_FOUND)
return;
CTimerControlItem* item = new CTimerControlItem;
item->m_repeater = m_callsign;
item->m_day = (unsigned int)day;
item->m_hour = (unsigned int)hour;
item->m_minute = (unsigned int)minute * 5U;
if (reflector != 0) {
wxString callsign = m_reflector->GetStringSelection();
callsign.Append(wxT(" "));
callsign.Truncate(7U);
callsign.Append(m_channel->GetStringSelection());
item->m_reflector = callsign;
}
item->m_reconnect = RECONNECT(reconnect);
m_day->SetSelection(0);
m_hour->SetSelection(0);
m_minute->SetSelection(0);
m_reflector->SetSelection(0);
m_channel->SetSelection(0);
m_reconnect->SetSelection(0);
reload(item);
::wxGetApp().writeItems();
}
void CTimerControlRepeaterPanel::onModify(wxCommandEvent&)
{
if (m_item == NULL)
return;
int day = m_day->GetSelection();
int hour = m_hour->GetSelection();
int minute = m_minute->GetSelection();
int reflector = m_reflector->GetSelection();
int channel = m_channel->GetSelection();
int reconnect = m_reconnect->GetSelection();
if (day == wxNOT_FOUND || hour == wxNOT_FOUND || minute == wxNOT_FOUND || reflector == wxNOT_FOUND || channel == wxNOT_FOUND || reconnect == wxNOT_FOUND)
return;
CTimerControlItem* item = new CTimerControlItem;
item->m_repeater = m_callsign;
item->m_day = (unsigned int)day;
item->m_hour = (unsigned int)hour;
item->m_minute = (unsigned int)minute * 5U;
if (reflector != 0) {
wxString callsign = m_reflector->GetStringSelection();
callsign.Append(wxT(" "));
callsign.Truncate(7U);
callsign.Append(m_channel->GetStringSelection());
item->m_reflector = callsign;
}
item->m_reconnect = RECONNECT(reconnect);
m_list->DeleteItem(m_n);
delete m_item;
m_item = NULL;
m_day->SetSelection(0);
m_hour->SetSelection(0);
m_minute->SetSelection(0);
m_reflector->SetSelection(0);
m_channel->SetSelection(0);
m_reconnect->SetSelection(0);
reload(item);
::wxGetApp().writeItems();
}
void CTimerControlRepeaterPanel::onDelete(wxCommandEvent&)
{
if (m_item == NULL)
return;
m_list->DeleteItem(m_n);
delete m_item;
m_item = NULL;
m_day->SetSelection(0);
m_hour->SetSelection(0);
m_minute->SetSelection(0);
m_reflector->SetSelection(0);
m_channel->SetSelection(0);
m_reconnect->SetSelection(0);
::wxGetApp().writeItems();
}
void CTimerControlRepeaterPanel::reload(CTimerControlItem* item)
{
int n = m_list->GetItemCount();
CTimerControlItem** items = new CTimerControlItem*[n + 1];
unsigned int count = 0U;
for (int i = 0; i < n; i++) {
CTimerControlItem* listItem = (CTimerControlItem*)m_list->GetItemData(i);
// Reject any that have the same day, hour and minute settings
if (item != NULL) {
// Match the exact day, hour, and minute
if (listItem->m_day == item->m_day && listItem->m_hour == item->m_hour && listItem->m_minute == item->m_minute) {
delete listItem;
// Match every day, hour, and minute
} else if (7U == item->m_day && listItem->m_hour == item->m_hour && listItem->m_minute == item->m_minute) {
delete listItem;
// Match every day, hour, and minute
} else if (listItem->m_day == 7U && listItem->m_hour == item->m_hour && listItem->m_minute == item->m_minute) {
delete listItem;
// Match week day, hour, and minute
} else if (8U == item->m_day && ((listItem->m_day >= 1U && listItem->m_day <= 5U) || listItem->m_day == 7U) && listItem->m_hour == item->m_hour && listItem->m_minute == item->m_minute) {
delete listItem;
// Match week day, hour, and minute
} else if (listItem->m_day == 8U && ((item->m_day >= 1U && item->m_day <= 5U) || item->m_day == 7U) && listItem->m_hour == item->m_hour && listItem->m_minute == item->m_minute) {
delete listItem;
// Match weekend, hour, and minute
} else if (9U == item->m_day && (listItem->m_day == 0U || listItem->m_day == 6U || listItem->m_day == 7U) && listItem->m_hour == item->m_hour && listItem->m_minute == item->m_minute) {
delete listItem;
// Match weekend, hour, and minute
} else if (listItem->m_day == 9U && (item->m_day == 0U || item->m_day == 6U || item->m_day == 7U) && listItem->m_hour == item->m_hour && listItem->m_minute == item->m_minute) {
delete listItem;
} else {
items[count] = listItem;
count++;
}
} else {
items[count] = listItem;
count++;
}
}
// Put the new one at the end of the list
if (item != NULL) {
items[count] = item;
count++;
}
m_list->DeleteAllItems();
::qsort(items, count, sizeof(CTimerControlItem*), itemCompare);
for (unsigned int i = 0U; i < count; i++)
insertItem(items[i]);
delete[] items;
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2011 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlRepeaterPanel_H
#define TimerControlRepeaterPanel_H
#include "TimerControlItem.h"
#include <wx/wx.h>
#include <wx/listctrl.h>
class CTimerControlRepeaterPanel : public wxPanel {
public:
CTimerControlRepeaterPanel(wxWindow* parent, int id, const wxString& callsign);
virtual ~CTimerControlRepeaterPanel();
virtual void onSelect(wxListEvent& event);
virtual void onAdd(wxCommandEvent& event);
virtual void onModify(wxCommandEvent& event);
virtual void onDelete(wxCommandEvent& event);
virtual void load(CTimerControlItem** items, unsigned int count);
virtual unsigned int getCount() const;
virtual CTimerControlItem** getItems() const;
private:
wxString m_callsign;
wxListCtrl* m_list;
wxChoice* m_day;
wxChoice* m_hour;
wxChoice* m_minute;
wxChoice* m_reflector;
wxChoice* m_channel;
wxChoice* m_reconnect;
CTimerControlItem* m_item;
int m_n;
DECLARE_EVENT_TABLE()
void insertItem(CTimerControlItem* item);
void reload(CTimerControlItem* item = NULL);
};
#endif

View file

@ -0,0 +1,291 @@
/*
* Copyright (C) 2011,2012 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlItemFile.h"
#include "TimerControlThread.h"
#include "SHA256.h"
CTimerControlThread::CTimerControlThread() :
m_password(),
m_fileName(),
m_delay(false),
m_count(0U),
m_items(NULL),
m_mutex(),
m_handler(NULL),
m_killed(false)
{
}
CTimerControlThread::~CTimerControlThread()
{
if (m_items != NULL) {
for (unsigned int i = 0U; i < m_count; i++)
delete m_items[i];
delete[] m_items;
}
delete m_handler;
}
void CTimerControlThread::run()
{
if (m_delay) {
for (unsigned int i = 0U; i < 20U; i++) {
if (m_killed)
return;
::wxMilliSleep(1000UL);
}
} else {
::wxMilliSleep(100UL);
}
int lastDay = 0;
int lastHour = 0;
int lastMin = 0;
while (!m_killed) {
time_t t;
::time(&t);
struct tm* tm = ::localtime(&t);
int day = tm->tm_wday;
int hour = tm->tm_hour;
int min = tm->tm_min;
if (day != lastDay || hour != lastHour || min != lastMin) {
m_mutex.Lock();
bool open = false;
for (unsigned int i = 0U; i < m_count; i++) {
// Check the day matching
if (int(m_items[i]->m_day) == day || // Exact day match
m_items[i]->m_day == 7U || // Every day match
(m_items[i]->m_day == 8U && day >= 1 && day <= 5) || // Weekday match
(m_items[i]->m_day == 9U && (day == 0 || day == 6))) { // Weekend match
// Check the time matching
if (int(m_items[i]->m_hour) == hour && int(m_items[i]->m_minute) == min) {
if (m_items[i]->m_reflector.IsEmpty())
wxLogMessage(wxT("Linking \"%s\" to \"None\" with reconnect %d"), m_items[i]->m_repeater.c_str(), m_items[i]->m_reconnect);
else
wxLogMessage(wxT("Linking \"%s\" to \"%s\" with reconnect %d"), m_items[i]->m_repeater.c_str(), m_items[i]->m_reflector.c_str(), m_items[i]->m_reconnect);
if (!open)
open = login();
if (open)
link(m_items[i]->m_repeater, m_items[i]->m_reconnect, m_items[i]->m_reflector);
}
}
}
m_mutex.Unlock();
if (open)
logoff();
lastDay = day;
lastHour = hour;
lastMin = min;
}
::wxMilliSleep(5000UL);
}
}
void CTimerControlThread::setGateway(const wxString& address, unsigned int port, const wxString& password)
{
m_password = password;
delete m_handler;
m_handler = new CTimerControlRemoteControlHandler(address, port);
}
void CTimerControlThread::setDelay(bool enabled)
{
m_delay = enabled;
}
void CTimerControlThread::setFileName(const wxString& fileName)
{
m_fileName = fileName;
}
void CTimerControlThread::reload()
{
wxMutexLocker lock(m_mutex);
wxLogMessage(wxT("Reloading the schedule file"));
// Remove the old schedule
if (m_items != NULL) {
for (unsigned int i = 0U; i < m_count; i++)
delete m_items[i];
delete[] m_items;
m_items = NULL;
}
CTimerControlItemFile file(m_fileName);
m_items = file.readItems(m_count);
}
void CTimerControlThread::kill()
{
m_killed = true;
}
bool CTimerControlThread::login()
{
wxASSERT(m_handler != NULL);
wxLogMessage(wxT("Logging into the gateway"));
bool ret = m_handler->open();
if (!ret) {
wxLogError(wxT("Error opening the port"));
return false;
}
TC_TYPE type;
do {
ret = m_handler->login();
if (!ret) {
wxLogError(wxT("Error when sending the login command"));
m_handler->close();
return false;
}
::wxMilliSleep(100UL);
type = m_handler->readType();
switch (type) {
case TCT_RANDOM:
wxLogMessage(wxT("Read the random number"));
break;
case TCT_NAK:
wxLogError(wxT("Received a NAK when asking for the random number"));
m_handler->setLoggedIn(false);
m_handler->readNAK();
m_handler->close();
return false;
default:
::wxMilliSleep(100UL);
break;
}
} while (type != TCT_RANDOM);
unsigned int rnd = m_handler->readRandom();
do {
ret = sendHash(rnd);
if (!ret) {
wxLogError(wxT("Error when sending the hash"));
m_handler->close();
return false;
}
::wxMilliSleep(100UL);
type = m_handler->readType();
switch (type) {
case TCT_ACK:
wxLogMessage(wxT("Logged in to the gateway"));
m_handler->setLoggedIn(true);
break;
case TCT_NAK:
wxLogError(wxT("Received a NAK after sending the hash"));
m_handler->setLoggedIn(false);
m_handler->readNAK();
m_handler->close();
return false;
default:
::wxMilliSleep(100UL);
break;
}
} while (type != TCT_ACK);
return true;
}
bool CTimerControlThread::link(const wxString& repeater, RECONNECT reconnect, const wxString& reflector)
{
wxASSERT(m_handler != NULL);
for (;;) {
bool ret = m_handler->link(repeater, reconnect, reflector);
if (!ret) {
wxLogError(wxT("Error when sending the link command"));
return false;
}
::wxMilliSleep(100UL);
TC_TYPE type = m_handler->readType();
switch (type) {
case TCT_ACK:
wxLogMessage(wxT("Sent the link command OK"));
return true;
case TCT_NAK:
wxLogError(wxT("Received a NAK after sending the link command"));
m_handler->readNAK();
return false;
default:
::wxMilliSleep(100UL);
break;
}
}
}
void CTimerControlThread::logoff()
{
wxASSERT(m_handler != NULL);
wxLogMessage(wxT("Logging out of the gateway"));
m_handler->logout();
m_handler->setLoggedIn(false);
m_handler->close();
}
bool CTimerControlThread::sendHash(unsigned int rnd)
{
unsigned int len = m_password.Len() + sizeof(unsigned int);
unsigned char* in = new unsigned char[len];
unsigned char* out = new unsigned char[32U];
::memcpy(in, &rnd, sizeof(unsigned int));
for (unsigned int i = 0U; i < m_password.Len(); i++)
in[i + sizeof(unsigned int)] = m_password.GetChar(i);
CSHA256 sha256;
sha256.buffer(in, len, out);
bool ret = m_handler->sendHash(out, 32U);
delete[] in;
delete[] out;
return ret;
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (C) 2011,2012 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlThread_H
#define TimerControlThread_H
#include "TimerControlRemoteControlHandler.h"
#include "TimerControlItem.h"
#include "Defs.h"
#include <wx/wx.h>
class CTimerControlThread {
public:
CTimerControlThread();
virtual ~CTimerControlThread();
virtual void setGateway(const wxString& address, unsigned int port, const wxString& password);
virtual void setDelay(bool enabled);
virtual void setFileName(const wxString& fileName);
virtual void reload();
virtual void run();
virtual void kill();
private:
wxString m_password;
wxString m_fileName;
bool m_delay;
unsigned int m_count;
CTimerControlItem** m_items;
wxMutex m_mutex;
CTimerControlRemoteControlHandler* m_handler;
bool m_killed;
bool login();
bool link(const wxString& repeater, RECONNECT reconnect, const wxString& reflector);
void logoff();
bool sendHash(unsigned int rnd);
};
#endif

View file

@ -0,0 +1,65 @@
/*
* Copyright (C) 2012 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "TimerControlThreadHelper.h"
CTimerControlThreadHelper::CTimerControlThreadHelper(CTimerControlThread* thread) :
wxThread(wxTHREAD_JOINABLE),
m_thread(thread)
{
wxASSERT(thread != NULL);
}
CTimerControlThreadHelper::~CTimerControlThreadHelper()
{
delete m_thread;
}
void CTimerControlThreadHelper::start()
{
Create();
SetPriority(100U);
Run();
}
void* CTimerControlThreadHelper::Entry()
{
wxASSERT(m_thread != NULL);
m_thread->run();
return NULL;
}
void CTimerControlThreadHelper::kill()
{
wxASSERT(m_thread != NULL);
m_thread->kill();
Wait();
}
void CTimerControlThreadHelper::reload()
{
wxASSERT(m_thread != NULL);
m_thread->reload();
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2012,2013 by Jonathan Naylor G4KLX
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef TimerControlThreadHelper_H
#define TimerControlThreadHelper_H
#include "TimerControlThread.h"
#include <wx/wx.h>
class CTimerControlThreadHelper : public wxThread {
public:
CTimerControlThreadHelper(CTimerControlThread* thread);
virtual ~CTimerControlThreadHelper();
virtual void start();
virtual void* Entry();
virtual void kill();
virtual void reload();
private:
CTimerControlThread* m_thread;
};
#endif