🎨 Sync 2026-09-21 22:47:18

This commit is contained in:
github-actions[bot] committed 2026-09-21 22:47:18 +08:00
1 parent 385706139a
commit fc7323d2bd
10 files changed
+112 -54

No files matched your search

+3 -3
View File
@@ -10,12 +10,12 @@ AGENTFLOW_ARCH_x86_64:=amd64
AGENTFLOW_ARCH_aarch64:=arm64 AGENTFLOW_ARCH_aarch64:=arm64
AGENTFLOW_ARCH:=$(AGENTFLOW_ARCH_$(ARCH)) AGENTFLOW_ARCH:=$(AGENTFLOW_ARCH_$(ARCH))
AGENTFLOW_HASH_x86_64:=478fdb17cfb2b1664e7bc01315186e71f228871c0d20c816d8b3b8fe789bdb4d AGENTFLOW_HASH_x86_64:=9174fec77dc835640f94ea8bef84b580b84f947823f4dd63fc495c4c58a68297
AGENTFLOW_HASH_aarch64:=257faeaad2445dd14f87c1e1d9ded869fd301c5df2c2c9af817e70303eab2512 AGENTFLOW_HASH_aarch64:=256adf7bcb836259dacbf583c52af04f0134587328689a49811c135260fa5aed
PKG_NAME:=agentflow PKG_NAME:=agentflow
PKG_VERSION:=0.3.3 PKG_VERSION:=0.3.3
PKG_RELEASE:=12 PKG_RELEASE:=13
AGENTFLOW_URL_FILE:=agentflow-linux-$(AGENTFLOW_ARCH) AGENTFLOW_URL_FILE:=agentflow-linux-$(AGENTFLOW_ARCH)
AGENTFLOW_DOWNLOAD:=$(AGENTFLOW_URL_FILE)-$(AGENTFLOW_HASH_$(ARCH)) AGENTFLOW_DOWNLOAD:=$(AGENTFLOW_URL_FILE)-$(AGENTFLOW_HASH_$(ARCH))
+1 -1
View File
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.9.16 PKG_VERSION:=26.9.16
PKG_RELEASE:=285 PKG_RELEASE:=286
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
@@ -1004,6 +1004,7 @@ local current_node = map:get(section)
opt.set(dom_prefix + 'method', method || ""); opt.set(dom_prefix + 'method', method || "");
opt.set(dom_prefix + 'ss_method', method || ""); opt.set(dom_prefix + 'ss_method', method || "");
opt.set(dom_prefix + 'tcp_fast_open', queryParam.tfo); opt.set(dom_prefix + 'tcp_fast_open', queryParam.tfo);
if (plugin && plugin != "none") { if (plugin && plugin != "none") {
plugin = (plugin === "simple-obfs") ? "obfs-local" : plugin; plugin = (plugin === "simple-obfs") ? "obfs-local" : plugin;
opt.set(dom_prefix + 'plugin_enabled', true); opt.set(dom_prefix + 'plugin_enabled', true);
@@ -1026,9 +1027,29 @@ local current_node = map:get(section)
opt.set(dom_prefix + 'tls_allowInsecure', true); opt.set(dom_prefix + 'tls_allowInsecure', true);
} }
} }
//部分订阅 ShadowTLS 采用 SIP003
if (plugin === "shadow-tls") {
pluginOpts = pluginOpts.replace(/(^|;)password=/, '$1passwd=');
pluginOpts = pluginOpts.replace(/(^|;)version=([123])(?=;|$)/, '$1v$2=1');
if (dom_prefix === "ssrust_") {
opt.set(dom_prefix + 'plugin_opts', pluginOpts || "");
} else if (dom_prefix === "singbox_") {
const opts = Object.fromEntries(pluginOpts.split(';').map(item => item.split('=', 2)));
const host = opts.host;
const password = opts.passwd;
const versionKey = Object.keys(opts).find(key => /^v[123]$/.test(key));
const version = versionKey ? versionKey.slice(1) : "1";
opt.set(dom_prefix + 'shadowtls', true);
opt.set(dom_prefix + 'shadowtls_version', version);
opt.set(dom_prefix + 'shadowtls_password', password || "");
opt.set(dom_prefix + 'shadowtls_serverName', host || "");
opt.set(dom_prefix + 'plugin_enabled', false);
}
}
} else { } else {
opt.set(dom_prefix + 'plugin', "none"); opt.set(dom_prefix + 'plugin', "none");
} }
if (param !== undefined) { if (param !== undefined) {
opt.set('remarks', decodeURIComponent(param)); opt.set('remarks', decodeURIComponent(param));
} }
@@ -1129,7 +1150,7 @@ local current_node = map:get(section)
opt.set(dom_prefix + 'finalmask', queryParam.fm || ""); opt.set(dom_prefix + 'finalmask', queryParam.fm || "");
if (queryParam["shadow-tls"]) { if (queryParam["shadow-tls"]) {
//解析SS Shadow-TLS 插件参数 //解析SS Shadow-TLS 专用参数
const parseShadowTLSParams = function(base64Str, outObj) { const parseShadowTLSParams = function(base64Str, outObj) {
try { try {
let obj = JSON.parse(b64decsafe(base64Str)); let obj = JSON.parse(b64decsafe(base64Str));
@@ -749,6 +749,11 @@ local function processData(szType, content, add_mode, group, sub_cfg)
if idx_pn then if idx_pn then
result.plugin = plugin_info:sub(1, idx_pn - 1) result.plugin = plugin_info:sub(1, idx_pn - 1)
result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info) result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info)
-- 部分订阅 ShadowTLS 采用 SIP003
result.plugin_opts = result.plugin_opts:gsub("^password=", "passwd=")
result.plugin_opts = result.plugin_opts:gsub(";password=", ";passwd=")
result.plugin_opts = result.plugin_opts:gsub("^version=([123])", "v%1=1")
result.plugin_opts = result.plugin_opts:gsub(";version=([123])", ";v%1=1")
else else
result.plugin = plugin_info result.plugin = plugin_info
end end
@@ -855,10 +860,22 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.plugin_opts = nil result.plugin_opts = nil
end end
elseif result.type == 'sing-box' then elseif result.type == 'sing-box' then
if result.plugin ~= "obfs-local" and result.plugin ~= "v2ray-plugin" then if result.plugin ~= "obfs-local" and result.plugin ~= "v2ray-plugin" and result.plugin ~= "shadow-tls" then
result.error_msg = "Sing-Box 不支持 SS " .. result.plugin .. " 插件。" result.error_msg = "Sing-Box 不支持 SS " .. result.plugin .. " 插件。"
else else
result.plugin_enabled = "1" result.plugin_enabled = "1"
-- 部分订阅 ShadowTLS 采用 SIP003
if result.plugin == "shadow-tls" then
for item in result.plugin_opts:gmatch("[^;]+") do
local key, value = item:match("^([^=]+)=(.*)$")
if key == "host" then result.shadowtls_serverName = value end
if key == "passwd" then result.shadowtls_password = value end
if key:match("^v[123]$") then result.shadowtls_version = key:sub(2) end
end
result.shadowtls = "1"
result.plugin_opts = nil
result.plugin_enabled = nil
end
end end
else else
result.plugin_enabled = "1" result.plugin_enabled = "1"
@@ -967,7 +984,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
if result.type ~= "sing-box" and result.type ~= "SS-Rust" then if result.type ~= "sing-box" and result.type ~= "SS-Rust" then
result.error_msg = sub_ss_type .. " 不支持 shadow-tls 插件。" result.error_msg = sub_ss_type .. " 不支持 shadow-tls 插件。"
else else
-- 解析SS Shadow-TLS 插件参数 -- 解析SS Shadow-TLS 专用参数
local function parseShadowTLSParams(b64str, out) local function parseShadowTLSParams(b64str, out)
local ok, data = pcall(jsonParse, base64Decode(b64str)) local ok, data = pcall(jsonParse, base64Decode(b64str))
if not ok or type(data) ~= "table" then return "" end if not ok or type(data) ~= "table" then return "" end
@@ -186,7 +186,7 @@ return view.extend({
{ tab: 'netsetup', type: form.Value, id: 'lan_ipaddr', title: _('LAN IPv4 Address'), datatype: 'ip4addr', placeholder: '10.0.0.1' }, { tab: 'netsetup', type: form.Value, id: 'lan_ipaddr', title: _('LAN IPv4 Address'), datatype: 'ip4addr', placeholder: '10.0.0.1' },
{ tab: 'netsetup', type: form.DynamicList, id: 'lan_dns', title: _('Custom DNS Server(s)'), datatype: 'ipaddr', placeholder: '223.5.5.5', desc: _('Leave empty for ISP DNS.') }, { tab: 'netsetup', type: form.DynamicList, id: 'lan_dns', title: _('Custom DNS Server(s)'), datatype: 'ipaddr', placeholder: '223.5.5.5', desc: _('Leave empty for ISP DNS.') },
{ tab: 'netsetup', type: form.Value, id: 'lan_gateway', title: _('Gateway Address'), datatype: 'ip4addr', placeholder: '', depends: { wan_proto: 'siderouter' }, desc: _('Primary router IP address used when operating in side-router mode.') }, { tab: 'netsetup', type: form.Value, id: 'lan_gateway', title: _('Gateway Address'), datatype: 'ip4addr', placeholder: '', depends: { wan_proto: 'siderouter' }, desc: _('Primary router IP address used when operating in side-router mode.') },
{ tab: 'netsetup', type: form.Flag, id: 'dhcp', title: _('Enable DHCP Server'), desc: _('Enable or disable LAN DHCP server (usually disabled in side-router mode to avoid IP address conflicts).') }, { tab: 'netsetup', type: form.Flag, id: 'dhcp', title: _('Enable DHCP Server'), desc: _('If this DHCP is enabled, disable the main router's DHCP. If disabled, manually set client devices' gateway and DNS to this bypass router's IP.') },
{ tab: 'netsetup', type: form.Flag, id: 'ipv6', title: _('IPv6 Support'), desc: _('Enable or disable IPv6 router advertisements and DHCPv6.') }, { tab: 'netsetup', type: form.Flag, id: 'ipv6', title: _('IPv6 Support'), desc: _('Enable or disable IPv6 router advertisements and DHCPv6.') },
// 固件与系统设置 // 固件与系统设置
+2 -2
View File
@@ -69,8 +69,8 @@ msgstr "在旁路由模式下工作时填写的上级主路由 IP 地址。"
msgid "Enable DHCP Server" msgid "Enable DHCP Server"
msgstr "启用 DHCP 服务器" msgstr "启用 DHCP 服务器"
msgid "Enable or disable LAN DHCP server (usually disabled in side-router mode to avoid IP address conflicts)." msgid "If this DHCP is enabled, disable the main router's DHCP. If disabled, manually set client devices' gateway and DNS to this bypass router's IP."
msgstr "开启或关闭局域网 DHCP 服务(旁路由模式下通常建议关闭,避免局域网 IP 分配冲突)。" msgstr "开启此DHCP则需要关闭主路由DHCP, 关闭此DHCP则需要手动将上网设备的网关和DNS改为此旁路由的IP。"
msgid "Leave empty for ISP DNS." msgid "Leave empty for ISP DNS."
msgstr "留空则使用 ISP 运营商DNS" msgstr "留空则使用 ISP 运营商DNS"
+3 -3
View File
@@ -17,12 +17,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-wwand PKG_NAME:=luci-app-wwand
PKG_VERSION:=1.6.7_p13 PKG_VERSION:=1.6.7_p14
PKG_RELEASE:=25 PKG_RELEASE:=26
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/ddimension/luci-app-wwand.git PKG_SOURCE_URL:=https://github.com/ddimension/luci-app-wwand.git
PKG_SOURCE_VERSION:=e97ffb8db7ca59049195d9a37ae86b69c1e1264d PKG_SOURCE_VERSION:=f46ba800d6f195c5c78a8bf566b4f340b9f1ee25
PKG_MIRROR_HASH:=skip PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPL-2.0-only PKG_LICENSE:=GPL-2.0-only
+1 -1
View File
@@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=my-default-settings PKG_NAME:=my-default-settings
PKG_VERSION:=2 PKG_VERSION:=2
PKG_RELEASE:=17 PKG_RELEASE:=18
include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk
+29 -17
View File
@@ -20,8 +20,8 @@ show_help() {
-h, --help 查看帮助信息 -h, --help 查看帮助信息
并发与等待机制: 并发与等待机制:
- 无参调用时:若已有 mywifi 在执行,直接终止退出; - 无参/热插拔调用时:若已有 mywifi 在执行,直接终止退出;
- 带 -f 或传参调用时:若已有 mywifi 在执行,自动排队等待其执行完成后再继续执行。 - 带 -f 或用户传参调用时:若已有 mywifi 在执行,自动排队等待其执行完成后再继续执行。
WiFi命名规范: WiFi命名规范:
2.4 GHz -> <WiFi名>_2.4G 2.4 GHz -> <WiFi名>_2.4G
@@ -29,21 +29,27 @@ WiFi命名规范:
6 GHz -> <WiFi名>_6G 6 GHz -> <WiFi名>_6G
使用示例: 使用示例:
mywifi # 默认执行(若已配置过或正在执行则自动终止) mywifi # 默认执行(使用 hostname,若已配置或正在执行则自动终止)
mywifi -f # 强制重新按 hostname 恢复默认配置(若有执行中则排队等待) mywifi -f # 强制重新按 hostname 恢复默认配置
mywifi "HomeWiFi" "12345678" # 设置指定 WiFi 名及密码(若有执行中则排队等待) mywifi "HomeWiFi" "12345678" # 设置指定 WiFi 名及密码
mywifi -f "HomeWiFi" "12345678" # 强制覆盖设置 mywifi -f "HomeWiFi" "12345678" # 强制覆盖设置
EOF_HELP EOF_HELP
} }
# ------------------------------------------------------------- # -------------------------------------------------------------
# 1. 优先解析命令行参数(判断是否带有 -f 或自定义参数) # 1. 命令行参数解析(过滤 OpenWrt Hotplug 热插拔系统事件传参)
# ------------------------------------------------------------- # -------------------------------------------------------------
CUSTOM_SSID="" CUSTOM_SSID=""
CUSTOM_PASSWD="" CUSTOM_PASSWD=""
HAS_PASSWD=0 HAS_PASSWD=0
FORCE=0 FORCE=0
# 判断是否是由系统 Hotplug 热插拔机制触发调用
is_hotplug=0
if [ -n "$HOTPLUG_TYPE" ] || [ -n "$ACTION" ] || [ -n "$DEVICENAME" ]; then
is_hotplug=1
fi
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
-h|--help) -h|--help)
@@ -62,27 +68,33 @@ while [ $# -gt 0 ]; do
CUSTOM_PASSWD="$1" CUSTOM_PASSWD="$1"
HAS_PASSWD=1 HAS_PASSWD=1
;; ;;
ieee80211|net|button|platform|usb|add|remove|bind|unbind)
# 过滤热插拔事件传参,避免将热插拔子系统名称(如 ieee80211)误当作 WiFi SSID
is_hotplug=1
;;
*) *)
if [ -z "$CUSTOM_SSID" ]; then # 仅在非系统热插拔事件传参时才接收位置参数
CUSTOM_SSID="$1" if [ $is_hotplug -eq 0 ]; then
elif [ $HAS_PASSWD -eq 0 ]; then if [ -z "$CUSTOM_SSID" ]; then
CUSTOM_PASSWD="$1" CUSTOM_SSID="$1"
HAS_PASSWD=1 elif [ $HAS_PASSWD -eq 0 ]; then
CUSTOM_PASSWD="$1"
HAS_PASSWD=1
fi
fi fi
;; ;;
esac esac
shift shift
done done
# 判断是否需要等待正在运行的实例完成 # 判断是否需要等待锁(带 -f 或传了有效自定义参数时排队等待,无参/热插拔直接退出)
# 只要指定了 -f 或传入了自定义 SSID / 密码,就启用等待锁机制
WAIT_LOCK=0 WAIT_LOCK=0
if [ $FORCE -eq 1 ] || [ -n "$CUSTOM_SSID" ] || [ $HAS_PASSWD -eq 1 ]; then if [ $FORCE -eq 1 ] || [ -n "$CUSTOM_SSID" ] || [ $HAS_PASSWD -eq 1 ]; then
WAIT_LOCK=1 WAIT_LOCK=1
fi fi
# ------------------------------------------------------------- # -------------------------------------------------------------
# 2. 检查 base_config 状态标记(无参且已配置过 wifi=1 时直接退出) # 2. 检查 base_config 状态标记(无参且已配置过 wifi=1 时,直接终止)
# ------------------------------------------------------------- # -------------------------------------------------------------
if [ $FORCE -eq 0 ]; then if [ $FORCE -eq 0 ]; then
if [ "$(uci -q get base_config.@status[0].wifi 2>/dev/null)" = "1" ]; then if [ "$(uci -q get base_config.@status[0].wifi 2>/dev/null)" = "1" ]; then
@@ -94,7 +106,7 @@ if [ $FORCE -eq 0 ]; then
fi fi
# ------------------------------------------------------------- # -------------------------------------------------------------
# 3. 并发锁处理:带参/-f 模式等待完成,无参模式直接终止 # 3. 防并发检测与等待处理
# ------------------------------------------------------------- # -------------------------------------------------------------
LOCK_FILE="/var/run/mywifi.lock" LOCK_FILE="/var/run/mywifi.lock"
@@ -102,7 +114,7 @@ acquire_lock() {
local cur_pid=$$ local cur_pid=$$
local cur_ppid=$PPID local cur_ppid=$PPID
# A. 优先采用 flock 文件描述符锁(内核自动回收,安全可靠) # A. 优先采用 flock 文件描述符锁
if command -v flock >/dev/null 2>&1; then if command -v flock >/dev/null 2>&1; then
exec 9>"$LOCK_FILE" 2>/dev/null || true exec 9>"$LOCK_FILE" 2>/dev/null || true
if [ $WAIT_LOCK -eq 1 ]; then if [ $WAIT_LOCK -eq 1 ]; then
@@ -277,7 +289,7 @@ if [ -n "$CUSTOM_SSID" ]; then
SSID="$CUSTOM_SSID" SSID="$CUSTOM_SSID"
else else
SSID="$(uci -q get system.@system[0].hostname 2>/dev/null)" SSID="$(uci -q get system.@system[0].hostname 2>/dev/null)"
[ -z "$SSID" ] && [ -r /proc/sys/kernel/hostname ] && SSID="$(cat /proc/sys/kernel/hostname)" [ -z "$SSID" ] && [ -r /proc/sys/kernel/hostname ] w&& SSID="$(cat /proc/sys/kernel/hostname)"
[ -z "$SSID" ] && SSID="$(uci -q get wizard.default.wifi_ssid 2>/dev/null)" [ -z "$SSID" ] && SSID="$(uci -q get wizard.default.wifi_ssid 2>/dev/null)"
[ -z "$SSID" ] && SSID="OpenWrt" [ -z "$SSID" ] && SSID="OpenWrt"
fi fi
+31 -23
View File
@@ -11,7 +11,7 @@
# wwand-ncm - NCM/ECM backend (DEPENDS wwand) # wwand-ncm - NCM/ECM backend (DEPENDS wwand)
# wwand-mhi - PCIe/MHI transport + drivers (DEPENDS wwand; add a backend) # wwand-mhi - PCIe/MHI transport + drivers (DEPENDS wwand; add a backend)
# wwand-esim - eSIM management (DEPENDS wwand + lpac; no backend) # wwand-esim - eSIM management (DEPENDS wwand + lpac; no backend)
# wwand-gps - GNSS/NMEA glue for ugps (DEPENDS wwand + ugps; no backend) # wwand-gps - GNSS/NMEA reader (DEPENDS wwand; no backend)
# A typical QMI router installs `wwand-qmi` (which pulls in `wwand`); add # A typical QMI router installs `wwand-qmi` (which pulls in `wwand`); add
# `wwand-mbim` / `wwand-ncm` for those modems, `wwand-mhi` for a PCIe/MHI modem. # `wwand-mbim` / `wwand-ncm` for those modems, `wwand-mhi` for a PCIe/MHI modem.
# The ucode tree ships PRECOMPILED to bytecode (repo-root CMakeLists.txt, # The ucode tree ships PRECOMPILED to bytecode (repo-root CMakeLists.txt,
@@ -50,12 +50,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=wwand PKG_NAME:=wwand
PKG_VERSION:=1.6.7_p60 PKG_VERSION:=1.6.7_p63
PKG_RELEASE:=51 PKG_RELEASE:=52
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/ddimension/wwand.git PKG_SOURCE_URL:=https://github.com/ddimension/wwand.git
PKG_SOURCE_VERSION:=f5cba40880e0a11c00cf6b9040a6eb74e3d222da PKG_SOURCE_VERSION:=2c428ced46e584daae9719f722d2ed7c9aa28fff
PKG_MIRROR_HASH:=skip PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPL-2.0-only PKG_LICENSE:=GPL-2.0-only
@@ -439,7 +439,7 @@ define Package/wwand-esim/install
endef endef
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# wwand-gps: point ugps at the modem's NMEA port. Backend-neutral — finding the # wwand-gps: read NMEA off the modem's NMEA port. Backend-neutral — finding the
# port and starting the receiver are both in the base package, and neither # port and starting the receiver are both in the base package, and neither
# depends on the control protocol. # depends on the control protocol.
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -447,34 +447,42 @@ define Package/wwand-gps
SECTION:=net SECTION:=net
CATEGORY:=Network CATEGORY:=Network
SUBMENU:=WWAN SUBMENU:=WWAN
TITLE:=GNSS/NMEA glue for wwand (ugps) TITLE:=GNSS/NMEA reader for wwand
# ugps is OpenWrt base: it parses NMEA, can set the clock, and publishes a # Reads NMEA off the modem's own port and reports it through wwand's ubus.
# `gps` ubus object. It knows nothing about modems, and it reads its tty from # It used to drive ugps (OpenWrt base) instead, and no longer depends on it:
# a STATIC /etc/config/gps — which is exactly the gap this package fills, # ugps takes ONE static tty out of /etc/config/gps and publishes ONE `gps`
# because wwand's NMEA port is discovered and can move between boots or when # object, so a two-modem box could only ever have one position; it exits on
# a modem is replaced. # tty EOF, which on a modem reset means respawning against a device that is
DEPENDS:=+wwand +ugps # not back; and it parses neither GSV (satellites in view) nor GSA (fix type,
# PDOP/VDOP) and drops every talker but $GP/$GN. wwand already finds the
# port, starts the receiver and owns the lifecycle, so the reading is the
# small part. Installing ugps alongside is harmless — wwand does not touch
# /etc/config/gps and does not claim the `gps` ubus name.
DEPENDS:=+wwand
endef endef
define Package/wwand-gps/description define Package/wwand-gps/description
Joins three pieces that already existed with nothing between them: wwand finds wwand finds the modem's NMEA port during enumeration (reported as `gps_port`)
the modem's NMEA port during enumeration (reported as `gps_port`), `option and `option gnss` starts the receiver with the vendor AT command — QMI's LOC
gnss` starts the receiver with the vendor AT command — QMI's LOC service is service is broken on Quectel and AT is what works, and only wwand has the
broken on Quectel and AT is what works, and only wwand has the port — and ugps port. This package reads that port: NMEA 0183 framing, checksums, RMC/GGA/GSA/
reads the NMEA and publishes a position. GSV/GLL/VTG/ZDA from ANY talker, reported through `modem_gps` as numbers, with
the satellites in view and their SNR, the fix type and the DOP values.
What this adds is the config write that connects them, plus a `modem_gps` ubus ONE READER PER MODEM, so a two-modem router has two positions. `option
method that answers with both halves at once: the port and receiver state wwand gnss_set_time` hands the receiver's clock to wwand's own set_clock, which only
knows, merged with whatever ugps reports. ever steps a clock that is plainly unset and so never fights sysntpd.
Good citizen: it manages exactly one `config gps` section and only one it Good citizen: it writes no config at all and does not claim the `gps` ubus
created itself (marked `option wwand '1'`). An operator's own section — a hat name, so ugps and an operator's own receiver are unaffected by installing it.
GPS on a serial port, a second receiver — is never touched or repointed. One port is only ever read once — a second modem naming a tty that is already
being read is refused rather than given half a stream.
endef endef
define Package/wwand-gps/install define Package/wwand-gps/install
$(INSTALL_DIR) $(1)$(UCDIR) $(INSTALL_DIR) $(1)$(UCDIR)
$(INSTALL_DATA) $(WWAND_UCODE)/gps.uc $(1)$(UCDIR)/ $(INSTALL_DATA) $(WWAND_UCODE)/gps.uc $(1)$(UCDIR)/
$(INSTALL_DATA) $(WWAND_UCODE)/nmea.uc $(1)$(UCDIR)/
endef endef
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------