mir3c/squashfs-root/usr/sbin/auto_speedtestd

1023 lines
32 KiB
Lua
Executable File

#!/usr/bin/lua
local px = require "posix"
local uci = require 'luci.model.uci'
local util = require 'luci.util'
local io = require 'io'
local socket = require 'socket'
local json = require 'json'
local fs = require "nixio.fs"
local ubus = require "ubus"
local g_ubus
local g_cursor
local g_wan_busy_threshold = 100
local g_wan_busy_zero_num = 20
local g_speedtest_interval = 24*60*60
local g_current_date = 0
local g_current_day_trynum = 0
local g_current_day_num = 0
local g_nextmins_speedtest = 0
local g_lasttime_speedtest = 0
local g_ubus_wanup_msg = 1
local g_max_log_num = 0
local g_current_log_num = 0
local MAX_TRYNUM_PERDAY = 1
local MAX_NUM_PERDAY = 1
local MAX_BAND_ERROR = 0.7
local g_user_band_up = 0
local g_user_band_down = 0
local g_begin_time = "02:00"
local g_end_time = "06:00"
local g_debug_file_id = nil
local g_debug_file = false
local g_debug = false
local g_need_test_again = false
local TEST_AGAIN_TICKS = 180
local PREPARE_SPEEDTEST_XML_INTERVEL = 30
local g_prepare_speedtest_xml_cnter = 0
local g_prepare_speedtest_xml_last_try = 0
local g_prepare_speedtest_xml_trycnt = 0
local g_test_again_ticks = TEST_AGAIN_TICKS
local cfg = {
['host'] = "127.0.0.1",
['port'] = "1036",
['cmd_nettb'] = "/usr/sbin/nettb",
['cmd_upload'] = "/usr/bin/upload_speedtest",
['cmd_download'] = "/usr/bin/download_speedtest",
['cmd_speedtesturls'] = "/usr/bin/prepare_speedtest_xml",
['cmd_miqos_set'] = "/etc/init.d/miqos change_band ",
['cmd_miqos_get'] = "/etc/init.d/miqos show_band ",
['tmp_log'] = "/tmp/speedtest.log",
['cfg_file'] = "/etc/config/ab",
['tmp_cfg_dir'] = "/tmp/etc/config/",
['tmp_cfg_file'] = "/tmp/etc/config/ab",
['tmp_speedtest_xml'] = "/tmp/speedtest_urls.xml"
}
local SPEEDTEST_VER='STD'
if #arg >= 1 then
if arg[1] == 'oversea' then
SPEEDTEST_VER='OVERSEA'
end
end
function time_to_mins(stime)
local _,_,hour = string.find(stime, '([0-9]+):')
local _,_,min = string.find(stime, ':([0-9]+)')
return (60*tonumber(hour)+tonumber(min))
end
function mins_to_time(mins)
local hour,min = 0,0
min = mins%60
hour = (mins-min)/60
return string.format("%2d:%2d", hour, min)
end
function log_to_file(fileid, msg)
local file_size = fileid:seek("end")
if file_size > 1024*1024 then
return
end
fileid:write(os.date("%x %X").." : "..msg.."\n")
end
--logger
--[[1 Alert, 3 Error 7 Debug ]]--
px.openlog("speedtest","np",LOG_USER)
function logger(loglevel,msg)
if loglevel == 10 then
if g_debug then
px.syslog(3,msg)
if g_debug_file and g_debug_file_id then
log_to_file(g_debug_file_id, msg)
end
end
else
px.syslog(loglevel,msg)
end
end
function execl2(command)
local pp = io.popen(command)
local line = ""
local data = {}
while true do
line = pp:read()
if line == nil then
break
end
data[#data+1] = line
end
pp:close()
return data
end
-- 读取cfg到tmp的meory文件夹中
function cfg2tmp()
local r1,r2,r3 = fs.mkdirr(cfg.tmp_cfg_dir)
if not r1 then
logger(3, 'fatal error: mkdir failed, code:' .. r2 .. ',msg:'..r3)
return nil
end
r1,r2,r3 = fs.copy(cfg.cfg_file, cfg.tmp_cfg_file)
if not r1 then
logger(3,'fatal error: copy cfg file 2 /tmp memory failed. code:' .. r2 .. ',msg:'..r3)
return nil
end
return true
end
-- 拷贝最新配置到memory中
function tmp2cfg()
if not fs.copy(cfg.tmp_cfg_file, cfg.cfg_file) then
logger(3,'fatal error: copy /tmp cfg file 2 /etc/config/ failed. exit.')
return nil
end
return true
end
function copytab(st)
local tab={}
for k,v in pairs(st or {}) do
if type(v) ~= 'table' then tab[k]=v
else tab[k]=copytab(v) end
end
return tab
end
function get_conf_std(conf,type,opt,default)
local x=uci.cursor()
local s,e = pcall(function() return x:get(conf,type,opt) end)
return e or default
end
-- execute command without anyoutput
function exec_cmd(tblist, ignore_error)
local status = 0
for _,v in pairs(tblist) do
local cmd = v
if g_debug then
logger(3, '++' .. cmd)
cmd = cmd .. ' >/dev/null 2>>' .. cfg.tmp_log
else
cmd = cmd .. " &>/dev/null "
end
if os.execute(cmd) ~= 0 and ignore_error ~= 1 then
if g_debug then
os.execute('echo "^^^ '.. cmd .. ' ^^^ " >>' .. cfg.tmp_log)
end
logger(3, '[ERROR]: ' .. cmd .. ' failed!')
dump_qdisc()
return false
end
end
return true
end
--split string with chars '$p'
string.split = function(s, p)
local rt= {}
string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
return rt
end
function system_exit()
logger(3,'======== Process Exit. =====')
if g_debug_file_id then
g_debug_file_id:flush()
g_debug_file_id:close()
end
os.exit()
end
function system_init()
if g_debug then
os.execute("echo auto speedtest starting..... >>" .. cfg.tmp_log)
end
if g_debug and g_debug_file then
g_debug_file_id = io.open(cfg.tmp_log, "a")
end
-- 将配置文件copy到tmp内存中,并初始化cursor
--[[ if not cfg2tmp() then
return false
end
--]]
g_cursor = uci.cursor()
if not g_cursor then
logger(3,'set uci cursor failed. exit.')
return false
end
if is_user_band_manual() then
g_user_band_up = 1
g_user_band_down = 1
logger(10,'user set band manual!')
else
logger(10,'user didnt set band manual!')
end
--[[
if not g_cursor:set_confdir(cfg.tmp_cfg_dir) then
logger(3,'set tmp config dir failed. exit.')
return false
end
--]]
g_ubus = ubus.connect()
if not g_ubus then
logger(3, 'failed to connect to ubusd!')
return false
end
logger(10, "************ auto speedtest startup **************")
g_current_date = tonumber(os.date("%d"))
g_nextmins_speedtest = get_nexttime_speedtest()
local lasttime = g_cursor:get("ab","settings","last_speedtest_time")
g_lasttime_speedtest = tonumber(lasttime)
local maxlog = g_cursor:get("ab","settings","max_log_num")
g_max_log_num = tonumber(maxlog)
local curntlog = g_cursor:get("ab","settings","current_log_num")
g_current_log_num = tonumber(curntlog)
if g_current_log_num > g_max_log_num then
g_current_log_num = 1
end
logger(10, "init get lasttime: "..lasttime.." lastdate: "..os.date("%x %X", g_lasttime_speedtest))
logger(10, "max log num: "..g_max_log_num.." current log num: "..g_current_log_num)
-- SIGTERM to clear and exit
px.signal(px.SIGTERM,
function ()
logger(3,'signal TERM to stop auto speed test.')
system_exit()
end)
px.signal(px.SIGINT,
function ()
logger(3,'signal INT to stop auto speed test.')
system_exit()
end)
return true
end
function get_list_wan_rate()
local ret = g_ubus:call("trafficd", "list_wan_rate", {})
if ret and ret.rate then
return ret.rate
end
return nil;
end
function get_lasttime_speedtest()
return g_lasttime_speedtest
end
function set_lasttime_speedtest()
g_lasttime_speedtest = os.time()
local date = string.format("%s", os.date("%x %X", g_lasttime_speedtest))
g_cursor:set("ab","settings","last_speedtest_date",date)
g_cursor:set("ab","settings","last_speedtest_time",tostring(g_lasttime_speedtest))
g_cursor:commit('ab')
logger(10, "set lasttime: "..g_lasttime_speedtest.." lastdate: "..os.date("%x %X", g_lasttime_speedtest))
end
-- choose a ramdom time between g_begin_time and g_end_time,
-- in case all routers start speedtest at the same moment
function get_nexttime_speedtest()
local start_mins = time_to_mins(g_begin_time)
local end_mins = time_to_mins(g_end_time)
math.randomseed(os.time())
local next_mins = math.random(start_mins, end_mins)
logger(10, "start mins: "..g_begin_time.." "..time_to_mins(g_begin_time))
logger(10, "end mins: "..g_end_time.." "..time_to_mins(g_end_time))
logger(10, "next mins: "..mins_to_time(next_mins).." "..next_mins)
return next_mins
end
--if speed test failed this time, we choose another time between now time and end time
function get_nexttime_case_fail()
local start_mins = time_to_mins(g_begin_time)
local end_mins = time_to_mins(g_end_time)
local date = os.date("%X")
local _,_,hour = string.find(date, '^([0-9]+):')
local _,_,min = string.find(date, '^[0-9]+:([0-9]+):')
local now_mins = 60*hour + min
if (now_mins > start_mins) and (now_mins < end_mins) then
start_mins = now_mins
end
math.randomseed(os.time())
local next_mins = math.random(start_mins, end_mins)
logger(10, "start mins: "..g_begin_time.." "..time_to_mins(g_begin_time))
logger(10, "end mins: "..g_end_time.." "..time_to_mins(g_end_time))
logger(10, "now mins: "..mins_to_time(now_mins).." "..now_mins)
logger(10, "next mins: "..mins_to_time(next_mins).." "..next_mins)
return next_mins
end
function uci_commit_save(flag)
if flag then
g_cursor:commit('ab')
-- tmp下的配置改变,复写回/etc下
--[[ if not tmp2cfg() then
logger(1, 'copy tmp cfg to /etc/config/ failed.')
end
--]]
end
end
function get_uptime()
local upt=io.open('/proc/uptime')
local n=upt:read('*n')
upt:close()
return math.ceil(n)
end
function newset()
local reverse = {}
local set = {}
return setmetatable(set, {__index = {
insert = function(set, value)
if not reverse[value] then
table.insert(set, value)
reverse[value] = table.getn(set)
end
end,
remove = function(set, value)
local index = reverse[value]
if index then
reverse[value] = nil
local top = table.remove(set)
if top ~= value then
reverse[top] = index
set[index] = top
end
end
end
}})
end
function is_user_band_manual()
local manual = g_cursor:get("xiaoqiang","common","MANUAL")
if manual then
local ucfg = tonumber(manual)
if ucfg and ucfg == 1 then
return true
end
end
return false
end
function is_lasttest_long_enough()
local last_time = get_lasttime_speedtest()
local now_time = os.time()
local year2000 = os.time{year=2000, month=1,day=1,hour=0}
if now_time < year2000 then
logger(10, "NTP is not ready now time: "..os.date("%x %X",now_time))
return false
end
if last_time == 0 then
logger(10, "Long enough now time: "..os.date("%x %X",now_time).." last time: "..os.date("%x %X",last_time))
return true
end
if (last_time+g_speedtest_interval) < now_time then
logger(10, "Long enough now time: "..os.date("%x %X",now_time).." last time: "..os.date("%x %X",last_time))
return true
end
logger(10, "Not long enough now time: "..os.date("%x %X",now_time).." last time: "..os.date("%x %X",last_time))
return false
end
function is_wan_busy()
local sum,avg,max,zeronum,min = 0,0,0,0,9999999
local listrate = get_list_wan_rate()
if listrate and #listrate ~= 0 then
for k,v in ipairs(listrate) do
if v > max then
max = v
end
if v < min then
min = v
end
if v==0 then
zeronum = zeronum+1
end
sum = sum + v
logger(10, k..": "..v)
end
avg = sum/#listrate
logger(10, "is_wan_busy: avg: "..avg.." max: "..max.." min: "..min.." zeronum: "..zeronum)
if (avg < g_wan_busy_threshold) and (zeronum >= g_wan_busy_zero_num)then
return false
else
logger(3, "stat_points_privacy network_speedtest=2|wanbusy|"..os.date("%x %X").."|"..avg.."|"..max.."|"..min.."|"..zeronum)
logger(10, "dotdata: network_speedtest=2|wanbusy|"..os.date("%x %X").."|"..avg.."|"..max.."|"..min.."|"..zeronum)
return true
end
end
return true
end
function is_just_power_up()
local start_time = get_uptime()
if start_time < 160 then
return true
end
return false
end
function is_time_to_speedtest()
local date = os.date("%X")
local _,_,hour = string.find(date, '^([0-9]+):')
local _,_,min = string.find(date, '^[0-9]+:([0-9]+):')
local now_mins = 60*tonumber(hour) + tonumber(min)
if (now_mins >= g_nextmins_speedtest) and (now_mins <= time_to_mins(g_end_time)) then
return true
end
logger(10, "Not time for speedtest now: "..date.." begin: "..g_begin_time.." end: "..g_end_time.." next: "..mins_to_time(g_nextmins_speedtest))
return false
end
function is_internet_connected()
local cmd = cfg.cmd_nettb
local res = execl2(cmd)
if next(res)~=nil then
for k,v in pairs(res) do
logger(10, "got nettb info: "..v)
end
return false
else
return true
end
end
function is_band_result_valid(new_up, new_down, old_up, old_down, flag)
if flag == 3 then
return true
end
if (new_up > 32) and (new_down > 128) then
logger(10, "band result valid!")
logger(10, "old_up: "..old_up.." old_down: "..old_down)
logger(10, "new_up: "..new_up.." new_down: "..new_down)
return true
end
logger(10, "band result invalid!")
logger(10, "old_up: "..old_up.." old_down: "..old_down)
logger(10, "new_up: "..new_up.." new_down: "..new_down)
logger(3, "stat_points_privacy network_speedtest="..flag.."|banderr|"..os.date("%x %X").."|"..old_up.."|"..old_down.."|"..new_up.."|"..new_down)
logger(10, "dotdata: network_speedtest="..flag.."|banderr|"..os.date("%x %X").."|"..old_up.."|"..old_down.."|"..new_up.."|"..new_down)
return false
end
-- if band result is unacceptable, we do speed test again after 1 hour
function is_band_result_acceptable(new_up, new_down, old_up, old_down, flag)
if flag == 3 then
return true
end
if (new_up > 0.5*old_up) and (new_down > 0.5*old_down) then
logger(10, "band result acceptable!")
logger(10, "old_up: "..old_up.." old_down: "..old_down)
logger(10, "new_up: "..new_up.." new_down: "..new_down)
return true
end
logger(10, "band result unacceptable!")
logger(10, "old_up: "..old_up.." old_down: "..old_down)
logger(10, "new_up: "..new_up.." new_down: "..new_down)
logger(3, "stat_points_privacy network_speedtest="..flag.."|banderr|"..os.date("%x %X").."|"..old_up.."|"..old_down.."|"..new_up.."|"..new_down)
logger(10, "dotdata: network_speedtest="..flag.."|banderr|"..os.date("%x %X").."|"..old_up.."|"..old_down.."|"..new_up.."|"..new_down)
return false
end
function get_miqosband()
local upband, downband = 0, 0
local cmd = cfg.cmd_miqos_get
local res = execl2(cmd)
logger(10, cmd)
if res and next(res)~=nil then
for k,v in ipairs(res) do
local _,_,tmp = string.find(v, 'status=([0-9]+)')
local _,_,up = string.find(v, 'uplink=([0-9]+%.?[0-9]+)')
local _,_,down = string.find(v, 'downlink=([0-9]+%.?[0-9]+)')
if tmp then
status = tonumber(tmp)
end
if up then
upband = tonumber(up)
end
if down then
downband = tonumber(down)
end
end
if status == 0 then
--logger(10, "Get miqos band up: "..upband.." down: "..downband)
return upband, downband
end
end
--logger(10, "Get miqos band up: 0 down: 0")
return 0, 0
end
function set_miqosband(up_band, down_band, flag)
local cmd = cfg.cmd_miqos_set.." "..up_band.." "..down_band
local res = execl2(cmd)
local status = 1
logger(10, cmd)
if res and next(res)~=nil then
for k,v in ipairs(res) do
local _,_,tmp = string.find(v, 'status=([0-9]+)')
if tmp then
status = tonumber(tmp)
end
end
if status == 0 then
logger(10, "set miqos band succeed!")
local info = os.date("%x %X: ").."flag: "..flag.." up: "..up_band.." down: "..down_band
if g_current_log_num > g_max_log_num then
g_current_log_num = 1
end
g_cursor:set("ab","settings","log"..g_current_log_num, info)
g_current_log_num = g_current_log_num + 1
g_cursor:set("ab","settings","current_log_num", g_current_log_num)
g_cursor:commit('ab')
set_lasttime_speedtest()
if not is_user_band_manual() then
local tmpup = string.format("%.2f", up_band/1024)
local tmpdown = string.format("%.2f", down_band/1024)
g_cursor:set("xiaoqiang","common","BANDWIDTH2", tmpup)
g_cursor:set("xiaoqiang","common","BANDWIDTH", tmpdown)
g_cursor:commit('xiaoqiang')
logger(10, "set xiaoqiang band up: "..tmpup.." down: "..tmpdown)
else
logger(10, "user band manual,dont set xiaoqiang config")
end
return true
end
end
return false
end
function do_speed_test_upload()
local cmd = cfg.cmd_upload
local res = execl2(cmd)
local band = 0
if next(res)~=nil then
for k,v in pairs(res) do
local _,_,tmp = string.find(v, 'tx:([0-9]+%.[0-9]+)')
if tmp then
band = tonumber(tmp) or 0
end
--logger(10, "got upload info: "..v)
end
--logger(10,"got up band: "..band)
return band
else
return 0
end
end
function do_speed_test_download()
local cmd = cfg.cmd_download
local res = execl2(cmd)
local band = 0
if next(res)~=nil then
for k,v in pairs(res) do
local _,_,tmp = string.find(v, 'rx:([0-9]+%.[0-9]+)')
if tmp then
band = tonumber(tmp) or 0
end
--logger(10, "got download info: "..v)
end
--logger(10,"got down band: "..band)
return band
else
return 0
end
end
--flag: 1.speedtest when power on 2.speedtest when time up 3.speedtest on cmd
-- 4.speedtest again in 1 hour if last band result unacceptable
--return 1 means failed, return 0 means succeed
function do_speed_test(flag)
local upband,downband = 0,0
logger(10, "do speed test!")
local miqos_upband,miqos_downband = get_miqosband()
if flag ~= 3 then
if miqos_upband==0 or miqos_downband==0 then
-- logger(3, "stat_points_privacy network_speedtest="..flag.."|miqosinvalid|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|0|0")
logger(10, "network_speedtest="..flag.."|miqosinvalid|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|0|0")
-- return 1
end
end
os.execute("/etc/init.d/miqos stop")
downband = do_speed_test_download()
upband = do_speed_test_upload()
os.execute("/etc/init.d/miqos start")
logger(10, "test upband: "..upband.." test downband: "..downband)
logger(10, "miqos upband: "..miqos_upband.." miqos downband: "..miqos_downband)
if upband==0 or downband==0 then
logger(10, "speedtest or miqos band invalid!")
if flag ~= 3 then
logger(3, "stat_points_privacy network_speedtest="..flag.."|bandinvalid|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
logger(10, "dotdata: network_speedtest="..flag.."|bandinvalid|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
end
return 1
else
if is_band_result_valid(upband,downband,miqos_upband,miqos_downband,flag) then
if flag == 4 or flag == 3 then
local res = set_miqosband(upband, downband, flag)
if res then
logger(3, "stat_points_privacy network_speedtest="..flag.."|success|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
logger(10, "dotdata: network_speedtest="..flag.."|success|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
return 0
else
if flag~= 3 then
logger(3, "stat_points_privacy network_speedtest="..flag.."|miqoserr1|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
logger(10, "dotdata: network_speedtest="..flag.."|miqoserr1|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
end
return 1
end
else
if is_band_result_acceptable(upband,downband,miqos_upband,miqos_downband,flag) then
local res = set_miqosband(upband, downband, flag)
if res then
logger(3, "stat_points_privacy network_speedtest="..flag.."|success|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
logger(10, "dotdata: network_speedtest="..flag.."|success|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
return 0
else
logger(3, "stat_points_privacy network_speedtest="..flag.."|miqoserr1|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
logger(10, "dotdata: network_speedtest="..flag.."|miqoserr1|"..os.date("%x %X").."|"..miqos_upband.."|"..miqos_downband.."|"..upband.."|"..downband)
return 1
end
else
g_need_test_again = true
g_test_again_ticks = TEST_AGAIN_TICKS
logger(10, "band result unacceptable, test again 1 hour later!")
end
end
end
end
return 1
end
function speedtest_by_cmd()
if (g_user_band_down ~= 0) or (g_user_band_up ~= 0) then
logger(10, "speedtest cmd user band is not zero: "..g_user_band_up.." "..g_user_band_down..", do nothing!")
return 1
end
if not is_internet_connected() then
logger(10, "speedtest cmd Internet is not connected, do nothing!")
return 2
end
local res = do_speed_test(3)
return res
end
function try_speedtest()
if (g_user_band_down ~= 0) or (g_user_band_up ~= 0) then
logger(10, "user band is not zero: "..g_user_band_up.." "..g_user_band_down..", do nothing!")
return
end
if not is_lasttest_long_enough() then
return
end
if (g_current_day_num >= MAX_NUM_PERDAY) or (g_current_day_trynum >= MAX_TRYNUM_PERDAY)then
logger(10, "Exceed max num perday! cur: "..g_current_day_num.."("..MAX_NUM_PERDAY..") trycur: "..g_current_day_trynum.."("..MAX_TRYNUM_PERDAY..")")
return
end
-- during the just startup time, we dont detect if wan is busy
if g_ubus_wanup_msg == 1 and is_just_power_up() then
if not is_internet_connected() then
logger(10, "Wanup but Internet is not connected, do nothing!")
return
end
logger(10, "Got wan up msg, do speed test!")
g_ubus_wanup_msg = 0
do_speed_test(1)
g_current_day_num = g_current_day_num +1
return
end
if is_time_to_speedtest() then
if not is_internet_connected() then
logger(10, "Internet is not connected, do nothing!")
logger(3, "stat_points_privacy network_speedtest=2|uninternet|"..os.date("%x %X"))
logger(10, "dotdata: network_speedtest=2|uninternet|"..os.date("%x %X"))
g_current_day_trynum = g_current_day_trynum + 1
return
end
if is_wan_busy() then
g_current_day_trynum = g_current_day_trynum + 1
logger(10, "Wan is busy, do nothing! ")
g_nextmins_speedtest = get_nexttime_speedtest()
else
logger(10, "Wan is free, do speed test!")
do_speed_test(2)
g_current_day_num = g_current_day_num +1
g_nextmins_speedtest = get_nexttime_speedtest()
end
end
end
--if last band result unacceptable, we do speed test again in 1 hour
function try_speedtest_again()
if (g_user_band_down ~= 0) or (g_user_band_up ~= 0) then
logger(10, "user band is not zero: "..g_user_band_up.." "..g_user_band_down..", do nothing!")
return
end
if true then
if not is_internet_connected() then
logger(10, "Internet is not connected, do nothing!")
logger(3, "stat_points_privacy network_speedtest=2|uninternet|"..os.date("%x %X"))
logger(10, "dotdata: network_speedtest=2|uninternet|"..os.date("%x %X"))
return
end
if is_wan_busy() then
logger(10, "Wan is busy, do nothing! ")
else
logger(10, "Wan is free, do speed test!")
do_speed_test(4)
end
end
end
function prepare_speedtest_urls()
local cmd = cfg.cmd_speedtesturls
if g_prepare_speedtest_xml_trycnt > 3 then
logger(10, "try num is enough do nothing: "..g_prepare_speedtest_xml_trycnt)
return
end
g_prepare_speedtest_xml_cnter = g_prepare_speedtest_xml_cnter + 1
if SPEEDTEST_VER ~= "OVERSEA" then
logger(10, "prepare urls is not oerversea version !")
return
end
filexml = io.open(cfg.tmp_speedtest_xml)
if filexml then
filexml:close()
logger(10, "prepare urls already got url xml !")
return
end
if not is_internet_connected() then
logger(10, "prepare urls Internet is not connected, do nothing!")
return
end
if g_prepare_speedtest_xml_trycnt ~= 0 then
if g_prepare_speedtest_xml_cnter - g_prepare_speedtest_xml_last_try < PREPARE_SPEEDTEST_XML_INTERVEL then
logger(10, "its not time for getting xml cnter: "..g_prepare_speedtest_xml_cnter.." last: "..g_prepare_speedtest_xml_last_try)
return
end
end
g_prepare_speedtest_xml_trycnt = g_prepare_speedtest_xml_trycnt + 1
g_prepare_speedtest_xml_last_try = g_prepare_speedtest_xml_cnter
logger(3, "start getting speedtest url xml !")
local res = execl2(cmd)
filexml = io.open(cfg.tmp_speedtest_xml)
if filexml then
filexml:close()
logger(3, "get speedtest url xml ok!")
else
logger(3, "get speedtest url xml failed!")
end
end
-----------------------------------------------------------------------------
-- loop work for speed test
-----------------------------------------------------------------------------
function main_loop()
local server = assert(socket.bind(cfg.host, cfg.port))
server:settimeout(1)
-- tables f
local set=newset()
set:insert(server) -- add 'server' into select events
local gc_timer=0
while true do
logger(10, "--------- main loop ---------")
local readable, _, error = socket.select(set, nil , 20)
gc_timer = gc_timer + 1
if gc_timer >= 20 then
gc_timer = 0
local tmp_cnt = collectgarbage("count")
logger(10, "LUA GC count: " .. tmp_cnt)
tmp_cnt = collectgarbage("collect")
logger(10, "LUA GC collect: " .. tmp_cnt)
end
for _,v in ipairs(readable) do
if v == server then
logger(3, 'new client come in ...')
local clt=v:accept()
if clt then
clt:settimeout(1)
set:insert(clt)
else
logger(3, 'accept client error.')
end
else
local data,error = v:receive()
if error then
v:close()
logger(3, 'client is disconnected.')
set:remove(v)
else
local args=string.split(data,' ')
if not args[1] then
v:send(json.encode({status=3}))
else
logger(10, "Recv cmd: "..args[1])
if args[1] == 'status' then
logger(3,'======== COMMAND status============')
local stats = string.format("\ng_begin_time : %s\n",g_begin_time)
stats = stats..string.format("g_end_time : %s\n",g_end_time)
stats = stats..string.format("g_lasttime_speedtest : %s\n",os.date("%x %X", g_lasttime_speedtest))
stats = stats..string.format("g_nextmins_speedtest : %s\n",mins_to_time(g_nextmins_speedtest))
stats = stats..string.format("g_current_date : %d\n",g_current_date)
stats = stats..string.format("g_current_day_trynum : %d\n",g_current_day_trynum)
stats = stats..string.format("g_current_day_num : %d\n",g_current_day_num)
stats = stats..string.format("g_max_log_num : %d\n",g_max_log_num)
stats = stats..string.format("g_current_log_num : %d\n",g_current_log_num)
stats = stats..string.format("g_user_band_up : %d\n",g_user_band_up)
stats = stats..string.format("g_user_band_down : %d\n",g_user_band_down)
v:send(json.encode({status=2,data=stats}))
elseif args[1] == 'stop' then
logger(3,'======== COMMAND stop ============')
v:send(json.encode({status=0}) .. "\n")
v:close()
system_exit() -- exit system
elseif args[1] == 'wan_up' then
logger(3,'======== COMMAND wan_up============')
g_ubus_wanup_msg = 1
v:send(json.encode({status=0}) .. "\n")
elseif args[1] == 'debug_on' then
logger(3,'======== COMMAND debug_on============')
g_debug = true
v:send(json.encode({status=0}) .. "\n")
elseif args[1] == 'debug_off' then
logger(3,'======== COMMAND debug_off============')
g_debug = false
v:send(json.encode({status=0}) .. "\n")
elseif args[1] == 'do_speedtest' then
logger(3,'======== COMMAND do_speedtest============')
local res = speedtest_by_cmd()
v:send(json.encode({status=res}) .. "\n")
elseif args[1] == 'set_userband' then
logger(3,'======== COMMAND set_userband============')
g_user_band_up = tonumber(args[2]) or 0
g_user_band_down = tonumber(args[3]) or 0
v:send(json.encode({status=0}) .. "\n")
elseif args[1] == 'next_time' then
logger(3,'======== COMMAND nexttime============')
g_nextmins_speedtest = time_to_mins(args[2])
v:send(json.encode({status=0, data=args[2].." "..g_nextmins_speedtest}) .. "\n")
else
v:send(json.encode({status=2,data='Not supported command.'}))
end
end
v:send('\n')
v:close()
set:remove(v)
end
end
end
prepare_speedtest_urls()
local date = tonumber(os.date("%d"))
if g_current_date ~= date then
logger(10, "date change from "..g_current_date.." to "..date)
g_current_day_trynum = 0
g_current_day_num = 0
g_current_date = date
end
if g_need_test_again then
if g_test_again_ticks > 1 then
g_test_again_ticks = g_test_again_ticks - 1
logger(10, "test again ticks left: "..g_test_again_ticks)
else
g_need_test_again = false
g_test_again_ticks = TEST_AGAIN_TICKS
logger(10, "try speed test again! ")
try_speedtest_again()
end
end
try_speedtest()
end
end
function main()
if system_init() then
local s, e = pcall(function() main_loop() end)
if not s
then
logger(3,e)
print("pcall exit!")
end
else
print("system initial failed. exit.")
logger(3, 'system initial failed. exit.')
end
end
main()