Custom Development and Feature Extension

Custom Development and Feature Extension

Creating a New OpenWRT Package

Overview:

  • An OpenWRT package is a modular unit of software that can be installed, updated, or removed using the opkg package manager.
  • Packages typically include executables, libraries, scripts, or configuration files to extend OpenWRT’s functionality.
  • Creating a package involves defining its build instructions and metadata in a structured format.

Package Structure:

  • Makefile: Defines how the package is built, installed, and packaged.
  • Files Directory: Contains configuration files, scripts, or data to be included in the package.
  • Patches: Optional patches for modifying source code.
  • Metadata: Includes package name, version, dependencies, and description.

Purpose:

  • Enables developers to add custom applications, services, or drivers to OpenWRT.
  • Integrates seamlessly with the OpenWRT build system for cross-compilation.
  • Supports distribution via package repositories for easy installation.

Key Components:

  • Source Code: Either included in the package or downloaded from a URL (e.g., GitHub, tarball).
  • Dependencies: Specified in the Makefile to ensure required libraries or tools are installed.
  • Installation Scripts: Define how files are placed in the filesystem (e.g., /usr/bin, /etc/config).

Benefits:

  • Modular design allows independent updates without rebuilding the entire firmware.
  • Community sharing through feeds and repositories.
  • Compatibility with OpenWRT’s lightweight architecture.

Makefile and Build System Integration

Overview:

  • OpenWRT’s build system uses Makefiles to compile and package software for specific architectures.
  • A package Makefile defines build rules, dependencies, and installation steps, integrating with the OpenWRT buildroot system.

Makefile Structure:

  • Package Metadata: Includes PKG_NAME, PKG_VERSION, PKG_RELEASE, and PKG_LICENSE.
  • Source Definition: Specifies source code location (e.g., PKG_SOURCE_URL, PKG_SOURCE).
  • Build Rules: Defines compilation steps using Build/Compile and Build/Install.
  • Dependencies: Lists required packages via DEPENDS and build tools via BUILD_DEPENDS.

Build System Integration:

  • Packages are placed in the /package directory of the OpenWRT source tree.
  • The build system uses make menuconfig to select packages for inclusion in the firmware.
  • Cross-compilation is handled automatically for the target architecture (e.g., ARM, MIPS).

Key Features:

  • Supports incremental builds to reduce compilation time.
  • Integrates with feeds for external package sources.
  • Ensures compatibility with OpenWRT’s toolchain (e.g., musl libc, GCC).

Benefits:

  • Simplifies package development with standardized templates.
  • Enables portability across supported devices.
  • Facilitates upstream contributions to OpenWRT’s package repository.

C Program Skeleton using UBUS and UCI APIs

Overview:

  • OpenWRT provides libubus and libuci for interacting with the UBUS interprocess communication framework and UCI configuration system.
  • A C program can use these APIs to create services, query system state, or modify configurations.

UBUS API:

  • Purpose: Enables communication with OpenWRT components (e.g., netifd, uci) via the UBUS message bus.
  • Key Functions:
    • ubus_connect: Establishes a connection to ubusd.
    • ubus_call: Invokes methods on UBUS objects (e.g., network.interface.status).
    • ubus_register_object: Registers a custom object to expose methods.
  • Use Case: Querying network status or subscribing to events like interface changes.

UCI API:

  • Purpose: Provides programmatic access to UCI configuration files (e.g., /etc/config/network).
  • Key Functions:
    • uci_alloc_context: Creates a UCI context.
    • uci_lookup_ptr: Retrieves configuration values.
    • uci_set: Modifies configuration settings.
  • Use Case: Reading or updating network or wireless settings.

Skeleton Structure:

  • Initialize libubus and connect to ubusd.
  • Register a UBUS object with methods (e.g., to expose custom functionality).
  • Use libuci to read/write UCI configurations.
  • Handle events or method calls via UBUS callbacks.

Benefits:

  • Tight integration with OpenWRT’s architecture.
  • Lightweight and efficient for embedded systems.
  • Enables dynamic system interactions (e.g., real-time configuration updates).

Adding a New Service to Procd

Overview:

  • procd is OpenWRT’s process manager and init system, responsible for starting, monitoring, and restarting services.
  • Adding a new service involves creating a script and integrating it with procd for lifecycle management.

Service Creation:

  • Init Script: Place a script in /etc/init.d/ with start, stop, and restart functions.
  • Procd Integration: Use procd utilities to define service parameters (e.g., command, respawn policy).
  • Configuration: Store service settings in UCI files (e.g., /etc/config/myservice).

Key Components:

  • Service Definition: Specify the executable, arguments, and environment via procd_set_param.
  • Watchdog: Enable procd watchdog for automatic restarts on failure.
  • UBUS Integration: Expose service status or methods via UBUS for interaction with other components.

Benefits:

  • Ensures robust service management with automatic restarts.
  • Integrates with OpenWRT’s event-driven architecture.
  • Simplifies service configuration via UCI.

Extending LuCI with a Custom Page

Overview:

  • LuCI is OpenWRT’s web interface, built using Lua and following an MVC (Model-View-Controller) architecture.
  • Extending LuCI involves adding a custom page to provide new functionality or configuration options.

Components:

  • Model: Uses UCI or UBUS to fetch system data (e.g., network status).
  • View: Lua templates or HTML for rendering the page.
  • Controller: Lua script to handle user input and interact with UCI/UBUS.

Process:

  • Create a new Lua module in /usr/lib/lua/luci/controller/.
  • Define routes to map URLs to controller functions.
  • Add templates in /usr/lib/lua/luci/view/ for the UI.
  • Integrate with UCI for configuration management.

Benefits:

  • Seamless integration with LuCI’s existing interface.
  • Enables user-friendly configuration for custom services.
  • Leverages OpenWRT’s lightweight web server (uhttpd).

Adding Configuration Parameters via UCI

Overview:

  • The Unified Configuration Interface (UCI) allows centralized management of system settings in /etc/config/ files.
  • Adding custom parameters involves defining a new UCI configuration file for a package or service.

Process:

  • Create a file in /etc/config/ (e.g., /etc/config/myservice).
  • Define sections and options (e.g., config myservice with option enabled '1').
  • Use uci CLI or libuci to read/write parameters.
  • Integrate with LuCI or UBUS for dynamic updates.

Structure:

  • Sections: Group related settings (e.g., config interface 'lan').
  • Options: Key-value pairs for settings (e.g., option proto 'dhcp').
  • Lists: Support multiple values (e.g., list dns '8.8.8.8').

Benefits:

  • Consistent configuration interface across OpenWRT.
  • Supports CLI, API, and web-based management.
  • Enables persistent and validated settings.

Debugging with Logread, GDB, and Strace

Overview:

  • OpenWRT provides tools for debugging system and application issues on resource-constrained devices.

Logread:

  • Purpose: Reads system logs from procd’s log buffer.
  • Usage: Access logs via logread CLI to diagnose service or system issues.
  • Features: Supports filtering and real-time monitoring (e.g., logread -f).

GDB:

  • Purpose: GNU Debugger for analyzing C/C++ programs.
  • Usage: Debug user-space applications or services compiled with debug symbols.
  • Limitations: Resource-intensive; requires sufficient RAM and storage.

Strace:

  • Purpose: Traces system calls and signals for a process.
  • Usage: Diagnose runtime issues by monitoring interactions with the kernel.
  • Features: Lightweight and effective for pinpointing errors in system calls.

Benefits:

  • Provides comprehensive debugging capabilities for embedded systems.
  • Integrates with OpenWRT’s lightweight architecture.
  • Enables rapid identification of issues in custom applications or services.