OpenWrt_Luci_Lua/1_1.Mi_Lua/xiaoqiang/util/XQDeviceUtil.lua
2015-06-13 22:22:49 +08:00

572 lines
21 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 主机5秒平均上传速度byte/s
@param download=25777 主机当前累计下载数据总量byte
@param downspeed=120 主机5秒平均下载速度byte/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