OpenWrt中web界面功能实现及状态获取实例分析

OpenWrt中web界面功能实现及状态获取实例分析

UCI介绍及实例练习

LuCI是OpenWrt上的Web管理界面,LuCI采用了MVC三层架构,使用Lua脚本开发;
具体介绍及功能添加练习,可参考链接:https://blog.csdn.net/icy_river/article/details/48179649;

自己动手分析openwrt中web界面switch功能模块实现

功能截图:
![标签位置:web功能界面Network中Switch下](https://img-blog.csdnimg.cn/2019032909334694.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h4Yl9wb3A=,size_16,color_FFFFFF,t_70)
	根据MVC架构,首先进入目录/usr/lib/lua/luci/controller/admin,找到对应的controller控制器文件,该文件中定义了Switch功能在web中Networ下的位置;
	vim network.lua,从中截取switch 相关代码片段,如下:
               ......
                uci:foreach("network", "switch",                      
                        function(s)                                   
                                has_switch = true                  
                                return false                                                        
                        end)   
                if has_switch then
                        page  = node("admin", "network", "vlan")
                        page.target = cbi("admin_network/vlan")
                        page.title  = _("Switch")
                        page.order  = 20                //在Web界面建立Switch标签节点
                                                
                        page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil)
                        page.leaf = true         
                end    
				......
				function switch_status(switches)                                
       				 local s = require "luci.tools.status"                   
                                                                
       				 luci.http.prepare_content("application/json")           
       				 luci.http.write_json(s.switch_status(switches))                                                
				end
				......
分析代码:
	X:foreach(“config_file”,“type”, function(s) ... End) 针对某一类型的section,调用回调函数,参数s是一个table,包含所有option的值,还包括两个特殊的值:
s[‘.type’]-->section type
s[‘.name’]-->section name

page.target = cbi("admin_network/vlan")    
 //表示调用cbi模块,这里将会调用到/usr/lib/lua/luci/model/cbi/admin_network/vlan.lua 
 //vlan.lua 文件中完成VLAN使用,PROT端口号等状态信息获取及功能信息配置等UCI操作,并通过参数上传给Controller和View中的相关文件;
m.uci:foreach("network", "switch",                                                                            
        function(x)                                                                                
                local sid         = x['.name']
                local switch_name = x.name or sid                        
                local has_vlan    = nil                     
                local has_learn   = nil          
                local has_vlan4k  = nil                                
                local has_jumbo3  = nil                         
                local has_mirror  = nil
                local min_vid     = 0                                      
                local max_vid     = 16                               
                local num_vlans   = 16 
                local cpu_port    = tonumber(fs.readfile("/proc/switch/eth0/cpuport") or 5)
                local num_ports   = cpu_port + 1   
                ......
                end
                ......
page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil)
//调用我们下面写的swithc_status函数
 local s = require "luci.tools.status"     
 //加载运行库:admin/tools/status.lua
 vim status.lua
function switch_status(devs)
	local dev
	local switches = { }
	for dev in devs:gmatch("[^%s,]+") do
		local ports = { }
		local swc = io.popen("swconfig dev %q show" % dev, "r")
		if swc then
			local l
			repeat
				l = swc:read("*l")
				if l then
					local port, up = l:match("port:(%d+) link:(%w+)")
					if port then
						local speed  = l:match(" speed:(%d+)")
						local duplex = l:match(" (%w+)-duplex")
						local txflow = l:match(" (txflow)")
						local rxflow = l:match(" (rxflow)")
						local auto   = l:match(" (auto)")

						ports[#ports+1] = {
							port   = tonumber(port) or 0,
							speed  = tonumber(speed) or 0,
							link   = (up == "up"),
							duplex = (duplex == "full"),
							rxflow = (not not rxflow),
							txflow = (not not txflow),
							auto   = (not not auto)
						}
					end
				end
			until not l
			swc:close()
		end
		switches[dev] = ports
	end
	return switches
end

local swc = io.popen(“swconfig dev %q show” % dev, “r”) //访问交换机芯片的底层驱动,获取link、speed等各种状态信息并存入switches数组返回;
swconfig命令模式
swconfig dev [port |vlan |csmap ] (help|set |get |load |show)
详细介绍参考:https://blog.csdn.net/oYangShanJin/article/details/38128295
OpenWRT swconfig wiki:http://wiki.openwrt.org/doc/techref/swconfig

在/usr/lib/lua/luci/controller/admin/netwrok.lua中:

				function switch_status(switches)                                
       				 local s = require "luci.tools.status"                   
                                                                
       				 luci.http.prepare_content("application/json")           
       				 luci.http.write_json(s.switch_status(switches))                                                
				end
luci.http.prepare_content("application/json")         

luci.http.write_json(s.switch_status(switches))
//luci与页面的数据交互命令格式,上传switches参数给页面
查看View页面显示代码,admin/view/admin_network/switch_status.htm

        var switches = [ '<%=table.concat(self.switches, "', '")%>' ];
        XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "switch_status")%>/' + switches.join(','), null,
                function(x, st)
                {
                        for (var i = 0; i < switches.length; i++)
                        {
                                var ports = st[switches[i]];
                                var th0 = document.getElementById('portstatus-' + switches[i]);

                                if (th0 && ports && ports.length)
                                {
                                        if (!th0.innerHTML)
                                                th0.innerHTML = '<%:Port status:%>';

                                        for (var j = 0; j < ports.length; j++)
                                        {
                                                var th = th0.parentNode.parentNode.childNodes[j+1];

                                                if (ports[j].link)
                                                {
                                                        th.innerHTML = String.format(
                                                                '<small><img src="<%=resource%>/icons/port_up.png" />' +
                                                                '<br />%d<%:baseT%><br />%s</small>',
                                                                ports[j].speed, ports[j].duplex
                                                                        ? '<%:full-duplex%>' : '<%:half-duplex%>'
                                                        );
                                                }
                                                else
                                                {
                                                        th.innerHTML = String.format(
                                                                '<small><img src="<%=resource%>/icons/port_down.png" />' +
                                                                '<br /><%:no link%></small>'
                                                        );
                                                }
                                        }
                                }
                        }
                }
        );
//]]></script>

htm中通过XHR 动态调用lua脚本获取switches参数信息并处理,lua script location : /usr/lib/lua/luci/controller/admin/network.lua
参考:https://blog.csdn.net/jf_xu/article/details/71480632

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值