This is my attempt to create a lightweight hotspot for DMR, D-STAR and C4FM on a Raspberry Pi 4 using the 64 bit operating system “Raspberry Pi OS”.

Preparation

warning
Do not use a cheap SD-card for your hotspot. We do not mount the filesystem read-only like on Pi-Star.
  1. Download the operating software image from raspberrypi.com.

  2. Boot the Raspberry Pi and set it up to your needs.

    • Localisation
    • Keyboard layout
    • Install needed packages
    • Install your favourite shell (bash, zsh, fish, csh …)
  3. Disable the serial console (and we will also disable Bluetooth)

    • Open /boot/cmdline.txt and remove the text console=serial0,115200

    • Open /boot/config.txt and add to the end

      1dtoverlay=disable-bt
      2enable_uart=1
      

      You may also run raspi-config and disable the console from there. Choose 3 Interface Options » I6 Serial Port » No (login shell) » Yes (serial hardware) » OK

      Disable the services

      1$ sudo systemctl disable [email protected]
      2$ sudo systemctl disable bluetooth.service
      

      Reboot the Raspberry Pi after those changes!

      1$ sudo reboot
      
  4. Install the needed packages to compile the software later

    1$ sudo apt update -y
    2$ sudo apt full-upgrade
    3$ sudo apt install git build-essential zsh nmap lsof vim cmake gcc-arm-none-eabi stm32flash libusb-1.0-0-dev libasound2-dev libwxgtk3.0-gtk3-dev
    

    Because wiringPi is currently not available from official sources, we have to install it manually.

    1$ git clone [email protected]:WiringPi/WiringPi.git
    2$ cd wiringPi
    3$ ./build
    

    This should suffice, make sure to read INSTALL and follow its instructions.

    Check wiringPi with gpio -v or gpio readall:

     1$ gpio -v
     2gpio version: 2.70
     3Copyright (c) 2012-2018 Gordon Henderson
     4This is free software with ABSOLUTELY NO WARRANTY.
     5For details type: gpio -warranty
     6
     7Raspberry Pi Details:
     8Type: Pi 4B, Revision: 01, Memory: 4096MB, Maker: Sony
     9  * Device tree is enabled.
    10  *--> Raspberry Pi 4 Model B Rev 1.1
    11  * This Raspberry Pi supports user-level GPIO access.
    
  5. Create a non-privileged user called mmdvm and add the user to the group dialout

    1$ sudo useradd mmdvm -g mmdvm -s /sbin/nologin
    2$ sudo usermod mmdvm -G dialout
    

    I had some problems with wiringPi, so I finally added the user mmdvm to the groups gpio and kmem. (To let the user mmdvm access /dev/mem and /dev/gpiomem.)

    1$ sudo usermod -G gpio,kmem -a mmdvm
    

Firmware

I hope we did not forgot: we use a DUAL_HAT extension on our Raspberry Pi and we have to compile the correct firmware for this. The actual version of the firmware is at 1.6.0:

MMDVM_HS_Dual_Hat-v1.6.0 20210919 12.2880MHz dual ADF7021 FW by CA6JAU GitID #d4cb546

But let us move to the fun (work) part.

Get the code

Clone the git repository. I prefer this in a separate folder like ~/git.

1$ git clone --recursive [email protected]:juribeparada/MMDVM_HS.git

Configuration

Enter the directory and copy an appropriate default configuration for your board.

1$ cp configs/MMDVM_HS_Dual_Hat-12mhz.h Config.h

Edit the file to your needs. The example below is what I use, be aware of the version of the installed TCXO of 12.2880 MHz!

 1// file: "Config.h"
 2#if !defined(CONFIG_H)
 3#define  CONFIG_H
 4
 5#define MMDVM_HS_DUAL_HAT_REV10
 6#define ENABLE_ADF7021
 7#define DUPLEX
 8#define ADF7021_12_2880
 9#define AD7021_GAIN_HIGH
10#define STM32_USART1_HOST
11#define I2C_ADDR 0x22
12#define ENABLE_SCAN_MODE
13#define SEND_RSSI_DATA
14#define SERIAL_REPEATER
15#define SERIAL_REPEATER_BAUD 115200
16#define QUIET_MODE_LEDS
17#define DISCREET_SRV_LED_INVERTED
18#define ENABLE_UDID
19
20#endif

Those settings are also interesting to play with in the file ADF7021.h:

 1// file: "ADF7021.h"
 2// Disable TX Raised Cosine filter for 4FSK modulation in ADF7021:
 3#define ADF7021_DISABLE_RC_4FSK
 4
 5// Enable AFC support for DMR, YSF, P25, and M17 (experimental):
 6// (AFC is already enabled by default in D-Star)
 7// #define ADF7021_ENABLE_4FSK_AFC
 8
 9// Configure AFC with positive initial frequency offset:
10// #define ADF7021_AFC_POS

I only disabled the Raised Cosine filter for 4FSK modulation because this works best for me. Enabling AFC did only cause lots of synchronisation errors on DMR. Also more firmware read errors occured with 4FSK AFC enabled.

You may want to leave that file intact if you just want your hotspot work without fiddling around with the source code.

Fine tuning and experimenting

If you want a hotspot that works: move over to the compilation process. If you want better response times on DMR keep on reading.

You may want to consider making the following changes on those two files.

1// file: "DMRDMOTX.cpp"
2//m_txDelay(240U),      // 200ms
3m_txDelay(120U),      // 200ms
1// file: "DMRDMOTX.cpp"
2void CDMRDMOTX::setTXDelay(uint8_t delay)
3{
4    //m_txDelay = 600U + uint16_t(delay) * 12U;        // 500ms + tx delay
5    m_txDelay = 60U + uint16_t(delay) * 12U;
6}
1// file: "DMRTX.cpp"
2// const uint32_t STARTUP_COUNT = 20U;
3const uint32_t STARTUP_COUNT = 2U;

I’ll leave you with this, if you have no idea what you are doing here: you should probably leave those files just as they are…

Those values were determined by Volker (DL2SDG) and I found them on one of the links below. Those values may not suit your configuratoin or board, so take them as a starting point and try the best values for you and your board.

Compile and upload to the board

If no errors were made in Config.h this should be as easy as the steps above.

1$ make clean
2$ make -j4
3$ sudo make mmdvm_hs_dual_hat

Finish this with a reboot of the Raspberry Pi.

1$ sudo reboot

Note, that we used -j4 as an argument of make because the Raspberry Pi 4 has 4 virtual cores and we use them to speed up the compilation process. {:.note title=“sidenote”}

Finally

And, as many operators tend to ignore manuals a lot, here are a few links that you can should read.

MMDVMHost

This is the program that connects our Gateways with the hardware board. This could be referred as the modem probably.

Get the code

We run this command also in our separated git folder. Just to keep all those git repositories in one place.

1$ git clone [email protected]:g4klx/MMDVMHost.git

Compile the code

Enter the newly created directory and compile it.

1$ make -j4 -f Makefile.Pi

Install the executables into /usr/local/bin by executing

1$ sudo make install

Configuration

Copy the default configuration file to /etc:

1$ sudo cp MMDVM.ini /etc/

and edit it to your needs. Most of the options are self-explanatory and I will only publish some excerpts of my /etc/MMDVM.ini file.

  1# file: "/etc/MMDVM.ini"
  2[Log]
  3# Logging levels, 0=No logging
  4DisplayLevel=2
  5FileLevel=2
  6FilePath=/var/log/mmdvm
  7FileRoot=MMDVM
  8FileRotate=0
  9
 10[Modem]
 11Hardware=mmdvmhshat
 12# Valid values are "null", "uart", "udp", and (on Linux) "i2c"
 13Protocol=uart
 14# The port and speed used for a UART connection
 15# UARTPort=\\.\COM4
 16# UARTPort=/dev/ttyACM0
 17UARTPort=/dev/ttyAMA0
 18UARTSpeed=115200
 19# The port and address for an I2C connection
 20I2CPort=/dev/i2c
 21I2CAddress=0x22
 22# IP parameters for UDP connection
 23ModemAddress=192.168.2.100
 24ModemPort=3334
 25LocalAddress=192.168.2.1
 26LocalPort=3335
 27TXInvert=1
 28RXInvert=0
 29PTTInvert=0
 30TXDelay=100
 31RXOffset=-50
 32TXOffset=300
 33DMRDelay=0
 34RXLevel=50
 35TXLevel=50
 36RXDCOffset=0
 37TXDCOffset=0
 38RFLevel=100
 39# CWIdTXLevel=50
 40# D-StarTXLevel=50
 41# DMRTXLevel=50
 42# YSFTXLevel=50
 43# P25TXLevel=50
 44# NXDNTXLevel=50
 45# M17TXLevel=50
 46# POCSAGTXLevel=50
 47# FMTXLevel=50
 48# AX25TXLevel=50
 49RSSIMappingFile=/usr/local/etc/RSSI.dat
 50UseCOSAsLockout=0
 51Trace=0
 52Debug=0
 53
 54[D-Star]
 55Enable=1
 56Module=B
 57SelfOnly=0
 58AckReply=1
 59AckTime=750
 60AckMessage=0
 61ErrorReply=1
 62RemoteGateway=0
 63# ModeHang=10
 64WhiteList=
 65
 66[DMR]
 67Enable=1
 68# Set your hotspot ID here (use your own DMR-ID and append two digits to it)
 69Id=XXXXXXXXX
 70Beacons=0
 71BeaconInterval=60
 72BeaconDuration=3
 73ColorCode=1
 74SelfOnly=0
 75EmbeddedLCOnly=0
 76DumpTAData=1
 77# Prefixes=234,235
 78# Slot1TGWhiteList=
 79# Slot2TGWhiteList=
 80CallHang=3
 81TXHang=4
 82# ModeHang=10
 83# OVCM Values, 0=off, 1=rx_on, 2=tx_on, 3=both_on, 4=force off
 84# OVCM=0
 85
 86[System Fusion]
 87Enable=1
 88LowDeviation=0
 89SelfOnly=0
 90TXHang=4
 91RemoteGateway=0
 92# ModeHang=10
 93
 94[D-Star Network]
 95Enable=1
 96LocalAddress=127.0.0.1
 97LocalPort=20011
 98GatewayAddress=127.0.0.1
 99GatewayPort=20010
100# ModeHang=3
101Debug=0
102
103[DMR Network]
104Enable=1
105# Type may be either 'Direct' or 'Gateway'. When Direct you must provide the Master's
106# address as well as the Password, and for DMR+, Options also.
107#Type=Direct
108Type=Gateway
109LocalAddress=127.0.0.1
110LocalPort=62032
111RemoteAddress=127.0.0.1
112RemotePort=62031
113#RemoteAddress=89.185.97.34
114#RemotePort=55555
115Password=passw0rd
116# [email protected]
117#Jitter=360
118Jitter=0
119Slot1=1
120Slot2=1
121# You would need the Options line if you want to connect MMDVMHost directly
122# to a DMR server (without Gateway)
123# Options="StartRef=4000;RelinkTime=15;UserLink=1;"
124# ModeHang=3
125Debug=0
126
127[System Fusion Network]
128Enable=1
129LocalAddress=127.0.0.1
130LocalPort=3200
131GatewayAddress=127.0.0.1
132GatewayPort=4200
133# ModeHang=3
134Debug=0

These are the most important parts of the configuration—make sure that you double check your file and insert your callsign and DMRID number correctly.

Within [DMR] you see the line starting with Id=. This is where you place the final Id for the DMR network, use your DMRID and append two digits to it, so you can run multiple hotspots on the same network/server (with different Ids, but still valid as they all start with your legit DMRID).

Create log file directory

1$ sudo mkdir /var/log/mmdvm
2$ sudo chown mmdvm:mmdvm /var/log/mmdvm

Check for errors

To check for errors, run MMDVMHost directly before setting up a system service. Make sure, that you have set Daemon=0 in your MMDVM.ini file for this test. Start MMDVMHost as user mmdvm

1$ sudo -u mmdvm MMDVMHost /etc/MMDVM.ini

Set Daemon=1 back in your MMDVM.ini if you haven’t already.

Setup the system service

Copy the unit file for Systemd to the system.

1$ sudo cp linux/systemd/mmdvmhost.service /etc/systemd/system/

No modification should be needed, but for reference this is the content of the file:

 1# file: "/etc/systemd/system/mmdvmhost.service"
 2[Unit]
 3Description=MMDVMHost Radio Service
 4After=syslog.target network.target
 5
 6[Service]
 7User=mmdvm
 8Type=forking
 9ExecStart=/usr/local/bin/MMDVMHost
10Restart=on-abnormal
11
12[Install]
13WantedBy=multi-user.target

Start and enable this service in one go with

1$ sudo systemctl daemon-reload
2$ sudo systemctl enable --now mmdvmhost.service

DMRGateway

We want to connect our hotspot to the austrian IPSC2-OE-DMO server aswell as the austrian brandmeister master server (BM2321).

Get the code

1$ git clone [email protected]:g4klx/DMRGateway.git

Configuration

  1# file: "/etc/DMRGateway.ini"
  2[General]
  3Timeout=10
  4# RFTimeout=10
  5# NetTimeout=7
  6RptAddress=127.0.0.1
  7RptPort=62032
  8LocalAddress=127.0.0.1
  9LocalPort=62031
 10RuleTrace=0
 11Daemon=1
 12Debug=0
 13
 14[Log]
 15# Logging levels, 0=No logging
 16DisplayLevel=2
 17FileLevel=2
 18FilePath=/var/log/mmdvm
 19FileRoot=DMRGateway
 20FileRotate=0
 21
 22[Voice]
 23Enabled=1
 24Language=en_GB
 25Directory=/home/pi/git/DMRGateway/Audio
 26
 27[Info]
 28Latitude=0.0
 29Longitude=0.0
 30Height=0
 31Location=Location, GRID
 32Description=Multi-Mode Hotspot
 33URL=https://oe7drt.com
 34
 35[XLX Network]
 36Enabled=0
 37File=XLXHosts.txt
 38Port=62030
 39Password=passw0rd
 40ReloadTime=60
 41# Local=3351
 42Slot=1
 43TG=6
 44Base=64000
 45Startup=950
 46Relink=10
 47Debug=0
 48#Allow user linking control using Private Calls
 49UserControl=1
 50#Override default module for startup reflector
 51#Module=A
 52
 53# BrandMeister
 54[DMR Network 1]
 55Enabled=1
 56Name=BM
 57Address=94.199.173.125
 58Port=62031
 59#Local=3352
 60# Local cluster
 61#TGRewrite=1,9,1,9,1
 62# Echo on RF slot 1 TG9990 to network slot 1 9990
 63TypeRewrite=1,9990,1,9990
 64SrcRewrite=1,9990,1,9990,1
 65# Dynamic rewriting of slot 2 TGs 90-999999 to TG9 to emulate reflector behaviour
 66#TGDynRewrite=2,90,4000,5000,9,999910,9990
 67# For normal repeater operation disable TGDyn coment out the above line
 68# After that remove the coments below
 69PassAllTG=1
 70# PassAllTG=2
 71# Pass all of the other private traffic on slot 1 and slot 2
 72PassAllPC=1
 73#PassAllPC=2
 74Password=passw0rd
 75Location=0
 76Debug=0
 77
 78# DMR+
 79[DMR Network 2]
 80Enabled=1
 81Name=DMR+
 82Address=89.185.97.34
 83Port=55555
 84# Local=3352
 85Password=PASSWORD
 86Options="StartRef=4000;RelinkTime=15;UserLink=1;TS1_1=110;"
 87TGRewrite=2,6,1,6,2
 88TGRewrite=2,110,1,110,1
 89TGRewrite=2,120,1,120,1
 90TGRewrite=2,130,1,130,1
 91TGRewrite=2,232,1,232,1
 92TGRewrite=2,8180,1,8180,10
 93TGRewrite=2,8191,1,8191,9
 94TGRewrite=2,9990,2,9990,1
 95TGRewrite=2,9,2,9,1
 96#PCRewrite=2,4000,2,4000,1001
 97PassAllPC=2
 98Location=0
 99Debug=0
100
101[...]
102
103[GPSD]
104Enable=0
105Address=127.0.0.1
106Port=2947
107
108[APRS]
109Enable=0
110Address=127.0.0.1
111Port=8673
112Description=APRS Description
113Suffix=3
114
115[Dynamic TG Control]
116Enabled=1
117Port=3769
118
119[Remote Control]
120Enable=0
121Address=127.0.0.1
122Port=7643

Test your setup

Change the configuration from above to Daemon=0 and start DMRGateway in a terminal with

1$ sudo -u mmdvm DMRGateway /etc/DMRGateway.ini

Check for errors and move on when everything is fine. You should hear the announcement coming from the ISPC2 server. In our case (Ref 4000) we should hear something like “Not connected” or “Repeater not connected”.

Create a system service

I copied the unit file from mmdvmhost.service and made my changes. If you don’t want to do that by yourself, use this one to start with.

 1# file: "/etc/systemd/system/dmrgateway.service"
 2[Unit]
 3Description=DMRGateway Radio Service
 4After=syslog.target network.target mmdvmhost.service
 5
 6[Service]
 7User=mmdvm
 8Type=forking
 9ExecStart=/usr/local/bin/DMRGateway
10Restart=on-abnormal
11
12[Install]
13WantedBy=multi-user.target

Change the configuration back Daemon=1 and enable the service/unit.

1$ sudo systemctl enable --now dmrgateway.service

YSFGateway (C4FM, YSF, YCS)

What we define: connect our hotspot to the AT-C4FM-Austria reflector via YSF.

Get the code

Use a quite actual but modified version of YSFClients

This is a fork of the original repository by Jonathan, G4KLX.

The only reason for using this version is the proper display in the servers dashboard. You will see your location aswell as the used frequency and the YSFGateway type in the YCS232 dashboard.

This version might not be as actual as the original repository, but it is ready-to-use with the changes made by Kurt, OE1KBC back in 2021.

I’ve included his changes in my fork and created a branch called YCS232.

1$ git clone [email protected]:oe7drt/YSFClients.git
2$ cd YSFClients
3$ git fetch --all
4$ git checkout YCS232

You can also add the original sources as an additional remote:

1$ git remote add upstream [email protected]:g4klx/YSFClients.git
2$ git fetch --all

Original, most actual codebase

1$ git clone [email protected]:g4klx/YSFClients.git

Either choice of source, compile it

Enter the created directory YSFClients and compile the code. Install them into /usr/local/bin

1$ cd YSFClients
2$ make -j4
3$ sudo make install

Configuration

Copy the default configuration file into /etc

1$ sudo cp YSFGateway/YSFGateway.ini /etc/

and edit the file. Here are some excerpts of mine:

 1# file: "/etc/YSFGateway.ini"
 2[General]
 3Callsign=OE7DRT
 4Suffix=RPT
 5# Suffix=ND
 6Id=XXXXXXX
 7RptAddress=127.0.0.1
 8RptPort=3200
 9LocalAddress=127.0.0.1
10LocalPort=4200
11WiresXMakeUpper=1
12WiresXCommandPassthrough=0
13Debug=0
14Daemon=1
15
16[Info]
17RXFrequency=430600000
18TXFrequency=439075000
19Power=1
20Latitude=0.0
21Longitude=0.0
22Height=0
23Name=Location, GRID
24Description=Multi-Mode Hotspot
25
26[Log]
27# Logging levels, 0=No logging
28DisplayLevel=2
29FileLevel=2
30FilePath=/var/log/mmdvm
31FileRoot=YSFGateway
32FileRotate=1
33
34[APRS]
35Enable=0
36Address=127.0.0.1
37Port=8673
38Description=APRS Description
39Suffix=Y
40
41[Network]
42# Startup=FCS00120
43Startup=AT-C4FM-Austria
44# book DG-ID for Reflector
45Options=10,20,22,24,28,32,62,35
46InactivityTimeout=0
47Revert=0
48Debug=0
49
50[YSF Network]
51Enable=1
52Port=42000
53Hosts=/usr/local/etc/YSFHosts.txt
54ReloadTime=60
55ParrotAddress=127.0.0.1
56ParrotPort=42012
57YSF2DMRAddress=127.0.0.1
58YSF2DMRPort=42013
59YSF2NXDNAddress=127.0.0.1
60YSF2NXDNPort=42014
61YSF2P25Address=127.0.0.1
62YSF2P25Port=42015
63
64[FCS Network]
65Enable=0
66Rooms=./FCSRooms.txt
67Port=42001

This is not the full file, but pretty much of it. Adopt to your needs but check and double-check that file like the other configuration files.

Test your setup

Change Daemon=0 in the configuration file for the test and run

1$ sudo -u mmdvm YSFGateway /etc/YSFGateway.ini

You should see yourself in the dashboard and also the screen should print something like Linked to AT-C4FM-AUSTRIA and Link successful to MMDVM.

Stop it with CTRL + C and move on to create a system service (unit file) for Systemd.

Change Daemon=1 back in your config if not already done.

Setup a system service

Create the unit file /etc/systemd/system/ysfgateway.service

 1# file: "/etc/systemd/system/ysfgateway.service"
 2[Unit]
 3Description=YSFGateway Service
 4After=syslog.target network.target
 5
 6[Service]
 7User=mmdvm
 8Type=forking
 9ExecStart=/usr/local/bin/YSFGateway
10Restart=on-abnormal
11
12[Install]
13WantedBy=multi-user.target

Start and enable the service.

1$ sudo systemctl daemon-reload
2$ sudo systemctl enable --now ysfgateway.service

ircDDBGateway (D-STAR)

Okay, this was the hardest part for me because I haven’t found much information about what programs and configuration files are really needed for D-STAR to work properly—I’m not even sure now if it is working fine or if something is still missing.

So the information in this section may be inaccurate or even wrong. Consider that, but if you have a correct answer I would be happy to hear about it.

I think that dstarrepeater was only used for the first hardware and it’s work is now done from MMDVMHost. Again, correct me if I’m wrong.

Get the code

In our ~/git directory (where else?)

1$ git clone [email protected]:g4klx/ircDDBGateway.git

Compile the code and install the programs

Open Makefile and change the parameters on top of the file to your needs. I like to use /var/log/mmdvm, /usr/local/bin and /usr/local/etc for example…

1$ cd ircDDBGateway
2$ make -j4
3$ sudo make install

Configuration

Sadly, I haven’t found any configuration file as an example, so I referred to the configuration files on anothor hotspot that was running Pi-Star.

These are the files that I use at the moment, changes may be done if needed.

/etc/ircddbgateway

  1# file: "/etc/ircddbgateway"
  2gatewayType=1
  3# gatewayType=0 is the default, but Pi-Star uses 1 here
  4# 0 repeater, 1 hotspot, 2 dongle, 3 starnet
  5gatewayCallsign=N0SIGN
  6gatewayAddress=0.0.0.0
  7icomAddress=172.16.0.20
  8icomPort=20000
  9hbAddress=127.0.0.1
 10hbPort=20010
 11latitude=0.0
 12longitude=0.0
 13description1=Location, GRID
 14description2=Location State
 15url=https://qrz.com/db/N0SIGN
 16repeaterCall1=N0SIGN
 17repeaterBand1=B
 18# repeaterType1=0 homebrew, 1 icom, 2 dummy
 19repeaterType1=0
 20repeaterAddress1=127.0.0.1
 21repeaterPort1=20011
 22reflector1=DCS009 A
 23atStartup1=1
 24reconnect1=0
 25frequency1=439.07500
 26offset1=-8.4750
 27rangeKms1=1.000
 28latitude1=0.0
 29longitude1=0.0
 30agl1=3.000
 31description1_1=Location, GRID
 32description1_2=Location State
 33url1=
 34band1_1=0
 35band1_2=0
 36band1_3=0
 37repeaterCall2=
 38repeaterBand2= 
 39repeaterType2=0
 40repeaterAddress2=127.0.0.1
 41repeaterPort2=20012
 42reflector2=
 43atStartup2=0
 44reconnect2=0
 45frequency2=0.00000
 46offset2=0.0000
 47rangeKms2=0.000
 48latitude2=0.000000
 49longitude2=0.000000
 50agl2=0.000
 51description2_1=
 52description2_2=
 53url2=
 54band2_1=0
 55band2_2=0
 56band2_3=0
 57repeaterCall3=
 58repeaterBand3= 
 59repeaterType3=0
 60repeaterAddress3=127.0.0.1
 61repeaterPort3=20013
 62reflector3=
 63atStartup3=0
 64reconnect3=0
 65frequency3=0.00000
 66offset3=0.0000
 67rangeKms3=0.000
 68latitude3=0.000000
 69longitude3=0.000000
 70agl3=0.000
 71description3_1=
 72description3_2=
 73url3=
 74band3_1=0
 75band3_2=0
 76band3_3=0
 77repeaterCall4=
 78repeaterBand4= 
 79repeaterType4=0
 80repeaterAddress4=127.0.0.1
 81repeaterPort4=20014
 82reflector4=
 83atStartup4=0
 84reconnect4=0
 85frequency4=0.00000
 86offset4=0.0000
 87rangeKms4=0.000
 88latitude4=0.000000
 89longitude4=0.000000
 90agl4=0.000
 91description4_1=
 92description4_2=
 93url4=
 94band4_1=0
 95band4_2=0
 96band4_3=0
 97ircddbEnabled=1
 98ircddbHostname=ircv4.openquad.net
 99ircddbUsername=N0SIGN
100ircddbPassword=
101ircddbEnabled2=0
102ircddbHostname2=rr.openquad.net
103ircddbUsername2=
104ircddbPassword2=
105ircddbEnabled3=0
106ircddbHostname3=
107ircddbUsername3=
108ircddbPassword3=
109ircddbEnabled4=0
110ircddbHostname4=
111ircddbUsername4=
112ircddbPassword4=
113aprsEnabled=1
114aprsHostname=euro.aprs2.net
115aprsPassword=00000
116aprsPort=14580
117dextraEnabled=1
118dextraMaxDongles=5
119dplusEnabled=1
120dplusMaxDongles=5
121dplusLogin=N0SIGN 
122dcsEnabled=1
123ccsEnabled=1
124ccsHost=CCS704  
125xlxEnabled=0
126xlxOverrideLocal=0
127xlxHostsFileUrl=http://xlxapi.rlx.lu/api.php?do=GetXLXDMRMaster
128starNetBand1=A
129starNetCallsign1=        
130starNetLogoff1=        
131starNetInfo1=
132starNetPermanent1=        
133starNetUserTimeout1=300
134starNetGroupTimeout1=300
135starNetCallsignSwitch1=0
136starNetTXMsgSwitch1=1
137starNetReflector1=
138starNetBand2=A
139starNetCallsign2=        
140starNetLogoff2=        
141starNetInfo2=
142starNetPermanent2=        
143starNetUserTimeout2=300
144starNetGroupTimeout2=300
145starNetCallsignSwitch2=0
146starNetTXMsgSwitch2=1
147starNetReflector2=
148starNetBand3=A
149starNetCallsign3=        
150starNetLogoff3=        
151starNetInfo3=
152starNetPermanent3=        
153starNetUserTimeout3=300
154starNetGroupTimeout3=300
155starNetCallsignSwitch3=0
156starNetTXMsgSwitch3=1
157starNetReflector3=
158starNetBand4=A
159starNetCallsign4=        
160starNetLogoff4=        
161starNetInfo4=
162starNetPermanent4=        
163starNetUserTimeout4=300
164starNetGroupTimeout4=300
165starNetCallsignSwitch4=0
166starNetTXMsgSwitch4=1
167starNetReflector4=
168starNetBand5=A
169starNetCallsign5=        
170starNetLogoff5=        
171starNetInfo5=
172starNetPermanent5=        
173starNetUserTimeout5=300
174starNetGroupTimeout5=300
175starNetCallsignSwitch5=0
176starNetTXMsgSwitch5=1
177starNetReflector5=
178remoteEnabled=1
179remotePassword=raspberry
180#remotePort=54321
181remotePort=10022
182language=0
183infoEnabled=1
184echoEnabled=1
185logEnabled=1
186dratsEnabled=0
187dtmfEnabled=1
188mobileGPSEnabled=0
189mobileGPSAddress=127.0.0.1
190mobileGPSPort=7834
191windowX=-1
192windowY=-1

I wasn’t aware what numbers need to be set on gatewayType or repeaterType, but a look into the source code made my decision easier. I’m not sure if that is correctly interpreted as I never finished learning C++ but I learned the basics back in school…

And so I found some information in Common/Defs.h:

64enum HW_TYPE {
65    HW_HOMEBREW,
66    HW_ICOM,
67    HW_DUMMY
68};
130enum GATEWAY_TYPE {
131    GT_REPEATER,
132    GT_HOTSPOT,
133    GT_DONGLE,
134    GT_STARNET
135};

View those two online on github: HW_TYPE, GATEWAY_TYPE

/etc/timeserver

timeserverd is used to produce time announcements. The interval of these can be set to

  • every 15 minutes:
    interval=0
  • every 30 minutes:
    interval=1
  • every hour:
    interval=2

Adopt those changes in /etc/timeserver.

 1# file: "/etc/timeserver"
 2callsign=N0SIGN
 3sendA=0
 4sendB=1
 5sendC=0
 6sendD=0
 7sendE=0
 8address=127.0.0.1
 9language=3
10format=1
11interval=2
12windowX=0
13windowY=0

First run

1$ sudo -u mmdvm ircddbgatewayd

Abort with CTRL + C when done.

Create the system services

You could copy over the unit files from ./debian, but the paths in those files need adjustement, so we create them directly with sudo vim /etc/systemd/system/...

 1# file: "/etc/systemd/system/ircddbgateway.service"
 2[Unit]
 3Description=D-STAR Gateway Daemon
 4After=network.target
 5
 6[Service]
 7User=mmdvm
 8ExecStart=/usr/local/bin/ircddbgatewayd
 9Restart=on-abort
10
11[Install]
12WantedBy=multi-user.target
 1# file: "/etc/systemd/system/timeserver.service"
 2[Unit]
 3Description=Timeserver (ircDDBGateway) Daemon
 4After=syslog.target network.target ircddbgateway.service
 5
 6[Service]
 7User=mmdvm
 8Type=forking
 9ExecStart=/usr/local/bin/timeserverd -daemon
10#ExecStop=/usr/local/sbin/timeserver.service stop
11#ExecReload=/usr/local/sbin/timeserver.service restart
12Restart=on-abort
13
14[Install]
15WantedBy=multi-user.target

Enable the services

1$ sudo systemctl daemon-reload
2$ sudo systemctl enable --now ircddbgateway.service
3$ sudo systemctl enable --now timeserver.service

The hotspot works

This is the end of the procedure if you want a working hotspot. If you want visualisation on a dashboard continue reading: we will install nginx as our webserver and host the dashboard made by Kim, DG9VH.

Dashboard

Preparation

There are a few things to prepare, before we can finally visualize the electro-magnetic stream in the air.

Install some needed packages

1$ sudo apt install python3-websockets python3-pip
2$ sudo pip3 install ansi2html
3$ sudo apt install python3-gpiozero python3-psutil python3-serial

Refer to the installation instructions on the repository for more information and the full instructions.

Allow the logtailer program access to MMDVMHost with sudo visudo and add this line to the user section of the sudoers file:

1www-data ALL=(ALL) NOPASSWD: /usr/local/bin/MMDVMHost

Webserver or built-in solution?

We could use a built-in solution to host our dashboard using Python. This is a fancy way to host a dashboard but I’ve never used such solutions myself, so I’ll stick to a real webserver in this article.

Install nginx with php support with

1$ sudo apt install nginx php-fpm
Configure and limit webserver

I’ve already added some limiting directives into the default configuration. We should not need this with the websockets based dashboard, but I add this anyway.

We also added index.php to the index directive, but not in front of the filenames → we want to disable the dashboard with an empty index.html file that we create in the document root of our webserver (sudo touch /var/www/html/index.html).

 1# file: "/etc/nginx/sites-enabled/default"
 2limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
 3
 4# Default server configuration
 5#
 6server {
 7  listen 80 default_server;
 8  listen [::]:80 default_server;
 9  limit_req zone=mylimit burst=5 nodelay;
10  # limit_req_status 444;
11
12  # SSL configuration
13  #
14  # listen 443 ssl default_server;
15  # listen [::]:443 ssl default_server;
16  #
17  # [...]
18  #
19  # include snippets/snakeoil.conf;
20
21  root /var/www/html;
22
23  # Add index.php to the list if you are using PHP
24  index index.html index.php index.htm index.nginx-debian.html;
25
26  server_name _;
27
28  location / {
29    # First attempt to serve request as file, then
30    # as directory, then fall back to displaying a 404.
31    try_files $uri $uri/ =404;
32  }
33
34  # pass PHP scripts to FastCGI server
35  #
36  location ~ \.php$ {
37    include snippets/fastcgi-php.conf;
38  
39    # With php-fpm (or other unix sockets):
40    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
41    # With php-cgi (or other tcp sockets):
42    #fastcgi_pass 127.0.0.1:9000;
43  }
44
45  # deny access to .htaccess files, if Apache's document root
46  # concurs with nginx's one
47  #
48  location ~ /\.ht {
49    deny all;
50  }
51}
52
53
54# Virtual Host configuration for example.com
55#
56# [...]

Get the code

1$ sudo mkdir /opt/MMDVMDash
2$ sudo chown pi /opt/MMDVMDash
3$ git clone --recursive [email protected]:dg9vh/MMDVMHost-Websocketboard.git /opt/MMDVMDash

We saved the dashboard repository now in /opt/MMDVMDash.

Configuration

Open logtailer.ini, this should look something like this (shrinked together)

 1# file: "/opt/MMDVMDash/logtailer.ini"
 2[DEFAULT]
 3Host=0.0.0.0
 4Port=5678
 5Ssl=False
 6SslCert=/path/to/cert
 7SslKey=/path/to/keyfile
 8MaxLines=500
 9Filerotate=True
10[MMDVMHost]
11Logdir=/var/log/mmdvm/
12Prefix=MMDVM
13DMR_ID_Lookup=1
14DMR_ID_LookupFile=/usr/local/etc/DMRIds.dat
15DMR_ID_Reload_Time=1440
16MMDVM_ini=/etc/MMDVM.ini
17MMDVM_bin=/usr/local/bin/MMDVMHost
18[DAPNETGateway]
19Logdir=/var/log/mmdvm/
20Prefix=DAPNETGateway
21[ServiceMonitoring]
22BinaryName1=MMDVMHost
23BinaryName2=ircddbgatewayd
24BinaryName3=YSFGateway
25BinaryName4=timeserverd

Next, open /opt/MMDVMDash/html/js/config.js and modify it to your needs

 1// file: "/opt/MMDVMDash/html/js/config.js"
 2var config_struc_ver = 20210501.1;
 3var qrz = 1;
 4var debug = 0;
 5var warnlevel = 200;
 6var emergencylevel = 500;
 7var currtx = 1;
 8var lastheard = 2;
 9var localheard = 1;
10var allheard = 1;
11var qso = 1;
12var dapnet = 0;
13var sysinfo = 1;
14var services = 1;
15var about = 0;
16var useClientTimezone = 1;
17var showBMTGLink = 0;
18var qrz_blacklist = [
19"N0CALL",
20]
21var dashboard_blacklist = [
22"MY0CALL",
23]
24var useDarkTheme = 0;
25var customHeadlineText = ``;
26var customText = ``;

Create and enable a system service

1$ sudo cp systemd/logtailer.service /etc/systemd/system/
2$ sudo systemctl daemon-reload
3$ sudo systemctl enable --now logtailer.service

Enjoy the multi-mode hotspot

Finally, a few last words should be written. I’ve spent quite some time with my research about the tools needed for a hotspot. Most of us use Pi-Star and go with it. And that’s fine, because Pi-Star is an awesome jack of all trades, but in this article I tried to explain my experiences that I learned when I created my lightweight hotspot that only runs programs that I really need.

You gain more control over the system tasks on your Raspberry Pi, but you loose some comfort functions. I always liked slim and lightweight systems since I learned about the linux world back in my school time. I went with Gentoo and fluxbox for some years and also used FreeBSD in combination with fluxbox on my older Lenovo T60 laptop.

So that’s why I try to make my systems small and compact and I’m very happy with the result. I personally thought that I’d stuck on the D-STAR configuration because I’ve found so less information about that mode—specially it’s configuration. But now it’s working fine and I can say: it wasn’t that hard (or abstract) as I thought before.