From 83458a6672f11f20ab907137c576b7a86ea902aa Mon Sep 17 00:00:00 2001 From: Tom Early Date: Fri, 10 Jul 2020 12:40:14 -0700 Subject: [PATCH] smarter configuration in makefile --- README.md | 65 +++++++++++++---------- dashboard.xlx/pgs/peers.php | 4 +- dashboard.xlx/pgs/repeaters.php | 4 +- src/Makefile | 93 +++++++++++++++++++++++++-------- src/ccallsignlistitem.cpp | 2 +- src/ccallsignlistitem.h | 10 ++-- src/cdcsprotocol.cpp | 10 +++- src/cdextraprotocol.cpp | 10 +++- src/cdmrmmdvmprotocol.cpp | 10 +++- src/cdmrplusprotocol.cpp | 10 +++- src/cdplusprotocol.cpp | 10 +++- src/cpacketstream.cpp | 17 ++++-- src/cpacketstream.h | 2 + src/cpeer.h | 2 +- src/cprotocol.cpp | 85 ++++++++++++++++++++++++++++++ src/cprotocol.h | 17 +++++- src/creflector.cpp | 11 +++- src/creflector.h | 23 +++++++- src/cudpsocket.cpp | 20 +++---- src/cudpsocket.h | 1 + src/cxlxprotocol.cpp | 14 ++++- src/cysfprotocol.cpp | 10 +++- src/main.cpp | 71 ++++++++++--------------- src/main.h | 45 +++++++++++++--- systemd/ambed.service | 2 +- systemd/xlxd.service | 2 +- systemd/xrfd.service | 2 +- 27 files changed, 415 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 33d1be8..0275856 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,7 @@ This will build **either** a new kind of XLX reflector **or** a tri-mode XRF ref This is an improved version of the multi-protocol Reflector. Nearly all std::vector containers have been replaced with std::list containers. This is a far better choice for any collection where it is common to delete elements that are not at the end of the collection. Also in this package, no classes are derived from any standard containers. Because standard containers don't have a virtual destructor, derriving from them is highly ill-advised and while the origin XLX server worked using such derivations, it represents a possible serious problem when considering future development. Also, the clean-up routines designed to be executed when shutting down were unreachable as designed and this has been fixed. In addtion, long sleep times in certain threads were preventing a polite systemd shutdown and this has been fixed. Please note that it can still take several seconds to complete the shutdown while some execution threads complete their i/o cycle. The C++ warning flag, -W has been turned on and a significant number of warning have been fixed. -The Makefiles have been improved to provide automatically generated dependencies. This significantly speeds up updating time and eliminates build errors. Be sure to do a `make clean` before you switch your build type between XLX and XRF. There are several switches in the Makefile for controlling what is to be made. By default, "make" will build an XLXD system with support for G3. The first switch will add gdb debugging support. The second switch will make a DStar-only xrfd reflector. The third switch will drop support for G3. This switch should be turned on if you are planning to have a DStar routing application also run on the server. If you want to turn on any of these switches, you should copy `Makefile` to `makefile` and then modify the `makefile`. - -These reflectors no longer has a daemon-mode. It is unnecessary for systemd. Only systemd-based operating systems are supported. Debian or Ubuntu is recommended. If you want to install this on a non-systemd based OS, you are on your own. Also, by default, ambed and xlxd or xrfd are built without gdb support. If you want to add it, modify the `Makefile` in each build directory. Finally, this repository is designed so that you don't have to modify any file in the repository when you build your system. Any file you need to modify to properly configure your reflector will be a file you copy from you locally cloned repo. This makes it easier to update the source code when this repository is updated. Follow the instructions below to build your transcoding XLX reflector or tri-mode XRF reflector. +Only systemd-based operating systems are supported. Debian or Ubuntu is recommended. If you want to install this on a non-systemd based OS, you are on your own. Also, by default, ambed and xlxd or xrfd are built without gdb support. If you want to add it, modify the `Makefile` in each build directory. Finally, this repository is designed so that you don't have to modify any file in the repository when you build your system. Any file you need to modify to properly configure your reflector will be a file you copy from you locally cloned repo. This makes it easier to update the source code when this repository is updated. Follow the instructions below to build your transcoding XLX reflector or tri-mode XRF reflector. - 73 de n7tae @@ -46,9 +44,43 @@ sudo apt install g++ ### Download the sources ```bash -git clone https://github.com/n7tae/tae-xlxd.git +git clone https://github.com/n7tae/new-xlxd.git +``` + +### move to the ambed directory + +```bash +cd ambed +``` + +### Edit the makefile + +You only need to do this if you are not going to use 127.0.0.1 for the ambed IP address: + +```bash +cp Makefile makefile +``` + +The only thing to change here is your new IP address. + +### Compile, install and start the ambed program + +```bash +make -j +sudo make install +``` + +### Configure your reflector software + +All of the software configuration is done in the makefile, so first, copy it: + +```bash +cd ../src +cp Makefile makefile ``` +Everything you need to change is in one section near the top of the `makefile`. Specify a reflector callsign that is not currently being used. Make sure you check carefully to be sure your callsign choice is not already in use. You need to also set the IPv4 and IPv6 addresses to be used for binding. This should be static IP address that uses only a dotted number for IPv4 or a coloned hexidecimal number for IPv6. You can comment out either the IPv4 or the IPv6 address to create an IPv4-only or an IPv6-only reflector. Define both to build a dual stack (IPv4 *and* IPv6) reflector. Of course if you build a reflector with only IPv6, you should disable G3 support, because it's the one protocol that only operates on IPv4. In fact, currently, it would be silly to build an IPv6-only XLX reflector because there are currently no DMR or YSF system that could use it. For and XLX reflector, you can also supply a binding address for the transcoder. If you comment out this definition, you will build an XLX reflector without transcoding support. You can also control whether you reflector will support linking from Icom's G3 routing transceivers. This lining is IPv4 only! Finally you can build your reflector software with debugging support. + ### Create and edit your blacklist, whitelist and linking files and systemd file If you are building an XLX reflector: @@ -58,7 +90,6 @@ cp ../config/xlxd.blacklist . cp ../config/xlxd.whitelist . cp ../config/xlxd.interlink . cp ../config/xlxd.terminal . -cp ../systemd/xlxd.service . ``` If you are building an XRF reflector (please note the name changes, especially for the interlink file): @@ -68,31 +99,11 @@ cp ../config/xlxd.blacklist xrfd.blacklist cp ../config/xlxd.whitelist xrfd.whitelist cp ../config/xlxd.interlink xrfd.interlink cp ../config/xlxd.terminal xrfd.terminal -cp ../systemd/xrfd.service . ``` If you are not going to support G3 links, you don't need to copy the .terminal file. Use your favorite editor to modify each of these files. If you want a totally open network, the blacklist and whitelist files are ready to go. The blacklist determine which callsigns can't use the reflector. The whitelist determines which callsigns can use the reflector and the interlink or linklist file sets up the XLX<--->XLX linking and/or out-going XRF linking. When building your network, remember that XLX only supports a single hop, so each XLX reflector needs to be interlinked with all the reflectors for that module's network. Along with multi-protocol support, this is the outstanding feature of the XLX design! The down-side is that a Brand Meister link is of the same Peer group as XLX, so if you want to set up a big XLX cluster that supports transcoding, you need a transcoder for all nodes! -This limitation was the main driving force to develop this new XLX and XRF system: Transcoder hardware can be attached to an isolated XLX reflector and then linked to a larger network via XRF reflectors. - -In the service file, change the `CHANGEME` to your reflector callsign, `XLX???` or `XRF???`, where `???` is a three digit number not already in use. The next two parameters are the IPv4 and IPv6 addresses to be used for binding. This should be static IP address that uses only a dotted number for IPv4 or a coloned hexidecimal number for IPv6. For either the IPv4 or the IPv6 address, you can also supply `none` and that means the module will not support that protocol. So you can configure an IPv4-only reflector, an IPv6-only reflector, or a dual stack (IPv4 *and* IPv6) reflector. Of course if you build a reflector with only IPv6, you should disable G3 support, because it's the one protocol that only operates on IPv4. For the xlxd.service file, a final parameter is the binding address for the transcoder. This can also be set to `none` and the transcoder thread will not start. If you have configured an IPv6-only reflector, you should be using an IPv6 address for the transcoder. (If it's a locally installed transcoder, use "::1".) - -### Copy and edit the ambed.service file - -```bash -cp ../systemd/ambed.service . -``` - -Make sure you are supplying the proper IP address to start ambed. - -### Compile, install and start the ambed program - -```bash -make -j -sudo make install -``` - -### Compile, install and start the reflector +### Start the reflector Now for the reflector: @@ -132,7 +143,7 @@ There are two supplied, one for XRF systems and one for XLX systems. sudo cp -r ~/xlxd/dashboard.xlx /var/www/db # or dashboard.xrf ``` -Please note that your www root directory might be some place else. There are one file that needs configuration. Edit the copied files, not the ones from the repository: +Please note that your www root directory might be some place else. There is one file that needs configuration. Edit the copied files, not the ones from the repository: - **pgs/config.inc.php** - At a minimum set your email address, country and comment. **Do not** enable the calling home feature if you built an XRF reflector. This feature is for **XLX systems only**. diff --git a/dashboard.xlx/pgs/peers.php b/dashboard.xlx/pgs/peers.php index 45a735d..b238b5b 100644 --- a/dashboard.xlx/pgs/peers.php +++ b/dashboard.xlx/pgs/peers.php @@ -84,9 +84,9 @@ for ($i=0;$i<$Reflector->PeerCount();$i++) { if ($count > 1) { if (1 == substr_count($ipstr, "::")) { $ipstr = str_replace("::", str_repeat(":", 9 - $count), $ipstr); } if (7 == substr_count($ipstr, ":")) { - echo $MC.':'.$MC.':'.$MC.':'.$MC; + echo $MC.':'.$MC.':'.$MC.':'.$MC.':'.$MC.':'.$MC; $Bytes = explode(":", $ipstr); - for( $k=4; $k<8; $k++) { echo (0==strlen($Bytes[$k])) ? ':0' : ':'.$Bytes[$k]; } + for( $k=6; $k<8; $k++) { echo (0==strlen($Bytes[$k])) ? ':0' : ':'.$Bytes[$k]; } } } } diff --git a/dashboard.xlx/pgs/repeaters.php b/dashboard.xlx/pgs/repeaters.php index b13f281..d82e49a 100644 --- a/dashboard.xlx/pgs/repeaters.php +++ b/dashboard.xlx/pgs/repeaters.php @@ -79,9 +79,9 @@ for ($i=0;$i<$Reflector->NodeCount();$i++) { if ($count > 1) { if (1 == substr_count($ipstr, "::")) { $ipstr = str_replace("::", str_repeat(":", 9 - $count), $ipstr); } if (7 == substr_count($ipstr, ":")) { - echo $MC.':'.$MC.':'.$MC.':'.$MC; + echo $MC.':'.$MC.':'.$MC.':'.$MC.':'.$MC.':'.$MC; $Bytes = explode(":", $ipstr); - for( $k=4; $k<8; $k++) { echo (0==strlen($Bytes[$k])) ? ':0' : ':'.$Bytes[$k]; } + for( $k=6; $k<8; $k++) { echo (0==strlen($Bytes[$k])) ? ':0' : ':'.$Bytes[$k]; } } } } diff --git a/src/Makefile b/src/Makefile index 8426190..b1092e0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,56 +18,107 @@ # if you change these locations, make sure the sgs.service file is updated! # you will also break hard coded paths in the dashboard file, index.php. +################## This is the part you can safely edit ####################### + +#### Callsign +# For an xlxd reflector, use XLX???, where ??? is an unused number. +# For an xrfd reflector, use XRF???, where ??? is an unused number. +callsign = XLX797 + +# set it to false for a DStar-only xrf reflector (instead of xlx) +is_xlx = true + +# how many modules? +nb_of_modules=26 + +#### IP Bindings +# IPv4 - comment out the next line for no IPV4 support +listen_ipv4 = 10.1.10.61 + +# IPv6 - comment out the next line for no IPv6 support +listen_ipv6 = any + +ifeq ($(is_xlx), true) +# We are only concerned with the transcoder if we are building an XLX +# Comment out the next line if there is no transcoder on an XLX build +#transcoder_ip = 127.0.0.1 + +ifdef transcoder_ip +# Which modules will be transcoded? (A through Z) +tc_mods = ABCDEFGHIJKLMNOPQRSTUVWXYZ +endif + +endif + +# Set it to false for no G3 support +use_g3 = true + +# Set it to true for debugging support +debug = false + +############################################################################### + # if you make changed in these two variable, you'll need to change things # in the main.h file as well as the systemd service file. BINDIR=/usr/local/bin CFGDIR=/usr/local/etc DATADIR=/var/lib/xlxd -################## This is the part you can safely edit ####################### -# uncomment the next line for debugging support -#DEBUG=true -# uncomment the next line for a DStar only xrf reflector (instead of xlx) -#NOXLX=true -# uncomment the next line for no G3 support -#NOG3=true -############################################################################### - CC=g++ -ifdef DEBUG -CFLAGS=-ggdb3 -W -c -std=c++11 -MMD -MD -c +ifeq ($(debug), true) +CFLAGS = -ggdb3 -W -c -std=c++11 -MMD -MD -c -DNB_OF_MODULES=$(nb_of_modules) -DCALLSIGN=\"$(callsign)\" else -CFLAGS=-c -W -std=c++11 -MMD -MD -c +CFLAGS = -c -W -std=c++11 -MMD -MD -c -DNB_OF_MODULES=$(nb_of_modules) -DCALLSIGN=\"$(callsign)\" +endif + +ifdef listen_ipv4 +CFLAGS += -DLISTEN_IPV4=\"$(listen_ipv4)\" +endif + +ifdef listen_ipv6 +CFLAGS += -DLISTEN_IPV6=\"$(listen_ipv6)\" endif -ifdef NOXLX + +ifdef transcoder_ip +CFLAGS += -DTRANSCODER_IP=\"$(transcoder_ip)\" -DTRANSCODED_MODULES=\"$(tc_mods)\" +endif + +ifneq ($(is_xlx), true) CFLAGS += -DNO_XLX endif -ifdef NOG3 + +ifneq ($(use_g3), true) CFLAGS += -DNO_G3 endif LDFLAGS=-pthread XRFSRCS = cbuffer.cpp ccallsign.cpp ccallsignlist.cpp ccallsignlistitem.cpp cclient.cpp cclients.cpp cdcsclient.cpp cdcsprotocol.cpp cdextraclient.cpp cdextrapeer.cpp cdextraprotocol.cpp cdplusclient.cpp cdplusprotocol.cpp cdvframepacket.cpp cdvheaderpacket.cpp cdvlastframepacket.cpp cgatekeeper.cpp cip.cpp cnotification.cpp cpacket.cpp cpacketstream.cpp cpeercallsignlist.cpp cpeer.cpp cpeers.cpp cprotocol.cpp cprotocols.cpp creflector.cpp ctimepoint.cpp cudpsocket.cpp cuser.cpp cusers.cpp cversion.cpp main.cpp -XLXSRCS = cbmclient.cpp cbmpeer.cpp cbptc19696.cpp ccodecstream.cpp ccrc.cpp cdmriddir.cpp cdmriddirfile.cpp cdmriddirhttp.cpp cdmrmmdvmclient.cpp cdmrmmdvmprotocol.cpp cdmrplusclient.cpp cdmrplusprotocol.cpp cgolay2087.cpp cgolay24128.cpp chamming.cpp cqr1676.cpp crs129.cpp csemaphore.cpp ctranscoder.cpp cutils.cpp cwiresxcmd.cpp cwiresxcmdhandler.cpp cwiresxinfo.cpp cxlxclient.cpp cxlxprotocol.cpp cxlxpeer.cpp cysfclient.cpp cysfconvolution.cpp cysffich.cpp cysfnode.cpp cysfnodedir.cpp cysfnodedirfile.cpp cysfnodedirhttp.cpp cysfpayload.cpp cysfprotocol.cpp cysfutils.cpp +XLXSRCS = cbmclient.cpp cbmpeer.cpp cbptc19696.cpp ccrc.cpp cdmriddir.cpp cdmriddirfile.cpp cdmriddirhttp.cpp cdmrmmdvmclient.cpp cdmrmmdvmprotocol.cpp cdmrplusclient.cpp cdmrplusprotocol.cpp cgolay2087.cpp cgolay24128.cpp chamming.cpp cqr1676.cpp crs129.cpp csemaphore.cpp cutils.cpp cwiresxcmd.cpp cwiresxcmdhandler.cpp cwiresxinfo.cpp cxlxclient.cpp cxlxprotocol.cpp cxlxpeer.cpp cysfclient.cpp cysfconvolution.cpp cysffich.cpp cysfnode.cpp cysfnodedir.cpp cysfnodedirfile.cpp cysfnodedirhttp.cpp cysfpayload.cpp cysfprotocol.cpp cysfutils.cpp G3SRCS = cg3client.cpp cg3protocol.cpp crawsocket.cpp cudpmsgsocket.cpp SRCS = $(XRFSRCS) -ifndef NOXLX + +ifeq ($(is_xlx), true) SRCS += $(XLXSRCS) endif -ifndef NOG3 + +ifdef transcoder_ip +SRCS += ctranscoder.cpp ccodecstream.cpp +endif + +ifeq ($(use_g3), true) SRCS += $(G3SRCS) endif OBJS = $(SRCS:.cpp=.o) DEPS = $(SRCS:.cpp=.d) -ifdef NOXLX -EXE=xrfd -else +ifeq ($(is_xlx), true) EXE=xlxd +else +EXE=xrfd endif all : $(EXE) @@ -90,7 +141,7 @@ install : $(EXE).blacklist $(EXE).whitelist $(EXE).interlink $(EXE).terminal $(E ifndef NOG3 ln -s $(shell pwd)/$(EXE).terminal $(CFGDIR)/$(EXE).terminal endif - cp -f $(EXE).service /etc/systemd/system/ + cp -f ../systemd/$(EXE).service /etc/systemd/system/ cp -f $(EXE) $(BINDIR) mkdir -p $(DATADIR) systemctl enable $(EXE).service diff --git a/src/ccallsignlistitem.cpp b/src/ccallsignlistitem.cpp index 61f3749..a7d8a76 100644 --- a/src/ccallsignlistitem.cpp +++ b/src/ccallsignlistitem.cpp @@ -129,7 +129,7 @@ bool CCallsignListItem::CheckListedModules(char *Modules) const if ( Modules != NULL ) { // build a list of common modules - char list[NB_MODULES_MAX+1]; + char list[27]; list[0] = 0; // for ( unsigned i = 0; i < ::strlen(Modules); i++ ) diff --git a/src/ccallsignlistitem.h b/src/ccallsignlistitem.h index 341b059..33467a4 100644 --- a/src/ccallsignlistitem.h +++ b/src/ccallsignlistitem.h @@ -45,7 +45,7 @@ public: CCallsignListItem(const CCallsign &, const CIp &, const char *); CCallsignListItem(const CCallsign &, const char *, const char *); CCallsignListItem(const CCallsignListItem &); - + // destructor virtual ~CCallsignListItem() {} @@ -54,21 +54,21 @@ public: bool HasSameCallsignWithWildcard(const CCallsign &) const; bool HasModuleListed(char) const; bool CheckListedModules(char*) const; - + // get const CCallsign &GetCallsign(void) const { return m_Callsign; } const CIp &GetIp(void) const { return m_Ip; } const char *GetModules(void) { return m_Modules; } - + // update void ResolveIp(void) { m_Ip = CIp(m_szUrl); } - + protected: // data CCallsign m_Callsign; char m_szUrl[URL_MAXLEN+1]; CIp m_Ip; - char m_Modules[NB_MODULES_MAX+1]; + char m_Modules[27]; }; diff --git a/src/cdcsprotocol.cpp b/src/cdcsprotocol.cpp index b275a83..ee2ed6c 100644 --- a/src/cdcsprotocol.cpp +++ b/src/cdcsprotocol.cpp @@ -61,7 +61,15 @@ void CDcsProtocol::Task(void) CDvFramePacket *Frame; // handle incoming packets - if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) ) +#ifdef DSTAR_IPV6 +#ifdef DSTAR_IPV4 + if ( ReceiveDS(Buffer, Ip, 20) ) +#else + if ( Receive6(Buffer, Ip, 20) ) +#endif +#else + if ( Receive4(Buffer, Ip, 20) ) +#endif { // crack the packet if ( IsValidDvPacket(Buffer, &Header, &Frame) ) diff --git a/src/cdextraprotocol.cpp b/src/cdextraprotocol.cpp index 07bf6d6..0a8460a 100644 --- a/src/cdextraprotocol.cpp +++ b/src/cdextraprotocol.cpp @@ -64,7 +64,15 @@ void CDextraProtocol::Task(void) CDvLastFramePacket *LastFrame; // any incoming packet ? - if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) ) +#ifdef DSTAR_IPV6 +#ifdef DSTAR_IPV4 + if ( ReceiveDS(Buffer, Ip, 20) ) +#else + if ( Receive6(Buffer, Ip, 20) ) +#endif +#else + if ( Receive4(Buffer, Ip, 20) ) +#endif { // crack the packet if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) diff --git a/src/cdmrmmdvmprotocol.cpp b/src/cdmrmmdvmprotocol.cpp index 926d2d0..01e1c4f 100644 --- a/src/cdmrmmdvmprotocol.cpp +++ b/src/cdmrmmdvmprotocol.cpp @@ -90,7 +90,15 @@ void CDmrmmdvmProtocol::Task(void) CDvLastFramePacket *LastFrame; // handle incoming packets - if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) ) +#ifdef DMR_IPV6 +#ifdef DMR_IPV4 + if ( ReceiveDS(Buffer, Ip, 20) ) +#else + if ( Receive6(Buffer, Ip, 20) ) +#endif +#else + if ( Receive4(Buffer, Ip, 20) ) +#endif { //Buffer.DebugDump(g_Reflector.m_DebugFile); // crack the packet diff --git a/src/cdmrplusprotocol.cpp b/src/cdmrplusprotocol.cpp index c0a246f..bf2dfd4 100644 --- a/src/cdmrplusprotocol.cpp +++ b/src/cdmrplusprotocol.cpp @@ -79,7 +79,15 @@ void CDmrplusProtocol::Task(void) CDvFramePacket *Frames[3]; // handle incoming packets - if ( m_Socket6.Receive(Buffer, Ip, 10) && m_Socket4.Receive(Buffer, Ip, 10) ) +#ifdef DMR_IPV6 +#ifdef DMR_IPV4 + if ( ReceiveDS(Buffer, Ip, 20) ) +#else + if ( Receive6(Buffer, Ip, 20) ) +#endif +#else + if ( Receive4(Buffer, Ip, 20) ) +#endif { // crack the packet if ( IsValidDvFramePacket(Ip, Buffer, Frames) ) diff --git a/src/cdplusprotocol.cpp b/src/cdplusprotocol.cpp index 11ff4ef..e866353 100644 --- a/src/cdplusprotocol.cpp +++ b/src/cdplusprotocol.cpp @@ -62,7 +62,15 @@ void CDplusProtocol::Task(void) CDvLastFramePacket *LastFrame; // handle incoming packets - if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) ) +#ifdef DSTAR_IPV6 +#ifdef DSTAR_IPV4 + if ( ReceiveDS(Buffer, Ip, 20) ) +#else + if ( Receive6(Buffer, Ip, 20) ) +#endif +#else + if ( Receive4(Buffer, Ip, 20) ) +#endif { // crack the packet if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) diff --git a/src/cpacketstream.cpp b/src/cpacketstream.cpp index 68824b8..db8b24a 100644 --- a/src/cpacketstream.cpp +++ b/src/cpacketstream.cpp @@ -34,7 +34,9 @@ CPacketStream::CPacketStream() m_uiStreamId = 0; m_uiPacketCntr = 0; m_OwnerClient = NULL; +#ifdef TRANSCODER_IP m_CodecStream = NULL; +#endif } //////////////////////////////////////////////////////////////////////////////////////// @@ -54,8 +56,11 @@ bool CPacketStream::Open(const CDvHeaderPacket &DvHeader, CClient *client) m_DvHeader = DvHeader; m_OwnerClient = client; m_LastPacketTime.Now(); -#ifndef NO_XLX - m_CodecStream = g_Transcoder.GetStream(this, client->GetCodec()); +#ifdef TRANSCODER_IP + if (std::string::npos != std::string(TRANSCODED_MODULES).find(DvHeader.GetRpt2Module())) + m_CodecStream = g_Transcoder.GetStream(this, client->GetCodec()); + else + m_CodecStream = g_Transcoder.GetStream(this, CODEC_NONE); #endif ok = true; } @@ -68,10 +73,10 @@ void CPacketStream::Close(void) m_bOpen = false; m_uiStreamId = 0; m_OwnerClient = NULL; -#ifndef NO_XLX +#ifdef TRANSCODER_IP g_Transcoder.ReleaseStream(m_CodecStream); -#endif m_CodecStream = NULL; +#endif } //////////////////////////////////////////////////////////////////////////////////////// @@ -83,6 +88,7 @@ void CPacketStream::Push(CPacket *Packet) m_LastPacketTime.Now(); Packet->UpdatePids(m_uiPacketCntr++); // transcoder avaliable ? +#ifdef TRANSCODER_IP if ( m_CodecStream != NULL ) { // todo: verify no possibilty of double lock here @@ -105,6 +111,7 @@ void CPacketStream::Push(CPacket *Packet) m_CodecStream->Unlock(); } else +#endif { // otherwise, push direct push push(Packet); @@ -113,7 +120,7 @@ void CPacketStream::Push(CPacket *Packet) bool CPacketStream::IsEmpty(void) const { -#ifndef NO_XLX +#ifdef TRANSCODER_IP bool bEmpty = empty(); // also check no packets still in Codec stream's queue if ( bEmpty && (m_CodecStream != NULL) ) diff --git a/src/cpacketstream.h b/src/cpacketstream.h index 2f99bf6..8050b6b 100644 --- a/src/cpacketstream.h +++ b/src/cpacketstream.h @@ -72,7 +72,9 @@ protected: CClient *m_OwnerClient; CTimePoint m_LastPacketTime; CDvHeaderPacket m_DvHeader; +#ifdef TRANSCODER_IP CCodecStream *m_CodecStream; +#endif }; //////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cpeer.h b/src/cpeer.h index ec03451..dc2da68 100644 --- a/src/cpeer.h +++ b/src/cpeer.h @@ -88,7 +88,7 @@ protected: // data CCallsign m_Callsign; CIp m_Ip; - char m_ReflectorModules[NB_MODULES_MAX+1]; + char m_ReflectorModules[27]; CVersion m_Version; std::list m_Clients; diff --git a/src/cprotocol.cpp b/src/cprotocol.cpp index b02ef9b..dc3d2b1 100644 --- a/src/cprotocol.cpp +++ b/src/cprotocol.cpp @@ -79,12 +79,16 @@ bool CProtocol::Initialize(const char *type, uint16 port) m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)type, 3); // create our sockets +#ifdef LISSTEN_IPV4 CIp ip4(AF_INET, port, g_Reflector.GetListenIPv4()); if ( ip4.IsSet() ) { if (! m_Socket4.Open(ip4)) return false; } +#endif + +#ifdef LISTEN_IPV6 CIp ip6(AF_INET6, port, g_Reflector.GetListenIPv6()); if ( ip6.IsSet() ) { @@ -94,14 +98,19 @@ bool CProtocol::Initialize(const char *type, uint16 port) return false; } } +#endif // start thread; m_pThread = new std::thread(CProtocol::Thread, this); if (m_pThread == NULL) { std::cerr << "Could not start DCS thread!" << std::endl; +#ifdef LISTEN_IPV4 m_Socket4.Close(); +#endif +#ifdef LISTEN_IV6 m_Socket6.Close(); +#endif return false; } @@ -126,8 +135,12 @@ void CProtocol::Close(void) delete m_pThread; m_pThread = NULL; } +#ifdef LISTEN_IPV4 m_Socket4.Close(); +#endif +#ifdef LISTEN_IPV6 m_Socket6.Close(); +#endif } //////////////////////////////////////////////////////////////////////////////////////// @@ -291,18 +304,78 @@ uint32 CProtocol::ModuleToDmrDestId(char m) const return (uint32)(m - 'A')+1; } +//////////////////////////////////////////////////////////////////////////////////////// +// Receivers + +#ifdef LISTEN_IPV6 +bool CProtocol::Receive6(CBuffer &buf, CIp &ip, int time_ms) +{ + return m_Socket6.Receive(buf, ip, time_ms); +} +#endif + +#ifdef LISTEN_IPV4 +bool CProtocol::Receive4(CBuffer &buf, CIp &ip, int time_ms) +{ + return m_Socket4.Receive(buf, ip, time_ms); +} +#endif + +#if defined(LISTEN_IPV4) && defined(LISTEN_IPV6) +bool CProtocol::ReceiveDS(CBuffer &buf, CIp &ip, int time_ms) +{ + auto fd4 = m_Socket4.GetSocket(); + auto fd6 = m_Socket6.GetSocket(); + + if (fd4 < 0) + { + if (fd6 < 0) + return false; + return m_Socket6.Receive(buf, ip, time_ms); + } + else if (fd6 < 0) + return m_Socket4.Receive(buf, ip, time_ms); + + fd_set fset; + FD_ZERO(&fset); + FD_SET(fd4, &fset); + FD_SET(fd6, &fset); + int max = (fd4 > fd6) ? fd4 : fd6; + struct timeval tv; + tv.tv_sec = time_ms / 1000; + tv.tv_usec = (time_ms % 1000) * 1000; + + auto rval = select(max+1, &fset, 0, 0, &tv); + if (rval <= 0) + { + if (rval < 0) + std::cerr << "ReceiveDS select error: " << strerror(errno) << std::endl; + return false; + } + + if (FD_ISSET(fd4, &fset)) + return m_Socket4.ReceiveFrom(buf, ip); + else + return m_Socket6.ReceiveFrom(buf, ip); +} +#endif + //////////////////////////////////////////////////////////////////////////////////////// // dual stack senders void CProtocol::Send(const CBuffer &buf, const CIp &Ip) const { switch (Ip.GetFamily()) { +#ifdef LISTEN_IPV4 case AF_INET: m_Socket4.Send(buf, Ip); break; +#endif +#ifdef LISTEN_IPV6 case AF_INET6: m_Socket6.Send(buf, Ip); break; +#endif default: std::cerr << "Wrong family: " << Ip.GetFamily() << std::endl; break; @@ -312,12 +385,16 @@ void CProtocol::Send(const CBuffer &buf, const CIp &Ip) const void CProtocol::Send(const char *buf, const CIp &Ip) const { switch (Ip.GetFamily()) { +#ifdef LISTEN_IPV4 case AF_INET: m_Socket4.Send(buf, Ip); break; +#endif +#ifdef LISTEN_IPV6 case AF_INET6: m_Socket6.Send(buf, Ip); break; +#endif default: std::cerr << "ERROR: wrong family: " << Ip.GetFamily() << std::endl; break; @@ -327,12 +404,16 @@ void CProtocol::Send(const char *buf, const CIp &Ip) const void CProtocol::Send(const CBuffer &buf, const CIp &Ip, uint16_t port) const { switch (Ip.GetFamily()) { +#ifdef LISTEN_IPV4 case AF_INET: m_Socket4.Send(buf, Ip, port); break; +#endif +#ifdef LISTEN_IPV6 case AF_INET6: m_Socket6.Send(buf, Ip, port); break; +#endif default: std::cerr << "Wrong family: " << Ip.GetFamily() << " on port " << port << std::endl; break; @@ -342,12 +423,16 @@ void CProtocol::Send(const CBuffer &buf, const CIp &Ip, uint16_t port) const void CProtocol::Send(const char *buf, const CIp &Ip, uint16_t port) const { switch (Ip.GetFamily()) { +#ifdef LISTEN_IPV4 case AF_INET: m_Socket4.Send(buf, Ip, port); break; +#endif +#ifdef LISTEN_IPV6 case AF_INET6: m_Socket6.Send(buf, Ip, port); break; +#endif default: std::cerr << "Wrong family: " << Ip.GetFamily() << " on port " << port << std::endl; break; diff --git a/src/cprotocol.h b/src/cprotocol.h index 0e5f659..4b1955a 100644 --- a/src/cprotocol.h +++ b/src/cprotocol.h @@ -122,13 +122,28 @@ protected: virtual char DmrDstIdToModule(uint32) const; virtual uint32 ModuleToDmrDestId(char) const; +#ifdef LISTEN_IPV6 + bool Receive6(CBuffer &buf, CIp &Ip, int time_ms); +#endif +#ifdef LISTEN_IPV4 + bool Receive4(CBuffer &buf, CIp &Ip, int time_ms); +#endif +#if defined(LISTEN_IPV4) && defined(LISTEN_IPV6) + bool ReceiveDS(CBuffer &buf, CIp &Ip, int time_ms); +#endif + void Send(const CBuffer &buf, const CIp &Ip) const; void Send(const char *buf, const CIp &Ip) const; void Send(const CBuffer &buf, const CIp &Ip, uint16 port) const; void Send(const char *buf, const CIp &Ip, uint16 port) const; // socket - CUdpSocket m_Socket4, m_Socket6; +#ifdef LISTEN_IPV4 + CUdpSocket m_Socket4; +#endif +#ifdef LISTEN_IPV6 + CUdpSocket m_Socket6; +#endif // streams std::list m_Streams; diff --git a/src/creflector.cpp b/src/creflector.cpp index 623d0e4..f7da52c 100644 --- a/src/creflector.cpp +++ b/src/creflector.cpp @@ -110,9 +110,11 @@ bool CReflector::Start(void) // init wiresx node directory. Likewise with the return vale. g_YsfNodeDir.Init(); +#ifdef TRANSCODER_IP // init the transcoder if (! g_Transcoder.Init()) return false; +#endif #endif // create protocols @@ -173,10 +175,12 @@ void CReflector::Stop(void) // close gatekeeper g_GateKeeper.Close(); -#ifndef NO_XLX +#ifdef TRANSCODER_IP // close transcoder g_Transcoder.Close(); +#endif +#ifndef NO_XLX // close databases g_DmridDir.Close(); g_YsfNodeDir.Close(); @@ -407,6 +411,7 @@ void CReflector::XmlReportThread(CReflector *This) } } +#ifdef JSON_MONITOR void CReflector::JsonReportThread(CReflector *This) { CUdpSocket Socket; @@ -498,6 +503,7 @@ void CReflector::JsonReportThread(CReflector *This) std::cout << "Error creating monitor socket" << std::endl; } } +#endif //////////////////////////////////////////////////////////////////////////////////////// // notifications @@ -651,6 +657,8 @@ void CReflector::WriteXmlFile(std::ofstream &xmlFile) xmlFile << "" << std::endl; } + +#ifdef JSON_MONITOR //////////////////////////////////////////////////////////////////////////////////////// // json helpers @@ -764,3 +772,4 @@ void CReflector::SendJsonOffairObject(CUdpSocket &Socket, CIp &Ip, const CCallsi //std::cout << Buffer << std::endl; Socket.Send(Buffer, Ip); } +#endif diff --git a/src/creflector.h b/src/creflector.h index eea1c35..872ac1d 100644 --- a/src/creflector.h +++ b/src/creflector.h @@ -58,12 +58,21 @@ public: // settings void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; } const CCallsign &GetCallsign(void) const { return m_Callsign; } + +#ifdef LISTEN_IPV4 void SetListenIPv4(const char *a, const int n) { memset(m_IPv4, 0, n); strncpy(m_IPv4, a, n-1); } - void SetListenIPv6(const char *a, const int n) { memset(m_IPv6, 0, n); strncpy(m_IPv6, a, n-1); } - void SetTranscoderIp(const char *a, const int n) { memset(m_AmbedIp, 0, n); strncpy(m_AmbedIp, a, n-1); } const char *GetListenIPv4(void) const { return m_IPv4; } +#endif + +#ifdef LISTEN_IPV6 + void SetListenIPv6(const char *a, const int n) { memset(m_IPv6, 0, n); strncpy(m_IPv6, a, n-1); } const char *GetListenIPv6(void) const { return m_IPv6; } +#endif + +#ifdef TRANSCODER_IP + void SetTranscoderIp(const char *a, const int n) { memset(m_AmbedIp, 0, n); strncpy(m_AmbedIp, a, n-1); } const char *GetTranscoderIp(void) const { return m_AmbedIp; } +#endif // operation bool Start(void); @@ -102,7 +111,9 @@ protected: // threads static void RouterThread(CReflector *, CPacketStream *); static void XmlReportThread(CReflector *); +#ifdef JSON_MONITOR static void JsonReportThread(CReflector *); +#endif // streams CPacketStream *GetStream(char); @@ -112,19 +123,27 @@ protected: // xml helpers void WriteXmlFile(std::ofstream &); +#ifdef JSON_MONITOR // json helpers void SendJsonReflectorObject(CUdpSocket &, CIp &); void SendJsonNodesObject(CUdpSocket &, CIp &); void SendJsonStationsObject(CUdpSocket &, CIp &); void SendJsonOnairObject(CUdpSocket &, CIp &, const CCallsign &); void SendJsonOffairObject(CUdpSocket &, CIp &, const CCallsign &); +#endif protected: // identity CCallsign m_Callsign; +#ifdef LISTEN_IPV4 char m_IPv4[INET_ADDRSTRLEN]; +#endif +#ifdef LISTEN_IPV6 char m_IPv6[INET6_ADDRSTRLEN]; +#endif +#ifdef TRANSCODER_IP char m_AmbedIp[INET6_ADDRSTRLEN]; +#endif // objects CUsers m_Users; // sorted list of lastheard stations diff --git a/src/cudpsocket.cpp b/src/cudpsocket.cpp index 0b57118..d3a1e61 100644 --- a/src/cudpsocket.cpp +++ b/src/cudpsocket.cpp @@ -130,27 +130,29 @@ bool CUdpSocket::Receive(CBuffer &Buffer, CIp &Ip, int timeout) struct timeval tv; tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; + auto rval = select(m_fd + 1, &FdSet, 0, 0, &tv); - if (0 > rval) - { + if (rval > 0) + return ReceiveFrom(Buffer, Ip); + + if (rval < 0) std::cerr << "select error on UPD port " << m_addr << ": " << strerror(errno) << std::endl; - return false; - } - else if (0 == rval) - return false; + return false; +} + +bool CUdpSocket::ReceiveFrom(CBuffer &Buffer, CIp &ip) +{ // read uint8_t buf[UDP_BUFFER_LENMAX]; unsigned int fromsize = sizeof(struct sockaddr_storage); - auto iRecvLen = recvfrom(m_fd, buf, UDP_BUFFER_LENMAX, 0, Ip.GetPointer(), &fromsize); + auto iRecvLen = recvfrom(m_fd, buf, UDP_BUFFER_LENMAX, 0, ip.GetPointer(), &fromsize); - // handle if (0 >= iRecvLen) return false; Buffer.Set(buf, iRecvLen); - // done return true; } diff --git a/src/cudpsocket.h b/src/cudpsocket.h index 5f42e9f..8e69db3 100644 --- a/src/cudpsocket.h +++ b/src/cudpsocket.h @@ -65,6 +65,7 @@ public: // read bool Receive(CBuffer &, CIp &, int); + bool ReceiveFrom(CBuffer &buf, CIp &ip); // write void Send(const CBuffer &, const CIp &) const; diff --git a/src/cxlxprotocol.cpp b/src/cxlxprotocol.cpp index 35de1cf..2de1093 100644 --- a/src/cxlxprotocol.cpp +++ b/src/cxlxprotocol.cpp @@ -56,14 +56,22 @@ void CXlxProtocol::Task(void) CBuffer Buffer; CIp Ip; CCallsign Callsign; - char Modules[NB_MODULES_MAX+1]; + char Modules[27]; CVersion Version; CDvHeaderPacket *Header; CDvFramePacket *Frame; CDvLastFramePacket *LastFrame; // any incoming packet ? - if ( m_Socket4.Receive(Buffer, Ip, 10) || m_Socket6.Receive(Buffer, Ip, 10) ) +#ifdef XLX_IPV6 +#ifdef XLX_IPV4 + if ( ReceiveDS(Buffer, Ip, 20) ) +#else + if ( Receive6(Buffer, Ip, 20) ) +#endif +#else + if ( Receive4(Buffer, Ip, 20) ) +#endif { // crack the packet if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) @@ -276,11 +284,13 @@ void CXlxProtocol::HandleQueue(void) break; case XLX_PROTOCOL_REVISION_2: default: +#ifdef TRANSCODER_IP if ( g_Transcoder.IsConnected() ) { Send(buffer, client->GetIp()); } else +#endif { Send(bufferLegacy, client->GetIp()); } diff --git a/src/cysfprotocol.cpp b/src/cysfprotocol.cpp index faa3efa..b5034dc 100644 --- a/src/cysfprotocol.cpp +++ b/src/cysfprotocol.cpp @@ -101,7 +101,15 @@ void CYsfProtocol::Task(void) } // handle incoming packets - if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) ) +#ifdef YSF_IPV6 +#ifdef YSF_IPV4 + if ( ReceiveDS(Buffer, Ip, 20) ) +#else + if ( Receive6(Buffer, Ip, 20) ) +#endif +#else + if ( Receive4(Buffer, Ip, 20) ) +#endif { // crack the packet if ( IsValidDvPacket(Buffer, &Fich) ) diff --git a/src/main.cpp b/src/main.cpp index 3ac5a05..0281853 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,42 +38,30 @@ CReflector g_Reflector; #include "cusers.h" -int main(int argc, const char * argv[]) +int main() { - - // check arguments -#ifndef NO_XLX - if ( argc != 5 ) - { - std::cout << "Usage: " << argv[0] << " callsign ipv4 ipv6 ambedip" << std::endl; - std::cout << "example: " << argv[0] << " XLX999 192.168.178.212 2001:400:534::675b 127.0.0.1" << std::endl; - return EXIT_FAILURE; - } -#else - if ( argc != 4 ) - { - std::cout << "Usage: " << argv[0] << " callsign ipv4 ipv6" << std::endl; - std::cout << "example: " << argv[0] << " XLX999 192.168.178.212 2001:400:534::675b" << std::endl; - return EXIT_FAILURE; - } -#endif - - bool is4none = 0 == strncasecmp(argv[2], "none", 4); - bool is6none = 0 == strncasecmp(argv[3], "none", 4); - if (is4none && is6none) { - std::cerr << "Both IPv4 and 6 address can't both be 'none'" << std::endl; + const std::string cs(CALLSIGN); + if ((cs.size() != 6) || (cs.compare(0, 3, "XLX") && cs.compare(0, 3, "XRF"))) + { + std::cerr << "Malformed reflector callsign: '" << cs << "', aborting!" << std::endl; return EXIT_FAILURE; } - // splash - std::cout << "Starting " << argv[0] << " " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << std::endl << std::endl; + std::cout << "Starting " << cs << " " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << std::endl << std::endl; // initialize reflector - g_Reflector.SetCallsign(argv[1]); - g_Reflector.SetListenIPv4(argv[2], INET_ADDRSTRLEN); - g_Reflector.SetListenIPv6(argv[3], INET6_ADDRSTRLEN); -#ifndef NO_XLX - g_Reflector.SetTranscoderIp(argv[4], INET6_ADDRSTRLEN); + g_Reflector.SetCallsign(cs.c_str()); + +#ifdef LISTEN_IPV4 + g_Reflector.SetListenIPv4(LISTEN_IPV4, INET_ADDRSTRLEN); +#endif + +#ifdef LISTEN_IPV6 + g_Reflector.SetListenIPv6(LISTEN_IPV6, INET6_ADDRSTRLEN); +#endif + +#ifdef TRANSCODER_IP + g_Reflector.SetTranscoderIp(TRANSCODER_IP, INET6_ADDRSTRLEN); #endif @@ -85,18 +73,17 @@ int main(int argc, const char * argv[]) } std::cout << "Reflector " << g_Reflector.GetCallsign() << "started and listening on "; - if (! is4none) - { - std::cout << g_Reflector.GetListenIPv4() << " for IPv4"; - if (! is6none) - { - std::cout << " and " << g_Reflector.GetListenIPv6() << " for IPv6" << std::endl; - } - } - else - { - std::cout << g_Reflector.GetListenIPv6() << " for IPv6" << std::endl; - } +#if defined LISTEN_IPV4 + std::cout << g_Reflector.GetListenIPv4() << " for IPv4"; +#ifdef LISTEN_IPV6 + std::cout << " and " << g_Reflector.GetListenIPv6() << " for IPv6" << std::endl; +#endif +#elif defined LISTEN_IPV6 + std::cout << g_Reflector.GetListenIPv6() << " for IPv6" << std::endl; +#else + std::cout << "...ABORTING! No IP addresses defined!" << std::endl; + return EXIT_FAILURE; +#endif pause(); // wait for any signal diff --git a/src/main.h b/src/main.h index 974cdb9..8696dac 100644 --- a/src/main.h +++ b/src/main.h @@ -47,6 +47,33 @@ //////////////////////////////////////////////////////////////////////////////////////// // defines +// this is just for any "smart" editor, so everything will be "on" +#if ! defined(LISTEN_IPV4) && ! defined(LISTEN_IPV6) && ! defined(CALLSIGN) +#define CALLSIGN "XLX797" +#define LISTEN_IPV4 "10.1.10.61" +#define LISTEN_IPV6 "any" +#define TRANSCODER_IP "127.0.0.1" +#endif + +#ifndef TRANSCODED_MODULES +#define TRANSCODED_MODULES "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#endif + +//// Module configuration +#ifdef LISTEN_IPV4 +#define DSTAR_IPV4 +#define DMR_IPV4 +#define YSF_IPV4 +#define XLX_IPV4 +#endif + +#ifdef LISTEN_IPV6 +#define DSTAR_IPV6 +//#define DMR_IPV6 // these are off beacuse there are none available for IPv6 +//#define YSF_IPV6 +//#define XLX_IPV6 +#endif + // version ----------------------------------------------------- #define VERSION_MAJOR 2 @@ -64,12 +91,14 @@ // system constants --------------------------------------------- -#define NB_MODULES_MAX 26 - -// reflector --------------------------------------------------- - -//#define NB_OF_MODULES 10 -#define NB_OF_MODULES NB_MODULES_MAX +#ifndef NB_OF_MOUDLES +#define NB_OF_MODULES 26 +#endif +#if NB_OF_MODULES < 1 +#define NB_OF_MODULES 1 +#elif NB_OF_MODULES > 26 +#define NB_OF_MODULES 26 +#endif // protocols --------------------------------------------------- @@ -146,7 +175,7 @@ #define G3_KEEPALIVE_TIMEOUT 3600 // in seconds, 1 hour #endif -#ifndef NO_XLX +#ifdef TRANSCODER_IP // Transcoder server -------------------------------------------- #define TRANSCODER_PORT 10100 // UDP port @@ -180,8 +209,10 @@ #define LASTHEARD_USERS_MAX_SIZE 100 #define XML_UPDATE_PERIOD 10 // in seconds +#ifdef JSON_MONITOR #define JSON_UPDATE_PERIOD 10 // in seconds #define JSON_PORT 10001 +#endif // system paths ------------------------------------------------- diff --git a/systemd/ambed.service b/systemd/ambed.service index d608e84..2856a03 100644 --- a/systemd/ambed.service +++ b/systemd/ambed.service @@ -7,7 +7,7 @@ After=systemd-user-session.service network.target Type=simple ExecStartPre=-/sbin/rmmod ftdi_sio ExecStartPre=-/sbin/rmmod usbserial -ExecStart=/usr/local/bin/ambed 127.0.0.1 +ExecStart=/usr/local/bin/ambed Restart=always [Install] diff --git a/systemd/xlxd.service b/systemd/xlxd.service index f32ed3e..fcf3d94 100644 --- a/systemd/xlxd.service +++ b/systemd/xlxd.service @@ -5,7 +5,7 @@ After=systemd-user-session.service network.target [Service] Type=simple -ExecStart=/usr/local/bin/xlxd CHANGE_ME any any local +ExecStart=/usr/local/bin/xlxd Restart=always [Install] diff --git a/systemd/xrfd.service b/systemd/xrfd.service index f89df92..152ccd0 100644 --- a/systemd/xrfd.service +++ b/systemd/xrfd.service @@ -5,7 +5,7 @@ After=systemd-user-session.service network.target [Service] Type=simple -ExecStart=/usr/local/bin/xrfd CHANGEME any any +ExecStart=/usr/local/bin/xrfd Restart=always [Install]