Skip to main content

Kerlink gateways

This page has not been fully updated to represent the latest state of the Helium Network following the migration to Solana on April 18, 2023.

All Kerlink gateways share the same operating system, called KerOS. It is based on Linux and uses OPKG, however not directly.

Logging in

Use SSH. Your username is root and the default password is pdmk-XXXXXX where the X's should be replaced with the last 6 digits of the gateway Board ID or the EUI (see labels on the gateway).

Once logged in, please change your password.

Check KerOS version

We recommend to use the latest KerOS version, which is at the time of writing 4.3.3:

root@klk-wiis-050029:~ # opkg list
keros - 4.3.3-0-g993efce1

Installing an IPK

To install an IPK package, place it in /user/.updates and execute:

kerosd -u

Example: upload from your computer

user@computer:~ $ scp file.ipk root@gateway-ip:/user/.updates/

or directly from the gateway:

root@klk-wiis-050029:~ # wget
Connecting to (
Connecting to (
helium-gateway-v1.0. 100% |*************************************************************************************************************| 1032k 0:00:00 ETA
root@klk-wiis-050029:~ # mv helium-gateway-v1.0.0-alpha.8-klkgw.ipk /user/.updates
root@klk-wiis-050029:~ # sync; kerosd -u; reboot; exit

The system is going down for reboot NOW!029 (pts/0) (Tue Apr 20 17:49:37 2021)

This is used because KerOS uses a backup mechanism when installing packages. As soon as you install an IPK, a backup snapshot is made. You can then

  • restore to stock firmware: kerosd -s
  • restore to the latest backup: kerosd -b
  • trigger an update from /user/.updates: kerosd -u

Check installation

You need the latest KerOS version (see above) and the appropriate light miner software installed:

root@klk-wiis-050029:~ # opkg list
helium_gateway - 1.0.0-alpha.8
keros - 4.3.3-0-g993efce1

Configure LoRa Frequency Plan

Use the built-in tool klk_apps_config to activate the Kerlink Packet Forwarder (CPF) on the appropriate region:

# this is multiline just for readability
root@klk-wiis-050029:~ # klk_apps_config --activate-cpf \
--lns-server \
--lns-dport 1680 --lns-uport 1680 \
--loradconf US915-US.json
Stopping lorad 1.3.0
Stopping lorafwd 1.2.0
Starting lorad 1.3.0
Starting lorafwd 1.2.0
lorafwd[1447]: <6> Parsing configuration file: /var/run/lora/gateway-id.toml
lorafwd[1447]: <6> Parsing configuration file: /etc/lorafwd.toml
root@klk-wiis-050029:~ #

The list of available preconfigured regions are in /etc/lorad/XXX where XXX is the gateway model nickname:

  • iFemtoCell: wifc
  • iFemtoCell Evolution: fevo
  • iStation: wiis
root@klk-wiis-050029:~ # ll /etc/lorad/wiis/
drwxr-xr-x 2 root root 220 Aug 3 2020 .
drwxr-xr-x 1 root root 4.0K Apr 20 17:55 ..
-rw-r--r-- 1 root root 2.4K Aug 3 2020 AS923-JP.json
-rw-r--r-- 1 root root 2.0K Aug 3 2020 AS923-TH-SG-HK-TW.json
-rw-r--r-- 1 root root 1.9K Aug 3 2020 AU915-AU.json
-rw-r--r-- 1 root root 2.0K Aug 3 2020 EU868-FR.json
-rw-r--r-- 1 root root 1.8K Aug 3 2020 IN865-IN.json
-rw-r--r-- 1 root root 2.3K Aug 3 2020 KR920-KR.json
-rw-r--r-- 1 root root 1.9K Aug 3 2020 RU864-RU.json
-rw-r--r-- 1 root root 1.9K Aug 3 2020 RU864-RU_Legacy.json
-rw-r--r-- 1 root root 1.9K Aug 3 2020 US915-US.json

If the desired configuration file is not available, feel free to create a new one and restart the tool.


Kerlink uses the first sub-band in these regions by default. To use the appropriate sub-band (second), use this command:

source /etc/default/lorad
# US915
sed -i s/902700000/904300000/ $CONFIGURATION_FILE
sed -i s/903400000/905000000/ $CONFIGURATION_FILE
# AU915
sed -i s/915600000/917200000/ $CONFIGURATION_FILE
sed -i s/916300000/917900000/ $CONFIGURATION_FILE
# all regions:
monit restart lorad

TX frequencies

By default, Kerlink restricts the TX frequencies (downlinks) to what LoRaWAN defines. Helium Proofs of Coverage use the uplink bands for the transmission of the challenge RF packet.

This is only required in US915 and AU915:

# US915
sed -i s/923300000/902300000/ ${CONFIGURATION_FILE}
# AU915
sed -i s/923300000/915200000/ ${CONFIGURATION_FILE}
# all regions:
monit restart lorad


LoRa logs are available in /var/log/lora.log:

Radio configuration

Restart the lora daemon and see if it loads the appropriate channels:

# note: timestamps removed for readability
root@klk-wiis-050029:~ # tail -f /var/log/lora.log &
[1] 2041
root@klk-wiis-050029:~ # monit restart lorad
lorad[1414]: <5> Stopping lorad
lorad[1414]: <3> TTY PORT FAIL TO CLOSE
lorad[1414]: <4> Failed to close GPS device
lorad[1414]: <4> concentrator was already disconnected
lorafwd[1449]: <6> Heartbeat (3E33) sent
lorafwd[1449]: <6> Heartbeat (3E33) acknowledged in 1.00509 ms
lorad[2011]: <5> Starting lorad 1.3.0
lorad[2011]: <6> Programming FPGA with spectral scan firmware
lorad[2011]: <6> Using PPS device /sys/class/pps/pps1
lorad[2011]: <6> Parsing configuration file: /etc/lorad/lorad.json
lorad[2011]: <6> Initialize JIT queue (nb_pkt=64, size=19716)
lorad[2011]: <6> Using board: lorawan_public=true
lorad[2011]: <6> Using lbt: enable=false
lorad[2011]: <6> Using txgain: lut=0 dig_gain=3 dac_gain=3 mix_gain=9 pa_gain=1 rf_power=-2
lorad[2011]: <6> Using txgain: lut=1 dig_gain=3 dac_gain=3 mix_gain=11 pa_gain=1 rf_power=2
lorad[2011]: <6> Using txgain: lut=2 dig_gain=3 dac_gain=3 mix_gain=12 pa_gain=1 rf_power=4
lorad[2011]: <6> Using txgain: lut=3 dig_gain=3 dac_gain=3 mix_gain=14 pa_gain=1 rf_power=7
lorad[2011]: <6> Using txgain: lut=4 dig_gain=3 dac_gain=3 mix_gain=10 pa_gain=2 rf_power=8
lorad[2011]: <6> Using txgain: lut=5 dig_gain=3 dac_gain=3 mix_gain=11 pa_gain=2 rf_power=10
lorad[2011]: <6> Using txgain: lut=6 dig_gain=3 dac_gain=3 mix_gain=12 pa_gain=2 rf_power=12
lorad[2011]: <6> Using txgain: lut=7 dig_gain=3 dac_gain=3 mix_gain=13 pa_gain=2 rf_power=14
lorad[2011]: <6> Using txgain: lut=8 dig_gain=3 dac_gain=3 mix_gain=14 pa_gain=2 rf_power=15
lorad[2011]: <6> Using txgain: lut=9 dig_gain=3 dac_gain=3 mix_gain=9 pa_gain=3 rf_power=17
lorad[2011]: <6> Using txgain: lut=10 dig_gain=3 dac_gain=3 mix_gain=10 pa_gain=3 rf_power=19
lorad[2011]: <6> Using txgain: lut=11 dig_gain=3 dac_gain=3 mix_gain=11 pa_gain=3 rf_power=21
lorad[2011]: <6> Using txgain: lut=12 dig_gain=3 dac_gain=3 mix_gain=12 pa_gain=3 rf_power=23
lorad[2011]: <6> Using txgain: lut=13 dig_gain=3 dac_gain=3 mix_gain=13 pa_gain=3 rf_power=25
lorad[2011]: <6> Using txgain: lut=14 dig_gain=3 dac_gain=3 mix_gain=14 pa_gain=3 rf_power=26
lorad[2011]: <6> Using txgain: lut=15 dig_gain=3 dac_gain=3 mix_gain=15 pa_gain=3 rf_power=27
lorad[2011]: <6> Using rxrf: chain=0 enable=true freq_hz=904300000 rssi_offset=-169.5 type=SX1257 tx_enable=true tx_notch_freq=129000
lorad[2011]: <6> Using rxrf: chain=1 enable=true freq_hz=905000000 rssi_offset=-168.7 type=SX1257 tx_enable=false
lorad[2011]: <6> Using rxif: channel=0 enable=true type=MULTI rf_chain=0 freq_hz=903900000 bw=125000 sf=7-12
lorad[2011]: <6> Using rxif: channel=1 enable=true type=MULTI rf_chain=0 freq_hz=904100000 bw=125000 sf=7-12
lorad[2011]: <6> Using rxif: channel=2 enable=true type=MULTI rf_chain=0 freq_hz=904300000 bw=125000 sf=7-12
lorad[2011]: <6> Using rxif: channel=3 enable=true type=MULTI rf_chain=0 freq_hz=904500000 bw=125000 sf=7-12
lorad[2011]: <6> Using rxif: channel=4 enable=true type=MULTI rf_chain=1 freq_hz=904700000 bw=125000 sf=7-12
lorad[2011]: <6> Using rxif: channel=5 enable=true type=MULTI rf_chain=1 freq_hz=904900000 bw=125000 sf=7-12
lorad[2011]: <6> Using rxif: channel=6 enable=true type=MULTI rf_chain=1 freq_hz=905100000 bw=125000 sf=7-12
lorad[2011]: <6> Using rxif: channel=7 enable=true type=MULTI rf_chain=1 freq_hz=905300000 bw=125000 sf=7-12
lorad[2011]: <6> Using rxif: channel=8 enable=true type=STD rf_chain=0 freq_hz=904600000 bw=500000 sf=8
lorad[2011]: <6> Using rxif: channel=9 enable=false
lorad[2011]: <6> Using beacon: enable=false
lorad[2011]: <6> Using api: uplink="ipc:///var/run/lora/uplink"
lorad[2011]: <6> Using api: downlink="ipc:///var/run/lora/downlink"
lorad[2011]: <6> Using api: control="ipc:///var/run/lora/lorad"
lorad[2011]: <6> Programming FPGA with spectral scan firmware
lorad[2011]: <5> detected FPGA with SPI mux header (v31)
lorad[2011]: <6> FPGA supported features: [TX filter] [Spectral Scan]
lorad[2011]: <6> sx1272 version: 0x22, initial mode:0x1
lorad[2011]: <6> TAI offset has been set to 37
lorad[2011]: <6> Setting mode standby OK
lorad[2011]: <6> Selected single side bandwidth: 100000
lorad[2011]: <6> PPS is enabled
lorad[2011]: <6> Setting mode RX OK
lorafwd[1449]: <6> Received uplink message: system event "Started"

We can see it loaded channels 903.9MHz, 904.1MHz, etc: this is the appropriate frequency sub-band for US915.

LoRa traffic

# note: timestamps removed for readability
root@klk-wiis-050029:~ # tail -f /var/log/lora.log
lorad[20071]: <6> Received downlink message
lorad[20071]: <6> Sent downlink message
lorafwd[6973]: <6> Received uplink message: transmission event (000093C7 / 00000000), status "Transmitted"
lorafwd[6973]: <6> Downlink message (93C7) acknowledged
lorafwd[6973]: <6> Heartbeat (B0A6) sent
lorafwd[6973]: <6> Heartbeat (B0A6) acknowledged in 1.4919 ms
lorafwd[6973]: <6> Received uplink message:
lorafwd[6973]: <6> | lora uplink (6D700004), payload 23 B, channel 903.3 MHz, crc ok, bw 125 kHz, sf 10, cr 4/5
lorafwd[6973]: <6> | Join Request, JoinEUI 0000000000000000, DevEUI 7076FF006A03004E, DevNonce 41214
lorafwd[6973]: <6> | - radio (00000005)
lorafwd[6973]: <6> | - demodulator counter 21645692, TAI time 2021-04-20T18:36:02.146512Z, rssi -65 dB, snr 15 dB
lorafwd[6973]: <6> | - localization encrypted 7DB2593A662F37578CA8C7439523E199, rssi -65 dB, frequency offset 2295 Hz, version 1
lorafwd[6973]: <6> Uplink message (43A6) sent
lorad[20071]: <6> Sent 1 uplink message
lorafwd[6973]: <6> Uplink message (43A6) acknowledged in 1.0356 ms

Here we can confirm:

  • that the packet forwarder communicates well with the Helium light gateway because all the heartbeats / uplinks are acknowledged in a millisecond
  • that the radio is well configured because it received an uplink message (Join Request) at 903.3MHz, -65dBm RSSI and 15dB SNR (device was close)