# Hikvision ISUP Client (Pi5 compatible) C-language **Hikvision ISUP5.0 (Ehome) device client** for **Ubuntu 24.04** and **Raspberry Pi 5 (BCM2712 / Cortex-A76 / aarch64 8GB)**. It registers the device to a platform, encapsulates an H.264 stream into **MPEG-PS** and pushes it to **ZLMediaKit via RTMP**, drives **record playback** (`NET_ESTREAM_StartListenPlayBack` + `NET_ECMS_StartPlayBack`) and ingests **alarms** (`NET_EALARM_StartListen`). Platform (from the device Web-UI screenshot used as the reference config): - 平台接入方式: ISUP(原Ehome) 协议版本: ISUP5.0 - 服务器地址: 117.131.63.98 端口: 7031 - 设备ID: AX5324540 加密密钥: abc12345 ## Architecture ``` main.c --> platform.c (CMS init / listen / register / heartbeat / logout) --> stream.c (PS packer: SYS header + PES(0xE0, PTS 90k) -> RTMP) --> playback.c (StartListenPlayBack + NET_ECMS_StartPlayBack state machine) --> alarm.c (NET_EALARM_StartListen + ring-buffer event queue) --> config.c (parse config.ini) --> portable.c (endian / monotonic clock / thread-stack layer) --> isup_stub.c (mock SDK for -DISUP_SIM build & self-test) ``` ## Directory layout ``` include/ portable.h common.h config.h platform.h stream.h playback.h alarm.h isup_sdk.h src/ portable.c config.c platform.c stream.c playback.c alarm.c main.c isup_stub.c scripts/ setup.sh build_pi5.sh git_sync.sh systemd/ hikvision-isup.service config.ini Makefile .gitignore README.md CHANGELOG.md ``` ## Build ```bash # 1) Verify on any host (no vendor SDK needed): make simulate # builds build/hikvision-isup-client--sim make test # runs the full self-test (-t) # 2) Production build (needs vendor SDK): # put aarch64 libHCNetSDK.so (+ deps) into ./libs on the Pi5 make # builds ...--real # Raspberry Pi 5 helper: ./scripts/build_pi5.sh ``` On the Pi5, `uname -m` returns `aarch64`; the Makefile auto-detects the arch and names the binary `hikvision-isup-client-aarch64-{sim,real}`. You can cross-build with `make ARCH=aarch64 CC=aarch64-linux-gnu-gcc simulate`. ## Run ```bash ./build/hikvision-isup-client-$(uname -m)-sim -c config.ini -s # demo w/o SDK ./build/hikvision-isup-client-$(uname -m)-sim -t # self-test ./build/hikvision-isup-client-$(uname -m)-real -c config.ini # production ``` ## System service (Pi5) ```bash sudo cp systemd/hikvision-isup.service /etc/systemd/system/ sudo systemctl daemon-reload && sudo systemctl enable --now hikvision-isup ``` ## PS -> RTMP push chain (screenshot-style flow) 1. device frame (H.264 Annex-B AU) -> `stream_push_frame()` 2. build MPEG-PS: `pack_system_header` (0x000001BA) + `PES` (0x000001E0, PTS in 90kHz ticks, big-endian written with `be_write*`) 3. RTMP publish `rtmp://:1935/live/ch` to ZLMediaKit (real sockets wired in production mode; counted in simulate mode) ## API quick reference | Function | Purpose | |----------|---------| | `platform_register()` | send ISUP registration (cms_ip:cms_port, device_id, license) | | `platform_heartbeat()` | keepalive, monotonic-clock gated | | `stream_simulate_loop(ch, n)` | push n synthetic frames through the PS packer | | `playback_start/pause/resume/stop` | NET_ECMS_StartPlayBack lifecycle | | `alarm_ingest(ch, type, desc)` | feed an alarm event into the queue | | `alarm_ack(id)` | acknowledge & retire an event | ## Git auto-sync (Gogs) After every change run: ```bash ./scripts/git_sync.sh # default branch: main ``` It commits everything and pushes to `https://git.zhonjin.com:40717/steven_roc/hikvision-isup-client`. The access token is embedded in the remote URL (override with `GOGS_TOKEN=...`). ## Raspberry Pi 5 notes - 64-bit Bookworm (aarch64) is the supported image; `portable.h` avoids all ILP32/`long`-width assumptions and never casts `char*` to wider types. - `char` is unsigned on ARM AAPCS: every raw byte uses `uint8_t` explicitly. - Big buffers live on the heap (not the thread stack) via `portable_thread_create`. - 8GB board: `MemoryMax=1G` in the systemd unit; raise it when adding channels. ## Troubleshooting - `cannot dlopen libHCNetSDK.so` -> use `-s`/simulate, or drop the .so in `libs/`. - PS stream shows green/garbage on ZLMediaKit -> verify your H.264 AU start codes (00 00 00 01) and that SPS/PPS precede the first IDR (this code emits SPS+IDR on keyframes every `fps` frames). - Registration never goes online -> confirm the platform's ISUP listen port and that device_id/license match the platform's whitelist. ## Security - The Gogs token is embedded in `scripts/git_sync.sh` and the git remote as requested. Rotate by exporting `GOGS_TOKEN`; keep the repo private. Do not expose `117.131.63.98` / device credentials in public logs (log level in `config.ini` controls verbosity).