OpenWrt_Luci_Lua/1_1.Mi_Lua/xiaoqiang/util/XQDeviceUtil.lua

572 lines
21 KiB
Lua
Raw Normal View History

2015-05-09 10:48:46 +00:00
module ("xiaoqiang.util.XQDeviceUtil", package.seeall)
local Json = require("cjson")
local XQConfigs = require("xiaoqiang.common.XQConfigs")
local XQFunction = require("xiaoqiang.common.XQFunction")
local XQEquipment = require("xiaoqiang.XQEquipment")
function getDeviceCompany(mac)
local companyInfo = { name = "", icon = "" }
if XQFunction.isStrNil(mac) or string.len(mac) < 8 then
return companyInfo
end
return XQEquipment.identifyDevice(mac, nil)
end
function getDeviceInfoFromDB()
local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
local result = {}
local deviceList = XQDBUtil.fetchAllDeviceInfo()
if #deviceList > 0 then
for _,device in ipairs(deviceList) do
result[device.mac] = device
end
end
return result
end
function saveDeviceName(mac,name)
local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
local code = XQDBUtil.updateDeviceNickname(XQFunction.macFormat(mac),name)
if code == 0 then
return true
else
return false
end
end
--
-- Get DHCP list
--
function getDHCPList()
local NixioFs = require("nixio.fs")
local LuciUci = require("luci.model.uci")
local uci = LuciUci.cursor()
local result = {}
local leasefile = XQConfigs.DHCP_LEASE_FILEPATH
uci:foreach("dhcp", "dnsmasq",
function(s)
if s.leasefile and NixioFs.access(s.leasefile) then
leasefile = s.leasefile
return false
end
end)
local dhcp = io.open(leasefile, "r")
if dhcp then
for line in dhcp:lines() do
if line then
local ts, mac, ip, name = line:match("^(%d+) (%S+) (%S+) (%S+)")
if name == "*" then
name = ""
end
if ts and mac and ip and name then
result[#result+1] = {
mac = XQFunction.macFormat(mac),
ip = ip,
name = name
}
end
end
end
dhcp:close()
return result
else
return false
end
end
function getDHCPDict()
local dhcpDict = {}
local dhcpList = getDHCPList()
for _,value in ipairs(dhcpList) do
dhcpDict[value.mac] = value
end
return dhcpDict
end
function getDHCPIpDict()
local dhcpDict = {}
local dhcpList = getDHCPList()
for _,value in ipairs(dhcpList) do
dhcpDict[value.ip] = value
end
return dhcpDict
end
function getMacfilterInfoList()
local LuciUtil = require("luci.util")
local macFilterInfo = {}
local metaData = LuciUtil.execi("/usr/sbin/sysapi macfilter get")
for filterInfo in metaData do
filterInfo = filterInfo..";"
local mac = filterInfo:match('mac=(%S-);') or ""
local wan = filterInfo:match('wan=(%S-);') or ""
local lan = filterInfo:match('lan=(%S-);') or ""
local admin = filterInfo:match('admin=(%S-);') or ""
local pridisk = filterInfo:match('pridisk=(%S-);') or ""
local entry = {}
if (not XQFunction.isStrNil(mac)) then
entry["mac"] = XQFunction.macFormat(mac)
entry["wan"] = (string.upper(wan) == "YES" and true or false)
entry["lan"] = (string.upper(lan) == "YES" and true or false)
entry["admin"] = (string.upper(admin) == "YES" and true or false)
entry["pridisk"] = (string.upper(pridisk) == "YES" and true or false)
table.insert(macFilterInfo, entry)
end
end
return macFilterInfo
end
function getMacfilterInfoDict()
local macFilterDict = {}
local macFilterList = getMacfilterInfoList()
for _,value in ipairs(macFilterList) do
macFilterDict[value.mac] = value
end
return macFilterDict
end
--[[
@param devName : lan/wan DEVNAME = DEV
]]--
function getWanLanNetworkStatistics(devName)
local LuciUtil = require("luci.util")
local tracmd = ""
if devName == "lan" then
tracmd = "ubus call trafficd lan"
elseif devName == "wan" then
tracmd = "ubus call trafficd wan"
end
local statistics = {
["upload"] = "0",
["upspeed"] = "0",
["download"] = "0",
["downspeed"] = "0",
["devname"] = "",
["maxuploadspeed"] = "0",
["maxdownloadspeed"] = "0"
}
local ubusinfo = LuciUtil.exec(tracmd)
if XQFunction.isStrNil(ubusinfo) then
return statistics
end
local ubusinfo = Json.decode(ubusinfo)
if devName == "wan" then
statistics.devname = tostring(ubusinfo.ifname)
statistics.upload = tostring(ubusinfo.tx_bytes)
statistics.download = tostring(ubusinfo.rx_bytes)
statistics.upspeed = tostring(math.floor(ubusinfo.tx_rate or 0))
statistics.downspeed = tostring(math.floor(ubusinfo.rx_rate or 0))
statistics.maxuploadspeed = tostring(math.floor(ubusinfo.max_tx_rate or 0))
statistics.maxdownloadspeed = tostring(math.floor(ubusinfo.max_rx_rate or 0))
local history = LuciUtil.exec("ubus call trafficd list_wan_rate")
if not XQFunction.isStrNil(history) then
historylist = {}
history = Json.decode(history)
for _, rate in ipairs(history.rate) do
if rate then
table.insert(historylist, tostring(rate))
end
end
statistics.history = table.concat(historylist, ",")
end
else
statistics.devname = tostring(ubusinfo.ifname)
statistics.upload = tostring(ubusinfo.rx_bytes)
statistics.download = tostring(ubusinfo.tx_bytes)
statistics.upspeed = tostring(math.floor(ubusinfo.rx_rate or 0))
statistics.downspeed = tostring(math.floor(ubusinfo.tx_rate or 0))
statistics.maxuploadspeed = tostring(math.floor(ubusinfo.max_rx_rate or 0))
statistics.maxdownloadspeed = tostring(math.floor(ubusinfo.max_tx_rate or 0))
end
return statistics
end
--[[
@param mac=B8:70:F4:27:0C:1B mac地址
@param upload=14745 byte
@param upspeed=54 5byte/s
@param download=25777 byte
@param downspeed=120 5byte/s
@param oneline=169 线
@param devname
@param maxuploadspeed
@param maxdownloadspeed
]]--
function getDevNetStatisticsList()
local LuciUtil = require("luci.util")
local statList = {}
local dhcpNameDict = getDHCPDict()
local deviceInfoDict = getDeviceInfoFromDB()
local deviceinfo = LuciUtil.exec("ubus call trafficd hw")
if XQFunction.isStrNil(deviceinfo) then
return statList
else
deviceinfo = Json.decode(deviceinfo)
end
for key, dev in pairs(deviceinfo) do
if dev then
local item = {}
local mac = XQFunction.macFormat(key)
local name, nickName, oriName
if dhcpNameDict[mac] then
oriName = dhcpNameDict[mac].name
end
local device = deviceInfoDict[mac]
if device then
if XQFunction.isStrNil(oriName) then
oriName = device.oName
end
nickName = device.nickname
end
local company = XQEquipment.identifyDevice(mac, oriName)
local dtype = company["type"]
if not XQFunction.isStrNil(nickName) then
name = nickName
end
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(dtype.n) then
name = dtype.n
end
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(oriName) then
name = oriName
end
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(company.name) then
name = company.name
end
if XQFunction.isStrNil(name) then
name = mac
end
local tx_bytes, tx_rate, rx_bytes, rx_rate, max_tx_rate, max_rx_rate = 0, 0, 0, 0, 0, 0
local iplist = dev.ip_list
if #iplist > 0 then
for _, ip in ipairs(iplist) do
tx_bytes = tx_bytes + ip.tx_bytes or 0
rx_bytes = rx_bytes + ip.rx_bytes or 0
tx_rate = tx_rate + ip.tx_rate or 0
rx_rate = rx_rate + ip.rx_rate or 0
max_tx_rate = max_tx_rate + ip.max_tx_rate or 0
max_rx_rate = max_rx_rate + ip.max_rx_rate or 0
end
end
item["mac"] = mac
item["upload"] = tostring(tx_bytes)
item["upspeed"] = tostring(math.floor(tx_rate))
item["download"] = tostring(rx_bytes)
item["downspeed"] = tostring(math.floor(rx_rate))
item["online"] = tostring(dev.online_timer or 0)
item["devname"] = name
item["maxuploadspeed"] = tostring(math.floor(max_tx_rate))
item["maxdownloadspeed"] = tostring(math.floor(max_rx_rate))
statList[#statList+1] = item
end
end
return statList
end
function getDevNetStatisticsDict()
local statDict = {}
local statlist = getDevNetStatisticsList()
for _, item in ipairs(statlist) do
if item then
statDict[item.mac] = item
end
end
return statDict
end
function getConnectDeviceCount()
local LuciUtil = require("luci.util")
local count = 0
local deviceinfo = LuciUtil.exec("ubus call trafficd hw")
if XQFunction.isStrNil(deviceinfo) then
return count
else
deviceinfo = Json.decode(deviceinfo)
end
for _,device in pairs(deviceinfo) do
if device and device.ip_list and #device.ip_list > 0 then
local dev = device.ifname
if not XQFunction.isStrNil(dev) and (tonumber(device.assoc) == 1 or not dev:match("wl")) then
local tcount = 0
for _,ip in ipairs(device.ip_list) do
if ip.ageing_timer <= 300 then
if tcount >= 1 then
break
end
count = count + 1
tcount = tcount + 1
end
end
end
end
end
return count
end
--[[
@return online: 0 (offline) 1 (online)
@return ip: ip address
@return mac: mac address
@return type: wifi/line
@return tag: 1 (normal) 2 (in denylist)
@return port: 1 (2.4G wifi) 2 (5G wifi)
@return name: name for show
@return origin_name: origin name
@return signal: wifi signal
@return statistics:
]]--
function getConnectDeviceList()
local XQWifiUtil = require("xiaoqiang.util.XQWifiUtil")
local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
local XQEquipment = require("xiaoqiang.XQEquipment")
local XQLog = require("xiaoqiang.XQLog")
local LuciUtil = require("luci.util")
local deviceList = {}
local deviceinfo = LuciUtil.exec("ubus call trafficd hw")
if XQFunction.isStrNil(deviceinfo) then
return deviceList
else
deviceinfo = Json.decode(deviceinfo)
end
local macFilterDict = getMacfilterInfoDict()
local dhcpDeviceDict = getDHCPDict()
local dhcpDevIpDict = getDHCPIpDict()
local deviceInfoDict = getDeviceInfoFromDB()
local wifiDeviceDict = XQWifiUtil.getAllWifiConnetDeviceDict()
for key ,item in pairs(deviceinfo) do
if item and item.ip_list and #item.ip_list > 0 then
local devicesignal, devicetype, deviceport
local dev = item.ifname
local mac = XQFunction.macFormat(key)
if not XQFunction.isStrNil(dev) and (tonumber(item.assoc) == 1 or not dev:match("wl")) then
-- 信号强度
local signal = wifiDeviceDict[mac]
if signal and signal.signal then
devicesignal = signal.signal
else
devicesignal = ""
end
if dev:match("eth") then
devicetype = "line"
deviceport = 0
elseif dev == "wl0" then
devicetype = "wifi"
deviceport = 2
elseif dev == "wl1" then
devicetype = "wifi"
deviceport = 1
elseif dev == "wl1.2" then
devicetype = "wifi"
deviceport = 3
end
-- 访问权限
local authority = {}
if (macFilterDict[mac]) then
authority["wan"] = macFilterDict[mac]["wan"] and 1 or 0
authority["lan"] = macFilterDict[mac]["lan"] and 1 or 0
authority["admin"] = macFilterDict[mac]["admin"] and 1 or 0
authority["pridisk"] = macFilterDict[mac]["pridisk"] and 1 or 0
else
authority["wan"] = 1
authority["lan"] = 1
authority["admin"] = 1
-- private disk deny access default
authority["pridisk"] = 0
end
local deviceInfo = deviceInfoDict[mac]
local dhcpinfo = dhcpDeviceDict[mac]
if not deviceInfo and dhcpinfo then
XQDBUtil.saveDeviceInfo(mac,dhcpinfo.name,"","","")
end
local count = 0
for _,ip in ipairs(item.ip_list) do
if ip.ageing_timer <= 300 then
if count >= 1 then
break
end
-- 设备名称
local name, originName, nickName, company
if dhcpDevIpDict[ip.ip] ~= nil then
originName = dhcpDevIpDict[ip.ip].name
end
if originName and originName:match("^xiaomi%-ir") then -- fix miio model string
originName = originName:gsub("%-",".")
end
if deviceInfo then
if XQFunction.isStrNil(originName) then
originName = deviceInfo.oName
end
nickName = deviceInfo.nickname
end
if not XQFunction.isStrNil(nickName) then
name = nickName
end
company = XQEquipment.identifyDevice(mac, originName)
local dtype = company["type"]
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(dtype.n) then
name = dtype.n
end
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(originName) then
name = originName
end
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(company.name) then
name = company.name
end
if XQFunction.isStrNil(name) then
name = mac
end
if dtype.c == 3 and XQFunction.isStrNil(nickName) then
name = dtype.n
end
local device = {
["ip"] = ip.ip,
["mac"] = mac,
["online"] = 1,
["type"] = devicetype,
["port"] = deviceport,
["ctype"] = dtype.c,
["ptype"] = dtype.p,
["origin_name"] = originName or "",
["name"] = name,
["company"] = company,
["authority"] = authority
}
local statistics = {}
statistics["dev"] = dev
statistics["mac"] = mac
statistics["ip"] = ip.ip
statistics["upload"] = tostring(ip.tx_bytes or 0)
statistics["upspeed"] = tostring(math.floor(ip.tx_rate or 0))
statistics["download"] = tostring(ip.rx_bytes or 0)
statistics["downspeed"] = tostring(math.floor(ip.rx_rate or 0))
statistics["online"] = tostring(item.online_timer or 0)
statistics["maxuploadspeed"] = tostring(math.floor(ip.max_tx_rate or 0))
statistics["maxdownloadspeed"] = tostring(math.floor(ip.max_rx_rate or 0))
device["statistics"] = statistics
table.insert(deviceList, device)
count = count + 1
end
end
end
end
end
-- if #deviceList > 0 then
-- table.sort(deviceList,
-- function(a, b)
-- return b.statistics.onlinets < a.statistics.onlinets
-- end
-- )
-- end
return deviceList
end
function getConDevices(withbrlan)
local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
local XQEquipment = require("xiaoqiang.XQEquipment")
local XQLog = require("xiaoqiang.XQLog")
local LuciUtil = require("luci.util")
local deviceList = {}
local deviceinfo = LuciUtil.exec("ubus call trafficd hw")
if XQFunction.isStrNil(deviceinfo) then
return deviceList
else
deviceinfo = Json.decode(deviceinfo)
end
local dhcpDevIpDict = getDHCPIpDict()
--local dhcpDeviceDict = getDHCPDict()
local deviceInfoDict = getDeviceInfoFromDB()
for key ,item in pairs(deviceinfo) do
if item and item.ip_list and #item.ip_list > 0 then
local dev = item.ifname
local mac = XQFunction.macFormat(key)
if not XQFunction.isStrNil(dev) and ((not dev:match("wl") and withbrlan) or (dev:match("wl") and tonumber(item.assoc) == 1)) then
local count = 0
for _,ip in ipairs(item.ip_list) do
if count >= 1 then
break
end
local name, originName, nickName, company
if dhcpDevIpDict[ip.ip] ~= nil then
originName = dhcpDevIpDict[ip.ip].name
end
local deviceInfo = deviceInfoDict[mac]
if deviceInfo then
if XQFunction.isStrNil(originName) then
originName = deviceInfo.oName
end
nickName = deviceInfo.nickname
end
if not XQFunction.isStrNil(nickName) then
name = nickName
end
company = XQEquipment.identifyDevice(mac, originName)
local dtype = company["type"]
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(dtype.n) then
name = dtype.n
end
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(originName) then
name = originName
end
if XQFunction.isStrNil(name) and not XQFunction.isStrNil(company.name) then
name = company.name
end
if XQFunction.isStrNil(name) then
name = mac
end
if dtype.c == 3 and XQFunction.isStrNil(nickName) then
name = dtype.n
end
if ip.ageing_timer <= 300 then
local device = {
["ip"] = ip.ip,
["mac"] = mac,
["online"] = 1,
["ctype"] = dtype.c,
["ptype"] = dtype.p,
["origin_name"] = originName or "",
["name"] = name,
["company"] = company
}
local statistics = {}
statistics["dev"] = dev
statistics["mac"] = mac
statistics["ip"] = ip.ip
statistics["upload"] = tostring(ip.tx_bytes or 0)
statistics["upspeed"] = tostring(math.floor(ip.tx_rate or 0))
statistics["download"] = tostring(ip.rx_bytes or 0)
statistics["downspeed"] = tostring(math.floor(ip.rx_rate or 0))
statistics["online"] = tostring(item.online_timer or 0)
statistics["maxuploadspeed"] = tostring(math.floor(ip.max_tx_rate or 0))
statistics["maxdownloadspeed"] = tostring(math.floor(ip.max_rx_rate or 0))
device["statistics"] = statistics
table.insert(deviceList, device)
count = count + 1
end
end
end
end
end
return deviceList
end