Skip to content

Add Baichuan.send_binary() for talk/audio streaming - #191

Closed
matthewholm wants to merge 2 commits into
starkillerOG:mainfrom
matthewholm:add-talk-binary-send
Closed

Add Baichuan.send_binary() for talk/audio streaming#191
matthewholm wants to merge 2 commits into
starkillerOG:mainfrom
matthewholm:add-talk-binary-send

Conversation

@matthewholm

Copy link
Copy Markdown

What

Adds Baichuan.send_binary(): sends an encrypted extension XML followed
by a raw, unencrypted binary payload in a single message.

Why

send() always encrypts both the extension and the body, so it can't
express the framing some Baichuan commands need — an encrypted header
immediately followed by raw binary data that must reach the camera
unencrypted. cmd_id 202 (two-way talk audio) is one of these.

Without this, a caller has to reach into private internals
(_connection, _mess_id, _aes_encrypt, receive_futures) to build
that framing by hand — which is exactly what I had to do in a downstream
Home Assistant integration adding two-way talk support for Reolink
cameras behind a Home Hub/NVR. That approach is fragile: those
attributes aren't part of the public API and can change without notice
between reolink_aio releases.

send_binary() builds the same on-wire header send() does, encrypts
only the extension, and reuses the existing connection.send() for
transmission and ack-matching — no changes to the connection layer.

Testing

Validated against a real Reolink Home Hub + battery camera over
several weeks in production use (one-shot TTS playback and live
streaming push-to-talk), via the downstream integration linked above.

CI (pylint, flake8, isort, black, mypy) passes on all four Python
versions in the test matrix.

Mathias Holm added 2 commits August 6, 2026 13:30
send() always encrypts both the extension and the body, which cannot
express the framing some commands need: an encrypted extension XML
followed by a raw, unencrypted binary payload (used by cmd_id 202,
two-way talk audio). Without this, callers have to reach into private
internals (_connection, _mess_id, _aes_encrypt, receive_futures) to
build that framing by hand, which is exactly what a downstream
integration adding talk support for Home Hub/NVR cameras had to do.

send_binary() builds the same on-wire header send() does, encrypts
only the extension, and reuses the existing connection.send() for
transmission and ack-matching -- no new connection-layer code needed.
@matthewholm

Copy link
Copy Markdown
Author

Closing in favor of #165, which implements the same underlying binary-payload framing as part of a much more complete talk API (start_talk/send_talk_data/stop_talk) with full test coverage. No need for two overlapping PRs -- I'll add my real-world validation over there instead.

@matthewholm matthewholm closed this Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant