Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions run_cast.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,31 @@ in_tcp="tcpcli://localhost:${tcp_port}#${receiver_format}"
#in_ext_tcp is mainly for dev purpose to receive a raw stream from another base
in_ext_tcp="tcpcli://${ext_tcp_source}:${ext_tcp_port}#${receiver_format}"

out_caster_A="-msg ${rtcm_msg_a} -out ntrips://:${svr_pwd_a}@${svr_addr_a}:${svr_port_a}/${mnt_name_a}#rtcm3 -p ${position}"
#add receiver options if it exists
[[ ! -z "${ntrip_a_receiver_options}" ]] && out_caster_A=""${out_caster_A}" -opt "${ntrip_a_receiver_options}""

out_caster_B="-msg ${rtcm_msg_b} -out ntrips://:${svr_pwd_b}@${svr_addr_b}:${svr_port_b}/${mnt_name_b}#rtcm3 -p ${position}"
#add receiver options if it exists
[[ ! -z "${ntrip_b_receiver_options}" ]] && out_caster_B=""${out_caster_B}" -opt "${ntrip_b_receiver_options}""
build_out_caster() {
local suffix="${1^^}"
local suffix_lower="${suffix,,}"
local msg_var="rtcm_msg_${suffix_lower}"
local pwd_var="svr_pwd_${suffix_lower}"
local addr_var="svr_addr_${suffix_lower}"
local port_var="svr_port_${suffix_lower}"
local mount_var="mnt_name_${suffix_lower}"
local options_var="ntrip_${suffix_lower}_receiver_options"
local out_caster="-msg ${!msg_var} -out ntrips://:${!pwd_var}@${!addr_var}:${!port_var}/${!mount_var}#rtcm3 -p ${position}"

[[ -n "${!options_var}" ]] && out_caster="${out_caster} -opt \"${!options_var}\""
printf '%s' "${out_caster}"
}

run_out_caster() {
local input_var="${1}"
local suffix="${2^^}"
local out_caster
out_caster="$(build_out_caster "${suffix}")"
${cast} -in ${!input_var} ${out_caster} -i "${receiver_info}" -a "${antenna_info}" -t ${level} -fl ${logdir}/str2str_ntrip_${suffix}.log
}

out_caster_A="$(build_out_caster A)"
out_caster_B="$(build_out_caster B)"

array_pos=(${position})
if [[ ${local_ntripc_user} == '' ]] && [[ ${local_ntripc_pwd} == '' ]]
Expand Down Expand Up @@ -63,12 +81,16 @@ mkdir -p ${logdir}
;;

out_caster_A)
#echo ${cast} -in ${!1} -out $out_caster
${cast} -in ${!1} ${out_caster_A} -i "${receiver_info}" -a "${antenna_info}" -t ${level} -fl ${logdir}/str2str_ntrip_A.log
run_out_caster "$1" "A"
;;

out_caster_B)
${cast} -in ${!1} ${out_caster_B} -i "${receiver_info}" -a "${antenna_info}" -t ${level} -fl ${logdir}/str2str_ntrip_B.log
run_out_caster "$1" "B"
;;

out_caster)
[[ -z "${3}" ]] && { echo "Missing NTRIP caster suffix"; exit 1; }
run_out_caster "$1" "$3"
;;

out_local_caster)
Expand Down
19 changes: 8 additions & 11 deletions tools/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -537,14 +537,12 @@ configure_gnss(){
source <( grep -v '^#' "${rtkbase_path}"/settings.conf | grep '=' )
systemctl is-active --quiet str2str_tcp.service && systemctl stop str2str_tcp.service
#cleaning receiver options
sudo -u "${RTKBASE_USER}" sed -i s/^ntrip_a_receiver_options=.*/ntrip_a_receiver_options=/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^ntrip_b_receiver_options=.*/ntrip_b_receiver_options=/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^local_ntripc_receiver_options=.*/local_ntripc_receiver_options=/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_receiver_options=.*/rtcm_receiver_options=/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_client_receiver_options=.*/rtcm_client_receiver_options=/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_udp_svr_receiver_options=.*/rtcm_udp_svr_receiver_options=/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_udp_client_receiver_options=.*/rtcm_udp_client_receiver_options=/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_serial_receiver_options=.*/rtcm_serial_receiver_options=/ "${rtkbase_path}"/settings.conf
for option_name in $(grep -Eo '^ntrip_[a-z0-9]+_receiver_options' "${rtkbase_path}"/settings.conf); do
sudo -u "${RTKBASE_USER}" sed -i "s/^${option_name}=.*/${option_name}=/" "${rtkbase_path}"/settings.conf || return 1
done
for option_name in local_ntripc_receiver_options rtcm_receiver_options rtcm_client_receiver_options rtcm_udp_svr_receiver_options rtcm_udp_client_receiver_options rtcm_serial_receiver_options; do
sudo -u "${RTKBASE_USER}" sed -i "s/^${option_name}=.*/${option_name}=/" "${rtkbase_path}"/settings.conf || return 1
done

#if the receiver is a U-Blox F9P, launch the set_zed-f9p.sh. This script will reset the F9P and configure it with the corrects settings for rtkbase
if [[ $(python3 "${rtkbase_path}"/tools/ubxtool -f /dev/"${com_port}" -s ${com_port_settings%%:*} -p MON-VER) =~ 'ZED-F9P' ]]
Expand All @@ -560,9 +558,8 @@ configure_gnss(){
sudo -u "${RTKBASE_USER}" sed -i s/^com_port_settings=.*/com_port_settings=\'115200:8:n:1\'/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^receiver=.*/receiver=\'U-blox_ZED-F9P\'/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^receiver_format=.*/receiver_format=\'ubx\'/ "${rtkbase_path}"/settings.conf && \
#add option -TADJ=1 on rtcm/ntrip_a/ntrip_b/serial outputs
sudo -u "${RTKBASE_USER}" sed -i s/^ntrip_a_receiver_options=.*/ntrip_a_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^ntrip_b_receiver_options=.*/ntrip_b_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \
#add option -TADJ=1 on RTK outputs
for option_name in $(grep -Eo '^ntrip_[a-z0-9]+_receiver_options' "${rtkbase_path}"/settings.conf); do sudo -u "${RTKBASE_USER}" sed -i "s/^${option_name}=.*/${option_name}=\'-TADJ=1\'/" "${rtkbase_path}"/settings.conf || exit 1; done && \
sudo -u "${RTKBASE_USER}" sed -i s/^local_ntripc_receiver_options=.*/local_ntripc_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_receiver_options=.*/rtcm_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \
sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_client_receiver_options=.*/rtcm_client_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \
Expand Down
3 changes: 3 additions & 0 deletions tools/rtkbase_update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ checking=$6
str2str_active=$(systemctl is-active str2str_tcp)
str2str_ntrip_A_active=$(systemctl is-active str2str_ntrip_A)
str2str_ntrip_B_active=$(systemctl is-active str2str_ntrip_B)
mapfile -t str2str_dynamic_ntrip_active_units < <(systemctl list-units 'str2str_ntrip@*.service' --plain --all --no-legend 2>/dev/null | awk '$3=="active" {print $1}')
str2str_local_caster=$(systemctl is-active str2str_local_ntrip_caster)
str2str_rtcm=$(systemctl is-active str2str_rtcm_svr)
str2str_serial=$(systemctl is-active str2str_rtcm_serial)
Expand Down Expand Up @@ -171,6 +172,7 @@ upd_2.4.2() {
# restart previously running services
[ $str2str_ntrip_A_active = 'active' ] && systemctl start str2str_ntrip_A
[ $str2str_ntrip_B_active = 'active' ] && systemctl start str2str_ntrip_B
for unit_name in "${str2str_dynamic_ntrip_active_units[@]}"; do systemctl start "${unit_name}"; done
[ $str2str_local_caster = 'active' ] && systemctl start str2str_local_ntrip_caster
[ $str2str_rtcm = 'active' ] && systemctl start str2str_rtcm_svr
[ $str2str_serial = 'active' ] && systemctl start str2str_rtcm_serial
Expand Down Expand Up @@ -320,6 +322,7 @@ chown -R ${standard_user}:${standard_user} ${destination_directory}
# restart needed with all update to propagate the release number in the rtcm stream
[ $str2str_ntrip_A_active = 'active' ] && systemctl restart str2str_ntrip_A
[ $str2str_ntrip_B_active = 'active' ] && systemctl restart str2str_ntrip_B
for unit_name in "${str2str_dynamic_ntrip_active_units[@]}"; do systemctl restart "${unit_name}"; done
[ $str2str_local_caster = 'active' ] && systemctl restart str2str_local_ntrip_caster
[ $str2str_rtcm = 'active' ] && systemctl restart str2str_rtcm_svr
[ $str2str_serial = 'active' ] && systemctl restart str2str_rtcm_serial
Expand Down
11 changes: 11 additions & 0 deletions tools/uninstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ BASEDIR=$(dirname "$0")
for service_name in str2str_tcp.service \
str2str_ntrip_A.service \
str2str_ntrip_B.service \
str2str_ntrip@.service \
str2str_local_ntrip_caster \
str2str_rtcm_svr.service \
str2str_rtcm_client.service \
Expand All @@ -29,6 +30,16 @@ do
systemctl reset-failed
done

for service_name in $(systemctl list-units 'str2str_ntrip@*.service' --plain --all --no-legend 2>/dev/null | awk '{print $1}'); do
echo 'Deleting ' "${service_name}"
systemctl stop "${service_name}"
systemctl disable "${service_name}"
rm /etc/systemd/system/"${service_name}"
rm /usr/lib/systemd/system/"${service_name}"
systemctl daemon-reload
systemctl reset-failed
done

# removing rtklib binaries
echo 'Deleting RTKLib binaries'
rm /usr/bin/str2str
Expand Down
23 changes: 23 additions & 0 deletions unit/str2str_ntrip@.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[Unit]
Description=RTKBase Ntrip %i
#After=network-online.target
#Wants=network-online.target
Requires=str2str_tcp.service
After=str2str_tcp.service

[Service]
Type=simple
SyslogIdentifier=str2str_ntrip_%i
User={user}
ExecStart={script_path}/run_cast.sh in_tcp out_caster %i
Restart=on-failure
RestartSec=30
#Limiting log to 1 msg per minute
LogRateLimitIntervalSec=1 minute
LogRateLimitBurst=1
ProtectHome=read-only
ProtectSystem=strict
ReadWritePaths={script_path}

[Install]
WantedBy=multi-user.target
108 changes: 98 additions & 10 deletions web_app/RTKBaseConfigManager.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import os
from configparser import ConfigParser
from secrets import token_urlsafe
import string

class RTKBaseConfigManager:
""" A class to easily access the settings from RTKBase settings.conf """

NON_QUOTED_KEYS = ("basedir", "web_authentification", "new_web_password", "web_password_hash",
"flask_secret_key", "archive_name", "user")
NTRIP_TEMPLATE_SECTION = "ntrip_A"

def __init__(self, default_settings_path, user_settings_path):
"""
Expand Down Expand Up @@ -119,22 +121,109 @@ def get_ntrip_A_settings(self):
Get a subset of the settings from the ntrip A section in an ordered object
and remove the single quotes.
"""
ordered_ntrip = [{"source_section" : "ntrip_A"}]
for key in ("svr_addr_A", "svr_port_A", "svr_pwd_A", "mnt_name_A", "rtcm_msg_A", "ntrip_A_receiver_options"):
ordered_ntrip.append({key : self.config.get('ntrip_A', key).strip("'")})
return ordered_ntrip
return self.get_legacy_ntrip_settings("ntrip_A")

def get_ntrip_B_settings(self):
"""
Get a subset of the settings from the ntrip B section in an ordered object
and remove the single quotes.
"""
#TODO need refactoring with get_ntrip_A_settings
ordered_ntrip = [{"source_section" : "ntrip_B"}]
for key in ("svr_addr_B", "svr_port_B", "svr_pwd_B", "mnt_name_B", "rtcm_msg_B", "ntrip_B_receiver_options"):
ordered_ntrip.append({key : self.config.get('ntrip_B', key).strip("'")})
return self.get_legacy_ntrip_settings("ntrip_B")

def is_ntrip_section(self, section):
return section.startswith("ntrip_") and section != "local_ntrip_caster"

def get_ntrip_suffix(self, section):
return section.split("_", 1)[1].upper()

def get_ntrip_sections(self):
return sorted(
[section for section in self.config.sections() if self.is_ntrip_section(section)],
key=lambda section: self.get_ntrip_suffix(section),
)

def _get_ntrip_field_names(self, suffix):
suffix = suffix.upper()
suffix_lower = suffix.lower()
return {
"svr_addr": f"svr_addr_{suffix}",
"svr_port": f"svr_port_{suffix}",
"svr_pwd": f"svr_pwd_{suffix}",
"mnt_name": f"mnt_name_{suffix}",
"rtcm_msg": f"rtcm_msg_{suffix}",
"receiver_options": f"ntrip_{suffix}_receiver_options",
}, suffix_lower

def get_legacy_ntrip_settings(self, section):
suffix = self.get_ntrip_suffix(section)
field_names, _ = self._get_ntrip_field_names(suffix)
ordered_ntrip = [{"source_section" : section}]
for key in field_names.values():
ordered_ntrip.append({key : self.config.get(section, key).strip("'")})
return ordered_ntrip

def get_ntrip_settings(self, section):
suffix = self.get_ntrip_suffix(section)
field_names, _ = self._get_ntrip_field_names(suffix)
return {
"source_section": section,
"service_name": section,
"service_label": f"Ntrip {suffix} service",
"switch_id": f"{section}-switch",
"suffix": suffix,
"svr_addr": {"name": field_names["svr_addr"], "value": self.config.get(section, field_names["svr_addr"]).strip("'")},
"svr_port": {"name": field_names["svr_port"], "value": self.config.get(section, field_names["svr_port"]).strip("'")},
"svr_pwd": {"name": field_names["svr_pwd"], "value": self.config.get(section, field_names["svr_pwd"]).strip("'")},
"mnt_name": {"name": field_names["mnt_name"], "value": self.config.get(section, field_names["mnt_name"]).strip("'")},
"rtcm_msg": {"name": field_names["rtcm_msg"], "value": self.config.get(section, field_names["rtcm_msg"]).strip("'")},
"receiver_options": {
"name": field_names["receiver_options"],
"value": self.config.get(section, field_names["receiver_options"]).strip("'"),
},
}

def get_all_ntrip_settings(self):
return [self.get_ntrip_settings(section) for section in self.get_ntrip_sections()]

def get_first_ntrip_mount_name(self):
sections = self.get_ntrip_sections()
if not sections:
return "RTKBase"
field_names, _ = self._get_ntrip_field_names(self.get_ntrip_suffix(sections[0]))
return self.config.get(sections[0], field_names["mnt_name"]).strip("'")

def _load_default_ntrip_template(self):
defaults = ConfigParser(interpolation=None)
defaults.read(self.default_settings_path)
if defaults.has_section(self.NTRIP_TEMPLATE_SECTION):
return defaults[self.NTRIP_TEMPLATE_SECTION]
return self.config[self.NTRIP_TEMPLATE_SECTION]

def _next_ntrip_suffix(self):
existing_suffixes = {self.get_ntrip_suffix(section) for section in self.get_ntrip_sections()}
for suffix in string.ascii_uppercase:
if suffix not in existing_suffixes:
return suffix
raise ValueError("No available NTRIP caster suffix left")

def add_ntrip_settings(self):
suffix = self._next_ntrip_suffix()
suffix_lower = suffix.lower()
section = f"ntrip_{suffix}"
template = self._load_default_ntrip_template()
self.config.add_section(section)
self.config[section][f"svr_addr_{suffix_lower}"] = template.get("svr_addr_a", "'caster.centipede.fr'")
self.config[section][f"svr_port_{suffix_lower}"] = template.get("svr_port_a", "'2101'")
self.config[section][f"svr_pwd_{suffix_lower}"] = template.get("svr_pwd_a", "''")
self.config[section][f"mnt_name_{suffix_lower}"] = template.get("mnt_name_a", "'Your_mount_name'")
self.config[section][f"rtcm_msg_{suffix_lower}"] = template.get(
"rtcm_msg_a",
"'1004,1005(10),1006,1008(10),1012,1019,1020,1033(10),1042,1045,1046,1077,1087,1097,1107,1127,1230'",
)
self.config[section][f"ntrip_{suffix_lower}_receiver_options"] = template.get("ntrip_a_receiver_options", "''")
self.write_file()
return section

def get_local_ntripc_settings(self):
"""
Get a subset of the settings from the local ntrip section in an ordered object
Expand Down Expand Up @@ -212,8 +301,7 @@ def get_ordered_settings(self):
"""
ordered_settings = {}
ordered_settings['main'] = self.get_main_settings()
ordered_settings['ntrip_A'] = self.get_ntrip_A_settings()
ordered_settings['ntrip_B'] = self.get_ntrip_B_settings()
ordered_settings['ntrip'] = self.get_all_ntrip_settings()
ordered_settings['local_ntripc'] = self.get_local_ntripc_settings()
ordered_settings['file'] = self.get_file_settings()
ordered_settings['rtcm_svr'] = self.get_rtcm_svr_settings()
Expand Down
Loading