WiFiDog modules to add Luci to the OpenWrt router
This article turns from: http://blog.chinaunix.net/uid-9688646-id-5025303.html
"First, Luci Configuration Interface Development Framework"
Luci is the Web management interface on OpenWrt, Luci employs the MVC three-tier architecture and uses LUA scripting, so developing a Luci configuration interface does not require editing any HTML code, unless you want to create a Web page (view layer) alone. Otherwise we basically just need to modify the model layer on it. The official also has a description of how to create modules, although the writing is more obscure:
Http://luci.subsignal.org/trac/wiki/Documentation/ModulesHowTo
To add a new module to the Luci, you first need to create two files, one at the controller (/usr/lib/lua/luci/controller/), the entry for the module, and the other in model (/usr/lib/lua/luci/ model/cbi/), the actual code for the configuration module.
First we define the portal of the module and create a LUA file under/usr/lib/lua/luci/controller/, similar to the following:
Module ("Luci.controller. Controller name", Package.seeall)
function index ()
entry (path, call target, _ ("Display Name"), display order) end
The first line describes the program and the name of the module, such as creating a Mymodule.lua in the controller/directory, so you can write "Luci.controller.mymodule", if your program is more, it may be divided into several modules, Then you can controller a subdirectory, such as controller/myapp/, then you can write "Luci.controller.myapp.mymodule".
The next entry represents the addition of a new module entry, and the official definition of entry, the last two of which are nullable:
Entry (path, target, Title=nil, Order=nil)
The first entry is the path to the access, but the path is given as a string array, for example, the path is written as follows "{click", "Here" and "Now"} "so you can access the Http://192.168.1.1/cgi-bin/luci/click in the browser" /here/now "To access this script. And usually we want to add a script to the admin menu, then we need to write "{" admin "," menu Name "," menu item Name "}" as follows, and the system automatically generates menu items in the corresponding menu. For example, to create a menu item under the Network menu, a single-name can be written as "network."
The second item is the calling target, which is divided into three types, namely executing the specified method (Action), accessing the specified page (views), and invoking the CBI Module. The first can call the specified function directly, such as clicking on the menu item to restart the router directly, etc., such as "Call (" Function_name ")", and then write a function called Function_name under the Lua file to invoke. The second can access the specified page, such as "template" ("Myapp/mymodule") to invoke the/usr/lib/lua/luci/view/myapp/mymodule.htm file. If you want to write a configuration page, then the third method is the most convenient, such as "CBI (" Myapp/mymodule ")" Can invoke the/usr/lib/lua/luci/model/cbi/myapp/mymodule.lua file.
The title and order are for the admin menu only, and you can refer to other LUA files to decide what to write.
Here we create the/usr/lib/lua/luci/controller/njitclient.lua file, define our entry, code as follows:
Module ("Luci.controller.njitclient", Package.seeall)
function index ()
entry ({"admin", "Network", " Njitclient "}, CBI (" Njitclient "), _ (" Njit Client ") End
"Two, develop Luci configuration module with LUA and UCI interface"
Njit-client:
The Web configuration interface for Njit-client has also been open source, address: https://github.com/mayswind/luci-app-njitclient.
What we want to do is actually want to be able to store the user name, the password and so on the information in the router file, at the same time the router boot can according to set configuration automatically run Njit-client, at the same time we also want to be able to dynamically disable and enable Njit-client and so on. So the easiest way to do this is to use CBI Module, which we added in the previous section, and then we'll create the/usr/lib/lua/luci/model/cbi/njitclient.lua file based on the path written above.
There are a number of ways to develop Luci configuration modules, the basic can be used simpleform, similar to the development of ordinary Web applications, of course, the most convenient is the use of UCI (Unified Configuration Interface, unified Configuration Interface) way, Because the UCI interface allows the configuration file to be stored and read without having to be considered in Luci (this will automatically create a "Save & Apply", "Save" and "Reset" three buttons) and can be easily stored and read in a bash file.
For the use of UCI, we first need to create the corresponding configuration file (if the configuration file does not exist, the Access Configuration page will be the error), the format is the format of the Linux configuration file, the file needs to be stored in/etc/config, such as the file path is "/etc/config/ Njitclient ", the contents are as follows:
Config login
option username ' option
password '
option ifname ' eth0 '
option domain '
Then we need to first map the relationship to the storage file in the Lua file of CBI module, for example:
m = Map (profile file name, configuration page title, configuration page description)
The first parameter is the file name of the profile store and does not contain a path, such as "Njitclient" if created as described above, and the second and third parameters are displayed on the page, such as the following figure:
Next you need to create the corresponding section,section in the configuration file into two types, namedsection and Typedsection, which are based on the section name in the configuration file and the latter according to the section type in the configuration file, where we use the , the code is as follows. At the same time we do not allow adding or removing section (". AddRemove = False"), and the name of the section (". Anonymous = True") is not displayed.
s = m:section (typedsection, "Login", "")
S.addremove = False
S.anonymous = True
Next we need to create the interaction of different content in the section (create option), such as the value (text box), ListValue (dropdown box), Flag (selection box), and so on, and so on, the official documents can be referred to in detail: http:// Luci.subsignal.org/trac/wiki/documentation/cbi
The process of creating an option is simple, and the system will automatically process the system without considering the problem of reading and writing to the configuration file after it is created. However, according to the above requirements, we may want to enable, disable or restart the njit-client after the application of the configuration, so we also need to determine at the end of the page whether the user clicked the "Application" button, here and write ASP pages are the same, we can use the following code to determine whether the click Apply button:
Local apply = Luci.http.formvalue ("cbi.apply")
if Apply then
--[[
code to be processed
]]--
End
Because the rest of the code is very simple, so the entire code for this section is shown below:
Require ("Luci.sys")
m = Map ("Njitclient", Translate ("NJIT client"), translate ("Configure njit 802.11x client."
) s = m:section (typedsection, "Login", "")
S.addremove = False
S.anonymous = true
enable = S:option (Flag, "Enab Le ", Translate (" Enable "))
name = S:option (value," username ", translate (" username ")) Pass
= s:option (Value," Password ", Translate (" password "))
Pass.password = true
domain = s:option (Value," domain ", translate (" domain ") )
ifname = S:option (ListValue, "ifname", Translate ("interfaces")) for
K, v. in Ipairs (Luci.sys.net.devices ()) Do
if v ~= "Lo" then
ifname:value (v) End of local
apply = Luci.http.formvalue ("cbi.apply") C16/>if Apply then
io.popen ("/etc/init.d/njitclient restart") End return
m
The function definition and use instructions of Luci all class libraries can refer to the following address: http://luci.subsignal.org/api/luci/index.html "Three, call the UCI interface in bash file"
Above we have completed the development of the Luci Configuration interface, in the configuration interface we have been able to read and save the configuration file. Next we're going to write the/etc/init.d/njitclient script so that the program can eventually run. The official description of the UCI interface in the script file can refer to: http://wiki.openwrt.org/doc/devel/config-scripting to use the UCI invoke script, the first step is to read the configuration file, the command is "Config_ Load profile filename ", for example, we can read the configuration file just like this:
Config_load njitclient
Next, to traverse the section in the configuration file, you can use the Config_foreach Traversal Function name section type, for example we can:
Config_foreach Run_njit Login
Then we'll write a function called "Run_njit", in which we can get the value of the variable using the "Config_get Variable Name section name", or use the Config_get_bool variable name section name The name of the section parameter gets the value of the Boolean. So all the code is as follows:
#!/bin/sh/etc/rc.common
start=50
Run_njit ()
{local
enable
Config_get_bool enable
if [$enable]; then local
username local password local domain local
ifname
config_get Username $ username
config_get Password $ password
config_get domain \ domain
CONFIG_GET ifname $ ifna Me
if ["$domain" "!="]; Then
njit-client $username @ $domain $password $ifname &
Else
njit-client $username $password $ IfName &
fi
echo "Njit Client has started."
Fi
}
start ()
{
config_load njitclient
config_foreach run_njit Login
}
Stop ()
{
killall njit-client
killall udhcpc
echo "NJIT client has stoped."
}
"Four, compile the development of the program"
If the above 4 files are created by the above content, then the configuration pages and programs can be run on the OpenWrt. But if you want to package the program you write, you will also need to create openwrt makefile to use the OpenWrt SDK for compilation.
An official description of the makefile on the Luci can be found at this address: http://luci.subsignal.org/trac/wiki/Documentation/Modules
Nothing more than defining the name of the package (Pkg_name), the version and the number of builds (Pkg_version, pkg_release), the classification in Menuconfig, and so on (define package/ Luci-app-njitclient), as well as the operations performed at installation (define Package/luci-app-njitclient/install), and so on. The files that are installed are divided into three types, configuration files, executables, and other data files, which automatically join execution permissions when the executable is configured, so no additional processing is required. Makefile all the code see below:
Include $ (topdir)/rules.mk
Pkg_name:=luci-app-njitclient
pkg_version=1.0
Pkg_release:=1
pkg_build_dir:=$ (Build_dir)/$ (pkg_name)
Include $ (include_dir)/package.mk
Define Package/luci-app-njitclient
Section:=luci
Category:=luci
Submenu:=3. Applications
Title:=njit 802.1X Client for Luci
Pkgarch:=all
Endef
Define Package/luci-app-njitclient/description
This package contains Luci configuration the pages for njit8021xclient.
Endef