luci下的action中的sip request uri_URI操作过程

您正在使用IE低版浏览器,为了您的IThao123账号安全和更好的产品体验,强烈建议使用更快更安全的浏览器
openwrt中luci界面中简单的添加一个配置说明
openwrt中luci界面中简单的添加一个配置说明
1.先在system中添加一个ipv6config
&&&操作:先在/usr/lib/ lua/luci/controller/admin/system.lua 文件中的index页面中添加&
entry({&admin&, &system&, &ipv6config&}, cbi(&admin_system/ipv6config&), &ipv6config&, 30).dependent=false
system.lua页面全部代码
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth &steven@midlink.org&
Jo-Philipp Wich &xm@subsignal.org&
Licensed under the Apache License, Version 2.0 (the &License&);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id: system.lua -26 00:58:12Z jow $
module(&luci.controller.admin.system&, package.seeall)
function index()
entry({&admin&, &system&}, alias(&admin&, &system&, &system&), _(&System&), 30).index = true
entry({&admin&, &system&, &system&}, cbi(&admin_system/system&), _(&System&), 1)
entry({&admin&, &system&, &clock_status&}, call(&action_clock_status&))
entry({&admin&, &system&, &admin&}, cbi(&admin_system/admin&), _(&Administration&), 2)
if nixio.fs.access(&/bin/opkg&) then
entry({&admin&, &system&, &packages&}, call(&action_packages&), _(&Software&), 10)
entry({&admin&, &system&, &packages&, &ipkg&}, form(&admin_system/ipkg&))
entry({&admin&, &system&, &startup&}, form(&admin_system/startup&), _(&Startup&), 45)
entry({&admin&, &system&, &crontab&}, form(&admin_system/crontab&), _(&Scheduled Tasks&), 46)
if nixio.fs.access(&/etc/config/fstab&) then
entry({&admin&, &system&, &fstab&}, cbi(&admin_system/fstab&), _(&Mount Points&), 50)
entry({&admin&, &system&, &fstab&, &mount&}, cbi(&admin_system/fstab/mount&), nil).leaf = true
entry({&admin&, &system&, &fstab&, &swap&},
cbi(&admin_system/fstab/swap&),
nil).leaf = true
if nixio.fs.access(&/sys/class/leds&) then
entry({&admin&, &system&, &leds&}, cbi(&admin_system/leds&), _(&&abbr title=&Light Emitting Diode&&LED&/abbr& Configuration&), 60)
entry({&admin&, &system&, &ipv6config&}, cbi(&admin_system/ipv6config&), &ipv6config&, 30).dependent=false
entry({&admin&, &system&, &flashops&}, call(&action_flashops&), _(&Backup / Flash Firmware&), 70)
entry({&admin&, &system&, &flashops&, &backupfiles&}, form(&admin_system/backupfiles&))
entry({&admin&, &system&, &reboot&}, call(&action_reboot&), _(&Reboot&), 90)
function action_clock_status()
local set = tonumber(luci.http.formvalue(&set&))
if set ~= nil and set & 0 then
local date = os.date(&*t&, set)
if date then
-- prevent session timeoutby updating mtime
nixio.fs.utimes(luci.sauth.sessionpath .. &/& .. luci.dispatcher.context.authsession, set, set)
luci.sys.call(&date -s '%04d-%02d-%02d %02d:%02d:%02d'& %{
date.year, date.month, date.day, date.hour, date.min, date.sec
luci.http.prepare_content(&application/json&)
luci.http.write_json({ timestring = os.date(&%c&) })
function action_packages()
local ipkg = require(&luci.model.ipkg&)
local submit = luci.http.formvalue(&submit&)
local changes = false
local install = { }
local remove
local stdout
local stderr
local out, err
-- Display
local display = luci.http.formvalue(&display&) or &installed&
local letter = string.byte(luci.http.formvalue(&letter&) or &A&, 1)
letter = (letter == 35 or (letter &= 65 and letter &= 90)) and letter or 65
-- Search query
local query = luci.http.formvalue(&query&)
query = (query ~= '') and query or nil
-- Packets to be installed
local ninst = submit and luci.http.formvalue(&install&)
local uinst = nil
-- Install from URL
local url = luci.http.formvalue(&url&)
if url and url ~= '' and submit then
uinst = url
-- Do install
if ninst then
install[ninst], out, err = ipkg.install(ninst)
stdout[#stdout+1] = out
stderr[#stderr+1] = err
changes = true
if uinst then
for pkg in luci.util.imatch(uinst) do
install[uinst], out, err = ipkg.install(pkg)
stdout[#stdout+1] = out
stderr[#stderr+1] = err
changes = true
-- Remove packets
local rem = submit and luci.http.formvalue(&remove&)
if rem then
remove[rem], out, err = ipkg.remove(rem)
stdout[#stdout+1] = out
stderr[#stderr+1] = err
changes = true
-- Update all packets
local update = luci.http.formvalue(&update&)
if update then
update, out, err = ipkg.update()
stdout[#stdout+1] = out
stderr[#stderr+1] = err
-- Upgrade all packets
local upgrade = luci.http.formvalue(&upgrade&)
if upgrade then
upgrade, out, err = ipkg.upgrade()
stdout[#stdout+1] = out
stderr[#stderr+1] = err
-- List state
local no_lists = true
local old_lists = false
local tmp = nixio.fs.dir(&/var/opkg-lists/&)
if tmp then
for tmp in tmp do
no_lists = false
tmp = nixio.fs.stat(&/var/opkg-lists/&..tmp)
if tmp and tmp.mtime & (os.time() - (24 * 60 * 60)) then
old_lists = true
luci.template.render(&admin_system/packages&, {
= display,
= install,
= upgrade,
= no_lists,
old_lists = old_lists,
= table.concat(stdout, &&),
= table.concat(stderr, &&)
-- Remove index cache
if changes then
nixio.fs.unlink(&/tmp/luci-indexcache&)
function action_flashops()
local sys = require &luci.sys&
= require &luci.fs&
local upgrade_avail = nixio.fs.access(&/lib/upgrade/platform.sh&)
local reset_avail
= os.execute([[grep '&rootfs_data&' /proc/mtd &/dev/null 2&&1]]) == 0
local restore_cmd = &tar -xzC/ &/dev/null 2&&1&
local backup_cmd
= &tar -czT %s 2&/dev/null&
local image_tmp
= &/tmp/firmware.img&
local function image_supported()
-- XXX: yay...
return ( 0 == os.execute(
&. /etc/functions. & ..
&include /lib/ & ..
&platform_check_image %q &/dev/null&
% image_tmp
local function image_checksum()
return (luci.sys.exec(&md5sum %q& % image_tmp):match(&^([^%s]+)&))
local function storage_size()
local size = 0
if nixio.fs.access(&/proc/mtd&) then
for l in io.lines(&/proc/mtd&) do
local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+&([^%s]+)&')
if n == &linux& or n == &firmware& then
size = tonumber(s, 16)
elseif nixio.fs.access(&/proc/partitions&) then
for l in io.lines(&/proc/partitions&) do
local x, y, b, n = l:match('^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+)')
if b and n and not n:match('[0-9]') then
size = tonumber(b) * 1024
return size
luci.http.setfilehandler(
function(meta, chunk, eof)
if not fp then
if meta and meta.name == &image& then
fp = io.open(image_tmp, &w&)
fp = io.popen(restore_cmd, &w&)
if chunk then
fp:write(chunk)
if eof then
fp:close()
if luci.http.formvalue(&backup&) then
-- Assemble file list, generate backup
local filelist = &/tmp/luci-backup-list.%d& % os.time()
&( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' /etc/sysupgrade.conf & ..
&/lib/upgrade/keep.d/* 2&/dev/null) -type f 2&/dev/ & ..
&opkg list-changed-conffiles ) | sort -u & %s& % filelist
if fs.access(filelist) then
local reader = ltn12_popen(backup_cmd:format(filelist))
luci.http.header('Content-Disposition', ' filename=&backup-%s-%s.tar.gz&' % {
luci.sys.hostname(), os.date(&%Y-%m-%d&)})
luci.http.prepare_content(&application/x-targz&)
luci.ltn12.pump.all(reader, luci.http.write)
fs.unlink(filelist)
elseif luci.http.formvalue(&restore&) then
-- Unpack received .tar.gz
local upload = luci.http.formvalue(&archive&)
if upload and #upload & 0 then
luci.template.render(&admin_system/applyreboot&)
luci.sys.reboot()
elseif luci.http.formvalue(&image&) or luci.http.formvalue(&step&) then
-- Initiate firmware flash
local step = tonumber(luci.http.formvalue(&step&) or 1)
if step == 1 then
if image_supported() then
luci.template.render(&admin_system/upgrade&, {
checksum = image_checksum(),
= storage_size(),
= nixio.fs.stat(image_tmp).size,
= (not not luci.http.formvalue(&keep&))
nixio.fs.unlink(image_tmp)
luci.template.render(&admin_system/flashops&, {
reset_avail
= reset_avail,
upgrade_avail = upgrade_avail,
image_invalid = true
-- Start sysupgrade flash
elseif step == 2 then
local keep = (luci.http.formvalue(&keep&) == &1&) and && or &-n&
luci.template.render(&admin_system/applyreboot&, {
title = luci.i18n.translate(&Flashing...&),
= luci.i18n.translate(&The system is flashing now.&br /& DO NOT POWER OFF THE DEVICE!&br /& Wait a few minutes until you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings.&),
= (#keep & 0) and &192.168.1.1& or nil
fork_exec(&kil sleep 1; /sbin/sysupgrade %s %q& %{ keep, image_tmp })
elseif reset_avail and luci.http.formvalue(&reset&) then
-- Reset system
luci.template.render(&admin_system/applyreboot&, {
title = luci.i18n.translate(&Erasing...&),
= luci.i18n.translate(&The system is erasing the configuration partition now and will reboot itself when finished.&),
= &192.168.1.1&
fork_exec(&kil sleep 1; mtd -r erase rootfs_data&)
-- Overview
luci.template.render(&admin_system/flashops&, {
reset_avail
= reset_avail,
upgrade_avail = upgrade_avail
function action_passwd()
local p1 = luci.http.formvalue(&pwd1&)
local p2 = luci.http.formvalue(&pwd2&)
local stat = nil
if p1 or p2 then
if p1 == p2 then
stat = luci.sys.user.setpasswd(&root&, p1)
luci.template.render(&admin_system/passwd&, {stat=stat})
function action_reboot()
local reboot = luci.http.formvalue(&reboot&)
luci.template.render(&admin_system/reboot&, {reboot=reboot})
if reboot then
luci.sys.reboot()
function fork_exec(command)
local pid = nixio.fork()
if pid & 0 then
elseif pid == 0 then
-- change to root dir
nixio.chdir(&/&)
-- patch stdin, out, err to /dev/null
local null = nixio.open(&/dev/null&, &w+&)
if null then
nixio.dup(null, nixio.stderr)
nixio.dup(null, nixio.stdout)
nixio.dup(null, nixio.stdin)
if null:fileno() & 2 then
null:close()
-- replace with target command
nixio.exec(&/bin/sh&, &-c&, command)
function ltn12_popen(command)
local fdi, fdo = nixio.pipe()
local pid = nixio.fork()
if pid & 0 then
fdo:close()
local close
return function()
local buffer = fdi:read(2048)
local wpid, stat = nixio.waitpid(pid, &nohang&)
if not close and wpid and stat == &exited& then
close = true
if buffer and #buffer & 0 then
return buffer
elseif close then
fdi:close()
return nil
elseif pid == 0 then
nixio.dup(fdo, nixio.stdout)
fdi:close()
fdo:close()
nixio.exec(&/bin/sh&, &-c&, command)
2. 编写model
&操作:在先在/usr/lib/ lua/luci/model/cbi/admin_system文件中的添加ipv6config.lua 文件
文件全部代码
require(&luci.sys&)
require(&luci.sys.zoneinfo&)
require(&luci.tools.webadmin&)
require(&luci.fs&)
require(&luci.config&)
local m, s, o
m = Map(&ipv6config&, translate(&ipv6config&), translate(&this is ipv6 pre config&))
m:chain(&luci&)
s = m:section(TypedSection, &ipv6config&, translate(&System ipv6&))
s.anonymous = true
s.addremove = false
s:tab(&general&,
translate(&General Settings&))
o = s:taboption(&general&, Value, &ipv6pre&, translate(&ipv6 pre config&))
o.datatype = &ipv6config&
function o.write(self, section, value)
Value.write(self, section, value)
3. 添加配置文件
操作:在/etc/config中添加ipv6config文件
config 'ipv6config'
option 'ipv6pre' '2011:86'
&&&&&& config 中的ipv6config文件中的ipv6confg与ipv6pre与model中ipv6config.lua两个字段的对应
Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。
用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。
Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。
Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。
产品设计是互联网产品经理的核心能力,一个好的产品经理一定在产品设计方面有扎实的功底,本专题将从互联网产品设计的几个方面谈谈产品设计
随着国内互联网的发展,产品经理岗位需求大幅增加,在国内,从事产品工作的大部分岗位为产品经理,其实现实中,很多从事产品工作的岗位是不能称为产品经理,主要原因是对产品经理的职责不明确,那产品经理的职责有哪些,本专题将详细介绍产品经理的主要职责
IThao123周刊时间: December 30, 2014
分类: ,,,,,,,,
【一、LuCI配置界面开发的框架】
LuCI是OpenWrt上的Web管理界面,LuCI采用了MVC三层架构,同时其使用Lua脚本开发,所以开发LuCI的配置界面不需要编辑任何的Html代码,除非想自己单独去创建网页(View层),否则我们基本上只需要修改Model层就可以了。官方也有一个如何去创建模块的说明文档,虽然写的比较晦涩:
要为LuCI增加一个新模块,首先需要创建两个文件,一个位于Controller(/usr/lib/lua/luci/controller/)下,定义模块的入口;另一个位于Model(/usr/lib/lua/luci/model/cbi/)下,为配置模块实际的代码。
首先我们定义模块的入口,在/usr/lib/lua/luci/controller/下创建一个lua文件,类似如下:
module("luci.controller.控制器名", package.seeall)
function index()
entry(路径, 调用目标, _("显示名称"), 显示顺序)
第一行说明了程序和模块的名称,比如在controller/目录创建一个mymodule.lua,那么就可以写成“luci.controller.mymodule”,如果你的程序比较多,可能分为好几个模块,那么可以在controller下再常见一个子目录,比如controller/myapp/,那么就可以写成“luci.controller.myapp.mymodule”。
接下来的entry表示添加一个新的模块入口,官方给出了entry的定义,其中后两项都是可以为空的:
entry(path, target, title=nil, order=nil)
第一项是访问的路径,不过路径是按字符串数组给定的,比如路径按如下方式写“{"click", "here", "now"}”,那么就可以在浏览器里访问“”来访问这个脚本。而通常我们希望为管理员菜单添加脚本,那么我们需要按如下方式编写“{"admin", "一级菜单名", "菜单项名"}”,系统会自动在对应的菜单中生成菜单项。比如想在“网络”菜单下创建一个菜单项,那么一级菜单名可以写为“network”。
第二项为调用目标,调用目标分为三种,分别是执行指定方法(Action)、访问指定页面(Views)以及调用CBI Module。
第一种可以直接调用指定的函数,比如点击菜单项就直接重启路由器等等,比如写为“call("function_name")”,然后在lua文件下编写名为function_name的函数就可以调用了。
第二种可以访问指定的页面,比如写为“template("myapp/mymodule")”就可以调用/usr/lib/lua/luci/view/myapp/mymodule.htm文件了。
而如果要编写配置页面,那么使用第三种方法无非是最方便的,比如写为“cbi("myapp/mymodule")”就可以调用/usr/lib/lua/luci/model/cbi/myapp/mymodule.lua文件了。
而title和order无非是针对管理员菜单来的,可以参考其他的lua文件来决定编写的内容。
这里我们创建/usr/lib/lua/luci/controller/njitclient.lua文件,定义我们的入口,代码如下:
module("luci.controller.njitclient", package.seeall)
function index()
entry({"admin", "network", "njitclient"}, cbi("njitclient"), _("NJIT Client"), 100)
【二、 用Lua和UCI接口开发LuCI配置模块 】
njit-client:
为njit-client做好的Web配置界面也已经开源,地址: .
我们要做的实际上就是希望能将用户名、密码等信息存储在路由器文件中,同时路由器开机时能根据设定的配置自动运行njit-client,同时我们还希望能动态的禁用和启用njit-client等等。所以最方便的方式就是使用CBI Module,上一节我们也添加了这个调用,那么接下来我们就要根据上边写的路径来创建 /usr/lib/lua/luci/model/cbi/njitclient.lua文件。
开发LuCI的配置模块有很多种方式,比较基本的可以用SimpleForm,就跟开发普通的Web应用类似,当然最方便的还是使用UCI(Unified Configuration Interface,统一配置接口)的方式,因为使用UCI接口可以使得在LuCI中可以无需考虑配置文件如何存储和读取(这种方式也会自动创建“保存&应用”、“保存”以及“复位”三个按钮),同时在Bash文件中也可以非常方便的存储和读取。
对于使用UCI的方式,我们首先需要创建对应的配置文件(如果配置文件不存在的话,访问配置页面将会报错),格式即为linux配置文件的格式,文件需要存储在/etc/config,比如文件路径为“/etc/config/njitclient”,内容如下:
config login
option username ''
option password ''
option ifname 'eth0'
option domain ''
然后我们要在CBI Module的lua文件中首先需要映射与存储文件的关系,比如:
m = Map("配置文件文件名", "配置页面标题", "配置页面说明")
第一个参数即为配置文件存储的文件名,不包含路径,比如按上述创建的话,应该写为“njitclient”,而第二与第三个参数则是用在来页面上显示的,比如如下所示的图:
接下来需要创建与配置文件中对应的Section,Section分为两种,NamedSection和TypedSection,前者根据配置文件中的Section名,而后者根据配置文件中的Section类型,这里我们使用后者,代码如下。同时我们设定不允许增加或删除Section(“.addremove = false”),以及不显示Section的名称(“.anonymous = true”)。
s = m:section(TypedSection, "login", "")
s.addremove = false
s.anonymous = true
接下来我们需要创建Section中不同内容的交互(创建Option),常见的比如有Value(文本框)、ListValue(下拉框)、Flag(选择框)等等,详细的可以参考官方的文档:
创建Option的过程非常简单,而且创建后系统会无需考虑读取以及写入配置文件的问题,系统都会自动处理。但是根据上述的要求,我们在应用配置以后可能希望启用、禁用或重新启动njit-client,所以我们还需要在页面最后判断用户是否点击了“应用”按钮,这里与编写asp网页等都是相同的,我们可以通过如下的代码判断是否点击了“应用”按钮:
local apply = luci.http.formvalue("cbi.apply")
if apply then
需要处理的代码
由于剩余的代码都非常简单,所以所以这部分的全部代码见下:
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, "enable", 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)
local apply = luci.http.formvalue("cbi.apply")
if apply then
io.popen("/etc/init.d/njitclient restart")
其中Luci全部类库的函数定义和使用说明可以参考如下地址:
【三、在Bash文件中调用UCI接口】
上边我们已经完成了LuCI配置界面的开发,在配置界面中我们已经能读取并保存配置文件了。接下来我们要编写/etc/init.d/njitclient脚本,使程序最终能运行起来。关于UCI接口在脚本文件中的官方说明可以参考:
要使用UCI调用脚本,首先第一步需要读取配置文件,命令为“config_load 配置文件名”,比如我们可以这样读入刚才的配置文件:
config_load njitclient
接下来要遍历配置文件中的Section,可以使用“config_foreach 遍历函数名 Section类型”,例如我们可以这样:
config_foreach run_njit login
然后我们去编写名为“run_njit”的函数,在这个函数中,我们可以使用“config_get 变量名 Section名 Section参数名”获取变量的值,或者使用“config_get_bool 变量名 Section名 Section参数名”获取布尔型的值。所以全部的代码见下:
#!/bin/sh /mon
run_njit()
local enable
config_get_bool enable $1 enable
if [ $enable ]; then
local username
local password
local domain
local ifname
config_get username $1 username
config_get password $1 password
config_get domain $1 domain
config_get ifname $1 ifname
if [ "$domain" != "" ]; then
njit-client $username@$domain $password $ifname &
njit-client $username $password $ifname &
echo "NJIT Client has started."
config_load njitclient
config_foreach run_njit login
killall njit-client
killall udhcpc
echo "NJIT Client has stoped."
【四、 编译开发的程序 】
如果按上述内容创建好上述4个文件,那么配置页面和程序就能在OpenWrt上运行起来了。但是如果要想把自己写的程序打包,还需要创建OpenWrt的Makefile来使用OpenWrt的SDK进行编译。
关于LuCI上配置Makefile的官方说明可以见这个地址:
无非就是定义包的名称(PKG_NAME)、版本和生成次数(PKG_VERSION、PKG_RELEASE)、在menuconfig中的分类说明等(define Package/luci-app-njitclient)以及安装时进行的操作(define Package/luci-app-njitclient/install)等等。其中安装的文件分为三种,分别是配置文件、可执行文件以及其他数据文件,其中配置可执行文件时,会自动加入执行权限的,所以不需要额外进行处理。Makefile全部的代码见下:
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
define Package/luci-app-njitclient/description
This package contains LuCI configuration pages for njit8021xclient.
define Build/Prepare
define Build/Configure
define Build/Compile
define Package/luci-app-njitclient/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
$(INSTALL_CONF) ./files/root/etc/config/njitclient $(1)/etc/config/njitclient
$(INSTALL_BIN) ./files/root/etc/init.d/njitclient $(1)/etc/init.d/njitclient
$(INSTALL_DATA) ./files/root/usr/lib/lua/luci/model/cbi/njitclient.lua $(1)/usr/lib/lua/luci/model/cbi/njitclient.lua
$(INSTALL_DATA) ./files/root/usr/lib/lua/luci/controller/njitclient.lua $(1)/usr/lib/lua/luci/controller/njitclient.lua
$(eval $(call BuildPackage,luci-app-njitclient))
接下来在编译目录下的package目录下创建一个文件夹,如njitclient,然后将所有的文件按目录复制到该目录下即可。之后配置好OpenWrt的交叉编译环境后就可以使用OpenWrt SDK进行编译了,由于这类文章较多,故不再赘述,可以参考相关链接3及之后的文章。
整理编辑,转载请注明出处
: [...]1,NetGEAR WIND3800 移植http:/...

我要回帖

更多关于 request uri 的文章

 

随机推荐