曹為華,凌 強,張 雷,徐 駿,范 寅
(1.中國科學技術大學 自動化系,安徽 合肥 230027;2.科大國禎合肥城市云數據中心有限公司,安徽 合肥 230088)
基于OpenWrt系統路由器的模式切換與網頁設計*
曹為華1,凌 強1,張 雷1,徐 駿1,范 寅2
(1.中國科學技術大學 自動化系,安徽 合肥 230027;2.科大國禎合肥城市云數據中心有限公司,安徽 合肥 230088)
目前商用WiFi路由器已應用到多個領域,商家通過給用戶提供一個穩定免費WiFi熱點達到吸引客戶、提升服務的目標。傳統路由器自帶的Luci界面提供了工廠模式的Web界面,用戶可通過該界面配置路由器。Luci采用MVC模式(Model-View-Controller)構造網頁,能實現動態的程序設計,便于修改和擴展。本文主要針對OpenWrt系統的路由器,介紹如何使用Lua和JavaScript腳本語言添加用戶模式Web界面。此外,還介紹了工廠模式和用戶模式之間的切換、添加Web頁面的方法,給出了一些應用實例。
OpenWrt系統;Lua;Web界面;模式切換;MVC
基于OpenWrt系統的家用路由器作為免費WiFi以及廣告投放的解決方案,具有成本低、部署靈活的優點,被廣告商家以及大型連鎖門店以集中投放、集中管理的方式運用[1]。采用該方式需要解決以下問題:精簡配置管理界面,便于大規模投放部署;屏蔽認證頁、廣告頁投放等設置,避免路由器的經營價值受損。因此需要在路由器管理界面中設定工廠模式以及用戶模式,以便于設備的管理、調試、部署[2]。
本文首先介紹了 OpenWrt系統網頁的工作原理,然后具體介紹了如何添加用戶模式以及用戶模式和工廠模式的切換原理,接下來分析了基于 Luci編寫網頁的具體過程。文章的最后對下一步的改進工作提出展望。
1 Luci搭建網頁
要理解 Luci是如何搭建網頁的,首先就要了解 Luci、Uhttpd、CGI、MVC幾個概念。
Luci是 OpenWrt上的 Web管理界面,它提供給用戶UCI、API接口組件,用于用戶在Web界面上對路由器進行管理與設置。Luci由 Lua編寫完成,Lua是一種擴展語言,幾乎在所有操作系統和平臺上都可以編譯、運行。實際上,Lua程序的工作流程是嵌入到其他的程序中運行的[3]。
Uhttpd是OpenWrt系統路由下的一個精簡的Web服務器,它具有非常低的內存開銷,CPU占用率低,效能好,通常用于輕量級的嵌入式設備[4]。Uhttpd是 Luci默認的Web服務器,通過Web界面修改相關參數配置路由器。
CGI(Common Gateway Interface)是通用網關接口,它是外部應用程序與 Web服務器之間的接口標準[5]。CGI規定了 CGI程序和 Web服務器之間傳遞信息的規則和流程[5]。通常 Web服務器 Uhttpd的功能并沒有強大到直接運行 php、asp這樣的網頁文件,因此與第三方約定,把請求參數發送至第三方,然后接收第三方處理結果給客戶端。Lua語言編寫的 Luci就是這個第三方。
用戶端與 Web服務器 Uhttpd使用 CGI方式交互。Uhttpd服務器在工作過程中分叉出一個子進程,用于處理用戶的具體需求,然后傳遞給 Luci,并在網頁中將子進程的結果進行顯示。
Luci、Uhttpd、CGI與網頁之間的關系如圖1所示。

圖1 Luci、Uhttpd、CGI與網頁的關系圖
Luci采用 MVC(Model-View-Controller)模式搭建網頁。MVC模式把軟件系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。
(1)控制器(Controller):負責轉發和處理請求。
(2)視圖(View):設計的網頁界面。
(3)模型(Model):數據模型,是客觀事物的抽象。
使用 MVC模式的目的是實現一種動態的程序設計,使后續對程序的修改和擴展簡化,并且使程序某一部分的重復利用成為可能[6]。
Controller、View、Model三者之間的關系如圖2所示[7]。

圖2 Controller、View、Model三者之間的關系
2.1 MVC框架設計
Luci是一個單用戶框架,在/usr/lib/lua/luci/下有三個目錄,分別是model、view、controller,它們對應m、V、C[6]。公用的模塊放置在/usr/lib/lua/luci/controller/下面,各個用戶的模塊放置在該路徑下面對應的文件夾中。如路由器自帶的工廠模式就位于該目錄下的 admin文件夾下。新增用戶模式需新添加文件夾mini,然后在該路徑下添加功能程序。這樣既有效地管理了不同管理員的權限,又有利于系統的拓展和維護。Controller、Model、View生成網頁的關系如圖3所示。

圖3 Controller、Model、View生成網頁關系圖
在 controller目錄下,每個 Lua程序都以 index()作為起始函數。在 index()函數中,通過調用 entry()函數創建子節點,并把它放在全局節點樹的相應位置。entry()函數的參數規定了該節點的位置屬性。
2.2 利用控制器生成Target
Controller目錄下的子節點以 Target的方式生成網頁。Target是由每個子節點的 entry()函數創建的,這是dispatch()流程最后要執行的方法。Target主要有 alise、firstchild、call、cbi、form和 template 6種生成方式。總體上可以分成兩類,前兩種主要用于鏈接其他節點,后四種則是實現函數方法或頁面跳轉[7]。
鏈接節點:alias是網頁節點之間的鏈接。比如,當用戶登錄路由成功后,進入的網頁節點未定義內容,可以用 alias的方法,自動鏈接到有內容的 Web節點。
實現函數方法或頁面跳轉:這種方法一般用于一個路徑的葉節點 leaf,執行相應的操作,并且動態生成頁面 html文件,傳遞給用戶。在 call、cbi、form、template四種方法中,call調用了自定義的功能函數,直接調用以實現特定的目標,如發送數據、讀取文件等。調用 cbi函數能夠使用 CBI模塊簡潔高效地生成網頁。函數 template是直接鏈接到目錄view下面的 htm頁面,實現網頁跳轉。
如果要添加用戶模式(Mini),就必須在 Controller目錄下添加文件夾mini。這樣 Luci就能夠直接從 Controller目錄下讀取子節點的數目及名稱,以便生成對應的節點樹。在用戶模式的mini目錄下至少添加兩個文件。第一個是 index.lua文件,index.lua程序是為了實現用戶名、密碼的認證和網頁節點的配置。第二個是要具體實現的功能網頁,該網頁定義了生成的Target。以顯示路由系統狀態為例,需要添加 index.lua和system_state.lua文件。添加的用戶模式(Mini)文件結構如圖4所示。

圖4 用戶模式(Mini)文件結構
要說明的是,此處 system_state.lua規定是用 template的方式生成 Target,直接跳轉到 view/mini文件夾下的system_state.htm文件。
實際上,用戶模式和工廠模式都是使用 Luci搭建網頁,二者之間的原理完全相同。不同的是,在用戶模式下,給用戶顯示的是更加貼近實際使用需求的頁面。此外,使用用戶模式,關閉工廠模式的部分功能,還能使路由器更加高效地運轉。
在成功添加了用戶模式后,就要考慮登錄認證的問題。只有輸入正確的用戶名和密碼之后,才能成功登錄用戶模式。用戶模式下的所有子節點是由上而下逐層索引的,因此只要有一個節點需要認證,在該節點下的所有子節點也需要認證。只要mini節點有 sysauth值,它以下的所有子節點都需要認證才能查看、操作。
此外,OpenWrt的精簡內核是單用戶機制,路由器自動以 root用戶登錄。也就是說,工廠模式和用戶模式使用的是同一個用戶名和密碼。通過認證后,服務器端會發給用戶端一個 session值,該值以 cookie的形式存在于請求報文中,供服務器識別用戶。
2.3 Footer頁腳標簽
用戶成功登錄路由后,要求能夠在工廠模式與用戶模式之間自由切換。這個任務就由Footer頁腳標簽來完成。Footer的工作原理是由 Luci的主題決定的,主題包含兩個內容,分別是 header.htm和 footer.htm。header.htm能顯示每個頁面的菜單欄,footer.htm則會讀取 Controller目錄下的節點,最終顯示在頁腳中,以鏈接的方式切換用戶。
Footer頁腳標簽的工作原理如圖5所示。

圖5 Footer頁腳標簽的工作原理
在成功添加頁腳之后,整個添加用戶模式和模式切換的工作就完成了。結果如圖6所示,其中 footer.htm顯示在右下方,user model就是添加的用戶模式。
前面提到,為了在用戶模式下生成滿足特定功能的網頁,需要在controller/mini目錄下添加index.lua和 system_state.lua兩個文件。在 system_state.lua中,規定網頁是以 template的方式鏈接到 view/mini文件下的 system_state.htm文件。這樣只要設計 system_state.htm的內容,就可以實現對應的功能。

圖6 成功添加用戶模式
system_state.htm是將 Lua和 JavaScript兩種語言配合使用來完成相應的功能。如果編寫的功能模塊不需要訪問路由器的數據,則利用 Lua和 JavaScript可以比較輕松地實現[4]。特別地,還可以調用一些輔助性 Shell script。在網頁中,利用 Lua語言的 luci.sys.exec()函數,就可以調用shell腳本。
例如,要測試路由器與外網是否連通,可以簡單地通過 ping命令,訪問某一主流網站即可。如果 ping通,則返回值為1,否則返回0。該功能可以用shell腳本寫,在網頁中使用如下命令:
state=tonumber(luci.sys.exec("/shellfun/pingtest"))
這樣就能執行/shellfun文件夾下的 pingtest.sh Shell腳本,返回是否連通的狀態,在網頁中顯示相應的內容。
如果編寫的功能模塊需要訪問路由器的數據,這就需要一個從Lua腳本到 JavaScript腳本數據交互的過程。因為 JavaScript不太適合直接訪問路由器的數據,一般都是由Lua腳本程序讀取路由器的數據。然后,用JSON(JavaScript Object Notation)這種輕量級的數據交換格式發送給 JavaScript腳本,利用 JavaScript腳本在網頁上顯示出傳遞的數據。
例如,當要在網頁中顯示某一端口的實時流量時,需要不斷地訪問路由器的端口流量數據。可以在/luci/ controller/mini的 system_state.lua中某一節點規定,通過Lua的函數不斷地訪問數據,然后用 JSON數據格式輸出數據[5]。在 JavaScript腳本中,利用 XHR.poll()函數每隔一段時間接收JSON數據,最后將數據以圖表的方式動態顯示。
最終實現的路由器連通測試和流量監控結果如圖7所示。
本文深入地分析了路由器 Web系統 Luci搭建網頁的原理和實現細節。MVC模式是軟件工程實現網站搭建的核心,通過MVC模式,大大簡化了網站的開發和維護工作。在設計網頁的過程中,介紹了 Lua和 JavaScript如何進行數據交互,以及如何配合外部的 shell腳本實現特定功能。

圖7 路由系統狀態
目前家用路由已經支持采用 TF卡、U盤等外置存儲硬件,可以采用 Luci搭建接口實現路由器本地存儲以及內容的投放,使之具有更高的運營價值和潛力。
[1]海虎,李濤,韓俊剛,等.多態并行處理器的數據通信和路由器的設計[J].電子技術應用,2014,40(8):38-40,47.
[2]朱云雷.基于互聯與認證的無線路由器關鍵技術[J].微型機與應用,2014,33(24):57-58,65.
[3]張一弓.基于 OpenWrt平臺的進程問通信[J].科技創新與應用,2014(21):62.
[4]KIM C G,KIM K J.Implementation of a cost-effective home lighting controlsystem on embedded Linux with OpenWrt[J].Personal&Ubiquitous Computing,2014,18(3):535-542.
[5]PALAZZI C E,BRUNATIm,ROCCETTIm.An OpenWrt solution for future wireless homes[C].2010 IEEE International Conference on Multimedia and Expo,IEEE Computer Society,2010:1701-1706.
[6]吵吵博客.LuCI界面開發之CBI模塊[EB/OL].(2011-09-04)[2015-06-30]http://www.chaochaoblog.com/archives/698.
[7]吵吵博客.LuCI實現啟動應用程序等腳本命令 2011[EB/ OL].(2011-09-03)[2015-06-30]http://www.chaochaoblog.com/ archives/691.
Mode switching and Web design for OpenWrt-based routers
Cao Weihua1,Ling Qiang1,Zhang Lei1,Xu Jun1,Fan Yin2
(1.Deptartment of Automation,University of Science and Technology of China,Hefei 230027,China;2.USTC-GZ Hefei City Cloud Data Center Inc.,Hefei 230088,China)
Commercial WiFi routers have been implemented into many areas now.By providing customers with a stable free WiFi,vendors attempt to attract more customers and improve their service quality.Traditional routers provide factory mode Web interface by Luci.Users can configure routers via the supplied interface.Luci chooses the MVC pattern (Model-View-Controller)to construct web-pages,can achieve the goal of designing programs online,modifying or expanding programs very conveniently.This paper mainly focuses on the OpenWrt-based routers,introduces how to add user-mode and Web interface by using JavaScript and Lua scripting language.Moreover,the switch between the factory mode and user mode and adding Web pages are also introduced in this paper.Some examples are given.
OpenWrt system;Lua;Web interface;mode switching;MVC
TP368
A
1674-7720(2015)23-0091-04
曹為華,凌強,張雷,等.基于 OpenWrt系統路由器的模式切換與網頁設計 [J].微型機與應用,2015,34(23):91-94.
2015-08-05)
曹為華(1992-),男,碩士研究生,主要研究方向:嵌入式系統。
國家自然科學基金(61273112)
凌強(1975-),通信作者,男,博士,副教授,博士生導師,主要研究方向:網絡化控制、嵌入式系統。E-mail:qling@ustc.edu.cn。
張雷(1990-),男,碩士研究生,主要研究方向:嵌入式系統。