initial commit
This commit is contained in:
commit
7432d7ab83
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Python-generated files
|
||||||
|
__pycache__/
|
||||||
|
*.py[oc]
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
wheels/
|
||||||
|
*.egg-info
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
.venv
|
||||||
1
.python-version
Normal file
1
.python-version
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.12
|
||||||
6
main.py
Normal file
6
main.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
def main():
|
||||||
|
print("Hello from pi-modem!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
7
pyproject.toml
Normal file
7
pyproject.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[project]
|
||||||
|
name = "pi-modem"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = []
|
||||||
8
uv.lock
generated
Normal file
8
uv.lock
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
version = 1
|
||||||
|
revision = 3
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pi-modem"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = { virtual = "." }
|
||||||
91
wifi-dns
Executable file
91
wifi-dns
Executable file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
local json = require("luci.jsonc")
|
||||||
|
|
||||||
|
local function sh(cmd)
|
||||||
|
local h = io.popen(cmd .. " 2>&1")
|
||||||
|
local out = h:read("*a")
|
||||||
|
local ok = h:close()
|
||||||
|
return ok, out
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_servers()
|
||||||
|
local h = io.popen("uci -q get dhcp.@dnsmasq[0].server 2>/dev/null")
|
||||||
|
local out = h:read("*a") or ""
|
||||||
|
h:close()
|
||||||
|
local list = {}
|
||||||
|
for s in out:gmatch("%S+") do list[#list+1] = s end
|
||||||
|
return list
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_noresolv()
|
||||||
|
local h = io.popen("uci -q get dhcp.@dnsmasq[0].noresolv 2>/dev/null")
|
||||||
|
local out = (h:read("*a") or ""):gsub("%s+", "")
|
||||||
|
h:close()
|
||||||
|
return out == "1"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read_state()
|
||||||
|
return {
|
||||||
|
noresolv = get_noresolv(),
|
||||||
|
servers = get_servers(),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write("Content-Type: application/json\r\n\r\n")
|
||||||
|
|
||||||
|
local body = io.read("*a") or ""
|
||||||
|
local req = json.parse(body) or {}
|
||||||
|
local action = req.action or "status"
|
||||||
|
|
||||||
|
local ADGUARD = "127.0.0.1#5335"
|
||||||
|
|
||||||
|
if action == "status" then
|
||||||
|
io.write(json.stringify({ ok = true, state = read_state() }))
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_noresolv(v)
|
||||||
|
sh("uci set dhcp.@dnsmasq[0].noresolv='" .. (v and "1" or "0") .. "'")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clear_servers()
|
||||||
|
sh("uci -q delete dhcp.@dnsmasq[0].server")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function add_server(s)
|
||||||
|
sh("uci add_list dhcp.@dnsmasq[0].server='" .. s .. "'")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function apply()
|
||||||
|
sh("uci commit dhcp")
|
||||||
|
sh("/etc/init.d/dnsmasq restart")
|
||||||
|
end
|
||||||
|
|
||||||
|
if action == "normal" then
|
||||||
|
clear_servers()
|
||||||
|
add_server(ADGUARD)
|
||||||
|
set_noresolv(true)
|
||||||
|
apply()
|
||||||
|
|
||||||
|
elseif action == "portal" then
|
||||||
|
clear_servers()
|
||||||
|
set_noresolv(false)
|
||||||
|
apply()
|
||||||
|
|
||||||
|
elseif action == "set" then
|
||||||
|
if req.noresolv ~= nil then set_noresolv(req.noresolv and true or false) end
|
||||||
|
if req.servers ~= nil then
|
||||||
|
clear_servers()
|
||||||
|
for _, s in ipairs(req.servers) do
|
||||||
|
if s and s ~= "" then add_server(s) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
apply()
|
||||||
|
|
||||||
|
else
|
||||||
|
io.write(json.stringify({ ok = false, error = "unknown action: " .. tostring(action) }))
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write(json.stringify({ ok = true, action = action, state = read_state() }))
|
||||||
73
wifi-join
Executable file
73
wifi-join
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
local json = require("luci.jsonc")
|
||||||
|
|
||||||
|
local function uci(cmd)
|
||||||
|
local h = io.popen("uci " .. cmd .. " 2>&1")
|
||||||
|
local out = h:read("*a")
|
||||||
|
local ok = h:close()
|
||||||
|
return ok, out
|
||||||
|
end
|
||||||
|
|
||||||
|
local function next_uplink_index()
|
||||||
|
local h = io.popen("uci show wireless 2>/dev/null | grep -o 'trm_uplink[0-9]*' | grep -o '[0-9]*'")
|
||||||
|
local used = {}
|
||||||
|
for n in h:lines() do used[tonumber(n)] = true end
|
||||||
|
h:close()
|
||||||
|
local i = 0
|
||||||
|
while used[i] do i = i + 1 end
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write("Content-Type: application/json\r\n\r\n")
|
||||||
|
|
||||||
|
local body = io.read("*a") or ""
|
||||||
|
local req = json.parse(body)
|
||||||
|
|
||||||
|
if not req or not req.ssid or req.ssid == "" then
|
||||||
|
io.write(json.stringify({ ok = false, error = "missing ssid" }))
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ssid = req.ssid
|
||||||
|
local key = req.key
|
||||||
|
local secured = req.secured and true or false
|
||||||
|
|
||||||
|
if secured and (not key or key == "") then
|
||||||
|
io.write(json.stringify({ ok = false, error = "secured network requires key" }))
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local idx = next_uplink_index()
|
||||||
|
local sec = "wireless.trm_uplink" .. idx
|
||||||
|
|
||||||
|
local function q(s) return "'" .. tostring(s):gsub("'", "'\\''") .. "'" end
|
||||||
|
|
||||||
|
uci("set " .. sec .. "=wifi-iface")
|
||||||
|
uci("set " .. sec .. ".device='radio0'")
|
||||||
|
uci("set " .. sec .. ".mode='sta'")
|
||||||
|
uci("set " .. sec .. ".network='tm_wwan'")
|
||||||
|
uci("set " .. sec .. ".ssid=" .. q(ssid))
|
||||||
|
uci("set " .. sec .. ".disabled='0'")
|
||||||
|
if secured then
|
||||||
|
uci("set " .. sec .. ".encryption='psk2+ccmp'")
|
||||||
|
uci("set " .. sec .. ".key=" .. q(key))
|
||||||
|
else
|
||||||
|
uci("set " .. sec .. ".encryption='none'")
|
||||||
|
end
|
||||||
|
|
||||||
|
local up = "travelmate.trm_uplink" .. idx
|
||||||
|
uci("set " .. up .. "=uplink")
|
||||||
|
uci("set " .. up .. ".device='radio0'")
|
||||||
|
uci("set " .. up .. ".ssid=" .. q(ssid))
|
||||||
|
uci("set " .. up .. ".enabled='1'")
|
||||||
|
|
||||||
|
local ok_w = uci("commit wireless")
|
||||||
|
local ok_t = uci("commit travelmate")
|
||||||
|
|
||||||
|
io.write(json.stringify({
|
||||||
|
ok = (ok_w and ok_t) and true or false,
|
||||||
|
ssid = ssid,
|
||||||
|
section = "trm_uplink" .. idx,
|
||||||
|
secured = secured,
|
||||||
|
}))
|
||||||
53
wifi-scan
Executable file
53
wifi-scan
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
local function read_scan()
|
||||||
|
local h = io.popen("ubus call iwinfo scan '{\"device\":\"radio0\"}' 2>/dev/null")
|
||||||
|
local raw = h:read("*a")
|
||||||
|
h:close()
|
||||||
|
return raw
|
||||||
|
end
|
||||||
|
|
||||||
|
local function jsondec(s)
|
||||||
|
local json = require("luci.jsonc")
|
||||||
|
return json.parse(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function jsonenc(t)
|
||||||
|
local json = require("luci.jsonc")
|
||||||
|
return json.stringify(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write("Content-Type: application/json\r\n\r\n")
|
||||||
|
|
||||||
|
local raw = read_scan()
|
||||||
|
local data = raw and jsondec(raw)
|
||||||
|
|
||||||
|
if not data or not data.results then
|
||||||
|
io.write(jsonenc({ ok = false, error = "scan failed or no results" }))
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local best = {}
|
||||||
|
for _, n in ipairs(data.results) do
|
||||||
|
local ssid = n.ssid
|
||||||
|
if ssid and ssid ~= "" then
|
||||||
|
local prev = best[ssid]
|
||||||
|
if not prev or (n.signal or -999) > prev.signal then
|
||||||
|
best[ssid] = {
|
||||||
|
ssid = ssid,
|
||||||
|
signal = n.signal or -999,
|
||||||
|
quality = n.quality or 0,
|
||||||
|
quality_max = n.quality_max or 70,
|
||||||
|
band = n.band,
|
||||||
|
channel = n.channel,
|
||||||
|
secured = n.encryption and n.encryption.enabled or false,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local list = {}
|
||||||
|
for _, v in pairs(best) do list[#list+1] = v end
|
||||||
|
table.sort(list, function(a, b) return a.signal > b.signal end)
|
||||||
|
|
||||||
|
io.write(jsonenc({ ok = true, networks = list }))
|
||||||
38
wifi-status
Executable file
38
wifi-status
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
local json = require("luci.jsonc")
|
||||||
|
|
||||||
|
io.write("Content-Type: application/json\r\n\r\n")
|
||||||
|
|
||||||
|
local f = io.open("/tmp/trm_runtime.json", "r")
|
||||||
|
if not f then
|
||||||
|
io.write(json.stringify({ ok = false, error = "no runtime file" }))
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local raw = f:read("*a")
|
||||||
|
f:close()
|
||||||
|
|
||||||
|
local rt = json.parse(raw)
|
||||||
|
if not rt or not rt.data then
|
||||||
|
io.write(json.stringify({ ok = false, error = "bad runtime json" }))
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local d = rt.data
|
||||||
|
local status = d.travelmate_status or ""
|
||||||
|
local connected = status:match("^connected") ~= nil
|
||||||
|
local net_ok = status:match("net ok") ~= nil
|
||||||
|
|
||||||
|
local ssid = nil
|
||||||
|
if d.station_id then
|
||||||
|
ssid = d.station_id:match("radio0/(.+)/%-") or d.station_id:match("radio0/(.+)/")
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write(json.stringify({
|
||||||
|
ok = true,
|
||||||
|
connected = connected,
|
||||||
|
net_ok = net_ok,
|
||||||
|
ssid = ssid,
|
||||||
|
raw_status = status,
|
||||||
|
}))
|
||||||
Loading…
Reference in New Issue
Block a user