onvif_simple_server 是由开发者 roleoroleo 开发的一个轻量级 ONVIF 服务端实现,专门为资源受限的嵌入式设备(如网络摄像头)设计。它不依赖于重量级的 gSOAP 或 libxml2,而是通过 C 语言和模板技术实现。
该项目的代码结构非常清晰,按照 ONVIF 标准的服务标准(Device, Media, PTZ 等)进行了模块化划分。以下是代码库中各层次主要文件的详细作用说明:
1. 核心架构与入口
onvif_simple_server.c: 主程序入口。它作为一个 CGI 程序 运行(通常配合 Web 服务器如 lighttpd 或 busybox httpd),负责接收 HTTP POST 请求,通过环境变量(如CONTENT_LENGTH)获取 SOAP XML 数据,解析并分发到具体服务。wsd_simple_server.c: 设备发现服务 (WS-Discovery) 。这是一个独立的守护进程,监听 UDP 3702 端口,处理客户端(如 ODM 或 NVR)发送的 Probe 请求,使摄像头能在网络上被自动搜索到。onvif_notify_server.c: 事件通知服务器。处理事件订阅(PullPoint 或 Base Subscription),通过监控本地文件变化来触发并发送事件报警(如移动侦测)。
2. ONVIF 标准服务模块 (Services)
每个文件对应 ONVIF 协议的一个子服务:
device_service.c / .h: 实现Device服务。处理设备信息(制造商、序列号)、网络配置、功能列表(GetCapabilities)、系统时间等基础操作。media_service.c / .h: 实现Media (Profile S)服务。负责流媒体配置、获取视频/音频流地址(RTSP URL)以及快照地址(Snapshot URI)。media2_service.c / .h: 实现Media2 (Profile T)服务。ONVIF 较新标准的媒体服务实现,支持 H.265 等更高级的媒体配置。ptz_service.c / .h: 实现PTZ控制。处理云台的相对/绝对移动、连续移动、预置点(Presets)跳转和停止。events_service.c / .h: 实现Events服务。处理订阅管理(Subscribe, Renew, Unsubscribe)和事件拉取(PullMessages)。deviceio_service.c / .h: 实现DeviceIO服务。主要涉及继电器输出(Relay Outputs)控制。
3. 系统核心组件与工具
conf.c / .h: 负责加载和解析配置文件(通常是.conf或.json格式),将摄像头参数(如 RTSP 地址、PTZ 命令行)注入到程序中。ezxml_wrapper.c / .h: 核心 XML 解析封装。该项目使用轻量级的ezxml库配合模板匹配来解析 SOAP 报文,避免了 gSOAP 的复杂性。fault.c / .h: 定义 SOAP Fault(错误处理)。当客户端请求不支持的方法或参数错误时,构造标准的 XML 错误响应。utils.c / .h: 通用工具函数。包含字符串处理、时间格式化、网络操作等。log.c / .h: 日志系统。控制调试信息的输出级别。
4. 模板与数据文件夹 (Templates)
这些文件夹中存放的是 XML 模板文件。程序通过读取这些模板并使用占位符填充动态数据(如 IP 地址、Token 等)来生成响应:
device_service_files/,media_service_files/,ptz_service_files/等:存放对应服务的 XML 响应骨架。
5. 第三方库与构建
ezxml/: 包含 ezxml XML 解析库的源代码。extras/: 包含辅助脚本(如build.sh)以及为 lighttpd 或 busybox 准备的配置示例。Makefile/Makefile.static: 编译脚本。支持交叉编译,可以指定使用不同的加密库(Libtomcrypt, MbedTLS 或 WolfSSL)进行用户鉴权。
系统逻辑层次图
总结
- 交互层:
onvif_simple_server.c(CGI) 与wsd_simple_server.c(Discovery)。 - 业务逻辑层:以
_service.c结尾的文件,负责具体的 ONVIF 命令逻辑。 - 数据层:
ezxml_wrapper和*_files/文件夹,负责 XML 的解析与拼装。 - 适配层:
conf.c,通过配置文件将 ONVIF 指令映射为真实的系统命令(如通过system()调用摄像头的 PTZ 驱动)。