- cause
Recently, I just finished my postgraduate entrance examination and began to have time to write articles. When reviewing, I often couldn't help tossing all kinds of things, so one day I took a fancy to the Huawei router in my hand. what? Huawei router, you may have such a question. Isn't Huawei router a self-developed chip? Just like the Huawei router I have in my hand, it is a Lingxiao chip developed by Huawei itself. It's not open to the outside world. How can I deal with it? So there is the following research process.
- Toss about what
First, what can you toss about? Like my raspberry pie, it's easy to brush an OpenWrt system. Some people may have some questions. What is the OpenWrt system? In fact, this is an open source router operating system. Many router systems are developed on this basis. This system has high playability. However, Huawei routers are not even open to firmware download, so it is not appropriate to toss the system. What about developing router plug-ins? It seems feasible, but at this time, I only know that the router plug-in can only be installed in the market dedicated to Huawei's router, and the router has been bought for several years. There are only a few plug-ins, mainly IOT home appliance control applications, but this path is theoretically feasible, so I decided to toss the router plug-in development.
- Apply for Debug version firmware
At present, as long as Huawei routers have a plug-in application market, they theoretically support router plug-in development, and many routers of other brands also support it. However, the development methods of each router are different. You can refer to the official documents. At present, I only have Huawei's router. The model is glory route Pro2. This is a router a few years ago. It has been out of the market, and the firmware is not updated. Through the documents on Huawei's official website, I send the router serial number to Huawei's contact email, wait for the router adaptation to be completed, update the firmware, and then go to the Debug version.
- Understanding plug-in systems
Huawei router runs the OpenEE development platform, and the plug-in is developed on this basis. At the same time, the router hardware provides external calling capability through OSGI interface, and the plug-in runs on the JVM. JVM? Yes, it's the JVM that we Java programmers like. The Debug version can log in to the background of the router directly with the root user, and the basic Linux commands are supported. Then I found the JVM on the router and studied it. In fact, I studied the source code of rt.jar. This JVM is an extremely simplified version. Many classes unrelated to the operation of the router have been removed, and many classes written by Huawei have been added. However, the classes most commonly used in our programming are not simplified.
Plug in development is divided into front-end and back-end. The back-end can develop API interfaces based on JVM for front-end calls. The front-end can be developed directly using any front-end technologies such as HTML. However, if you need to call the back-end API, you can only use specific functions. Finally, upload the developed application to the router to run. At the same time, the application can also be directly opened, run and unloaded in the router market.

- Run through Demo
You can operate according to the official documents. I won't post links here. If you have development needs, you can directly search the router development documents on the Huawei developer's official website or discuss with me. First, you need to prepare the development environment, jdk1 8. Maven is basically enough, and then run the official script to import several Huawei's own Jar packages into Maven's local library.
Demo project is a Maven type project. Those familiar with Java development should be familiar with it. They can develop with their favorite software. For example, I like to develop with idea. Execute mvn install to generate the corresponding Jar package, and then package it into an Apk file through the official script. Yes, it is an Apk file, but it is not the Apk on Android, but the Apk file corresponding to Huawei router. Then, the official also provides a tool for uploading applications, which can be uploaded directly.

In this way, a Hello Word application runs to the router. However, the official Demo project has no front end and can only view the corresponding output on the background console. If the front-end needs to be developed, the corresponding front-end file needs to be uploaded to the public network server and called through IP.
- Implementation of running Web server on Router
The Demo application runs through. What are you going to do next. Since the router is running JVM, there should be no problem running Web applications. Moreover, my router still has 512M memory, and there should be no problem with low load Web applications. On this basis, we can do anything we want to do, such as being a NAS server, an internal blog server, etc. of course, if you have public network conditions, you can also be used as a small blog server. Here we only discuss intranet applications. JDK1.8 originally, a simple HttpServer class was built in. Unfortunately, the router JVM streamlined this class, so I wrote the following class file.
package ml.minli.tool.util; import javax.activation.MimetypesFileTypeMap; import java.io.*; import java.net.*; public class HttpServer extends Thread { private final int port; private ServerSocket serverSocket; private static final MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap(); public HttpServer(int port) { this.port = port; } @Override public void run() { try { serverSocket = new ServerSocket(port); while (true) { Socket socket = serverSocket.accept(); HttpRequestHandler httpRequestHandler = new HttpRequestHandler(socket); httpRequestHandler.handle(); socket.close(); } } catch (Exception e) { e.printStackTrace(); } finally { if (serverSocket != null && !serverSocket.isClosed()) { try { serverSocket.close(); } catch (Exception e) { e.printStackTrace(); } } } } private static class HttpRequestHandler { private final Socket socket; public HttpRequestHandler(Socket socket) { this.socket = socket; } public void handle() { try { StringBuilder stringBuilder = new StringBuilder(); InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream()); char[] chars = new char[1024]; int mark; while ((mark = inputStreamReader.read(chars)) != -1) { stringBuilder.append(chars, 0, mark); if (mark < chars.length) { break; } } if (stringBuilder.length() == 0) { return; } //Intercept each line of request String[] lines = stringBuilder.toString().split("\r\n"); if (!lines[0].isEmpty()) { //Intercept URL String[] infos = lines[0].split(" "); String info = URLDecoder.decode(infos[1], "UTF-8"); File file; if (info.equals("/")) { file = new File(USBInfo.usbPath + "/index.html"); } else { file = new File(USBInfo.usbPath + info); } //File does not exist return 404 if (!file.exists()) { socket.getOutputStream().write(("HTTP/1.1 404 Not Found\r\n" + "Content-Type: text/html; charset=utf-8\r\n" + "\r\n").getBytes()); return; } String contentType = mimetypesFileTypeMap.getContentType(file); socket.getOutputStream().write(("HTTP/1.1 200 OK\r\n" + "Content-Type: " + contentType + "; charset=utf-8\r\n" + "\r\n").getBytes()); FileInputStream fileInputStream = new FileInputStream(file); byte[] bytes = new byte[1024]; int length; while ((length = fileInputStream.read(bytes)) != -1) { socket.getOutputStream().write(bytes, 0, length); } } } catch (Exception e) { e.printStackTrace(); } finally { if (socket != null && !socket.isClosed()) { try { socket.close(); } catch (Exception e) { e.printStackTrace(); } } } } } }
Since I am only going to implement the parsing of the static web server first, I am going to implement this: the front-end files, such as HTML, CSS and JS, are stored in the USB flash drive, and then the server parses the files and returns them, so it is much simpler. All you need to do is get the request and parse it. However, the appropriate content type is required for the return, which requires the judgment of the file type, so javax is used The activation package was originally jdk1 8 comes with it. Unfortunately, the router JVM is streamlined. However, you can package the files through the Maven plug-in.
<build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>5.1.2</version> <extensions>true</extensions> <configuration> <archive> <addMavenDescriptor>false</addMavenDescriptor> </archive> <instructions> <bundleName>{project.name}</bundleName> <bundleDescription>{project.description}</bundleDescription> <bundleVendor>minli</bundleVendor> <Bundle-Activator>ml.minli.tool.Activator</Bundle-Activator> <Service-Component>OSGI-INF/USBInfo.xml</Service-Component> <Embed-Dependency>*;scope=compile|runtime;inline=false</Embed-Dependency> </instructions> </configuration> </plugin> </plugins> </build>
Finally, it can be called in the started instance class. Here we use port 22222 for testing. It is worth noting that some ports are occupied by the router itself, so we can only use other ports.
package ml.minli.tool; import ml.minli.tool.util.HttpServer; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { public Activator() { } @Override public void start(BundleContext bundleContext) { new HttpServer(22222).start(); } @Override public void stop(BundleContext bundleContext) { } }
At the same time, we should also pay attention to the problem of permission. In many places, programs without permission will throw exceptions. The permission configuration is as follows.
(org.osgi.framework.PackagePermission "*" "import") (java.util.logging.LoggingPermission "control") (org.osgi.framework.ServicePermission "com.huawei.hilink.rest.RESTResource" "register") (java.io.FilePermission "/mnt/-" "read") (com.huawei.hilink.coreapi.perm.USBPermission "*" "list") (org.osgi.framework.ServicePermission "com.huawei.hilink.openapi.usbstorage.USBStorage" "get") (java.net.SocketPermission "*" "accept,connect,listen,resolve") (java.util.PropertyPermission "*" "read")
Finally, the function of router running Web application is successfully realized, and any Web page can be run. At the same time, if some ordinary files are accessed through URL, it is equivalent to downloading, so it seems easy to be a simple NAS server.
- follow-up
The toss came to an end at that time, because I was still preparing for the postgraduate entrance examination at that time, and I have written down these contents until the end of the postgraduate entrance examination, but now I can toss again and see what applications can be done. If there is progress, I will continue to share.